From: Nathan Scott Date: Fri, 11 Nov 2005 14:22:25 +0000 (+0000) Subject: Implement the di_extsize allocator hint for non-realtime files as well. Also provide... X-Git-Tag: v2.8.0~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae541a2b3f44d7d61483a731b9464dc657d2c3ee;p=thirdparty%2Fxfsprogs-dev.git Implement the di_extsize allocator hint for non-realtime files as well. Also provides a mechanism for inheriting this property from the parent directory for new files. Merge of master-melb:xfs-cmds:24368a by kenmcd. --- diff --git a/db/inode.c b/db/inode.c index 85cbc136d..cbaffb293 100644 --- a/db/inode.c +++ b/db/inode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -146,6 +146,12 @@ const field_t inode_core_flds[] = { { "nosymlinks", FLDT_UINT1, OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_NOSYMLINKS_BIT-1), C1, 0, TYP_NONE }, + { "extsz", FLDT_UINT1, + OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_EXTSIZE_BIT-1),C1, + 0, TYP_NONE }, + { "extszinherit", FLDT_UINT1, + OI(COFF(flags) + bitsz(__uint16_t) - XFS_DIFLAG_EXTSZINHERIT_BIT-1),C1, + 0, TYP_NONE }, { "gen", FLDT_UINT32D, OI(COFF(gen)), C1, 0, TYP_NONE }, { NULL } }; diff --git a/include/xfs_dinode.h b/include/xfs_dinode.h index 62ab87c41..79d0d9e1f 100644 --- a/include/xfs_dinode.h +++ b/include/xfs_dinode.h @@ -253,8 +253,10 @@ typedef enum xfs_dinode_fmt #define XFS_DIFLAG_NOATIME_BIT 6 /* do not update atime */ #define XFS_DIFLAG_NODUMP_BIT 7 /* do not dump */ #define XFS_DIFLAG_RTINHERIT_BIT 8 /* create with realtime bit set */ -#define XFS_DIFLAG_PROJINHERIT_BIT 9 /* create with parents projid */ -#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ +#define XFS_DIFLAG_PROJINHERIT_BIT 9 /* create with parents projid */ +#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ +#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ +#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) @@ -266,11 +268,14 @@ typedef enum xfs_dinode_fmt #define XFS_DIFLAG_RTINHERIT (1 << XFS_DIFLAG_RTINHERIT_BIT) #define XFS_DIFLAG_PROJINHERIT (1 << XFS_DIFLAG_PROJINHERIT_BIT) #define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) +#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) +#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) #define XFS_DIFLAG_ANY \ (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ - XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS) + XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ + XFS_DIFLAG_EXTSZINHERIT) #endif /* __XFS_DINODE_H__ */ diff --git a/include/xfs_fs.h b/include/xfs_fs.h index cced90441..14010f1fa 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -65,6 +65,8 @@ struct fsxattr { #define XFS_XFLAG_RTINHERIT 0x00000100 /* create with rt bit set */ #define XFS_XFLAG_PROJINHERIT 0x00000200 /* create with parents projid */ #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ +#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ +#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* diff --git a/io/attr.c b/io/attr.c index 8854256e6..9c9d7bf70 100644 --- a/io/attr.c +++ b/io/attr.c @@ -43,25 +43,26 @@ static unsigned int andflags; unsigned int recurse_all; unsigned int recurse_dir; -#define CHATTR_XFLAG_LIST "riasAdtPn" - static struct xflags { uint flag; char *shortname; char *longname; } xflags[] = { - { XFS_XFLAG_REALTIME, "r", "realtime" }, - { XFS_XFLAG_PREALLOC, "p", "prealloc" }, - { XFS_XFLAG_IMMUTABLE, "i", "immutable" }, - { XFS_XFLAG_APPEND, "a", "append-only" }, - { XFS_XFLAG_SYNC, "s", "sync" }, - { XFS_XFLAG_NOATIME, "A", "no-atime" }, - { XFS_XFLAG_NODUMP, "d", "no-dump" }, - { XFS_XFLAG_RTINHERIT, "t", "rt-inherit" }, - { XFS_XFLAG_PROJINHERIT,"P", "proj-inherit" }, - { XFS_XFLAG_NOSYMLINKS, "n", "nosymlinks" }, + { XFS_XFLAG_REALTIME, "r", "realtime" }, + { XFS_XFLAG_PREALLOC, "p", "prealloc" }, + { XFS_XFLAG_IMMUTABLE, "i", "immutable" }, + { XFS_XFLAG_APPEND, "a", "append-only" }, + { XFS_XFLAG_SYNC, "s", "sync" }, + { XFS_XFLAG_NOATIME, "A", "no-atime" }, + { XFS_XFLAG_NODUMP, "d", "no-dump" }, + { XFS_XFLAG_RTINHERIT, "t", "rt-inherit" }, + { XFS_XFLAG_PROJINHERIT, "P", "proj-inherit" }, + { XFS_XFLAG_NOSYMLINKS, "n", "nosymlinks" }, + { XFS_XFLAG_EXTSIZE, "e", "extsize" }, + { XFS_XFLAG_EXTSZINHERIT, "E", "extsz-inherit" }, { 0, NULL, NULL } }; +#define CHATTR_XFLAG_LIST "r"/*p*/"iasAdtPneE" static void lsattr_help(void) @@ -81,6 +82,8 @@ lsattr_help(void) " t -- child created in this directory has realtime bit set by default\n" " P -- child created in this directory has parents project ID by default\n" " n -- symbolic links cannot be created in this directory\n" +" e -- for non-realtime files, observe the inode extent size value\n" +" E -- children created in this directory inherit the extent size value\n" "\n" " Options:\n" " -R -- recursively descend (useful when current file is a directory)\n" @@ -112,6 +115,8 @@ chattr_help(void) " +/-t -- set/clear the realtime inheritance flag\n" " +/-P -- set/clear the project ID inheritance flag\n" " +/-n -- set/clear the no-symbolic-links flag\n" +" +/-e -- set/clear the extent-size flag\n" +" +/-E -- set/clear the extent-size inheritance flag\n" " Note1: user must have certain capabilities to modify immutable/append-only.\n" " Note2: immutable/append-only files cannot be deleted; removing these files\n" " requires the immutable/append-only flag to be cleared first.\n" diff --git a/io/open.c b/io/open.c index 11b694b38..38c488a51 100644 --- a/io/open.c +++ b/io/open.c @@ -555,8 +555,9 @@ extsize_f( char **argv) { struct fsxattr fsx; + struct stat64 stat; long extsize; - unsigned int blocksize, sectsize; + size_t blocksize, sectsize; init_cvtnum(&blocksize, §size); extsize = (long)cvtnum(blocksize, sectsize, argv[1]); @@ -564,11 +565,25 @@ extsize_f( printf(_("non-numeric extsize argument -- %s\n"), argv[1]); return 0; } + if (fstat64(file->fd, &stat) < 0) { + perror("fstat64"); + return 0; + } if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) { perror("XFS_IOC_FSGETXATTR"); return 0; } + + if (S_ISREG(stat.st_mode)) { + fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE; + } else if (S_ISDIR(stat.st_mode)) { + fsx.fsx_xflags |= XFS_XFLAG_EXTSZINHERIT; + } else { + printf(_("invalid target file type - file %s\n"), file->name); + return 0; + } fsx.fsx_extsize = extsize; + if ((xfsctl(file->name, file->fd, XFS_IOC_FSSETXATTR, &fsx)) < 0) { perror("XFS_IOC_FSSETXATTR"); return 0; @@ -710,7 +725,5 @@ open_init(void) add_command(&statfs_cmd); add_command(&chproj_cmd); add_command(&lsproj_cmd); - - if (expert) - add_command(&extsize_cmd); + add_command(&extsize_cmd); } diff --git a/man/man3/xfsctl.3 b/man/man3/xfsctl.3 index fb875d839..78cf7af13 100644 --- a/man/man3/xfsctl.3 +++ b/man/man3/xfsctl.3 @@ -207,6 +207,20 @@ directories also inherit the project inheritance bit. Can only be set on a directory and disallows creation of symbolic links in that directory. .TP +.SM "Bit 11 (0x800) \- XFS_XFLAG_EXTSIZE" +Extent size bit - if a basic extent size value is set on the file +then the allocator will allocate in multiples of the set size for +this file (see +.B XFS_IOC_FSSETXATTR +below). +.TP +.SM "Bit 12 (0x1000) \- XFS_XFLAG_EXTSZINHERIT" +Extent size inheritance bit - new files and directories created in +the directory will inherit the parents basic extent size value (see +.B XFS_IOC_FSSETXATTR +below). +Can only be set on a directory. +.TP .SM "Bit 31 (0x80000000) \- XFS_XFLAG_HASATTR" The file has extended attributes associated with it. .RE @@ -232,8 +246,11 @@ and .BR fsx_extsize . The .B fsx_xflags -realtime file bit, and the file's extent size, may be changed only -when the file is empty. +realtime file bit and the file's extent size may be changed only +when the file is empty, except in the case of a directory where +the extent size can be set at any time (this value is only used +for regular file allocations, so should only be set on a directory +in conjunction with the XFS_XFLAG_EXTSZINHERIT flag). .TP .B XFS_IOC_GETBMAP diff --git a/repair/dinode.c b/repair/dinode.c index fe7744ebf..c477b2f24 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2069,19 +2069,30 @@ process_dinode_int(xfs_mount_t *mp, } /* - * only realtime inodes should have extsize set + * only regular files with REALTIME or EXTSIZE flags set can have + * extsize set, or directories with EXTSZINHERIT. */ - if (type != XR_INO_RTDATA && INT_GET(dinoc->di_extsize, ARCH_CONVERT) != 0) { - do_warn( - _("bad non-zero extent size value %u for non-realtime inode %llu, "), - INT_GET(dinoc->di_extsize, ARCH_CONVERT), lino); + if (INT_GET(dinoc->di_extsize, ARCH_CONVERT) != 0) { + if ((type == XR_INO_RTDATA) || + (type == XR_INO_DIR && + (INT_GET(dinoc->di_flags, ARCH_CONVERT) & + XFS_DIFLAG_EXTSZINHERIT)) || + (type == XR_INO_DATA && + (INT_GET(dinoc->di_flags, ARCH_CONVERT) & + XFS_DIFLAG_EXTSIZE))) { + /* s'okay */ ; + } else { + do_warn( + _("bad non-zero extent size %u for non-realtime/extsize inode %llu, "), + INT_GET(dinoc->di_extsize, ARCH_CONVERT), lino); - if (!no_modify) { - do_warn(_("resetting to zero\n")); - dinoc->di_extsize = 0; - *dirty = 1; - } else { - do_warn(_("would reset to zero\n")); + if (!no_modify) { + do_warn(_("resetting to zero\n")); + dinoc->di_extsize = 0; + *dirty = 1; + } else { + do_warn(_("would reset to zero\n")); + } } }