Message ID | 20220707190456.64972-1-slava@bacher09.org |
---|---|
State | Superseded |
Headers | show |
Series | [v2] tune2fs: allow disabling casefold feature | expand |
On Thu, Jul 07, 2022 at 10:04:56PM +0300, Slava Bacherikov wrote: > diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in > index 628dcdc0..8ef28860 100644 > --- a/misc/tune2fs.8.in > +++ b/misc/tune2fs.8.in > @@ -593,8 +593,10 @@ Enable the file system to be larger than 2^32 blocks. > .TP > .B casefold > Enable support for file system level casefolding. > -.B Tune2fs > -currently only supports setting this file system feature. > +The option could be disabled only if filesystem has no > +directories with > +.B F > +attribute. Please use present tense: "could" => "can". Otherwise this can be interpreted as the opposite of what you meant. Also, "cleared" instead of "disabled", to be consistent with the rest of the page. > static errcode_t disable_uninit_bg(ext2_filsys fs, __u32 csum_feature_flag) > { > struct ext2_group_desc *gd; > @@ -1554,6 +1590,20 @@ mmp_error: > enabling_casefold = 1; > } > > + if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD)) { > + if (mount_flags & EXT2_MF_MOUNTED) { > + fputs(_("The casefold feature may only be disabled when " > + "the filesystem is unmounted.\n"), stderr); > + return 1; > + } > + if (has_casefold_inode(fs)) { > + fputs(_("The casefold feature couldn't be disabled when " > + "there are inodes with +F flag.\n"), stderr); > + return 1; > + } > + enabling_casefold = 0; Likewise, "couldn't" => "can't". Also, what are the semantics of disabling casefold, exactly? Do the encoding and encoding flags fields in the superblock also get cleared? - Eric
Eric Biggers <ebiggers@kernel.org> writes: > On Thu, Jul 07, 2022 at 10:04:56PM +0300, Slava Bacherikov wrote: >> + if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD)) { >> + if (mount_flags & EXT2_MF_MOUNTED) { >> + fputs(_("The casefold feature may only be disabled when " >> + "the filesystem is unmounted.\n"), stderr); >> + return 1; >> + } >> + if (has_casefold_inode(fs)) { >> + fputs(_("The casefold feature couldn't be disabled when " >> + "there are inodes with +F flag.\n"), stderr); >> + return 1; >> + } >> + enabling_casefold = 0; > > Likewise, "couldn't" => "can't". > > Also, what are the semantics of disabling casefold, exactly? Do the encoding > and encoding flags fields in the superblock also get cleared? The kernel is able to ignore the non-zero encoding field if the feature is not set, but we definitely don't want to rely on that. The patch should explicitly zero both s_encoding and s_encoding_flags.
07.07.2022 22:50, Eric Biggers wrote: > On Thu, Jul 07, 2022 at 10:04:56PM +0300, Slava Bacherikov wrote: > Also, what are the semantics of disabling casefold, exactly? Do the encoding > and encoding flags fields in the superblock also get cleared? > > - Eric Sorry, I've totally missed that. It worked just fine on a kernel compiled without casefold, because kernel is ignoring encoding if there is no casefold flag. And dumpe2fs wasn't showing character encoding on fs that had no casefold feature. Anyway, I've already updated patch. -- Slava Bacherikov
diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index 628dcdc0..8ef28860 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -593,8 +593,10 @@ Enable the file system to be larger than 2^32 blocks. .TP .B casefold Enable support for file system level casefolding. -.B Tune2fs -currently only supports setting this file system feature. +The option could be disabled only if filesystem has no +directories with +.B F +attribute. .TP .B dir_index Use hashed b-trees to speed up lookups for large directories. diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 6c162ba5..1c5c2969 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -204,7 +204,8 @@ static __u32 clear_ok_features[3] = { EXT4_FEATURE_INCOMPAT_FLEX_BG | EXT4_FEATURE_INCOMPAT_MMP | EXT4_FEATURE_INCOMPAT_64BIT | - EXT4_FEATURE_INCOMPAT_CSUM_SEED, + EXT4_FEATURE_INCOMPAT_CSUM_SEED | + EXT4_FEATURE_INCOMPAT_CASEFOLD, /* R/O compat */ EXT2_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_HUGE_FILE| @@ -1020,6 +1021,41 @@ out: return retval; } +static int has_casefold_inode(ext2_filsys fs) +{ + int length = EXT2_INODE_SIZE(fs->super); + struct ext2_inode *inode = NULL; + ext2_inode_scan scan; + errcode_t retval; + ext2_ino_t ino; + int found_casefold = 0; + + retval = ext2fs_get_mem(length, &inode); + if (retval) + fatal_err(retval, "while allocating memory"); + + retval = ext2fs_open_inode_scan(fs, 0, &scan); + if (retval) + fatal_err(retval, "while opening inode scan"); + + do { + retval = ext2fs_get_next_inode_full(scan, &ino, inode, length); + if (retval) + fatal_err(retval, "while getting next inode"); + if (!ino) + break; + + if(inode->i_flags & EXT4_CASEFOLD_FL) { + found_casefold = 1; + break; + } + } while(1); + + ext2fs_free_mem(&inode); + ext2fs_close_inode_scan(scan); + return found_casefold; +} + static errcode_t disable_uninit_bg(ext2_filsys fs, __u32 csum_feature_flag) { struct ext2_group_desc *gd; @@ -1554,6 +1590,20 @@ mmp_error: enabling_casefold = 1; } + if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD)) { + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The casefold feature may only be disabled when " + "the filesystem is unmounted.\n"), stderr); + return 1; + } + if (has_casefold_inode(fs)) { + fputs(_("The casefold feature couldn't be disabled when " + "there are inodes with +F flag.\n"), stderr); + return 1; + } + enabling_casefold = 0; + } + if (FEATURE_ON(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CSUM_SEED)) { if (!ext2fs_has_feature_metadata_csum(sb)) {
Casefold can be safely disabled if there are no directories with +F attribute ( EXT4_CASEFOLD_FL ). This checks all inodes for that flag and in case there isn't any, it disables casefold FS feature. When FS has directories with +F attributes, user could convert these directories, probably by mounting FS and executing some script or by doing it manually. Afterwards, it would be possible to disable casefold FS flag via tune2fs. Signed-off-by: Slava Bacherikov <slava@bacher09.org> --- misc/tune2fs.8.in | 6 ++++-- misc/tune2fs.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-)