Message ID | 1483967189-27313-2-git-send-email-amir73il@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Jan 09, 2017 at 03:06:27PM +0200, Amir Goldstein wrote: > Fix the size of the xfs_mode_to_ftype conversion table, > which was too small to handle an invalid value of mode=S_IFMT. > > Use a convenience macro S_DT(mode) to convert from > mode to dirent file type and change the name of the table > to xfs_dtype_to_ftype to correctly describe its index values. This looks like an awful lot of magic. Would a switch statement generate so much worse code? -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jan 9, 2017 at 5:51 PM, Christoph Hellwig <hch@infradead.org> wrote: > On Mon, Jan 09, 2017 at 03:06:27PM +0200, Amir Goldstein wrote: >> Fix the size of the xfs_mode_to_ftype conversion table, >> which was too small to handle an invalid value of mode=S_IFMT. >> >> Use a convenience macro S_DT(mode) to convert from >> mode to dirent file type and change the name of the table >> to xfs_dtype_to_ftype to correctly describe its index values. > > This looks like an awful lot of magic. Would a switch statement > generate so much worse code? I doubt it really matters that much, so it's down to a matter of taste. I personally like the existing map table better than switch if anyone cares ;-) but I think that the strongest argument in favor of the existing code is that it works, so no reason to change it. IMHO, this minor fix and cleanup do not justify switching the code over to switch statement. -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jan 09, 2017 at 07:21:25PM +0200, Amir Goldstein wrote: > On Mon, Jan 9, 2017 at 5:51 PM, Christoph Hellwig <hch@infradead.org> wrote: > > On Mon, Jan 09, 2017 at 03:06:27PM +0200, Amir Goldstein wrote: > >> Fix the size of the xfs_mode_to_ftype conversion table, > >> which was too small to handle an invalid value of mode=S_IFMT. > >> > >> Use a convenience macro S_DT(mode) to convert from > >> mode to dirent file type and change the name of the table > >> to xfs_dtype_to_ftype to correctly describe its index values. > > > > This looks like an awful lot of magic. Would a switch statement > > generate so much worse code? > > I doubt it really matters that much, so it's down to a matter of taste. > I personally like the existing map table better than switch if anyone cares ;-) > but I think that the strongest argument in favor of the existing code > is that it works, so no reason to change it. > IMHO, this minor fix and cleanup do not justify switching the code over to > switch statement. I can't feed a garbage index to a switch statement and have it fly off the end of an array; plus we can throw asserts in a default: case. --D > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Jan 9, 2017 at 11:17 PM, Darrick J. Wong <darrick.wong@oracle.com> wrote: > On Mon, Jan 09, 2017 at 07:21:25PM +0200, Amir Goldstein wrote: >> On Mon, Jan 9, 2017 at 5:51 PM, Christoph Hellwig <hch@infradead.org> wrote: >> > On Mon, Jan 09, 2017 at 03:06:27PM +0200, Amir Goldstein wrote: >> >> Fix the size of the xfs_mode_to_ftype conversion table, >> >> which was too small to handle an invalid value of mode=S_IFMT. >> >> >> >> Use a convenience macro S_DT(mode) to convert from >> >> mode to dirent file type and change the name of the table >> >> to xfs_dtype_to_ftype to correctly describe its index values. >> > >> > This looks like an awful lot of magic. Would a switch statement >> > generate so much worse code? >> >> I doubt it really matters that much, so it's down to a matter of taste. >> I personally like the existing map table better than switch if anyone cares ;-) >> but I think that the strongest argument in favor of the existing code >> is that it works, so no reason to change it. >> IMHO, this minor fix and cleanup do not justify switching the code over to >> switch statement. > > I can't feed a garbage index to a switch statement and have it fly > off the end of an array; plus we can throw asserts in a default: case. > I think we are in agreement that ASSERT for malformed on-disk data is a bad idea, as patch 2 demonstrates, and that we are better off returning -EFSCORRUPTED is such cases. OK, so just that we are all clear on what I think you are suggesting: 1. retire xfs_mode_to_ftype[] table 2. create helper xfs_mode_to_ftype() that uses a switch statement and returns XFS_DIR3_FT_UNKNOWN for invalid modes 3. change xfs_dentry_to_name() to return -EFSCORRUPTED for unknown ftype and check return value on call sites where mode come from disk (e.g. xfs_generic_create(), xfs_vn_link(), xfs_vn_rename()) 4. convert call sites xfs_dentry_to_name(n,d,0) (e.g. xfs_cleanup_inode()) to use a helper xfs_dentry_to_name_unknown(n,d) which sets ftype to unknown instead of calling xfs_mode_to_ftype() 5. in xfs_dinode_verify(), sanity check that di_mode is a valid ftype Should I cook this patch? Amir. -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index c58d72c..48d7c45 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -41,15 +41,15 @@ struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; * for file type specification. This will be propagated into the directory * structure if appropriate for the given operation and filesystem config. */ -const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = { - [0] = XFS_DIR3_FT_UNKNOWN, - [S_IFREG >> S_SHIFT] = XFS_DIR3_FT_REG_FILE, - [S_IFDIR >> S_SHIFT] = XFS_DIR3_FT_DIR, - [S_IFCHR >> S_SHIFT] = XFS_DIR3_FT_CHRDEV, - [S_IFBLK >> S_SHIFT] = XFS_DIR3_FT_BLKDEV, - [S_IFIFO >> S_SHIFT] = XFS_DIR3_FT_FIFO, - [S_IFSOCK >> S_SHIFT] = XFS_DIR3_FT_SOCK, - [S_IFLNK >> S_SHIFT] = XFS_DIR3_FT_SYMLINK, +const unsigned char xfs_dtype_to_ftype[S_DT_MAX+1] = { + [0] = XFS_DIR3_FT_UNKNOWN, + [S_DT(S_IFREG)] = XFS_DIR3_FT_REG_FILE, + [S_DT(S_IFDIR)] = XFS_DIR3_FT_DIR, + [S_DT(S_IFCHR)] = XFS_DIR3_FT_CHRDEV, + [S_DT(S_IFBLK)] = XFS_DIR3_FT_BLKDEV, + [S_DT(S_IFIFO)] = XFS_DIR3_FT_FIFO, + [S_DT(S_IFSOCK)] = XFS_DIR3_FT_SOCK, + [S_DT(S_IFLNK)] = XFS_DIR3_FT_SYMLINK, }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.h b/fs/xfs/libxfs/xfs_dir2.h index 0197590..4934d38 100644 --- a/fs/xfs/libxfs/xfs_dir2.h +++ b/fs/xfs/libxfs/xfs_dir2.h @@ -35,7 +35,9 @@ extern struct xfs_name xfs_name_dotdot; * directory filetype conversion tables. */ #define S_SHIFT 12 -extern const unsigned char xfs_mode_to_ftype[]; +#define S_DT(mode) (((mode) & S_IFMT) >> S_SHIFT) +#define S_DT_MAX S_DT(S_IFMT) +extern const unsigned char xfs_dtype_to_ftype[]; /* * directory operations vector for encode/decode routines diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 308bebb..d2da9ca 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -103,7 +103,7 @@ xfs_dentry_to_name( { namep->name = dentry->d_name.name; namep->len = dentry->d_name.len; - namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT]; + namep->type = xfs_dtype_to_ftype[S_DT(mode)]; } STATIC void