From 63b5e354d926413d365eeff8a6d5347b3fb212d0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 10 Aug 2008 22:43:24 -0400 Subject: [PATCH] e2fsck: Fix check to see if an extent-based file is fragmented Also added support for "e2fsck -E fragcheck" which issues a comprehensive report of discontiguous file extents. Signed-off-by: "Theodore Ts'o" --- e2fsck/e2fsck.8.in | 11 ++++++++--- e2fsck/e2fsck.h | 1 + e2fsck/pass1.c | 27 +++++++++++++++++++++++++-- e2fsck/unix.c | 9 +++++++-- tests/d_loaddump/expect | 2 +- tests/f_badjour_indblks/expect.1 | 2 +- tests/f_badjour_indblks/expect.2 | 2 +- tests/f_dup_resize/expect.2 | 2 +- tests/f_extents2/expect.1 | 2 +- tests/f_extents2/expect.2 | 2 +- tests/f_full_bg/expect.1 | 2 +- tests/f_full_bg/expect.2 | 2 +- tests/f_uninit_last_uninit/expect.1 | 2 +- tests/f_uninit_last_uninit/expect.2 | 2 +- tests/f_zero_inode_size/expect.1 | 2 +- tests/f_zero_inode_size/expect.2 | 2 +- tests/m_dasd_bs/expect.1 | 2 +- tests/m_large_file/expect.1 | 2 +- tests/m_std/expect.1 | 2 +- tests/m_uninit/expect.1 | 2 +- 20 files changed, 57 insertions(+), 23 deletions(-) diff --git a/e2fsck/e2fsck.8.in b/e2fsck/e2fsck.8.in index d176fb78..9707a4c3 100644 --- a/e2fsck/e2fsck.8.in +++ b/e2fsck/e2fsck.8.in @@ -185,9 +185,14 @@ following options are supported: .RS 1.2i .TP .BI ea_ver= extended_attribute_version -Assume the format of the extended attribute blocks in the filesystem is -the specified version number. The version number may be 1 or 2. The -default extended attribute version format is 2. +Set the version of the extended attribute blocks which +.B e2fsck +will require while checking the filesystem. The version number may +be 1 or 2. The default extended attribute version format is 2. +.TP +.BI fragcheck +During pass 1, print a detailed report of any discontiguous blocks for +files in the filesystem. .RE .TP .B \-f diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 5523ed69..1d76f377 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -154,6 +154,7 @@ struct resource_track { #define E2F_OPT_FORCE 0x0100 #define E2F_OPT_WRITECHECK 0x0200 #define E2F_OPT_COMPRESS_DIRS 0x0400 +#define E2F_OPT_FRAGCHECK 0x0800 /* * E2fsck flags diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index c240195f..c2f7b3b7 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -1694,6 +1694,18 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx, goto next; } + if ((pb->previous_block != 0) && + (pb->previous_block+1 != extent.e_pblk)) { + if (ctx->options & E2F_OPT_FRAGCHECK) + printf(("%6lu: expecting %6lu actual extent " + "phys %6lu log %lu len %lu\n"), + (unsigned long) pctx->ino, + (unsigned long) pb->previous_block+1, + (unsigned long) extent.e_pblk, + (unsigned long) extent.e_lblk, + (unsigned long) extent.e_len); + pb->fragmented = 1; + } for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0; i < extent.e_len; blk++, blockcnt++, i++) { @@ -1712,6 +1724,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx, } } pb->num_blocks += extent.e_len; + pb->previous_block = extent.e_pblk + extent.e_len - 1; start_block = pb->last_block = extent.e_lblk + extent.e_len - 1; next: pctx->errcode = ext2fs_extent_get(ehandle, @@ -1740,6 +1753,9 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx, scan_extent_node(ctx, pctx, pb, 0, ehandle); + if (pb->fragmented && pb->num_blocks < fs->super->s_blocks_per_group) + ctx->fs_fragmented++; + ext2fs_extent_free(ehandle); } @@ -2066,9 +2082,16 @@ static int process_block(ext2_filsys fs, * file be contiguous. (Which can never be true for really * big files that are greater than a block group.) */ - if (!HOLE_BLKADDR(p->previous_block)) { - if (p->previous_block+1 != blk) + if (!HOLE_BLKADDR(p->previous_block) && p->ino != EXT2_RESIZE_INO) { + if (p->previous_block+1 != blk) { + if (ctx->options & E2F_OPT_FRAGCHECK) + printf(_("%6lu: expecting %6lu got %6lu (%lu)\n"), + (unsigned long) pctx->ino, + (unsigned long) p->previous_block+1, + (unsigned long) blk, + (unsigned long) blockcnt); p->fragmented = 1; + } } p->previous_block = blk; diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 4262906d..379f19aa 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -553,6 +553,9 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) continue; } ctx->ext_attr_ver = ea_ver; + } else if (strcmp(token, "fragcheck") == 0) { + ctx->options |= E2F_OPT_FRAGCHECK; + continue; } else { fprintf(stderr, _("Unknown extended option: %s\n"), token); @@ -565,8 +568,10 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) fputs(("\nExtended options are separated by commas, " "and may take an argument which\n" "is set off by an equals ('=') sign. " - "Valid extended options are:\n" - "\tea_ver=\n\n"), stderr); + "Valid extended options are:\n"), stderr); + fputs(("\tea_ver=\n"), stderr); + fputs(("\tfragcheck\n"), stderr); + fputc('\n', stderr); exit(1); } } diff --git a/tests/d_loaddump/expect b/tests/d_loaddump/expect index 1fc45618..f66e2183 100644 --- a/tests/d_loaddump/expect +++ b/tests/d_loaddump/expect @@ -10,7 +10,7 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 12/64 files (8.3% non-contiguous), 158/512 blocks +test_filesys: 12/64 files (0.0% non-contiguous), 158/512 blocks Exit status is 0 debugfs -R ''dump test_data test.verify'' ./test.img Exit status is 0 diff --git a/tests/f_badjour_indblks/expect.1 b/tests/f_badjour_indblks/expect.1 index c0de516d..0190bf2a 100644 --- a/tests/f_badjour_indblks/expect.1 +++ b/tests/f_badjour_indblks/expect.1 @@ -29,5 +29,5 @@ Creating journal (1024 blocks): Done. *** journal has been re-created - filesystem is now ext3 again *** test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** -test_filesys: 11/256 files (9.1% non-contiguous), 1112/8192 blocks +test_filesys: 11/256 files (0.0% non-contiguous), 1112/8192 blocks Exit status is 1 diff --git a/tests/f_badjour_indblks/expect.2 b/tests/f_badjour_indblks/expect.2 index 74153ad2..35365fad 100644 --- a/tests/f_badjour_indblks/expect.2 +++ b/tests/f_badjour_indblks/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/256 files (9.1% non-contiguous), 1112/8192 blocks +test_filesys: 11/256 files (0.0% non-contiguous), 1112/8192 blocks Exit status is 0 diff --git a/tests/f_dup_resize/expect.2 b/tests/f_dup_resize/expect.2 index ed116f46..198acb95 100644 --- a/tests/f_dup_resize/expect.2 +++ b/tests/f_dup_resize/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 12/2560 files (16.7% non-contiguous), 485/10240 blocks +test_filesys: 12/2560 files (8.3% non-contiguous), 485/10240 blocks Exit status is 0 diff --git a/tests/f_extents2/expect.1 b/tests/f_extents2/expect.1 index 62ce0ab6..094021d5 100644 --- a/tests/f_extents2/expect.1 +++ b/tests/f_extents2/expect.1 @@ -66,5 +66,5 @@ Fix? yes test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** -test_filesys: 18/32 files (0.0% non-contiguous), 145/200 blocks +test_filesys: 18/32 files (44.4% non-contiguous), 145/200 blocks Exit status is 1 diff --git a/tests/f_extents2/expect.2 b/tests/f_extents2/expect.2 index a81164ee..54f781a0 100644 --- a/tests/f_extents2/expect.2 +++ b/tests/f_extents2/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 18/32 files (0.0% non-contiguous), 145/200 blocks +test_filesys: 18/32 files (44.4% non-contiguous), 145/200 blocks Exit status is 0 diff --git a/tests/f_full_bg/expect.1 b/tests/f_full_bg/expect.1 index 00819bf6..3d5453f1 100644 --- a/tests/f_full_bg/expect.1 +++ b/tests/f_full_bg/expect.1 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/3744 files (9.1% non-contiguous), 685/769 blocks +test_filesys: 11/3744 files (0.0% non-contiguous), 685/769 blocks Exit status is 0 diff --git a/tests/f_full_bg/expect.2 b/tests/f_full_bg/expect.2 index 00819bf6..3d5453f1 100644 --- a/tests/f_full_bg/expect.2 +++ b/tests/f_full_bg/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/3744 files (9.1% non-contiguous), 685/769 blocks +test_filesys: 11/3744 files (0.0% non-contiguous), 685/769 blocks Exit status is 0 diff --git a/tests/f_uninit_last_uninit/expect.1 b/tests/f_uninit_last_uninit/expect.1 index 85f05ee2..248bd290 100644 --- a/tests/f_uninit_last_uninit/expect.1 +++ b/tests/f_uninit_last_uninit/expect.1 @@ -5,5 +5,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/32 files (9.1% non-contiguous), 105/10000 blocks +test_filesys: 11/32 files (0.0% non-contiguous), 105/10000 blocks Exit status is 0 diff --git a/tests/f_uninit_last_uninit/expect.2 b/tests/f_uninit_last_uninit/expect.2 index 435a8a7b..e95e5ede 100644 --- a/tests/f_uninit_last_uninit/expect.2 +++ b/tests/f_uninit_last_uninit/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/32 files (9.1% non-contiguous), 105/10000 blocks +test_filesys: 11/32 files (0.0% non-contiguous), 105/10000 blocks Exit status is 0 diff --git a/tests/f_zero_inode_size/expect.1 b/tests/f_zero_inode_size/expect.1 index 3e541705..9202131f 100644 --- a/tests/f_zero_inode_size/expect.1 +++ b/tests/f_zero_inode_size/expect.1 @@ -6,5 +6,5 @@ Pass 4: Checking reference counts Pass 5: Checking group summary information test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** -test_filesys: 11/2512 files (9.1% non-contiguous), 415/10000 blocks +test_filesys: 11/2512 files (0.0% non-contiguous), 415/10000 blocks Exit status is 1 diff --git a/tests/f_zero_inode_size/expect.2 b/tests/f_zero_inode_size/expect.2 index a6f1434e..da948061 100644 --- a/tests/f_zero_inode_size/expect.2 +++ b/tests/f_zero_inode_size/expect.2 @@ -3,5 +3,5 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/2512 files (9.1% non-contiguous), 415/10000 blocks +test_filesys: 11/2512 files (0.0% non-contiguous), 415/10000 blocks Exit status is 0 diff --git a/tests/m_dasd_bs/expect.1 b/tests/m_dasd_bs/expect.1 index 6ad145e4..59fc457b 100644 --- a/tests/m_dasd_bs/expect.1 +++ b/tests/m_dasd_bs/expect.1 @@ -22,7 +22,7 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/16384 files (9.1% non-contiguous), 1104/32768 blocks +test_filesys: 11/16384 files (0.0% non-contiguous), 1104/32768 blocks Exit status is 0 Filesystem volume name: diff --git a/tests/m_large_file/expect.1 b/tests/m_large_file/expect.1 index 212ed607..ae27f021 100644 --- a/tests/m_large_file/expect.1 +++ b/tests/m_large_file/expect.1 @@ -20,7 +20,7 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/64 files (9.1% non-contiguous), 17/16384 blocks +test_filesys: 11/64 files (0.0% non-contiguous), 17/16384 blocks Exit status is 0 Filesystem volume name: diff --git a/tests/m_std/expect.1 b/tests/m_std/expect.1 index 1139dab9..9f5e66e6 100644 --- a/tests/m_std/expect.1 +++ b/tests/m_std/expect.1 @@ -22,7 +22,7 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/16384 files (9.1% non-contiguous), 3364/65536 blocks +test_filesys: 11/16384 files (0.0% non-contiguous), 3364/65536 blocks Exit status is 0 Filesystem volume name: diff --git a/tests/m_uninit/expect.1 b/tests/m_uninit/expect.1 index ed57e42b..02649d88 100644 --- a/tests/m_uninit/expect.1 +++ b/tests/m_uninit/expect.1 @@ -22,7 +22,7 @@ Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information -test_filesys: 11/32768 files (9.1% non-contiguous), 5691/131072 blocks +test_filesys: 11/32768 files (0.0% non-contiguous), 5691/131072 blocks Exit status is 0 Filesystem volume name: