Signed-off-by: Jan Kara <jack@xxxxxxx> --- misc/tune2fs.8.in | 5 +++ misc/tune2fs.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index b963f30edef3..849f94b68d6e 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -257,6 +257,11 @@ program. This superblock setting is only honored in 2.6.35+ kernels; and not at all by the ext2 and ext3 file system drivers. .TP +.BI orphan_file_size= size +Set size of the file for tracking unlinked but still open inodes and inodes +with truncate in progress. Larger file allows for better scalability, reserving +a few blocks per cpu is ideal. +.TP .B force_fsck Set a flag in the filesystem superblock indicating that errors have been found. This will force fsck to run at the next mount. diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 4200104ee0b1..c2b18d2fbf61 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -106,6 +106,7 @@ int enabling_casefold; int journal_size, journal_fc_size, journal_flags; char *journal_device; static blk64_t journal_location = ~0LL; +static e2_blkcnt_t orphan_file_blocks; static struct list_head blk_move_list; @@ -152,7 +153,8 @@ static __u32 ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX | EXT4_FEATURE_COMPAT_FAST_COMMIT | - EXT4_FEATURE_COMPAT_STABLE_INODES, + EXT4_FEATURE_COMPAT_STABLE_INODES | + EXT4_FEATURE_COMPAT_ORPHAN_FILE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE | EXT3_FEATURE_INCOMPAT_EXTENTS | @@ -183,7 +185,8 @@ static __u32 clear_ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_RESIZE_INODE | EXT2_FEATURE_COMPAT_DIR_INDEX | - EXT4_FEATURE_COMPAT_FAST_COMMIT, + EXT4_FEATURE_COMPAT_FAST_COMMIT | + EXT4_FEATURE_COMPAT_ORPHAN_FILE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_FLEX_BG | @@ -1145,6 +1148,56 @@ static int update_feature_set(ext2_filsys fs, char *features) } } + if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) { + ext2_ino_t ino; + + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The orphan_file feature may only be cleared " + "when the filesystem is unmounted.\n"), stderr); + return 1; + } + if (ext2fs_has_feature_orphan_present(sb) && f_flag < 2) { + fputs(_("The orphan_present feature is set. Please " + "run e2fsck before clearing orphan_file " + "feature.\n"), + stderr); + return 1; + } + err = ext2fs_read_bitmaps(fs); + if (err) { + com_err(program_name, err, "%s", + _("while loading bitmaps")); + return 1; + } + err = ext2fs_truncate_orphan_file(fs); + if (err) { + com_err(program_name, err, + _("\n\twhile trying to delete orphan file\n")); + return 1; + } + ino = sb->s_orphan_file_inum; + sb->s_orphan_file_inum = 0; + ext2fs_inode_alloc_stats2(fs, ino, -1, 0); + ext2fs_clear_feature_orphan_file(sb); + ext2fs_clear_feature_orphan_present(sb); + ext2fs_mark_super_dirty(fs); + } + + if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) { + if (!ext2fs_has_feature_journal(sb)) { + fputs(_("orphan_file feature can be set only for " + "filesystems with journal.\n"), stderr); + return 1; + } + /* + * If adding an orphan file, let the create orphan file + * code below handle setting the flag and creating it. + * We supply a default size if necessary. + */ + orphan_file_blocks = ext2fs_default_orphan_file_blocks(fs); + ext2fs_set_feature_orphan_file(sb); + } + if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) { if (ext2fs_has_feature_meta_bg(sb)) { @@ -2268,6 +2321,21 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) continue; } encoding_flags = arg; + } else if (!strcmp(token, "orphan_file_size")) { + if (!arg) { + r_usage++; + continue; + } + orphan_file_blocks = parse_num_blocks2(arg, + fs->super->s_log_block_size); + + if (orphan_file_blocks < 1) { + fprintf(stderr, + _("Invalid size of orphan file %s\n"), + arg); + r_usage++; + continue; + } } else r_usage++; } @@ -3253,6 +3321,24 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n" if (rc) goto closefs; } + if (orphan_file_blocks) { + errcode_t err; + + err = ext2fs_read_bitmaps(fs); + if (err) { + com_err(program_name, err, "%s", + _("while loading bitmaps")); + rc = 1; + goto closefs; + } + err = ext2fs_create_orphan_file(fs, orphan_file_blocks); + if (err) { + com_err(program_name, err, "%s", + _("while creating orphan file")); + rc = 1; + goto closefs; + } + } if (Q_flag) { if (mount_flags & EXT2_MF_MOUNTED) { -- 2.26.2