}
pb->fragmented = 1;
}
+ /*
+ * If we notice a gap in the logical block mappings of an
+ * extent-mapped directory, offer to close the hole by
+ * moving the logical block down, otherwise we'll go mad in
+ * pass 3 allocating empty directory blocks to fill the hole.
+ */
+ if (is_dir &&
+ pb->last_block + 1 < (e2_blkcnt_t)extent.e_lblk) {
+ blk64_t new_lblk;
+
+ new_lblk = pb->last_block + 1;
+ if (EXT2FS_CLUSTER_RATIO(ctx->fs) > 1)
+ new_lblk = ((new_lblk +
+ EXT2FS_CLUSTER_RATIO(ctx->fs)) &
+ EXT2FS_CLUSTER_MASK(ctx->fs)) |
+ (extent.e_lblk &
+ EXT2FS_CLUSTER_MASK(ctx->fs));
+ pctx->blk = extent.e_lblk;
+ pctx->blk2 = new_lblk;
+ if (fix_problem(ctx, PR_1_COLLAPSE_DBLOCK, pctx)) {
+ extent.e_lblk = new_lblk;
+ pb->inode_modified = 1;
+ pctx->errcode = ext2fs_extent_replace(ehandle,
+ 0, &extent);
+ if (pctx->errcode) {
+ pctx->errcode = 0;
+ goto alloc_later;
+ }
+ pctx->errcode = ext2fs_extent_fix_parents(ehandle);
+ if (pctx->errcode)
+ goto failed_add_dir_block;
+ pctx->errcode = ext2fs_extent_goto(ehandle,
+ extent.e_lblk);
+ if (pctx->errcode)
+ goto failed_add_dir_block;
+ last_lblk = extent.e_lblk + extent.e_len - 1;
+ }
+ }
+alloc_later:
while (is_dir && (++pb->last_db_block <
(e2_blkcnt_t) extent.e_lblk)) {
pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
PROMPT_CLEAR, 0 },
+ /* Directory inode block <block> should be at block <otherblock> */
+ { PR_1_COLLAPSE_DBLOCK,
+ N_("@d @i %i @b %b should be at @b %c. "),
+ PROMPT_FIX, 0 },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
/* Couldn't clone file (error) */
#define PR_1D_CLONE_ERROR 0x013008
+/* Directory inode has a missing block (hole) */
+#define PR_1_COLLAPSE_DBLOCK 0x010072
+
/*
* Pass 2 errors
*/
Pass 1: Checking inodes, blocks, and sizes
Inode 12, i_size is 0, should be 5120. Fix? yes
-Inode 13, i_size is 4096, should be 5120. Fix? yes
+Directory inode 13 block 2 should be at block 1. Fix? yes
Pass 2: Checking directory structure
Directory inode 12 has an unallocated block #3. Allocate? yes
-Directory inode 13 has an unallocated block #1. Allocate? yes
-
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-Free blocks count wrong for group #0 (79, counted=77).
+Free blocks count wrong for group #0 (78, counted=77).
Fix? yes
-Free blocks count wrong (79, counted=77).
+Free blocks count wrong (78, counted=77).
Fix? yes
--- /dev/null
+Pass 1: Checking inodes, blocks, and sizes
+Directory inode 12 block 5 should be at block 2. Fix? yes
+
+Inode 12, i_size is 6144, should be 3072. Fix? yes
+
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 17/128 files (5.9% non-contiguous), 1093/2048 blocks
+Exit status is 1
--- /dev/null
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 17/128 files (5.9% non-contiguous), 1093/2048 blocks
+Exit status is 0
--- /dev/null
+real directories with holes and zero i_size
+