From 153d2ff9bb3c2b4013723f61ba32cb990667678b Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Wed, 12 Dec 2018 11:42:40 -0600 Subject: [PATCH] mkfs.xfs: null-terminate symlinks created via protofile Now that we have a symlink verifier which checks that in-memory symlink names are null-terminated, be sure we do that when we create them via the mkfs protofile. We only want to null-terminate inline data if it's a symlink; we only ever /call/ newfile() with "dolocal" for symlinks, so rename that function argument for clarity. Then, rather than open-coding all this, just call xfs_init_local_fork which handles it properly. Zorro found this by running xfs/019 on an s390x machine, it failed with: Metadata corruption detected at 0x101214a, inode 0x89 data fork Signed-off-by: Eric Sandeen Reported-by: Zorro Lang Reviewed-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- libxfs/libxfs_api_defs.h | 1 + mkfs/proto.c | 13 ++++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index ad5d65dea..c3792e120 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -149,5 +149,6 @@ #define xfs_dir_get_ops libxfs_dir_get_ops #define xfs_default_ifork_ops libxfs_default_ifork_ops #define xfs_fs_geometry libxfs_fs_geometry +#define xfs_init_local_fork libxfs_init_local_fork #endif /* __LIBXFS_API_DEFS_H__ */ diff --git a/mkfs/proto.c b/mkfs/proto.c index 1cd5436b9..3bba49171 100644 --- a/mkfs/proto.c +++ b/mkfs/proto.c @@ -15,7 +15,7 @@ static char *getstr(char **pp); static void fail(char *msg, int i); static struct xfs_trans * getres(struct xfs_mount *mp, uint blocks); static void rsvfile(xfs_mount_t *mp, xfs_inode_t *ip, long long len); -static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, int dolocal, int logit, +static int newfile(xfs_trans_t *tp, xfs_inode_t *ip, int symlink, int logit, char *buf, int len); static char *newregfile(char **pp, int *len); static void rtinit(xfs_mount_t *mp); @@ -220,7 +220,7 @@ static int newfile( xfs_trans_t *tp, xfs_inode_t *ip, - int dolocal, + int symlink, int logit, char *buf, int len) @@ -236,13 +236,8 @@ newfile( flags = 0; mp = ip->i_mount; - if (dolocal && len <= XFS_IFORK_DSIZE(ip)) { - libxfs_idata_realloc(ip, len, XFS_DATA_FORK); - if (buf) - memmove(ip->i_df.if_u1.if_data, buf, len); - ip->i_d.di_size = len; - ip->i_df.if_flags &= ~XFS_IFEXTENTS; - ip->i_df.if_flags |= XFS_IFINLINE; + if (symlink && len <= XFS_IFORK_DSIZE(ip)) { + libxfs_init_local_fork(ip, XFS_DATA_FORK, buf, len); ip->i_d.di_format = XFS_DINODE_FMT_LOCAL; flags = XFS_ILOG_DDATA; } else if (len > 0) { -- 2.47.2