From b7c5b4030870b31d73019d9d9ec55d550772590b Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 5 Mar 2009 19:40:20 -0500 Subject: [PATCH] Add support for a new superblock field: s_kbytes_written This field tracks the lifetime amount of writes to the filesystem. It will be updated by the kernel as well as by e2fsprogs programs which write to the filesystem. Signed-off-by: "Theodore Ts'o" --- debugfs/set_fields.c | 1 + lib/e2p/ls.c | 18 ++++++++++++++++++ lib/ext2fs/closefs.c | 21 +++++++++++++++++---- lib/ext2fs/ext2_fs.h | 3 ++- lib/ext2fs/swapfs.c | 1 + misc/mke2fs.c | 8 ++++++++ 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c index f36943a..7c9697e 100644 --- a/debugfs/set_fields.c +++ b/debugfs/set_fields.c @@ -133,6 +133,7 @@ static struct field_set_info super_fields[] = { { "mmp_block", &set_sb.s_mmp_block, 8, parse_uint }, { "raid_stripe_width", &set_sb.s_raid_stripe_width, 4, parse_uint }, { "log_groups_per_flex", &set_sb.s_log_groups_per_flex, 1, parse_uint }, + { "kbytes_written", &set_sb.s_kbytes_written, 8, parse_uint }, { 0, 0, 0, 0 } }; diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c index 6d2ce70..eb9a772 100644 --- a/lib/e2p/ls.c +++ b/lib/e2p/ls.c @@ -267,6 +267,24 @@ void list_super2(struct ext2_super_block * sb, FILE *f) next = sb->s_lastcheck + sb->s_checkinterval; fprintf(f, "Next check after: %s", ctime(&next)); } +#define POW2(x) ((__u64) 1 << (x)) + if (sb->s_kbytes_written) { + fprintf(f, "Lifetime writes: "); + if (sb->s_kbytes_written < POW2(13)) + fprintf(f, "%llu kB\n", sb->s_kbytes_written); + else if (sb->s_kbytes_written < POW2(23)) + fprintf(f, "%llu MB\n", + (sb->s_kbytes_written + POW2(9)) >> 10); + else if (sb->s_kbytes_written < POW2(33)) + fprintf(f, "%llu GB\n", + (sb->s_kbytes_written + POW2(19)) >> 20); + else if (sb->s_kbytes_written < POW2(43)) + fprintf(f, "%llu TB\n", + (sb->s_kbytes_written + POW2(29)) >> 30); + else + fprintf(f, "%llu PB\n", + (sb->s_kbytes_written + POW2(39)) >> 40); + } fprintf(f, "Reserved blocks uid: "); print_user(sb->s_def_resuid, f); fprintf(f, "Reserved blocks gid: "); diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c index baf8ce1..b04f33b 100644 --- a/lib/ext2fs/closefs.c +++ b/lib/ext2fs/closefs.c @@ -370,16 +370,29 @@ errout: errcode_t ext2fs_close(ext2_filsys fs) { errcode_t retval; + int meta_blks; + io_stats stats = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); - if (fs->flags & EXT2_FLAG_DIRTY) { - retval = ext2fs_flush(fs); + if (fs->write_bitmaps) { + retval = fs->write_bitmaps(fs); if (retval) return retval; } - if (fs->write_bitmaps) { - retval = fs->write_bitmaps(fs); + if (fs->super->s_kbytes_written && + fs->io->manager->get_stats) + fs->io->manager->get_stats(fs->io, &stats); + if (stats && stats->bytes_written && (fs->flags & EXT2_FLAG_RW)) { + fs->super->s_kbytes_written += stats->bytes_written >> 10; + meta_blks = fs->desc_blocks + 1; + if (!(fs->flags & EXT2_FLAG_SUPER_ONLY)) + fs->super->s_kbytes_written += meta_blks / + (fs->blocksize / 1024); + ext2fs_mark_super_dirty(fs); + } + if (fs->flags & EXT2_FLAG_DIRTY) { + retval = ext2fs_flush(fs); if (retval) return retval; } diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index d7d7bdb..6c3fb15 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -579,7 +579,8 @@ struct ext2_super_block { __u8 s_log_groups_per_flex; /* FLEX_BG group size */ __u8 s_reserved_char_pad; __u16 s_reserved_pad; /* Padding to next 32bits */ - __u32 s_reserved[162]; /* Padding to the end of the block */ + __u64 s_kbytes_written; /* nr of lifetime kilobytes written */ + __u32 s_reserved[160]; /* Padding to the end of the block */ }; /* diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index 5ccc87f..42bc01e 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -70,6 +70,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb) sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize); sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize); sb->s_flags = ext2fs_swab32(sb->s_flags); + sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); for (i=0; i < 4; i++) sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); for (i=0; i < 17; i++) diff --git a/misc/mke2fs.c b/misc/mke2fs.c index c5f4da1..746d973 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -1892,6 +1892,14 @@ int main (int argc, char *argv[]) if (fs_param.s_flags & EXT2_FLAGS_TEST_FILESYS) fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS; + if ((fs_param.s_feature_incompat & + (EXT3_FEATURE_INCOMPAT_EXTENTS|EXT4_FEATURE_INCOMPAT_FLEX_BG)) || + (fs_param.s_feature_ro_compat & + (EXT4_FEATURE_RO_COMPAT_HUGE_FILE|EXT4_FEATURE_RO_COMPAT_GDT_CSUM| + EXT4_FEATURE_RO_COMPAT_DIR_NLINK| + EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE))) + fs->super->s_kbytes_written = 1; + /* * Wipe out the old on-disk superblock */ -- 1.8.3.1