summaryrefslogtreecommitdiff
path: root/misc/tune2fs.c
diff options
context:
space:
mode:
authorSlava Bacherikov <slava@bacher09.org>2022-07-08 15:26:58 +0300
committerTheodore Ts'o <tytso@mit.edu>2022-08-12 22:38:35 -0400
commit47f9c3c00bbfdef4a64f400d1c95d9140aab3199 (patch)
tree58184fa41855749b23b430c512a48bbafe3d2e39 /misc/tune2fs.c
parentd05a33bd3e255d8d279b3399eadccbcaeb3613a5 (diff)
downloade2fsprogs-47f9c3c00bbfdef4a64f400d1c95d9140aab3199.tar.gz
tune2fs: allow disabling casefold feature
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. Link: https://lore.kernel.org/r/20220708122658.17907-1-slava@bacher09.org Signed-off-by: Slava Bacherikov <slava@bacher09.org> Reviewed-by: Gabriel Krisman Bertazi <krisman@collabora.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'misc/tune2fs.c')
-rw-r--r--misc/tune2fs.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 50bba990..eca77a5a 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -205,7 +205,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|
@@ -1021,6 +1022,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;
@@ -1555,6 +1591,22 @@ 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 can't be cleared when "
+ "there are inodes with +F flag.\n"), stderr);
+ return 1;
+ }
+ fs->super->s_encoding = 0;
+ fs->super->s_encoding_flags = 0;
+ enabling_casefold = 0;
+ }
+
if (FEATURE_ON(E2P_FEATURE_INCOMPAT,
EXT4_FEATURE_INCOMPAT_CSUM_SEED)) {
if (!ext2fs_has_feature_metadata_csum(sb)) {