mkfs: pass a custom cowextsize into the created filesystem
PATCH 2/2 mkfs: pass a custom cowextsize into the created filesystem
Create a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
--- libxfs/util.c | 26 ++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 +++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-)
libxfs/util.c +24 -2
@@ -175,6 +175,26 @@ libxfs_trans_ichgtime( } } +static inline uint16_t +xflags_to_diflags ( +__u32 xflags) +{ +/* bottom 15 xflag bits correspond to diflag bits */ +return xflags &0x7FFF ; +} + +static inline uint64_t +xflags_to_diflags2 ( +__u32 xflags) +{ +uint64_t ret =0 ; + +if (xflags &FS_XFLAG_COWEXTSIZE ) + ret |=XFS_DIFLAG2_COWEXTSIZE ; + +return ret; +} +/* * Allocate an inode on disk and return a copy of its in-core version. * Set mode, nlink, and rdev appropriately within the inode.
@@ -254,15 +274,17 @@ libxfs_ialloc( ip->i_d.di_extsize = pip ?0 : fsx->fsx_extsize; ip->i_d.di_dmevmask =0 ; ip->i_d.di_dmstate =0 ; - ip->i_d.di_flags = pip ?0 : fsx->fsx_xflags; + ip->i_d.di_flags = pip ?0 :xflags_to_diflags (fsx->fsx_xflags);if (ip->i_d.di_version ==3 ) {ASSERT (ip->i_d.di_ino == ino);ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));VFS_I (ip)->i_version =1 ; - ip->i_d.di_flags2 =0 ; + ip->i_d.di_flags2 = pip ?0 : +xflags_to_diflags2 (fsx->fsx_xflags); ip->i_d.di_crtime.t_sec = (int32_t )VFS_I (ip)->i_mtime.tv_sec; ip->i_d.di_crtime.t_nsec = (int32_t )VFS_I (ip)->i_mtime.tv_nsec; + ip->i_d.di_cowextsize = pip ?0 : fsx->fsx_cowextsize; } flags =XFS_ILOG_CORE ;
man/man8/mkfs.xfs.8 +7 -0
@@ -279,6 +279,13 @@ and .B agsize suboptions are mutually exclusive. .TP +.BI cowextsize= value +Set the copy-on-write extent size hint on all inodes created by +.BR mkfs.xfs "." +The value must be provided in units of filesystem blocks. +If the value is zero, the default value (currently 32 blocks) will be used. +Directories will pass on this hint to newly created children. +.TP .BI name= value This can be used to specify the name of the special file containing the filesystem. In this case, the log section must be specified as
mkfs/xfs_mkfs.c +20 -0
@@ -187,6 +187,8 @@ struct opt_params dopts = { "projinherit",#define D_EXTSZINHERIT 14 "extszinherit", +#define D_COWEXTSIZE 15 +"cowextsize" ,NULL }, .subopt_params = {
@@ -303,6 +305,12 @@ struct opt_params dopts = { .maxval = UINT_MAX, .defaultval = SUBOPT_NEEDS_VAL, }, + { .index = D_COWEXTSIZE, + .conflicts = { LAST_CONFLICT }, + .minval = 0, + .maxval = UINT_MAX, + .defaultval = SUBOPT_NEEDS_VAL, + }, }, };
@@ -1638,6 +1646,13 @@ main( fsx.fsx_xflags |=XFS_DIFLAG_EXTSZINHERIT ;break ; +case D_COWEXTSIZE : + fsx.fsx_cowextsize =getnum (value, + &dopts, +D_COWEXTSIZE ); + fsx.fsx_xflags |= +FS_XFLAG_COWEXTSIZE ; +break ;default :unknown ('d' , value); }
@@ -2142,6 +2157,11 @@ _("reflink not supported without CRC support\n")); sb_feat.reflink = false; } +if ((fsx.fsx_xflags &FS_XFLAG_COWEXTSIZE ) && !sb_feat.reflink) { +fprintf (stderr, +_ ("cowextsize not supported without reflink support\n" )); +usage (); + }if (nsflag || nlflag) { if (dirblocksize < blocksize ||
Quoted 15 lines · Darrick J. Wong
Create a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
Signed-off-by Darrick J. Wong <[email protected]>--- libxfs/util.c | 26 ++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 +++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-)libxfs/util.c +0
-0
libxfs/util.c libxfs_trans_ichgtime( · line 183
Quoted 9 lines
libxfs/util.c +6
-0@@ -175,6 +175,26 @@ libxfs_trans_ichgtime( } } +static inline uint16_t +xflags_to_diflags ( +__u32 xflags) +{ +/* bottom 15 xflag bits correspond to diflag bits */ +return xflags &0x7FFF ;
Do we really want to rely on that fact?
libxfs/util.c libxfs_trans_ichgtime( · line 196
Quoted 13 lines
libxfs/util.c +13
-0+} + +static inline uint64_t +xflags_to_diflags2 ( +__u32 xflags) +{ +uint64_t ret =0 ; + +if (xflags &FS_XFLAG_COWEXTSIZE ) + ret |=XFS_DIFLAG2_COWEXTSIZE ; + +return ret; +}
It seems like we should just lift the kernels xfs_flags2diflags and xfs_flags2diflags2 to libxfs and use them here?
Quoted 28 lines · Christoph Hellwig
Quoted 15 lines · Darrick J. Wong
Create a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
Signed-off-by Darrick J. Wong <[email protected]>--- libxfs/util.c | 26 ++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 +++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-)libxfs/util.c +0
-0libxfs/util.c libxfs_trans_ichgtime( · line 183
Quoted 9 lines
libxfs/util.c +6
-0@@ -175,6 +175,26 @@ libxfs_trans_ichgtime( } } +static inline uint16_t +xflags_to_diflags ( +__u32 xflags) +{ +/* bottom 15 xflag bits correspond to diflag bits */ +return xflags &0x7FFF ;Do we really want to rely on that fact?
Quoted 16 lines
libxfs/util.c libxfs_trans_ichgtime( · line 196
Quoted 13 lines
libxfs/util.c +13
-0+} + +static inline uint64_t +xflags_to_diflags2 ( +__u32 xflags) +{ +uint64_t ret =0 ; + +if (xflags &FS_XFLAG_COWEXTSIZE ) + ret |=XFS_DIFLAG2_COWEXTSIZE ; + +return ret; +}It seems like we should just lift the kernels
xfs_flags2diflagsandxfs_flags2diflags2to libxfs and use them here?
Once that they exist upstream, sure! :)
--D
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 2/2 mkfs: pass a custom cowextsize into the created filesystem
In reply to Darrick J. WongCreate a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
---
v2: port flags2diflags from the kernel
--- libxfs/util.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 ++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-)
libxfs/util.c +62 -2
@@ -175,6 +175,64 @@ libxfs_trans_ichgtime( } } +STATIC uint16_t +xfs_flags2diflags ( +struct xfs_inode *ip, +unsigned int xflags) +{ +/* can't set PREALLOC this way, just preserve it */ +uint16_t di_flags = + (ip->i_d.di_flags &XFS_DIFLAG_PREALLOC ); + +if (xflags &FS_XFLAG_IMMUTABLE ) + di_flags |=XFS_DIFLAG_IMMUTABLE ; +if (xflags &FS_XFLAG_APPEND ) + di_flags |=XFS_DIFLAG_APPEND ; +if (xflags &FS_XFLAG_SYNC ) + di_flags |=XFS_DIFLAG_SYNC ; +if (xflags &FS_XFLAG_NOATIME ) + di_flags |=XFS_DIFLAG_NOATIME ; +if (xflags &FS_XFLAG_NODUMP ) + di_flags |=XFS_DIFLAG_NODUMP ; +if (xflags &FS_XFLAG_NODEFRAG ) + di_flags |=XFS_DIFLAG_NODEFRAG ; +if (xflags &FS_XFLAG_FILESTREAM ) + di_flags |=XFS_DIFLAG_FILESTREAM ; +if (S_ISDIR (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_RTINHERIT ) + di_flags |=XFS_DIFLAG_RTINHERIT ; +if (xflags &FS_XFLAG_NOSYMLINKS ) + di_flags |=XFS_DIFLAG_NOSYMLINKS ; +if (xflags &FS_XFLAG_EXTSZINHERIT ) + di_flags |=XFS_DIFLAG_EXTSZINHERIT ; +if (xflags &FS_XFLAG_PROJINHERIT ) + di_flags |=XFS_DIFLAG_PROJINHERIT ; + }else if (S_ISREG (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_REALTIME ) + di_flags |=XFS_DIFLAG_REALTIME ; +if (xflags &FS_XFLAG_EXTSIZE ) + di_flags |=XFS_DIFLAG_EXTSIZE ; + } + +return di_flags; +} + +STATIC uint64_t +xfs_flags2diflags2 ( +struct xfs_inode *ip, +unsigned int xflags) +{ +uint64_t di_flags2 = + (ip->i_d.di_flags2 &XFS_DIFLAG2_REFLINK ); + +if (xflags &FS_XFLAG_DAX ) + di_flags2 |=XFS_DIFLAG2_DAX ; +if (xflags &FS_XFLAG_COWEXTSIZE ) + di_flags2 |=XFS_DIFLAG2_COWEXTSIZE ; + +return di_flags2; +} +/* * Allocate an inode on disk and return a copy of its in-core version. * Set mode, nlink, and rdev appropriately within the inode.
@@ -254,15 +312,17 @@ libxfs_ialloc( ip->i_d.di_extsize = pip ?0 : fsx->fsx_extsize; ip->i_d.di_dmevmask =0 ; ip->i_d.di_dmstate =0 ; - ip->i_d.di_flags = pip ?0 : fsx->fsx_xflags; + ip->i_d.di_flags = pip ?0 :xfs_flags2diflags (ip, fsx->fsx_xflags);if (ip->i_d.di_version ==3 ) {ASSERT (ip->i_d.di_ino == ino);ASSERT (uuid_equal (&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));VFS_I (ip)->i_version =1 ; - ip->i_d.di_flags2 =0 ; + ip->i_d.di_flags2 = pip ?0 :xfs_flags2diflags2 (ip, + fsx->fsx_xflags); ip->i_d.di_crtime.t_sec = (int32_t )VFS_I (ip)->i_mtime.tv_sec; ip->i_d.di_crtime.t_nsec = (int32_t )VFS_I (ip)->i_mtime.tv_nsec; + ip->i_d.di_cowextsize = pip ?0 : fsx->fsx_cowextsize; } flags =XFS_ILOG_CORE ;
man/man8/mkfs.xfs.8 +7 -0
@@ -279,6 +279,13 @@ and .B agsize suboptions are mutually exclusive. .TP +.BI cowextsize= value +Set the copy-on-write extent size hint on all inodes created by +.BR mkfs.xfs "." +The value must be provided in units of filesystem blocks. +If the value is zero, the default value (currently 32 blocks) will be used. +Directories will pass on this hint to newly created children. +.TP .BI name= value This can be used to specify the name of the special file containing the filesystem. In this case, the log section must be specified as
mkfs/xfs_mkfs.c +20 -0
@@ -187,6 +187,8 @@ struct opt_params dopts = { "projinherit",#define D_EXTSZINHERIT 14 "extszinherit", +#define D_COWEXTSIZE 15 +"cowextsize" ,NULL }, .subopt_params = {
@@ -303,6 +305,12 @@ struct opt_params dopts = { .maxval = UINT_MAX, .defaultval = SUBOPT_NEEDS_VAL, }, + { .index = D_COWEXTSIZE, + .conflicts = { LAST_CONFLICT }, + .minval = 0, + .maxval = UINT_MAX, + .defaultval = SUBOPT_NEEDS_VAL, + }, }, };
@@ -1638,6 +1646,13 @@ main( fsx.fsx_xflags |=XFS_DIFLAG_EXTSZINHERIT ;break ; +case D_COWEXTSIZE : + fsx.fsx_cowextsize =getnum (value, + &dopts, +D_COWEXTSIZE ); + fsx.fsx_xflags |= +FS_XFLAG_COWEXTSIZE ; +break ;default :unknown ('d' , value); }
@@ -2142,6 +2157,11 @@ _("reflink not supported without CRC support\n")); sb_feat.reflink = false; } +if ((fsx.fsx_xflags &FS_XFLAG_COWEXTSIZE ) && !sb_feat.reflink) { +fprintf (stderr, +_ ("cowextsize not supported without reflink support\n" )); +usage (); + }if (nsflag || nlflag) { if (dirblocksize < blocksize ||
Quoted 6 lines · Darrick J. Wong
Create a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
Signed-off-by Darrick J. Wong <[email protected]>---
v2: port flags2diflags from the kernel
hm, I wonder if we need a libxfs/util.c in the kernel for stuff like this so libxfs diff will keep such things in sync in the future.
a project for another day I guess. One question below.
Quoted 76 lines
--- libxfs/util.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 ++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-)libxfs/util.c +58
-0@@ -175,6 +175,64 @@ libxfs_trans_ichgtime( } } +STATIC uint16_t +xfs_flags2diflags ( +struct xfs_inode *ip, +unsigned int xflags) +{ +/* can't set PREALLOC this way, just preserve it */ +uint16_t di_flags = + (ip->i_d.di_flags &XFS_DIFLAG_PREALLOC ); + +if (xflags &FS_XFLAG_IMMUTABLE ) + di_flags |=XFS_DIFLAG_IMMUTABLE ; +if (xflags &FS_XFLAG_APPEND ) + di_flags |=XFS_DIFLAG_APPEND ; +if (xflags &FS_XFLAG_SYNC ) + di_flags |=XFS_DIFLAG_SYNC ; +if (xflags &FS_XFLAG_NOATIME ) + di_flags |=XFS_DIFLAG_NOATIME ; +if (xflags &FS_XFLAG_NODUMP ) + di_flags |=XFS_DIFLAG_NODUMP ; +if (xflags &FS_XFLAG_NODEFRAG ) + di_flags |=XFS_DIFLAG_NODEFRAG ; +if (xflags &FS_XFLAG_FILESTREAM ) + di_flags |=XFS_DIFLAG_FILESTREAM ; +if (S_ISDIR (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_RTINHERIT ) + di_flags |=XFS_DIFLAG_RTINHERIT ; +if (xflags &FS_XFLAG_NOSYMLINKS ) + di_flags |=XFS_DIFLAG_NOSYMLINKS ; +if (xflags &FS_XFLAG_EXTSZINHERIT ) + di_flags |=XFS_DIFLAG_EXTSZINHERIT ; +if (xflags &FS_XFLAG_PROJINHERIT ) + di_flags |=XFS_DIFLAG_PROJINHERIT ; + }else if (S_ISREG (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_REALTIME ) + di_flags |=XFS_DIFLAG_REALTIME ; +if (xflags &FS_XFLAG_EXTSIZE ) + di_flags |=XFS_DIFLAG_EXTSIZE ; + } + +return di_flags; +} + +STATIC uint64_t +xfs_flags2diflags2 ( +struct xfs_inode *ip, +unsigned int xflags) +{ +uint64_t di_flags2 = + (ip->i_d.di_flags2 &XFS_DIFLAG2_REFLINK ); + +if (xflags &FS_XFLAG_DAX ) + di_flags2 |=XFS_DIFLAG2_DAX ; +if (xflags &FS_XFLAG_COWEXTSIZE ) + di_flags2 |=XFS_DIFLAG2_COWEXTSIZE ; + +return di_flags2; +} +/* * Allocate an inode on disk and return a copy of its in-core version. * Set mode, nlink, and rdev appropriately within the inode.
libxfs/util.c libxfs_ialloc( · line 315
Quoted 5 lines
libxfs/util.c +1
-1@@ -254,15 +312,17 @@ libxfs_ialloc( ip->i_d.di_extsize = pip ?0 : fsx->fsx_extsize; ip->i_d.di_dmevmask =0 ; ip->i_d.di_dmstate =0 ; - ip->i_d.di_flags = pip ?0 : fsx->fsx_xflags; + ip->i_d.di_flags = pip ?0 :xfs_flags2diflags (ip, fsx->fsx_xflags);
is this a bugfix?
The rest seems ok, just wondering if the above should be hidden in here - at least a mention of the change in the changelog seems needed, but most likely thjis is a separate change, no? Or am I missing something?
-Eric
Quoted 88 lines · Eric Sandeen
Quoted 6 lines · Darrick J. Wong
Create a -d option to mkfs.xfs that enables administrators to set the CoW extent size hint on the created files.
Signed-off-by Darrick J. Wong <[email protected]>---
v2: port flags2diflags from the kernelhm, I wonder if we need a
libxfs/util.cin the kernel for stuff like this so libxfs diff will keep such things in sync in the future.a project for another day I guess. One question below.
Quoted 75 lines
--- libxfs/util.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++-- man/man8/mkfs.xfs.8 | 7 ++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-)libxfs/util.c +58
-0@@ -175,6 +175,64 @@ libxfs_trans_ichgtime( } } +STATIC uint16_t +xfs_flags2diflags ( +struct xfs_inode *ip, +unsigned int xflags) +{ +/* can't set PREALLOC this way, just preserve it */ +uint16_t di_flags = + (ip->i_d.di_flags &XFS_DIFLAG_PREALLOC ); + +if (xflags &FS_XFLAG_IMMUTABLE ) + di_flags |=XFS_DIFLAG_IMMUTABLE ; +if (xflags &FS_XFLAG_APPEND ) + di_flags |=XFS_DIFLAG_APPEND ; +if (xflags &FS_XFLAG_SYNC ) + di_flags |=XFS_DIFLAG_SYNC ; +if (xflags &FS_XFLAG_NOATIME ) + di_flags |=XFS_DIFLAG_NOATIME ; +if (xflags &FS_XFLAG_NODUMP ) + di_flags |=XFS_DIFLAG_NODUMP ; +if (xflags &FS_XFLAG_NODEFRAG ) + di_flags |=XFS_DIFLAG_NODEFRAG ; +if (xflags &FS_XFLAG_FILESTREAM ) + di_flags |=XFS_DIFLAG_FILESTREAM ; +if (S_ISDIR (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_RTINHERIT ) + di_flags |=XFS_DIFLAG_RTINHERIT ; +if (xflags &FS_XFLAG_NOSYMLINKS ) + di_flags |=XFS_DIFLAG_NOSYMLINKS ; +if (xflags &FS_XFLAG_EXTSZINHERIT ) + di_flags |=XFS_DIFLAG_EXTSZINHERIT ; +if (xflags &FS_XFLAG_PROJINHERIT ) + di_flags |=XFS_DIFLAG_PROJINHERIT ; + }else if (S_ISREG (VFS_I (ip)->i_mode)) { +if (xflags &FS_XFLAG_REALTIME ) + di_flags |=XFS_DIFLAG_REALTIME ; +if (xflags &FS_XFLAG_EXTSIZE ) + di_flags |=XFS_DIFLAG_EXTSIZE ; + } + +return di_flags; +} + +STATIC uint64_t +xfs_flags2diflags2 ( +struct xfs_inode *ip, +unsigned int xflags) +{ +uint64_t di_flags2 = + (ip->i_d.di_flags2 &XFS_DIFLAG2_REFLINK ); + +if (xflags &FS_XFLAG_DAX ) + di_flags2 |=XFS_DIFLAG2_DAX ; +if (xflags &FS_XFLAG_COWEXTSIZE ) + di_flags2 |=XFS_DIFLAG2_COWEXTSIZE ; + +return di_flags2; +} +/* * Allocate an inode on disk and return a copy of its in-core version. * Set mode, nlink, and rdev appropriately within the inode.
Quoted 8 lines
libxfs/util.c libxfs_ialloc( · line 315
Quoted 6 lines
libxfs/util.c +1
-1@@ -254,15 +312,17 @@ libxfs_ialloc( ip->i_d.di_extsize = pip ?0 : fsx->fsx_extsize; ip->i_d.di_dmevmask =0 ; ip->i_d.di_dmstate =0 ; - ip->i_d.di_flags = pip ?0 : fsx->fsx_xflags; + ip->i_d.di_flags = pip ?0 :xfs_flags2diflags (ip, fsx->fsx_xflags);is this a bugfix?
No.
Prior to this patch, the only fsx_xflags bits that mkfs could set are the ones that correspond exactly to di_flags bits, so it was fine to set them directly. Subtle and annoying, but it worked.
However, the xfs_mkfs.c changes enable us to set FS_XFLAG_COWEXTSIZE, which doesn't correspond to a di_flags bit, so now we need translation functions to return the correct di_flags/di_flags2 values for the given fsx_xflags.
(Granted you could argue that COWEXTSIZE is bit 17 so it'll just get truncated when we set di_flags and therefore it's not absolutely necessary to have a translation function for di_flags but that's sloppy.)
--D
Quoted 9 lines
The rest seems ok, just wondering if the above should be hidden in here - at least a mention of the change in the changelog seems needed, but most likely thjis is a separate change, no? Or am I missing something?
-Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Darrick J. Wong
Quoted 7 lines
libxfs/util.c libxfs_ialloc( · line 315
Quoted 6 lines
libxfs/util.c +1
-1@@ -254,15 +312,17 @@ libxfs_ialloc( ip->i_d.di_extsize = pip ?0 : fsx->fsx_extsize; ip->i_d.di_dmevmask =0 ; ip->i_d.di_dmstate =0 ; - ip->i_d.di_flags = pip ?0 : fsx->fsx_xflags; + ip->i_d.di_flags = pip ?0 :xfs_flags2diflags (ip, fsx->fsx_xflags);is this a bugfix?
No.
Quoted 8 lines
Prior to this patch, the only
fsx_xflagsbits that mkfs could set are the ones that correspond exactly todi_flagsbits, so it was fine to set them directly. Subtle and annoying, but it worked.However, the
xfs_mkfs.cchanges enable us to setFS_XFLAG_COWEXTSIZE, which doesn't correspond to adi_flagsbit, so now we need translation functions to return the correct di_flags/di_flags2 values for the givenfsx_xflags.
Oh, ok. Before I guess it was only XFS_DIFLAG_RTINHERIT, XFS_DIFLAG_PROJINHERIT and XFS_DIFLAG_EXTSZINHERIT.
Fair enough, maybe I should have seen that. Thanks.
(I might note it in the changelog on the way in, though, since it's subtle and annoying) ;)
-Eric