mirror of
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
synced 2024-11-23 18:14:25 +08:00
Merge branch 'maint' into next
This commit is contained in:
commit
94676ef2b3
@ -209,8 +209,6 @@ static pass_t e2fsck_passes[] = {
|
||||
e2fsck_pass1, e2fsck_pass1e, e2fsck_pass2, e2fsck_pass3,
|
||||
e2fsck_pass4, e2fsck_pass5, 0 };
|
||||
|
||||
#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
|
||||
|
||||
int e2fsck_run(e2fsck_t ctx)
|
||||
{
|
||||
int i;
|
||||
|
@ -175,10 +175,10 @@ struct resource_track {
|
||||
*/
|
||||
#define E2F_FLAG_ABORT 0x0001 /* Abort signaled */
|
||||
#define E2F_FLAG_CANCEL 0x0002 /* Cancel signaled */
|
||||
#define E2F_FLAG_SIGNAL_MASK 0x0003
|
||||
#define E2F_FLAG_SIGNAL_MASK (E2F_FLAG_ABORT | E2F_FLAG_CANCEL)
|
||||
#define E2F_FLAG_RESTART 0x0004 /* Restart signaled */
|
||||
#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK | E2F_FLAG_RESTART)
|
||||
#define E2F_FLAG_RESTART_LATER 0x0008 /* Restart after all iterations done */
|
||||
|
||||
#define E2F_FLAG_SETJMP_OK 0x0010 /* Setjmp valid for abort */
|
||||
|
||||
#define E2F_FLAG_PROG_BAR 0x0020 /* Progress bar on screen */
|
||||
|
@ -482,6 +482,10 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if there is no place for an EA header */
|
||||
if (inode->i_extra_isize >= max - sizeof(__u32))
|
||||
return;
|
||||
|
||||
eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
|
||||
inode->i_extra_isize);
|
||||
if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
|
||||
@ -1166,7 +1170,7 @@ void e2fsck_pass1(e2fsck_t ctx)
|
||||
pass1_readahead(ctx, &ra_group, &ino_threshold);
|
||||
ehandler_operation(old_op);
|
||||
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
|
||||
return;
|
||||
goto endit;
|
||||
if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
|
||||
/*
|
||||
* If badblocks says badblocks is bad, offer to clear
|
||||
@ -1847,6 +1851,8 @@ endit:
|
||||
|
||||
if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
|
||||
print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
|
||||
else
|
||||
ctx->invalid_bitmaps++;
|
||||
}
|
||||
#undef FINISH_INODE_LOOP
|
||||
|
||||
@ -2820,7 +2826,20 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
|
||||
ext2_ino_t ino = pctx->ino;
|
||||
errcode_t retval;
|
||||
blk64_t eof_lblk;
|
||||
struct ext3_extent_header *eh;
|
||||
|
||||
/* Check for a proper extent header... */
|
||||
eh = (struct ext3_extent_header *) &inode->i_block[0];
|
||||
retval = ext2fs_extent_header_verify(eh, sizeof(inode->i_block));
|
||||
if (retval) {
|
||||
if (fix_problem(ctx, PR_1_MISSING_EXTENT_HEADER, pctx))
|
||||
e2fsck_clear_inode(ctx, ino, inode, 0,
|
||||
"check_blocks_extents");
|
||||
pctx->errcode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ...since this function doesn't fail if i_block is zeroed. */
|
||||
pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
|
||||
if (pctx->errcode) {
|
||||
if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
|
||||
|
@ -161,14 +161,14 @@ void e2fsck_pass2(e2fsck_t ctx)
|
||||
check_dir_func = cd.ra_entries ? check_dir_block2 : check_dir_block;
|
||||
cd.pctx.errcode = ext2fs_dblist_iterate2(fs->dblist, check_dir_func,
|
||||
&cd);
|
||||
if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
|
||||
return;
|
||||
|
||||
if (ctx->flags & E2F_FLAG_RESTART_LATER) {
|
||||
ctx->flags |= E2F_FLAG_RESTART;
|
||||
return;
|
||||
ctx->flags &= ~E2F_FLAG_RESTART_LATER;
|
||||
}
|
||||
|
||||
if (ctx->flags & E2F_FLAG_RUN_RETURN)
|
||||
return;
|
||||
|
||||
if (cd.pctx.errcode) {
|
||||
fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
|
||||
ctx->flags |= E2F_FLAG_ABORT;
|
||||
@ -922,7 +922,7 @@ static int check_dir_block(ext2_filsys fs,
|
||||
ibuf = buf = cd->buf;
|
||||
ctx = cd->ctx;
|
||||
|
||||
if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
|
||||
if (ctx->flags & E2F_FLAG_RUN_RETURN)
|
||||
return DIRENT_ABORT;
|
||||
|
||||
if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
|
||||
|
@ -1114,6 +1114,11 @@ static struct e2fsck_problem problem_table[] = {
|
||||
N_("@i %i on bigalloc @f cannot be @b mapped. "),
|
||||
PROMPT_FIX, 0 },
|
||||
|
||||
/* Inode has corrupt extent header */
|
||||
{ PR_1_MISSING_EXTENT_HEADER,
|
||||
N_("@i %i has corrupt @x header. "),
|
||||
PROMPT_CLEAR_INODE, 0 },
|
||||
|
||||
/* Pass 1b errors */
|
||||
|
||||
/* Pass 1B: Rescan for duplicate/bad blocks */
|
||||
|
@ -651,6 +651,9 @@ struct problem_context {
|
||||
/* bigalloc fs cannot have blockmap files */
|
||||
#define PR_1_NO_BIGALLOC_BLOCKMAP_FILES 0x010080
|
||||
|
||||
/* Missing extent header */
|
||||
#define PR_1_MISSING_EXTENT_HEADER 0x010081
|
||||
|
||||
/*
|
||||
* Pass 1b errors
|
||||
*/
|
||||
|
@ -71,6 +71,8 @@ int e2fsck_dir_will_be_rehashed(e2fsck_t ctx, ext2_ino_t ino)
|
||||
return ext2fs_u32_list_test(ctx->dirs_to_hash, ino);
|
||||
}
|
||||
|
||||
#undef REHASH_DEBUG
|
||||
|
||||
struct fill_dir_struct {
|
||||
char *buf;
|
||||
struct ext2_inode *inode;
|
||||
@ -684,8 +686,8 @@ static errcode_t calculate_tree(ext2_filsys fs,
|
||||
struct write_dir_struct {
|
||||
struct out_dir *outdir;
|
||||
errcode_t err;
|
||||
ext2_ino_t ino;
|
||||
e2fsck_t ctx;
|
||||
blk64_t cleared;
|
||||
ext2_ino_t dir;
|
||||
};
|
||||
|
||||
@ -703,10 +705,15 @@ static int write_dir_block(ext2_filsys fs,
|
||||
blk64_t blk;
|
||||
char *dir, *buf = 0;
|
||||
|
||||
if (*block_nr == 0)
|
||||
return 0;
|
||||
if (blockcnt < 0)
|
||||
#ifdef REHASH_DEBUG
|
||||
printf("%u: write_dir_block %lld:%lld", wd->ino, blockcnt, *block_nr);
|
||||
#endif
|
||||
if ((*block_nr == 0) || (blockcnt < 0)) {
|
||||
#ifdef REHASH_DEBUG
|
||||
printf(" - skip\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (blockcnt < wd->outdir->num)
|
||||
dir = wd->outdir->buf + (blockcnt * fs->blocksize);
|
||||
else if (wd->ctx->lost_and_found == wd->dir) {
|
||||
@ -717,26 +724,20 @@ static int write_dir_block(ext2_filsys fs,
|
||||
dir = buf;
|
||||
wd->outdir->num++;
|
||||
} else {
|
||||
/* We don't need this block, so release it */
|
||||
e2fsck_read_bitmaps(wd->ctx);
|
||||
blk = *block_nr;
|
||||
/*
|
||||
* In theory, we only release blocks from the end of the
|
||||
* directory file, so it's fine to clobber a whole cluster at
|
||||
* once.
|
||||
*/
|
||||
if (blk % EXT2FS_CLUSTER_RATIO(fs) == 0) {
|
||||
ext2fs_block_alloc_stats2(fs, blk, -1);
|
||||
wd->cleared++;
|
||||
}
|
||||
*block_nr = 0;
|
||||
return BLOCK_CHANGED;
|
||||
/* Don't free blocks at the end of the directory, they
|
||||
* will be truncated by the caller. */
|
||||
#ifdef REHASH_DEBUG
|
||||
printf(" - not freed\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
wd->err = ext2fs_write_dir_block4(fs, *block_nr, dir, 0, wd->dir);
|
||||
if (buf)
|
||||
ext2fs_free_mem(&buf);
|
||||
|
||||
#ifdef REHASH_DEBUG
|
||||
printf(" - write (%d)\n", wd->err);
|
||||
#endif
|
||||
if (wd->err)
|
||||
return BLOCK_ABORT;
|
||||
return 0;
|
||||
@ -756,11 +757,11 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
|
||||
|
||||
wd.outdir = outdir;
|
||||
wd.err = 0;
|
||||
wd.ino = ino;
|
||||
wd.ctx = ctx;
|
||||
wd.cleared = 0;
|
||||
wd.dir = ino;
|
||||
|
||||
retval = ext2fs_block_iterate3(fs, ino, 0, 0,
|
||||
retval = ext2fs_block_iterate3(fs, ino, 0, NULL,
|
||||
write_dir_block, &wd);
|
||||
if (retval)
|
||||
return retval;
|
||||
@ -772,14 +773,17 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
|
||||
inode->i_flags &= ~EXT2_INDEX_FL;
|
||||
else
|
||||
inode->i_flags |= EXT2_INDEX_FL;
|
||||
retval = ext2fs_inode_size_set(fs, inode,
|
||||
outdir->num * fs->blocksize);
|
||||
#ifdef REHASH_DEBUG
|
||||
printf("%u: set inode size to %u blocks = %u bytes\n",
|
||||
ino, outdir->num, outdir->num * fs->blocksize);
|
||||
#endif
|
||||
retval = ext2fs_inode_size_set(fs, inode, (ext2_off64_t)outdir->num *
|
||||
fs->blocksize);
|
||||
if (retval)
|
||||
return retval;
|
||||
ext2fs_iblk_sub_blocks(fs, inode, wd.cleared);
|
||||
e2fsck_write_inode(ctx, ino, inode, "rehash_dir");
|
||||
|
||||
return 0;
|
||||
/* ext2fs_punch() calls ext2fs_write_inode() which writes the size */
|
||||
return ext2fs_punch(fs, ino, inode, NULL, outdir->num, ~0ULL);
|
||||
}
|
||||
|
||||
errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
|
||||
@ -789,12 +793,9 @@ errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
|
||||
errcode_t retval;
|
||||
struct ext2_inode inode;
|
||||
char *dir_buf = 0;
|
||||
struct fill_dir_struct fd;
|
||||
struct out_dir outdir;
|
||||
struct fill_dir_struct fd = { NULL };
|
||||
struct out_dir outdir = { 0 };
|
||||
|
||||
outdir.max = outdir.num = 0;
|
||||
outdir.buf = 0;
|
||||
outdir.hashes = 0;
|
||||
e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
|
||||
|
||||
if (ext2fs_has_feature_inline_data(fs->super) &&
|
||||
@ -802,24 +803,19 @@ errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino,
|
||||
return 0;
|
||||
|
||||
retval = ENOMEM;
|
||||
fd.harray = 0;
|
||||
dir_buf = malloc(inode.i_size);
|
||||
if (!dir_buf)
|
||||
goto errout;
|
||||
|
||||
fd.max_array = inode.i_size / 32;
|
||||
fd.num_array = 0;
|
||||
fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
|
||||
if (!fd.harray)
|
||||
goto errout;
|
||||
|
||||
fd.ino = ino;
|
||||
fd.ctx = ctx;
|
||||
fd.buf = dir_buf;
|
||||
fd.inode = &inode;
|
||||
fd.ino = ino;
|
||||
fd.err = 0;
|
||||
fd.dir_size = 0;
|
||||
fd.compress = 0;
|
||||
fd.dir = ino;
|
||||
if (!ext2fs_has_feature_dir_index(fs->super) ||
|
||||
(inode.i_size / fs->blocksize) < 2)
|
||||
|
@ -1819,8 +1819,15 @@ print_unsupp_features:
|
||||
}
|
||||
no_journal:
|
||||
|
||||
if (ctx->qctx) {
|
||||
if (run_result & E2F_FLAG_ABORT) {
|
||||
fatal_error(ctx, _("aborted"));
|
||||
} else if (run_result & E2F_FLAG_CANCEL) {
|
||||
log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ?
|
||||
ctx->device_name : ctx->filesystem_name);
|
||||
exit_value |= FSCK_CANCELED;
|
||||
} else if (ctx->qctx && !ctx->invalid_bitmaps) {
|
||||
int i, needs_writeout;
|
||||
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (qtype != -1 && qtype != i)
|
||||
continue;
|
||||
@ -1847,18 +1854,13 @@ no_journal:
|
||||
ext2fs_close_free(&ctx->fs);
|
||||
goto restart;
|
||||
}
|
||||
if (run_result & E2F_FLAG_ABORT)
|
||||
fatal_error(ctx, _("aborted"));
|
||||
|
||||
#ifdef MTRACE
|
||||
mtrace_print("Cleanup");
|
||||
#endif
|
||||
was_changed = ext2fs_test_changed(fs);
|
||||
if (run_result & E2F_FLAG_CANCEL) {
|
||||
log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ?
|
||||
ctx->device_name : ctx->filesystem_name);
|
||||
exit_value |= FSCK_CANCELED;
|
||||
} else if (!(ctx->options & E2F_OPT_READONLY)) {
|
||||
if (!(ctx->flags & E2F_FLAG_RUN_RETURN) &&
|
||||
!(ctx->options & E2F_OPT_READONLY)) {
|
||||
if (ext2fs_test_valid(fs)) {
|
||||
if (!(sb->s_state & EXT2_VALID_FS))
|
||||
exit_value |= FSCK_NONDESTRUCT;
|
||||
|
@ -48,7 +48,7 @@ static int check_zero_block(char *buf, int blocksize)
|
||||
*/
|
||||
static errcode_t ind_punch(ext2_filsys fs, struct ext2_inode *inode,
|
||||
char *block_buf, blk_t *p, int level,
|
||||
blk_t start, blk_t count, int max)
|
||||
blk64_t start, blk64_t count, int max)
|
||||
{
|
||||
errcode_t retval;
|
||||
blk_t b;
|
||||
@ -57,11 +57,11 @@ static errcode_t ind_punch(ext2_filsys fs, struct ext2_inode *inode,
|
||||
int freed = 0;
|
||||
|
||||
#ifdef PUNCH_DEBUG
|
||||
printf("Entering ind_punch, level %d, start %u, count %u, "
|
||||
printf("Entering ind_punch, level %d, start %llu, count %llu, "
|
||||
"max %d\n", level, start, count, max);
|
||||
#endif
|
||||
incr = 1ULL << ((EXT2_BLOCK_SIZE_BITS(fs->super)-2)*level);
|
||||
for (i=0, offset=0; i < max; i++, p++, offset += incr) {
|
||||
incr = 1ULL << ((EXT2_BLOCK_SIZE_BITS(fs->super) - 2) * level);
|
||||
for (i = 0, offset = 0; i < max; i++, p++, offset += incr) {
|
||||
if (offset >= start + count)
|
||||
break;
|
||||
if (*p == 0 || (offset+incr) <= start)
|
||||
@ -101,8 +101,9 @@ static errcode_t ind_punch(ext2_filsys fs, struct ext2_inode *inode,
|
||||
return ext2fs_iblk_sub_blocks(fs, inode, freed);
|
||||
}
|
||||
|
||||
#define BLK_T_MAX ((blk_t)~0ULL)
|
||||
static errcode_t ext2fs_punch_ind(ext2_filsys fs, struct ext2_inode *inode,
|
||||
char *block_buf, blk_t start, blk_t count)
|
||||
char *block_buf, blk64_t start, blk64_t end)
|
||||
{
|
||||
errcode_t retval;
|
||||
char *buf = 0;
|
||||
@ -111,6 +112,15 @@ static errcode_t ext2fs_punch_ind(ext2_filsys fs, struct ext2_inode *inode,
|
||||
blk_t *bp = inode->i_block;
|
||||
blk_t addr_per_block;
|
||||
blk64_t max = EXT2_NDIR_BLOCKS;
|
||||
blk_t count;
|
||||
|
||||
/* Check start/end don't overflow the 2^32-1 indirect block limit */
|
||||
if (start > BLK_T_MAX)
|
||||
return 0;
|
||||
if (end >= BLK_T_MAX || end - start + 1 >= BLK_T_MAX)
|
||||
count = BLK_T_MAX - start;
|
||||
else
|
||||
count = end - start + 1;
|
||||
|
||||
if (!block_buf) {
|
||||
retval = ext2fs_get_array(3, fs->blocksize, &buf);
|
||||
@ -119,11 +129,11 @@ static errcode_t ext2fs_punch_ind(ext2_filsys fs, struct ext2_inode *inode,
|
||||
block_buf = buf;
|
||||
}
|
||||
|
||||
addr_per_block = (blk_t) fs->blocksize >> 2;
|
||||
addr_per_block = (blk_t)fs->blocksize >> 2;
|
||||
|
||||
for (level = 0; level < 4; level++, max *= (blk64_t)addr_per_block) {
|
||||
#ifdef PUNCH_DEBUG
|
||||
printf("Main loop level %d, start %u count %u "
|
||||
printf("Main loop level %d, start %llu count %u "
|
||||
"max %llu num %d\n", level, start, count, max, num);
|
||||
#endif
|
||||
if (start < max) {
|
||||
@ -150,6 +160,7 @@ errout:
|
||||
ext2fs_free_mem(&buf);
|
||||
return retval;
|
||||
}
|
||||
#undef BLK_T_MAX
|
||||
|
||||
#ifdef PUNCH_DEBUG
|
||||
|
||||
@ -460,8 +471,8 @@ static errcode_t ext2fs_punch_inline_data(ext2_filsys fs, ext2_ino_t ino,
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate all logical blocks starting at start to end, inclusive.
|
||||
* If end is ~0, then this is effectively truncate.
|
||||
* Deallocate all logical _blocks_ starting at start to end, inclusive.
|
||||
* If end is ~0ULL, then this is effectively truncate.
|
||||
*/
|
||||
errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
|
||||
struct ext2_inode *inode,
|
||||
@ -485,19 +496,14 @@ errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
|
||||
return ext2fs_punch_inline_data(fs, ino, inode, start, end);
|
||||
else if (inode->i_flags & EXT4_EXTENTS_FL)
|
||||
retval = ext2fs_punch_extent(fs, ino, inode, start, end);
|
||||
else {
|
||||
blk_t count;
|
||||
|
||||
if (start > ~0U)
|
||||
return 0;
|
||||
if (end > ~0U)
|
||||
end = ~0U;
|
||||
count = ((end - start + 1) < ~0U) ? (end - start + 1) : ~0U;
|
||||
retval = ext2fs_punch_ind(fs, inode, block_buf,
|
||||
(blk_t) start, count);
|
||||
}
|
||||
else
|
||||
retval = ext2fs_punch_ind(fs, inode, block_buf, start, end);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
#ifdef PUNCH_DEBUG
|
||||
printf("%u: write inode size now %u blocks %u\n",
|
||||
ino, inode->i_size, inode->i_blocks);
|
||||
#endif
|
||||
return ext2fs_write_inode(fs, ino, inode);
|
||||
}
|
||||
|
@ -30,11 +30,11 @@
|
||||
#define DEL_BLK 0x0002
|
||||
|
||||
blk_t test1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0 };
|
||||
blk_t test2[] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 1 };
|
||||
blk_t test2[] = { 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 1, 0 };
|
||||
blk_t test3[] = { 3, 1, 4, 5, 9, 2, 7, 10, 5, 6, 10, 8, 0 };
|
||||
blk_t test4[] = { 20, 50, 12, 17, 13, 2, 66, 23, 56, 0 };
|
||||
blk_t test4a[] = {
|
||||
20, 1,
|
||||
20, 1,
|
||||
50, 1,
|
||||
3, 0,
|
||||
17, 1,
|
||||
|
@ -93,7 +93,7 @@ set on new or empty files. If it is set on a file which already has
|
||||
data blocks, it is undefined when the blocks assigned to the file will
|
||||
be fully stable. If the 'C' flag is set on a directory, it will have no
|
||||
effect on the directory, but new files created in that directory will
|
||||
the No_COW attribute.)
|
||||
have the No_COW attribute set.)
|
||||
.PP
|
||||
A file with the 'd' attribute set is not candidate for backup when the
|
||||
.BR dump (8)
|
||||
|
@ -3070,6 +3070,18 @@ retry_open:
|
||||
ext_mount_opts);
|
||||
free(ext_mount_opts);
|
||||
}
|
||||
|
||||
/* Warn if file system needs recovery and it is opened for writing. */
|
||||
if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
|
||||
(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
|
||||
(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
|
||||
fprintf(stderr,
|
||||
_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
|
||||
"\te2fsck -E journal_only %s\n\n"
|
||||
"then rerun this command. Otherwise, any changes made may be overwritten\n"
|
||||
"by journal recovery.\n"), device_name);
|
||||
}
|
||||
|
||||
free(device_name);
|
||||
remove_error_table(&et_ext2_error_table);
|
||||
|
||||
|
29
tests/f_extent_htree/expect.1
Normal file
29
tests/f_extent_htree/expect.1
Normal file
@ -0,0 +1,29 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Pass 2: Checking directory structure
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 3A: Optimizing directories
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
|
||||
352 inodes used (41.12%, out of 856)
|
||||
0 non-contiguous files (0.0%)
|
||||
1 non-contiguous directory (0.3%)
|
||||
# of inodes with ind/dind/tind blocks: 0/0/0
|
||||
Extent depth histogram: 342/1
|
||||
586 blocks used (68.94%, out of 850)
|
||||
0 bad blocks
|
||||
0 large files
|
||||
|
||||
340 regular files
|
||||
3 directories
|
||||
0 character device files
|
||||
0 block device files
|
||||
0 fifos
|
||||
0 links
|
||||
0 symbolic links (0 fast symbolic links)
|
||||
0 sockets
|
||||
------------
|
||||
343 files
|
||||
Exit status is 1
|
7
tests/f_extent_htree/expect.2
Normal file
7
tests/f_extent_htree/expect.2
Normal file
@ -0,0 +1,7 @@
|
||||
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: 352/856 files (0.3% non-contiguous), 586/850 blocks
|
||||
Exit status is 0
|
BIN
tests/f_extent_htree/image.gz
Normal file
BIN
tests/f_extent_htree/image.gz
Normal file
Binary file not shown.
1
tests/f_extent_htree/name
Normal file
1
tests/f_extent_htree/name
Normal file
@ -0,0 +1 @@
|
||||
htree extent compression
|
69
tests/f_extent_htree/script
Normal file
69
tests/f_extent_htree/script
Normal file
@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
|
||||
FSCK_OPT="-fyvD"
|
||||
. $cmd_dir/run_e2fsck
|
||||
|
||||
exit $?
|
||||
# This script depends on "mke2fs -d", which is only in master and not maint,
|
||||
# to populate the file directory tree poorly (namely that there are no
|
||||
# contiguous blocks in the directory leaf and the extent tree is large).
|
||||
|
||||
# Once the "mke2fs -d" option is available on the "maint" branch, the
|
||||
# above few lines should be deleted, along with the "image.gz" file.
|
||||
|
||||
TMPDIR=${TMPDIR:-"/tmp"}
|
||||
OUT=$test_name.log
|
||||
|
||||
FSCK_OPT="-fyvD"
|
||||
SKIP_GUNZIP="true"
|
||||
|
||||
NAMELEN=250
|
||||
SRC=$TMPDIR/$test_name.tmp
|
||||
SUB=subdir
|
||||
BASE=$SRC/$SUB/$(yes | tr -d '\n' | dd bs=$NAMELEN count=1 2> /dev/null)
|
||||
TMPFILE=${TMPFILE:-"$TMPDIR/image"}
|
||||
BSIZE=1024
|
||||
|
||||
> $OUT
|
||||
mkdir -p $SRC/$SUB
|
||||
# calculate the number of files needed to create the directory extent tree
|
||||
# deep enough to exceed the in-inode index and spill into an index block.
|
||||
#
|
||||
# dirents per block * extents per block * (index blocks > i_blocks)
|
||||
NUM=$(((BSIZE / (NAMELEN + 8)) * (BSIZE / 12) * 2))
|
||||
# Create source files. Unfortunately hard links will be copied as links,
|
||||
# and blocks with only NULs will be turned into holes.
|
||||
if [ ! -f $BASE.1 ]; then
|
||||
for N in $(seq $NUM); do
|
||||
echo "foo" > $BASE.$N
|
||||
done >> $OUT
|
||||
fi
|
||||
|
||||
# make filesystem with enough inodes and blocks to hold all the test files
|
||||
> $TMPFILE
|
||||
NUM=$((NUM * 5 / 3))
|
||||
echo "mke2fs -b $BSIZE -O dir_index,extent -d$SRC -N$NUM $TMPFILE $NUM" >> $OUT
|
||||
$MKE2FS -b $BSIZE -O dir_index,extent -d$SRC -N$NUM $TMPFILE $NUM >> $OUT 2>&1
|
||||
rm -r $SRC
|
||||
|
||||
# Run e2fsck to convert dir to htree before deleting the files, as mke2fs
|
||||
# doesn't do this. Run second e2fsck to verify there is no corruption yet.
|
||||
(
|
||||
EXP1=$test_dir/expect.pre.1
|
||||
EXP2=$test_dir/expect.pre.2
|
||||
OUT1=$test_name.pre.1.log
|
||||
OUT2=$test_name.pre.2.log
|
||||
DESCRIPTION="$(cat $test_dir/name) setup"
|
||||
. $cmd_dir/run_e2fsck
|
||||
)
|
||||
|
||||
# generate a list of filenames for debugfs to delete, one from each leaf block
|
||||
DELETE_LIST=$TMPDIR/delete.$$
|
||||
$DEBUGFS -c -R "htree subdir" $TMPFILE 2>> $OUT |
|
||||
grep -A2 "Reading directory block" |
|
||||
awk '/yyyyy/ { print "rm '$SUB'/"$4 }' > $DELETE_LIST
|
||||
$DEBUGFS -w -f $DELETE_LIST $TMPFILE >> $OUT 2>&1
|
||||
rm $DELETE_LIST
|
||||
cp $TMPFILE $TMPFILE.sav
|
||||
|
||||
. $cmd_dir/run_e2fsck
|
@ -27,8 +27,7 @@ Inode 17 extent tree (at level 1) could be shorter. Fix? yes
|
||||
|
||||
Inode 17, i_blocks is 32, should be 0. Fix? yes
|
||||
|
||||
Error while reading over extent tree in inode 18: Corrupt extent header
|
||||
Clear inode? yes
|
||||
Inode 18 has corrupt extent header. Clear inode? yes
|
||||
|
||||
Inode 18, i_blocks is 2, should be 0. Fix? yes
|
||||
|
||||
|
@ -14,5 +14,5 @@ Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
test_filesys: 47730/100192 files (0.0% non-contiguous), 13551/31745 blocks
|
||||
test_filesys: 47730/100192 files (0.0% non-contiguous), 13550/31745 blocks
|
||||
Exit status is 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: 47730/100192 files (0.0% non-contiguous), 13551/31745 blocks
|
||||
test_filesys: 47730/100192 files (0.0% non-contiguous), 13550/31745 blocks
|
||||
Exit status is 0
|
||||
|
22
tests/f_zeroed_ext_header/expect.1
Normal file
22
tests/f_zeroed_ext_header/expect.1
Normal file
@ -0,0 +1,22 @@
|
||||
Pass 1: Checking inodes, blocks, and sizes
|
||||
Inode 12 has corrupt extent header. Clear inode? yes
|
||||
|
||||
Pass 2: Checking directory structure
|
||||
Entry 'testa' in / (2) has deleted/unused inode 12. Clear? yes
|
||||
|
||||
Pass 3: Checking directory connectivity
|
||||
Pass 4: Checking reference counts
|
||||
Pass 5: Checking group summary information
|
||||
Inode bitmap differences: -12
|
||||
Fix? yes
|
||||
|
||||
Free inodes count wrong for group #0 (115, counted=116).
|
||||
Fix? yes
|
||||
|
||||
Free inodes count wrong (115, counted=116).
|
||||
Fix? yes
|
||||
|
||||
|
||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||
test_filesys: 12/128 files (0.0% non-contiguous), 15/256 blocks
|
||||
Exit status is 1
|
7
tests/f_zeroed_ext_header/expect.2
Normal file
7
tests/f_zeroed_ext_header/expect.2
Normal file
@ -0,0 +1,7 @@
|
||||
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: 12/128 files (0.0% non-contiguous), 15/256 blocks
|
||||
Exit status is 0
|
BIN
tests/f_zeroed_ext_header/image.gz
Normal file
BIN
tests/f_zeroed_ext_header/image.gz
Normal file
Binary file not shown.
1
tests/f_zeroed_ext_header/name
Normal file
1
tests/f_zeroed_ext_header/name
Normal file
@ -0,0 +1 @@
|
||||
zap inode with zeroed extent header
|
Loading…
Reference in New Issue
Block a user