From patchwork Wed May 22 06:01:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13670437 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9AA555221 for ; Wed, 22 May 2024 06:01:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357706; cv=none; b=rOylU+O9dhDEHY4l4WZ/LJSRyppuIvRlbiw3+KnimubR+6WKLelfemzFsw9CD3jkCC8VYDCffc7/OJ5HyGUdwZRkK3u9XxLtgVIybfZo8fux9DJYSUr6pr4Rv+8TKu6XsEO+gzNMurAHiGdTssSuW3hRKDvFpkJeU1WkEw2/e/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357706; c=relaxed/simple; bh=lamjiOdMSc1c4l6TdLyUBxzaTEMTZByTgH/gJvqxIpQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MnTUwIF9CT8JAn/eDz4MZFDCZUy3POzgrMq6RCo4hfBjHBu+48XeL99QauNbgodA/iB/T95LtRidKS5Zi8rW/4e/KiVlDx9SYBiT1oLx8V0H34ESRguRvDOtK8XjCcvt4vTG/PwHmc2CelkAbQRCj5GxXnERFlrXmIs2cIFOgTU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n9xY1LNy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n9xY1LNy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0F060C2BD11; Wed, 22 May 2024 06:01:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716357706; bh=lamjiOdMSc1c4l6TdLyUBxzaTEMTZByTgH/gJvqxIpQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=n9xY1LNyK6TLAjOOpmnyqBlPouh3Kr7alTN6am5JoOujtCnn4V6prtjk1vtXruDPv ZrPD4DQepDdo0LIP/Axdmpli5v5dNCBsTqkzEw01gW2M9I3GxH0KKc2iAK17ILtjSq VO03r5qRxwjt0Su4FBSmI0Z8nedlmlMMlCkNxD5X60YirkZc9m9AkwnvDkCZokc+KY vdbAntRI4dF0i97Y+QMf2TemAKOtTiiLrcI84phBbyx9k5v/w8e6I9l+zew7XQIXa9 fgVtCYrID6XJLAJcPquFGlpJNFFIUiBfNXRJOi9c3q1T92GG7RjDIwcjRubIo3F4xd niDwmyMhVE3zg== Date: Tue, 21 May 2024 23:01:45 -0700 Subject: [PATCH 1/4] xfs: drop xfarray sortinfo folio on error From: "Darrick J. Wong" To: djwong@kernel.org, chandanbabu@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <171635763387.2619960.8422112844689648321.stgit@frogsfrogsfrogs> In-Reply-To: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> References: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Chandan Babu reports the following livelock in xfs/708: run fstests xfs/708 at 2024-05-04 15:35:29 XFS (loop16): EXPERIMENTAL online scrub feature in use. Use at your own risk! XFS (loop5): Mounting V5 Filesystem e96086f0-a2f9-4424-a1d5-c75d53d823be XFS (loop5): Ending clean mount XFS (loop5): Quotacheck needed: Please wait. XFS (loop5): Quotacheck: Done. XFS (loop5): EXPERIMENTAL online scrub feature in use. Use at your own risk! INFO: task xfs_io:143725 blocked for more than 122 seconds. Not tainted 6.9.0-rc4+ #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:xfs_io state:D stack:0 pid:143725 tgid:143725 ppid:117661 flags:0x00004006 Call Trace: __schedule+0x69c/0x17a0 schedule+0x74/0x1b0 io_schedule+0xc4/0x140 folio_wait_bit_common+0x254/0x650 shmem_undo_range+0x9d5/0xb40 shmem_evict_inode+0x322/0x8f0 evict+0x24e/0x560 __dentry_kill+0x17d/0x4d0 dput+0x263/0x430 __fput+0x2fc/0xaa0 task_work_run+0x132/0x210 get_signal+0x1a8/0x1910 arch_do_signal_or_restart+0x7b/0x2f0 syscall_exit_to_user_mode+0x1c2/0x200 do_syscall_64+0x72/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e The shmem code is trying to drop all the folios attached to a shmem file and gets stuck on a locked folio after a bnobt repair. It looks like the process has a signal pending, so I started looking for places where we lock an xfile folio and then deal with a fatal signal. I found a bug in xfarray_sort_scan via code inspection. This function is called to set up the scanning phase of a quicksort operation, which may involve grabbing a locked xfile folio. If we exit the function with an error code, the caller does not call xfarray_sort_scan_done to put the xfile folio. If _sort_scan returns an error code while si->folio is set, we leak the reference and never unlock the folio. Therefore, change xfarray_sort to call _scan_done on exit. This is safe to call multiple times because it sets si->folio to NULL and ignores a NULL si->folio. Also change _sort_scan to use an intermediate variable so that we never pollute si->folio with an errptr. Fixes: 232ea052775f9 ("xfs: enable sorting of xfile-backed arrays") Reported-by: Chandan Babu R Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/scrub/xfarray.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c index 9185ae7088d4..cdd13ed9c569 100644 --- a/fs/xfs/scrub/xfarray.c +++ b/fs/xfs/scrub/xfarray.c @@ -822,12 +822,14 @@ xfarray_sort_scan( /* Grab the first folio that backs this array element. */ if (!si->folio) { + struct folio *folio; loff_t next_pos; - si->folio = xfile_get_folio(si->array->xfile, idx_pos, + folio = xfile_get_folio(si->array->xfile, idx_pos, si->array->obj_size, XFILE_ALLOC); - if (IS_ERR(si->folio)) - return PTR_ERR(si->folio); + if (IS_ERR(folio)) + return PTR_ERR(folio); + si->folio = folio; si->first_folio_idx = xfarray_idx(si->array, folio_pos(si->folio) + si->array->obj_size - 1); @@ -1048,6 +1050,7 @@ xfarray_sort( out_free: trace_xfarray_sort_stats(si, error); + xfarray_sort_scan_done(si); kvfree(si); return error; } From patchwork Wed May 22 06:02:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13670438 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA841360 for ; Wed, 22 May 2024 06:02:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357722; cv=none; b=UXDBEJVL9f1Fps1iJ6E1HB61sVd5piV5mV7MhrSuHrN/Y1OavaZVtSZ4E5LI3Il0yT/2lVmmaKm7ipzSGqo/AIJwuQjXaOwnVu6qxEJuYU7JQdrVW6KC47bMKfNTiDWC/6YeGYGiQt/0G4q3gwN9W0jWwi6MYiY6DfNB5IxLTRA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357722; c=relaxed/simple; bh=xGe4M8S8Qlh/VUZx31qzxQ+K1T8w++ur7J6Sdq0JGT0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZH+zKkc791Yk9M+4uaTek2AzGxlnP9NOCXnSJh9hNDS8BbyOV9iWsiKAZGJxaovYfTeudxI8G07Lyorf4qv+RcpQ16+sMGzQ0Z/979hwzAe5X6gR1gG4kI+YzmwADbr9Ewk+iuF3PxF7av0ZFx8mpSr0C9NgAqbLXxWkIyDrQXU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c8joWjo/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c8joWjo/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA1DCC2BD11; Wed, 22 May 2024 06:02:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716357721; bh=xGe4M8S8Qlh/VUZx31qzxQ+K1T8w++ur7J6Sdq0JGT0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=c8joWjo/jhhGt8u2SWAlypTr4/VDS/drEgegZUGLCvw7tMIKHpfVhuiU4mohNPOuo raCbfHt3ls4JpZT5sqHUV0T4Q0TNxdn32gMY7L5x/M5bINR0YTSXM4712Fj9A+uxdI lMjdCDgNypTJJPKaP+PMAmVR/Q9+fkivtdDuH2Rm7p1iAeU4ytbAGmMBwD5PulVJo4 8ZL1ADO6mwLDgavPaisLDoFC5H3XCF8aL2k6t1SVpRiOjMghVq0u8r1+fJWv7nTVdy bSURyfj0npu4bnlk7u6z/mE5wcm5pNF+g6tA89RfuNGEIxYlYuro1V60dUQHoCkQN0 M9SOH5H1KpTIA== Date: Tue, 21 May 2024 23:02:01 -0700 Subject: [PATCH 2/4] xfs: fix xfs_init_attr_trans not handling explicit operation codes From: "Darrick J. Wong" To: djwong@kernel.org, chandanbabu@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <171635763404.2619960.15369274752922556657.stgit@frogsfrogsfrogs> In-Reply-To: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> References: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong When we were converting the attr code to use an explicit operation code instead of keying off of attr->value being null, we forgot to change the code that initializes the transaction reservation. Split the function into two helpers that handle the !remove and remove cases, then fix both callsites to handle this correctly. Fixes: c27411d4c640 ("xfs: make attr removal an explicit operation") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_attr.c | 38 ++++++++++++++++++-------------------- fs/xfs/libxfs/xfs_attr.h | 3 +-- fs/xfs/xfs_attr_item.c | 17 +++++++++++++++-- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 430cd3244c14..f30bcc64100d 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -329,26 +329,20 @@ xfs_attr_calc_size( return nblks; } -/* Initialize transaction reservation for attr operations */ -void -xfs_init_attr_trans( - struct xfs_da_args *args, - struct xfs_trans_res *tres, - unsigned int *total) +/* Initialize transaction reservation for an xattr set/replace/upsert */ +inline struct xfs_trans_res +xfs_attr_set_resv( + const struct xfs_da_args *args) { - struct xfs_mount *mp = args->dp->i_mount; + struct xfs_mount *mp = args->dp->i_mount; + struct xfs_trans_res ret = { + .tr_logres = M_RES(mp)->tr_attrsetm.tr_logres + + M_RES(mp)->tr_attrsetrt.tr_logres * args->total, + .tr_logcount = XFS_ATTRSET_LOG_COUNT, + .tr_logflags = XFS_TRANS_PERM_LOG_RES, + }; - if (args->value) { - tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres + - M_RES(mp)->tr_attrsetrt.tr_logres * - args->total; - tres->tr_logcount = XFS_ATTRSET_LOG_COUNT; - tres->tr_logflags = XFS_TRANS_PERM_LOG_RES; - *total = args->total; - } else { - *tres = M_RES(mp)->tr_attrrm; - *total = XFS_ATTRRM_SPACE_RES(mp); - } + return ret; } /* @@ -1006,7 +1000,7 @@ xfs_attr_set( struct xfs_trans_res tres; int error, local; int rmt_blks = 0; - unsigned int total; + unsigned int total = 0; ASSERT(!args->trans); @@ -1033,10 +1027,15 @@ xfs_attr_set( if (!local) rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen); + + tres = xfs_attr_set_resv(args); + total = args->total; break; case XFS_ATTRUPDATE_REMOVE: XFS_STATS_INC(mp, xs_attr_remove); rmt_blks = xfs_attr3_max_rmt_blocks(mp); + tres = M_RES(mp)->tr_attrrm; + total = XFS_ATTRRM_SPACE_RES(mp); break; } @@ -1044,7 +1043,6 @@ xfs_attr_set( * Root fork attributes can use reserved data blocks for this * operation if necessary */ - xfs_init_attr_trans(args, &tres, &total); error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 088cb7b30168..0e51d0723f9a 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -565,8 +565,7 @@ bool xfs_attr_check_namespace(unsigned int attr_flags); bool xfs_attr_namecheck(unsigned int attr_flags, const void *name, size_t length); int xfs_attr_calc_size(struct xfs_da_args *args, int *local); -void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres, - unsigned int *total); +struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args); /* * Check to see if the attr should be upgraded from non-existent or shortform to diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 2b10ac4c5fce..f683b7a9323f 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -746,7 +746,7 @@ xfs_attr_recover_work( struct xfs_attri_log_format *attrp; struct xfs_attri_log_nameval *nv = attrip->attri_nameval; int error; - int total; + unsigned int total = 0; /* * First check the validity of the attr described by the ATTRI. If any @@ -763,7 +763,20 @@ xfs_attr_recover_work( return PTR_ERR(attr); args = attr->xattri_da_args; - xfs_init_attr_trans(args, &resv, &total); + switch (xfs_attr_intent_op(attr)) { + case XFS_ATTRI_OP_FLAGS_PPTR_SET: + case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE: + case XFS_ATTRI_OP_FLAGS_SET: + case XFS_ATTRI_OP_FLAGS_REPLACE: + resv = xfs_attr_set_resv(args); + total = args->total; + break; + case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE: + case XFS_ATTRI_OP_FLAGS_REMOVE: + resv = M_RES(mp)->tr_attrrm; + total = XFS_ATTRRM_SPACE_RES(mp); + break; + } resv = xlog_recover_resv(&resv); error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp); if (error) From patchwork Wed May 22 06:02:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13670439 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDAAB1C6B4 for ; Wed, 22 May 2024 06:02:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357738; cv=none; b=HFCuzJZzTIOwRbjnKx1kWWX8HfWul/QBskKES9QpgiTDvwbrxUN3HbYcJjb0aVc7PE3B8DXl87Mru1T5gRsGfTM6ItA+9O1evtddF7pUzLB9Tyd0yCWKTTNx8DqLA8uCGPfilnVQ7GZjIqnJ98jsG3EISVq4T53FA4bESqabWCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357738; c=relaxed/simple; bh=2t+w6r9L+RBAjIqAG5fVT1On6eMsHHgbG5Wr35+Qq/s=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=a/gHgZCcslr/956Gc3Mz9YKY33FFj2tk2KoVhgwyCJsbv1hE1/5f4mJ1GBaWL1+5DKgulJEGNYijCKhG+dLcX45Y8sYszJ9QMgYe7brr61bErgNSBGIlRlpyTYa2+anGlZ3camnA0c9xci8fsHzEICxcTKfJ14gx6lg+Eykl4tk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=etNW1Ca4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="etNW1Ca4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F268C2BD11; Wed, 22 May 2024 06:02:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716357737; bh=2t+w6r9L+RBAjIqAG5fVT1On6eMsHHgbG5Wr35+Qq/s=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=etNW1Ca4np2RNWrqdmW3Y2iF9HabDiUVZyxoLUBwYBwAWKrrEuO9YIubYs+4AnTED P9ST2I/2an598XjXMuv5GhvIBNGMaEjHzSp+f/iUaDjnX/rYQd5VAgDu8bmmP5ou1Y mliN+OHbh0WAemfzGtSe3k4xGB1+1XmVHnLJNWqKwMB0HaJxQ4SG2077UARjyhzqjs 05KKHH8Aq/VPGbo9ELq2dhYf1OeuLq3MN1Z71G7VRQsH+LPqh3/pF8KPiTlBplW3x2 /j4tvDde4w5rqIH5kVCc2xzKDZfOD713by4BkprO9nZA0bnQDb+5AqW4M84xz9C56F hj7RybuUPsA2A== Date: Tue, 21 May 2024 23:02:16 -0700 Subject: [PATCH 3/4] xfs: allow symlinks with short remote targets From: "Darrick J. Wong" To: djwong@kernel.org, chandanbabu@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <171635763423.2619960.122476714020756620.stgit@frogsfrogsfrogs> In-Reply-To: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> References: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong An internal user complained about log recovery failing on a symlink ("Bad dinode after recovery") with the following (excerpted) format: core.magic = 0x494e core.mode = 0120777 core.version = 3 core.format = 2 (extents) core.nlinkv2 = 1 core.nextents = 1 core.size = 297 core.nblocks = 1 core.naextents = 0 core.forkoff = 0 core.aformat = 2 (extents) u3.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,12,1,0] This is a symbolic link with a 297-byte target stored in a disk block, which is to say this is a symlink with a remote target. The forkoff is 0, which is to say that there's 512 - 176 == 336 bytes in the inode core to store the data fork. Eventually, testing of generic/388 failed with the same inode corruption message during inode recovery. In writing a debugging patch to call xfs_dinode_verify on dirty inode log items when we're committing transactions, I observed that xfs/298 can reproduce the problem quite quickly. xfs/298 creates a symbolic link, adds some extended attributes, then deletes them all. The test failure occurs when the final removexattr also deletes the attr fork because that does not convert the remote symlink back into a shortform symlink. That is how we trip this test. The only reason why xfs/298 only triggers with the debug patch added is that it deletes the symlink, so the final iflush shows the inode as free. I wrote a quick fstest to emulate the behavior of xfs/298, except that it leaves the symlinks on the filesystem after inducing the "corrupt" state. Kernels going back at least as far as 4.18 have written out symlink inodes in this manner and prior to 1eb70f54c445f they did not object to reading them back in. Because we've been writing out inodes this way for quite some time, the only way to fix this is to relax the check for symbolic links. Directories don't have this problem because di_size is bumped to blocksize during the sf->data conversion. Fixes: 1eb70f54c445f ("xfs: validate inode fork size against fork format") Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_inode_buf.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index d79002343d0b..e7a7bfbe75b4 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -374,17 +374,37 @@ xfs_dinode_verify_fork( /* * For fork types that can contain local data, check that the fork * format matches the size of local data contained within the fork. - * - * For all types, check that when the size says the should be in extent - * or btree format, the inode isn't claiming it is in local format. */ if (whichfork == XFS_DATA_FORK) { - if (S_ISDIR(mode) || S_ISLNK(mode)) { + /* + * A directory small enough to fit in the inode must be stored + * in local format. The directory sf <-> extents conversion + * code updates the directory size accordingly. + */ + if (S_ISDIR(mode)) { if (be64_to_cpu(dip->di_size) <= fork_size && fork_format != XFS_DINODE_FMT_LOCAL) return __this_address; } + /* + * A symlink with a target small enough to fit in the inode can + * be stored in extents format if xattrs were added (thus + * converting the data fork from shortform to remote format) + * and then removed. + */ + if (S_ISLNK(mode)) { + if (be64_to_cpu(dip->di_size) <= fork_size && + fork_format != XFS_DINODE_FMT_EXTENTS && + fork_format != XFS_DINODE_FMT_LOCAL) + return __this_address; + } + + /* + * For all types, check that when the size says the fork should + * be in extent or btree format, the inode isn't claiming to be + * in local format. + */ if (be64_to_cpu(dip->di_size) > fork_size && fork_format == XFS_DINODE_FMT_LOCAL) return __this_address; From patchwork Wed May 22 06:02:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13670440 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62CEE5221 for ; Wed, 22 May 2024 06:02:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357753; cv=none; b=ArPp+soi3cf0CHmSu6D0CypO6jXQoDdyYx5QkoqHeyt8i75vfAZqS2OIyS+AWaao/dD2+geZ16UdsUmYDAQxgmxk0Ii+W+y5/QLzmjh7eGt6+0uydE/6hkCd0+lEOpe0N8vXPa8go43oB7C0mCoLpaJs2N+dYnXshmZEk3TXS/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716357753; c=relaxed/simple; bh=Z/4l+7M/FKbkMknz6DHB4UNWMnwpKh3UbqiktjL6Zfk=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=g7kZSR1VklMg3gCW2kOIIsGIV3UEmqXr2KpB6LcnDUAekA5Oc+BHKLyZ0JbmUuGNAZUwQ5eCWGIQ56S6R6LoPoXaz0AJu90FwQBsq1N62DhiIlH6Sjf6l/2A4aE0E53XqKWLUuJBwSC5OygPqf6rqB5VrnCYII6FWVfzVVMTo0Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PeNgZvzy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PeNgZvzy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 300A7C2BD11; Wed, 22 May 2024 06:02:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1716357753; bh=Z/4l+7M/FKbkMknz6DHB4UNWMnwpKh3UbqiktjL6Zfk=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=PeNgZvzy3xxO28heAICAq8o/05MiEjODyOfQTVSrI9Jcg6sB1+UtQh7AduYECdTln R7DfYD7RtVd/ss9tej4TVx3E45BMeUx2Euoe/Sbd757SYASILgvCiqHkbRPW9euuyn 4F+TrGMlaSd0I8PpKz/CrZf3wYEd9iTQPfr2lZrLy6ifI90B/2Wyw0wcg+4mCM1Iv3 sGbJdAB4tpMVhmjH7a2Q6uIBCz5UA986ba+LaMt8maFDFYi2wPHeOOSw0vc6e66p/L KWcELSdexzN83gxOj61V8JKcZzhfCsL7fWICUW5M/6DTv9pUVJmT6M73v+7ogYx381 8dUQdRrJ9PDxg== Date: Tue, 21 May 2024 23:02:32 -0700 Subject: [PATCH 4/4] xfs: don't open-code u64_to_user_ptr From: "Darrick J. Wong" To: djwong@kernel.org, chandanbabu@kernel.org Cc: Christoph Hellwig , hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <171635763440.2619960.14439661076356669914.stgit@frogsfrogsfrogs> In-Reply-To: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> References: <171635763360.2619960.2969937208358016010.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Don't open-code what the kernel already provides. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/scrub/scrub.c | 2 +- fs/xfs/xfs_handle.c | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index c013f0ba4f36..4cbcf7a86dbe 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -856,7 +856,7 @@ xfs_ioc_scrubv_metadata( if (vec_bytes > PAGE_SIZE) return -ENOMEM; - uvectors = (void __user *)(uintptr_t)head.svh_vectors; + uvectors = u64_to_user_ptr(head.svh_vectors); vectors = memdup_user(uvectors, vec_bytes); if (IS_ERR(vectors)) return PTR_ERR(vectors); diff --git a/fs/xfs/xfs_handle.c b/fs/xfs/xfs_handle.c index c8785ed59543..a3f16e9b6fe5 100644 --- a/fs/xfs/xfs_handle.c +++ b/fs/xfs/xfs_handle.c @@ -773,11 +773,6 @@ xfs_getparents_expand_lastrec( trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr); } -static inline void __user *u64_to_uptr(u64 val) -{ - return (void __user *)(uintptr_t)val; -} - /* Retrieve the parent pointers for a given inode. */ STATIC int xfs_getparents( @@ -862,7 +857,7 @@ xfs_getparents( ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize); /* Copy the records to userspace. */ - if (copy_to_user(u64_to_uptr(gpx->gph.gph_request.gp_buffer), + if (copy_to_user(u64_to_user_ptr(gpx->gph.gph_request.gp_buffer), gpx->krecords, gpx->context.firstu)) error = -EFAULT;