From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: xfs <linux-xfs@vger.kernel.org>
Subject: [PATCH] xfs: allow zero-length symlinks (and directories), sort of
Date: Fri, 3 Mar 2017 16:05:29 -0800 [thread overview]
Message-ID: <20170304000529.GB5073@birch.djwong.org> (raw)
In commit ef388e2054 ("don't allow di_size with high bit set") and
commit 3c6f46eacd87 ("sanity check directory inode di_size") we
erroneously fail the inode verification checks for symlinks or
directories with di_size == 0.
This is proven incorrect by generic/388 because the unlink process uses
multiple unconnected transactions to truncate the remote symlink /
directory and to unlink and free the inode. If the fs goes down after
the truncate commit but before the unlink happens, we are left with a
zero-length inode. Worse yet, if the unlink /does/ commit, log recovery
will now break after the first transaction because we've zeroed di_size.
In order to prevent the crashes and ASSERTs that the old patches
covered, re-allow the zero-length inodes and change the functions that
interface with the vfs to return the appropriate error codes to
userspace.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/xfs/libxfs/xfs_inode_buf.c | 4 ----
fs/xfs/xfs_dir2_readdir.c | 6 ++----
fs/xfs/xfs_iops.c | 9 ++++++++-
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
index 3752bac..6e62999 100644
--- a/fs/xfs/libxfs/xfs_inode_buf.c
+++ b/fs/xfs/libxfs/xfs_inode_buf.c
@@ -402,10 +402,6 @@ xfs_dinode_verify(
if (mode && xfs_mode_to_ftype(mode) == XFS_DIR3_FT_UNKNOWN)
return false;
- /* No zero-length symlinks/dirs. */
- if ((S_ISLNK(mode) || S_ISDIR(mode)) && dip->di_size == 0)
- return false;
-
/* only version 3 or greater inodes are extensively verified here */
if (dip->di_version < 3)
return true;
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 0b3b636..be1367a 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -74,10 +74,8 @@ xfs_dir2_sf_getdents(
/*
* Give up if the directory is way too short.
*/
- if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
- ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
- return -EIO;
- }
+ if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent))
+ return -EFSCORRUPTED;
ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
ASSERT(dp->i_df.if_u1.if_data != NULL);
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 22c1615..b7b6807 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -457,6 +457,9 @@ xfs_vn_get_link(
char *link;
int error = -ENOMEM;
+ if (i_size_read(inode) == 0)
+ return ERR_PTR(-EFSCORRUPTED);
+
if (!dentry)
return ERR_PTR(-ECHILD);
@@ -483,8 +486,12 @@ xfs_vn_get_link_inline(
struct inode *inode,
struct delayed_call *done)
{
+ char *p;
ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE);
- return XFS_I(inode)->i_df.if_u1.if_data;
+ p = XFS_I(inode)->i_df.if_u1.if_data;
+ if (p)
+ return p;
+ return ERR_PTR(-EFSCORRUPTED);
}
STATIC int
next reply other threads:[~2017-03-04 0:06 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-04 0:05 Darrick J. Wong [this message]
2017-03-06 13:51 ` [PATCH] xfs: allow zero-length symlinks (and directories), sort of Brian Foster
2017-03-06 17:22 ` Darrick J. Wong
2017-03-06 18:18 ` Brian Foster
2017-03-06 21:47 ` Dave Chinner
2017-03-06 23:16 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170304000529.GB5073@birch.djwong.org \
--to=darrick.wong@oracle.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).