mirror of https://github.com/vitalif/e2fsprogs
Overhaul extended attribute handling. Should now be correct with
respect to the latest V2 bestbits ACL code.bitmap-optimize
parent
0ccd488a76
commit
0684a4f33b
|
@ -1,3 +1,71 @@
|
||||||
|
2002-08-17 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
|
* e2fsck.h, e2fsck.c (e2fsck_allocate_context): Add new field to
|
||||||
|
the e2fsck context, ext_attr_ver, which specifies the EA
|
||||||
|
format version.
|
||||||
|
|
||||||
|
* unix.c (usage, parse_extended_opts, PRS), e2fsck.8.in: Add new
|
||||||
|
option -E, which allows the users to specify extended
|
||||||
|
options. Added ea_ver extended option.
|
||||||
|
|
||||||
|
* pass1.c (e2fsck_pass1_check_device_inode): Add ext2_filsys
|
||||||
|
argument to this function, so we can account for the
|
||||||
|
presence of extended attribute blocks attached to device
|
||||||
|
inodes.
|
||||||
|
(e2fsck_pass1_check_symlink, e2fsck_pass1): Take into
|
||||||
|
account the fact that symlinks can also have extended
|
||||||
|
attribute blocks.
|
||||||
|
(check_ext_attr): Don't be flexible about the EA format
|
||||||
|
version. Check against the version number in
|
||||||
|
ctx->ext_attr_ver.
|
||||||
|
(check_blocks): Check all inodes, so that we account for
|
||||||
|
extended attribute blocks belonging to special files.
|
||||||
|
Clean up i_size checks.
|
||||||
|
|
||||||
|
* pass1b.c (pass1b): Check all inodes, so that we account for
|
||||||
|
extended attribute blocks belonging to special files.
|
||||||
|
(delete_file_block): Use ext2fs_alloc_block_stats() to
|
||||||
|
update the filesystem statistics.
|
||||||
|
(delete_file): Attempt to decrement the extended
|
||||||
|
attribute refcount, and free the EA block if the count
|
||||||
|
hits zero.
|
||||||
|
(clone_file): Fixed bugs in EA handling. Don't call
|
||||||
|
block_iterate on inodes that don't have a valid i_block[]
|
||||||
|
array. Reread the base inode since it may have been
|
||||||
|
changed by ext2fs_block_iterate. When updating inodes as
|
||||||
|
part of cloning an EA block, write out the correct inode
|
||||||
|
structure.
|
||||||
|
|
||||||
|
* pass2.c (deallocate_inode_block, deallocate_inode): Use standard
|
||||||
|
ext2fs_alloc_*_stats functions to update the filesystem
|
||||||
|
statistics.
|
||||||
|
(deallocate_inode): Attempt to decrement the extended
|
||||||
|
attribute refcount, and free the EA block if the count
|
||||||
|
hits zero.
|
||||||
|
(e2fsck_process_bad_inode): Add extra argument to calls
|
||||||
|
to e2fsck_pass1_check_device_inode ().
|
||||||
|
|
||||||
|
* pass3.c (e2fsck_get_lost_and_found): Use standard
|
||||||
|
ext2fs_alloc_*_stats functions to update the filesystem.
|
||||||
|
statistics when creating /lost+found.
|
||||||
|
(adjust_inode_count): Remove debugging code that can never
|
||||||
|
be triggered.
|
||||||
|
|
||||||
|
* pass4.c (disconnect_inode): Add explanation about why we only
|
||||||
|
clear inodes that have no data blocks and no EA blocks.
|
||||||
|
Use ext2fs_inode_alloc_stats2 function to update the
|
||||||
|
filesystem statistics when clearing a zero-length inode.
|
||||||
|
|
||||||
|
* problem.c, problem.h (PR_1B_ADJ_EA_REFCOUNT,
|
||||||
|
PR_2_ADJ_EA_REFCOUNT): Add new problem codes.
|
||||||
|
|
||||||
|
* super.c (release_inode_block), (release_orphan_inodes): Use the
|
||||||
|
standard ext2fs_alloc_*_stats functions to update the
|
||||||
|
filesystem statistics.
|
||||||
|
(release_inode_blocks): Attempt to decrement the extended
|
||||||
|
attribute refcount, and free the EA block if the count
|
||||||
|
hits zero.
|
||||||
|
|
||||||
2002-08-01 Theodore Ts'o <tytso@mit.edu>
|
2002-08-01 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
* dict.c, dict.h: New file from kazlib 1.20 which implements a
|
* dict.c, dict.h: New file from kazlib 1.20 which implements a
|
||||||
|
|
|
@ -30,6 +30,10 @@ e2fsck \- check a Linux second extended file system
|
||||||
@JDEV@.B \-j
|
@JDEV@.B \-j
|
||||||
@JDEV@.I external-journal
|
@JDEV@.I external-journal
|
||||||
@JDEV@]
|
@JDEV@]
|
||||||
|
[
|
||||||
|
.B \-E
|
||||||
|
.I extended_options
|
||||||
|
]
|
||||||
.I device
|
.I device
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B e2fsck
|
.B e2fsck
|
||||||
|
@ -122,6 +126,18 @@ filesystem supports directory indexing, or by sorting and compressing
|
||||||
directories for smaller directories, or for filesystems using
|
directories for smaller directories, or for filesystems using
|
||||||
traditional linear directories.
|
traditional linear directories.
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-E " extended_options"
|
||||||
|
Set e2fsck extended options. Extended options are comma
|
||||||
|
separated, and may take an argument using the equals ('=') sign. The
|
||||||
|
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.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
.B \-f
|
.B \-f
|
||||||
Force checking even if the file system seems clean.
|
Force checking even if the file system seems clean.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -30,6 +30,7 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret)
|
||||||
memset(context, 0, sizeof(struct e2fsck_struct));
|
memset(context, 0, sizeof(struct e2fsck_struct));
|
||||||
|
|
||||||
context->process_inode_size = 256;
|
context->process_inode_size = 256;
|
||||||
|
context->ext_attr_ver = 2;
|
||||||
|
|
||||||
*ret = context;
|
*ret = context;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -308,6 +308,8 @@ struct e2fsck_struct {
|
||||||
int fs_ext_attr_inodes;
|
int fs_ext_attr_inodes;
|
||||||
int fs_ext_attr_blocks;
|
int fs_ext_attr_blocks;
|
||||||
|
|
||||||
|
int ext_attr_ver;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For the use of callers of the e2fsck functions; not used by
|
* For the use of callers of the e2fsck functions; not used by
|
||||||
* e2fsck functions themselves.
|
* e2fsck functions themselves.
|
||||||
|
@ -382,7 +384,8 @@ extern void e2fsck_move_ext3_journal(e2fsck_t ctx);
|
||||||
|
|
||||||
/* pass1.c */
|
/* pass1.c */
|
||||||
extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
|
extern void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
|
||||||
extern int e2fsck_pass1_check_device_inode(struct ext2_inode *inode);
|
extern int e2fsck_pass1_check_device_inode(ext2_filsys fs,
|
||||||
|
struct ext2_inode *inode);
|
||||||
extern int e2fsck_pass1_check_symlink(ext2_filsys fs,
|
extern int e2fsck_pass1_check_symlink(ext2_filsys fs,
|
||||||
struct ext2_inode *inode, char *buf);
|
struct ext2_inode *inode, char *buf);
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ static void unwind_pass1(ext2_filsys fs)
|
||||||
* since they have the same requirement; the i_block fields should be
|
* since they have the same requirement; the i_block fields should be
|
||||||
* zero.
|
* zero.
|
||||||
*/
|
*/
|
||||||
int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
|
int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@ int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
|
||||||
* If i_blocks is non-zero, or the index flag is set, then
|
* If i_blocks is non-zero, or the index flag is set, then
|
||||||
* this is a bogus device/fifo/socket
|
* this is a bogus device/fifo/socket
|
||||||
*/
|
*/
|
||||||
if (inode->i_blocks || (inode->i_flags & EXT2_INDEX_FL))
|
if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
|
||||||
|
(inode->i_flags & EXT2_INDEX_FL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -179,14 +180,16 @@ int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode,
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
|
blk_t blocks;
|
||||||
|
|
||||||
if ((inode->i_size_high || inode->i_size == 0) ||
|
if ((inode->i_size_high || inode->i_size == 0) ||
|
||||||
(inode->i_flags & EXT2_INDEX_FL))
|
(inode->i_flags & EXT2_INDEX_FL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (inode->i_blocks) {
|
blocks = ext2fs_inode_data_blocks(fs, inode);
|
||||||
|
if (blocks) {
|
||||||
if ((inode->i_size >= fs->blocksize) ||
|
if ((inode->i_size >= fs->blocksize) ||
|
||||||
(inode->i_blocks != fs->blocksize >> 9) ||
|
(blocks != fs->blocksize >> 9) ||
|
||||||
(inode->i_block[0] < fs->super->s_first_data_block) ||
|
(inode->i_block[0] < fs->super->s_first_data_block) ||
|
||||||
(inode->i_block[0] >= fs->super->s_blocks_count))
|
(inode->i_block[0] >= fs->super->s_blocks_count))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -614,12 +617,12 @@ void e2fsck_pass1(e2fsck_t ctx)
|
||||||
ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
|
ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
|
||||||
ctx->fs_regular_count++;
|
ctx->fs_regular_count++;
|
||||||
} else if (LINUX_S_ISCHR (inode.i_mode) &&
|
} else if (LINUX_S_ISCHR (inode.i_mode) &&
|
||||||
e2fsck_pass1_check_device_inode(&inode)) {
|
e2fsck_pass1_check_device_inode(fs, &inode)) {
|
||||||
check_immutable(ctx, &pctx);
|
check_immutable(ctx, &pctx);
|
||||||
check_size(ctx, &pctx);
|
check_size(ctx, &pctx);
|
||||||
ctx->fs_chardev_count++;
|
ctx->fs_chardev_count++;
|
||||||
} else if (LINUX_S_ISBLK (inode.i_mode) &&
|
} else if (LINUX_S_ISBLK (inode.i_mode) &&
|
||||||
e2fsck_pass1_check_device_inode(&inode)) {
|
e2fsck_pass1_check_device_inode(fs, &inode)) {
|
||||||
check_immutable(ctx, &pctx);
|
check_immutable(ctx, &pctx);
|
||||||
check_size(ctx, &pctx);
|
check_size(ctx, &pctx);
|
||||||
ctx->fs_blockdev_count++;
|
ctx->fs_blockdev_count++;
|
||||||
|
@ -627,18 +630,19 @@ void e2fsck_pass1(e2fsck_t ctx)
|
||||||
e2fsck_pass1_check_symlink(fs, &inode, block_buf)) {
|
e2fsck_pass1_check_symlink(fs, &inode, block_buf)) {
|
||||||
check_immutable(ctx, &pctx);
|
check_immutable(ctx, &pctx);
|
||||||
ctx->fs_symlinks_count++;
|
ctx->fs_symlinks_count++;
|
||||||
if (!inode.i_blocks) {
|
if (ext2fs_inode_data_blocks(fs, &inode) == 0) {
|
||||||
ctx->fs_fast_symlinks_count++;
|
ctx->fs_fast_symlinks_count++;
|
||||||
|
check_blocks(ctx, &pctx, block_buf);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (LINUX_S_ISFIFO (inode.i_mode) &&
|
else if (LINUX_S_ISFIFO (inode.i_mode) &&
|
||||||
e2fsck_pass1_check_device_inode(&inode)) {
|
e2fsck_pass1_check_device_inode(fs, &inode)) {
|
||||||
check_immutable(ctx, &pctx);
|
check_immutable(ctx, &pctx);
|
||||||
check_size(ctx, &pctx);
|
check_size(ctx, &pctx);
|
||||||
ctx->fs_fifo_count++;
|
ctx->fs_fifo_count++;
|
||||||
} else if ((LINUX_S_ISSOCK (inode.i_mode)) &&
|
} else if ((LINUX_S_ISSOCK (inode.i_mode)) &&
|
||||||
e2fsck_pass1_check_device_inode(&inode)) {
|
e2fsck_pass1_check_device_inode(fs, &inode)) {
|
||||||
check_immutable(ctx, &pctx);
|
check_immutable(ctx, &pctx);
|
||||||
check_size(ctx, &pctx);
|
check_size(ctx, &pctx);
|
||||||
ctx->fs_sockets_count++;
|
ctx->fs_sockets_count++;
|
||||||
|
@ -990,7 +994,6 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
struct ext2_ext_attr_entry *entry;
|
struct ext2_ext_attr_entry *entry;
|
||||||
int count;
|
int count;
|
||||||
region_t region;
|
region_t region;
|
||||||
int ext_attr_ver;
|
|
||||||
|
|
||||||
blk = inode->i_file_acl;
|
blk = inode->i_file_acl;
|
||||||
if (blk == 0)
|
if (blk == 0)
|
||||||
|
@ -1068,12 +1071,13 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
goto clear_extattr;
|
goto clear_extattr;
|
||||||
header = (struct ext2_ext_attr_header *) block_buf;
|
header = (struct ext2_ext_attr_header *) block_buf;
|
||||||
pctx->blk = inode->i_file_acl;
|
pctx->blk = inode->i_file_acl;
|
||||||
if (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)
|
if (((ctx->ext_attr_ver == 1) &&
|
||||||
ext_attr_ver = 1;
|
(header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
|
||||||
if (header->h_magic != EXT2_EXT_ATTR_MAGIC)
|
((ctx->ext_attr_ver == 2) &&
|
||||||
ext_attr_ver = 2;
|
(header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
|
||||||
else if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
|
if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
|
||||||
goto clear_extattr;
|
goto clear_extattr;
|
||||||
|
}
|
||||||
|
|
||||||
if (header->h_blocks != 1) {
|
if (header->h_blocks != 1) {
|
||||||
if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
|
if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
|
||||||
|
@ -1099,9 +1103,9 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
|
if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
|
||||||
goto clear_extattr;
|
goto clear_extattr;
|
||||||
}
|
}
|
||||||
if ((ext_attr_ver == 1 &&
|
if ((ctx->ext_attr_ver == 1 &&
|
||||||
(entry->e_name_len == 0 || entry->e_name_index != 0)) ||
|
(entry->e_name_len == 0 || entry->e_name_index != 0)) ||
|
||||||
(ext_attr_ver == 2 &&
|
(ctx->ext_attr_ver == 2 &&
|
||||||
entry->e_name_index == 0)) {
|
entry->e_name_index == 0)) {
|
||||||
if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
|
if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
|
||||||
goto clear_extattr;
|
goto clear_extattr;
|
||||||
|
@ -1205,11 +1209,9 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
int dirty_inode = 0;
|
int dirty_inode = 0;
|
||||||
__u64 size;
|
__u64 size;
|
||||||
|
|
||||||
if (!ext2fs_inode_has_valid_blocks(inode))
|
|
||||||
return;
|
|
||||||
|
|
||||||
pb.ino = ino;
|
pb.ino = ino;
|
||||||
pb.num_blocks = pb.last_block = 0;
|
pb.num_blocks = 0;
|
||||||
|
pb.last_block = -1;
|
||||||
pb.num_illegal_blocks = 0;
|
pb.num_illegal_blocks = 0;
|
||||||
pb.suppress = 0; pb.clear = 0;
|
pb.suppress = 0; pb.clear = 0;
|
||||||
pb.fragmented = 0;
|
pb.fragmented = 0;
|
||||||
|
@ -1222,6 +1224,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
pb.pctx = pctx;
|
pb.pctx = pctx;
|
||||||
pb.ctx = ctx;
|
pb.ctx = ctx;
|
||||||
pctx->ino = ino;
|
pctx->ino = ino;
|
||||||
|
pctx->errcode = 0;
|
||||||
|
|
||||||
if (inode->i_flags & EXT2_COMPRBLK_FL) {
|
if (inode->i_flags & EXT2_COMPRBLK_FL) {
|
||||||
if (fs->super->s_feature_incompat &
|
if (fs->super->s_feature_incompat &
|
||||||
|
@ -1235,13 +1238,14 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ext2fs_inode_has_valid_blocks(inode))
|
||||||
pctx->errcode = ext2fs_block_iterate2(fs, ino,
|
pctx->errcode = ext2fs_block_iterate2(fs, ino,
|
||||||
pb.is_dir ? BLOCK_FLAG_HOLE : 0,
|
pb.is_dir ? BLOCK_FLAG_HOLE : 0,
|
||||||
block_buf, process_block, &pb);
|
block_buf, process_block, &pb);
|
||||||
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
|
|
||||||
goto out;
|
|
||||||
end_problem_latch(ctx, PR_LATCH_BLOCK);
|
end_problem_latch(ctx, PR_LATCH_BLOCK);
|
||||||
end_problem_latch(ctx, PR_LATCH_TOOBIG);
|
end_problem_latch(ctx, PR_LATCH_TOOBIG);
|
||||||
|
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
|
||||||
|
goto out;
|
||||||
if (pctx->errcode)
|
if (pctx->errcode)
|
||||||
fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
|
fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
|
||||||
|
|
||||||
|
@ -1280,15 +1284,6 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
((inode->i_size / fs->blocksize) >= 3))
|
((inode->i_size / fs->blocksize) >= 3))
|
||||||
ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
|
ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
|
||||||
|
|
||||||
if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
|
|
||||||
pb.num_blocks++;
|
|
||||||
|
|
||||||
pb.num_blocks *= (fs->blocksize / 512);
|
|
||||||
#if 0
|
|
||||||
printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
|
|
||||||
ino, inode->i_size, pb.last_block, inode->i_blocks,
|
|
||||||
pb.num_blocks);
|
|
||||||
#endif
|
|
||||||
if (!pb.num_blocks && pb.is_dir) {
|
if (!pb.num_blocks && pb.is_dir) {
|
||||||
if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
|
if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
|
||||||
inode->i_links_count = 0;
|
inode->i_links_count = 0;
|
||||||
|
@ -1299,9 +1294,19 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
|
||||||
ctx->fs_directory_count--;
|
ctx->fs_directory_count--;
|
||||||
pb.is_dir = 0;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
|
||||||
|
pb.num_blocks++;
|
||||||
|
|
||||||
|
pb.num_blocks *= (fs->blocksize / 512);
|
||||||
|
#if 0
|
||||||
|
printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
|
||||||
|
ino, inode->i_size, pb.last_block, inode->i_blocks,
|
||||||
|
pb.num_blocks);
|
||||||
|
#endif
|
||||||
if (pb.is_dir) {
|
if (pb.is_dir) {
|
||||||
int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
|
int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
|
||||||
if (nblock > (pb.last_block + 1))
|
if (nblock > (pb.last_block + 1))
|
||||||
|
@ -1312,19 +1317,19 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
|
||||||
bad_size = 2;
|
bad_size = 2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!LINUX_S_ISREG(inode->i_mode) && inode->i_size_high)
|
|
||||||
bad_size = 5;
|
|
||||||
size = inode->i_size | ((__u64) inode->i_size_high << 32);
|
size = inode->i_size | ((__u64) inode->i_size_high << 32);
|
||||||
if ((size < pb.last_block * fs->blocksize))
|
if ((pb.last_block >= 0) &&
|
||||||
|
(size < pb.last_block * fs->blocksize))
|
||||||
bad_size = 3;
|
bad_size = 3;
|
||||||
else if (size > ext2_max_sizes[fs->super->s_log_block_size])
|
else if (size > ext2_max_sizes[fs->super->s_log_block_size])
|
||||||
bad_size = 4;
|
bad_size = 4;
|
||||||
}
|
}
|
||||||
if (bad_size) {
|
/* i_size for symlinks is checked elsewhere */
|
||||||
|
if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
|
||||||
pctx->num = (pb.last_block+1) * fs->blocksize;
|
pctx->num = (pb.last_block+1) * fs->blocksize;
|
||||||
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
|
if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
|
||||||
inode->i_size = pctx->num;
|
inode->i_size = pctx->num;
|
||||||
if (LINUX_S_ISREG(inode->i_mode))
|
if (!LINUX_S_ISDIR(inode->i_mode))
|
||||||
inode->i_size_high = pctx->num >> 32;
|
inode->i_size_high = pctx->num >> 32;
|
||||||
dirty_inode++;
|
dirty_inode++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,15 +259,17 @@ static void pass1b(e2fsck_t ctx, char *block_buf)
|
||||||
while (ino) {
|
while (ino) {
|
||||||
pctx.ino = ctx->stashed_ino = ino;
|
pctx.ino = ctx->stashed_ino = ino;
|
||||||
if ((ino != EXT2_BAD_INO) &&
|
if ((ino != EXT2_BAD_INO) &&
|
||||||
(!ext2fs_test_inode_bitmap(ctx->inode_used_map, ino) ||
|
!ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
|
||||||
!ext2fs_inode_has_valid_blocks(&inode)))
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
pb.ino = ino;
|
pb.ino = ino;
|
||||||
pb.dup_blocks = 0;
|
pb.dup_blocks = 0;
|
||||||
pb.inode = &inode;
|
pb.inode = &inode;
|
||||||
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
|
||||||
process_pass1b_block, &pb);
|
if (ext2fs_inode_has_valid_blocks(&inode) ||
|
||||||
|
(ino == EXT2_BAD_INO))
|
||||||
|
pctx.errcode = ext2fs_block_iterate2(fs, ino,
|
||||||
|
0, block_buf, process_pass1b_block, &pb);
|
||||||
if (inode.i_file_acl)
|
if (inode.i_file_acl)
|
||||||
process_pass1b_block(fs, &inode.i_file_acl,
|
process_pass1b_block(fs, &inode.i_file_acl,
|
||||||
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
|
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
|
||||||
|
@ -543,7 +545,7 @@ static int delete_file_block(ext2_filsys fs,
|
||||||
*block_nr);
|
*block_nr);
|
||||||
} else {
|
} else {
|
||||||
ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
|
ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
|
||||||
ext2fs_unmark_block_bitmap(fs->block_map, *block_nr);
|
ext2fs_block_alloc_stats(fs, *block_nr, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -556,6 +558,7 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
struct process_block_struct pb;
|
struct process_block_struct pb;
|
||||||
struct ext2_inode inode;
|
struct ext2_inode inode;
|
||||||
struct problem_context pctx;
|
struct problem_context pctx;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
clear_problem_context(&pctx);
|
clear_problem_context(&pctx);
|
||||||
pctx.ino = pb.ino = ino;
|
pctx.ino = pb.ino = ino;
|
||||||
|
@ -563,6 +566,8 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
pb.ctx = ctx;
|
pb.ctx = ctx;
|
||||||
pctx.str = "delete_file";
|
pctx.str = "delete_file";
|
||||||
|
|
||||||
|
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
|
||||||
|
if (ext2fs_inode_has_valid_blocks(&inode))
|
||||||
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
||||||
delete_file_block, &pb);
|
delete_file_block, &pb);
|
||||||
if (pctx.errcode)
|
if (pctx.errcode)
|
||||||
|
@ -571,15 +576,37 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
|
||||||
if (ctx->inode_bad_map)
|
if (ctx->inode_bad_map)
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
|
||||||
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
|
ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
|
||||||
ext2fs_mark_ib_dirty(fs);
|
|
||||||
ext2fs_mark_bb_dirty(fs);
|
/* Inode may have changed by block_iterate, so reread it */
|
||||||
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
|
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
|
||||||
inode.i_links_count = 0;
|
inode.i_links_count = 0;
|
||||||
inode.i_dtime = time(0);
|
inode.i_dtime = time(0);
|
||||||
if (inode.i_file_acl)
|
if (inode.i_file_acl &&
|
||||||
|
(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
|
||||||
|
count = 1;
|
||||||
|
pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
|
||||||
|
block_buf, -1, &count);
|
||||||
|
if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
|
||||||
|
pctx.errcode = 0;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
if (pctx.errcode) {
|
||||||
|
pctx.blk = inode.i_file_acl;
|
||||||
|
fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the count is zero, then arrange to have the
|
||||||
|
* block deleted. If the block is in the block_dup_map,
|
||||||
|
* also call delete_file_block since it will take care
|
||||||
|
* of keeping the accounting straight.
|
||||||
|
*/
|
||||||
|
if ((count == 0) ||
|
||||||
|
ext2fs_test_block_bitmap(ctx->block_dup_map,
|
||||||
|
inode.i_file_acl))
|
||||||
delete_file_block(fs, &inode.i_file_acl,
|
delete_file_block(fs, &inode.i_file_acl,
|
||||||
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
|
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
|
||||||
|
}
|
||||||
e2fsck_write_inode(ctx, ino, &inode, "delete_file");
|
e2fsck_write_inode(ctx, ino, &inode, "delete_file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,6 +710,7 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
|
|
||||||
pctx.ino = ino;
|
pctx.ino = ino;
|
||||||
pctx.str = "clone_file";
|
pctx.str = "clone_file";
|
||||||
|
if (ext2fs_inode_has_valid_blocks(&dp->inode))
|
||||||
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
||||||
clone_file_block, &cs);
|
clone_file_block, &cs);
|
||||||
ext2fs_mark_bb_dirty(fs);
|
ext2fs_mark_bb_dirty(fs);
|
||||||
|
@ -697,6 +725,8 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
retval = cs.errcode;
|
retval = cs.errcode;
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
/* The inode may have changed on disk, so we have to re-read it */
|
||||||
|
e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
|
||||||
blk = dp->inode.i_file_acl;
|
blk = dp->inode.i_file_acl;
|
||||||
if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
|
if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
|
||||||
BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
|
BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
|
||||||
|
@ -717,7 +747,7 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
if (di->inode.i_file_acl == blk) {
|
if (di->inode.i_file_acl == blk) {
|
||||||
di->inode.i_file_acl = dp->inode.i_file_acl;
|
di->inode.i_file_acl = dp->inode.i_file_acl;
|
||||||
e2fsck_write_inode(ctx, ino_el->inode,
|
e2fsck_write_inode(ctx, ino_el->inode,
|
||||||
&dp->inode, "clone file EA");
|
&di->inode, "clone file EA");
|
||||||
decrement_badcount(ctx, blk, db);
|
decrement_badcount(ctx, blk, db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -886,7 +886,7 @@ static int deallocate_inode_block(ext2_filsys fs,
|
||||||
if (HOLE_BLKADDR(*block_nr))
|
if (HOLE_BLKADDR(*block_nr))
|
||||||
return 0;
|
return 0;
|
||||||
ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
|
ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
|
||||||
ext2fs_unmark_block_bitmap(fs->block_map, *block_nr);
|
ext2fs_block_alloc_stats(fs, *block_nr, -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,6 +898,7 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
|
||||||
ext2_filsys fs = ctx->fs;
|
ext2_filsys fs = ctx->fs;
|
||||||
struct ext2_inode inode;
|
struct ext2_inode inode;
|
||||||
struct problem_context pctx;
|
struct problem_context pctx;
|
||||||
|
__u32 count;
|
||||||
|
|
||||||
ext2fs_icount_store(ctx->inode_link_info, ino, 0);
|
ext2fs_icount_store(ctx->inode_link_info, ino, 0);
|
||||||
e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
|
e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
|
||||||
|
@ -915,8 +916,29 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
|
||||||
if (ctx->inode_bad_map)
|
if (ctx->inode_bad_map)
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
|
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
|
||||||
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
|
ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
|
||||||
ext2fs_mark_ib_dirty(fs);
|
|
||||||
|
if (inode.i_file_acl &&
|
||||||
|
(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
|
||||||
|
pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
|
||||||
|
block_buf, -1, &count);
|
||||||
|
if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
|
||||||
|
pctx.errcode = 0;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
if (pctx.errcode) {
|
||||||
|
pctx.blk = inode.i_file_acl;
|
||||||
|
fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
|
||||||
|
ctx->flags |= E2F_FLAG_ABORT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
ext2fs_unmark_block_bitmap(ctx->block_found_map,
|
||||||
|
inode.i_file_acl);
|
||||||
|
ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
|
||||||
|
}
|
||||||
|
inode.i_file_acl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ext2fs_inode_has_valid_blocks(&inode))
|
if (!ext2fs_inode_has_valid_blocks(&inode))
|
||||||
return;
|
return;
|
||||||
|
@ -925,13 +947,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
|
||||||
(inode.i_size_high || inode.i_size & 0x80000000UL))
|
(inode.i_size_high || inode.i_size & 0x80000000UL))
|
||||||
ctx->large_files--;
|
ctx->large_files--;
|
||||||
|
|
||||||
if (inode.i_file_acl) {
|
|
||||||
ext2fs_unmark_block_bitmap(ctx->block_found_map,
|
|
||||||
inode.i_file_acl);
|
|
||||||
ext2fs_unmark_block_bitmap(fs->block_map, inode.i_file_acl);
|
|
||||||
}
|
|
||||||
|
|
||||||
ext2fs_mark_bb_dirty(fs);
|
|
||||||
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
|
||||||
deallocate_inode_block, ctx);
|
deallocate_inode_block, ctx);
|
||||||
if (pctx.errcode) {
|
if (pctx.errcode) {
|
||||||
|
@ -947,7 +962,6 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
|
||||||
static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
|
static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
|
||||||
{
|
{
|
||||||
struct ext2_inode inode;
|
struct ext2_inode inode;
|
||||||
struct problem_context pctx;
|
|
||||||
|
|
||||||
e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
|
e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
|
||||||
inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
|
inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
|
||||||
|
@ -980,16 +994,16 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
|
||||||
!(LINUX_S_ISSOCK(inode.i_mode)))
|
!(LINUX_S_ISSOCK(inode.i_mode)))
|
||||||
problem = PR_2_BAD_MODE;
|
problem = PR_2_BAD_MODE;
|
||||||
else if (LINUX_S_ISCHR(inode.i_mode)
|
else if (LINUX_S_ISCHR(inode.i_mode)
|
||||||
&& !e2fsck_pass1_check_device_inode(&inode))
|
&& !e2fsck_pass1_check_device_inode(fs, &inode))
|
||||||
problem = PR_2_BAD_CHAR_DEV;
|
problem = PR_2_BAD_CHAR_DEV;
|
||||||
else if (LINUX_S_ISBLK(inode.i_mode)
|
else if (LINUX_S_ISBLK(inode.i_mode)
|
||||||
&& !e2fsck_pass1_check_device_inode(&inode))
|
&& !e2fsck_pass1_check_device_inode(fs, &inode))
|
||||||
problem = PR_2_BAD_BLOCK_DEV;
|
problem = PR_2_BAD_BLOCK_DEV;
|
||||||
else if (LINUX_S_ISFIFO(inode.i_mode)
|
else if (LINUX_S_ISFIFO(inode.i_mode)
|
||||||
&& !e2fsck_pass1_check_device_inode(&inode))
|
&& !e2fsck_pass1_check_device_inode(fs, &inode))
|
||||||
problem = PR_2_BAD_FIFO;
|
problem = PR_2_BAD_FIFO;
|
||||||
else if (LINUX_S_ISSOCK(inode.i_mode)
|
else if (LINUX_S_ISSOCK(inode.i_mode)
|
||||||
&& !e2fsck_pass1_check_device_inode(&inode))
|
&& !e2fsck_pass1_check_device_inode(fs, &inode))
|
||||||
problem = PR_2_BAD_SOCKET;
|
problem = PR_2_BAD_SOCKET;
|
||||||
else if (LINUX_S_ISLNK(inode.i_mode)
|
else if (LINUX_S_ISLNK(inode.i_mode)
|
||||||
&& !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
|
&& !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
|
||||||
|
|
|
@ -430,8 +430,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
|
ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
|
||||||
ext2fs_mark_block_bitmap(fs->block_map, blk);
|
ext2fs_block_alloc_stats(fs, blk, +1);
|
||||||
ext2fs_mark_bb_dirty(fs);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Next find a free inode.
|
* Next find a free inode.
|
||||||
|
@ -445,8 +444,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
|
||||||
}
|
}
|
||||||
ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
|
ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
|
||||||
ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
|
ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
|
||||||
ext2fs_mark_inode_bitmap(fs->inode_map, ino);
|
ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
|
||||||
ext2fs_mark_ib_dirty(fs);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now let's create the actual data block for the inode
|
* Now let's create the actual data block for the inode
|
||||||
|
@ -594,10 +592,6 @@ static errcode_t adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
|
||||||
return 0;
|
return 0;
|
||||||
ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
|
ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
|
||||||
inode.i_links_count--;
|
inode.i_links_count--;
|
||||||
} else {
|
|
||||||
/* Should never happen */
|
|
||||||
fatal_error(ctx, _("Debug error in e2fsck adjust_inode_count, "
|
|
||||||
"should never happen.\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = ext2fs_write_inode(fs, ino, &inode);
|
retval = ext2fs_write_inode(fs, ino, &inode);
|
||||||
|
|
|
@ -34,11 +34,14 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
|
||||||
pctx.ino = i;
|
pctx.ino = i;
|
||||||
pctx.inode = &inode;
|
pctx.inode = &inode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Offer to delete any zero-length files that does not have
|
||||||
|
* blocks. If there is an EA block, it might have useful
|
||||||
|
* information, so we won't prompt to delete it, but let it be
|
||||||
|
* reconnected to lost+found.
|
||||||
|
*/
|
||||||
if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
|
if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
|
||||||
LINUX_S_ISDIR(inode.i_mode))) {
|
LINUX_S_ISDIR(inode.i_mode))) {
|
||||||
/*
|
|
||||||
* This is a zero-length file; prompt to delete it...
|
|
||||||
*/
|
|
||||||
if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
|
if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
|
||||||
ext2fs_icount_store(ctx->inode_link_info, i, 0);
|
ext2fs_icount_store(ctx->inode_link_info, i, 0);
|
||||||
inode.i_links_count = 0;
|
inode.i_links_count = 0;
|
||||||
|
@ -51,8 +54,8 @@ static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
|
||||||
e2fsck_read_bitmaps(ctx);
|
e2fsck_read_bitmaps(ctx);
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
|
ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
|
||||||
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
|
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
|
||||||
ext2fs_unmark_inode_bitmap(fs->inode_map, i);
|
ext2fs_inode_alloc_stats2(fs, i, -1,
|
||||||
ext2fs_mark_ib_dirty(fs);
|
LINUX_S_ISDIR(inode.i_mode));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -736,6 +736,12 @@ static const struct e2fsck_problem problem_table[] = {
|
||||||
N_("Error while iterating over @bs in @i %i (%s): %m\n"),
|
N_("Error while iterating over @bs in @i %i (%s): %m\n"),
|
||||||
PROMPT_NONE, 0 },
|
PROMPT_NONE, 0 },
|
||||||
|
|
||||||
|
/* Error adjusting EA refcount */
|
||||||
|
{ PR_1B_ADJ_EA_REFCOUNT,
|
||||||
|
N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
|
||||||
|
PROMPT_NONE, 0 },
|
||||||
|
|
||||||
|
|
||||||
/* Pass 1C: Scan directories for inodes with dup blocks. */
|
/* Pass 1C: Scan directories for inodes with dup blocks. */
|
||||||
{ PR_1C_PASS_HEADER,
|
{ PR_1C_PASS_HEADER,
|
||||||
N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
|
N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
|
||||||
|
@ -1051,6 +1057,11 @@ static const struct e2fsck_problem problem_table[] = {
|
||||||
N_("@p @h %d (%q): bad @b number %b.\n"),
|
N_("@p @h %d (%q): bad @b number %b.\n"),
|
||||||
PROMPT_CLEAR_HTREE, 0 },
|
PROMPT_CLEAR_HTREE, 0 },
|
||||||
|
|
||||||
|
/* Error adjusting EA refcount */
|
||||||
|
{ PR_2_ADJ_EA_REFCOUNT,
|
||||||
|
N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
|
||||||
|
PROMPT_NONE, PR_FATAL },
|
||||||
|
|
||||||
/* Pass 3 errors */
|
/* Pass 3 errors */
|
||||||
|
|
||||||
/* Pass 3: Checking directory connectivity */
|
/* Pass 3: Checking directory connectivity */
|
||||||
|
|
|
@ -429,6 +429,9 @@ struct problem_context {
|
||||||
/* Error while iterating over blocks */
|
/* Error while iterating over blocks */
|
||||||
#define PR_1B_BLOCK_ITERATE 0x0110006
|
#define PR_1B_BLOCK_ITERATE 0x0110006
|
||||||
|
|
||||||
|
/* Error adjusting EA refcount */
|
||||||
|
#define PR_1B_ADJ_EA_REFCOUNT 0x0110007
|
||||||
|
|
||||||
|
|
||||||
/* Pass 1C: Scan directories for inodes with dup blocks. */
|
/* Pass 1C: Scan directories for inodes with dup blocks. */
|
||||||
#define PR_1C_PASS_HEADER 0x012000
|
#define PR_1C_PASS_HEADER 0x012000
|
||||||
|
@ -624,6 +627,9 @@ struct problem_context {
|
||||||
/* Bad block in htree interior node */
|
/* Bad block in htree interior node */
|
||||||
#define PR_2_HTREE_BADBLK 0x02003A
|
#define PR_2_HTREE_BADBLK 0x02003A
|
||||||
|
|
||||||
|
/* Error adjusting EA refcount */
|
||||||
|
#define PR_2_ADJ_EA_REFCOUNT 0x02003B
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass 3 errors
|
* Pass 3 errors
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -152,10 +152,7 @@ static int release_inode_block(ext2_filsys fs,
|
||||||
retval |= BLOCK_CHANGED;
|
retval |= BLOCK_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext2fs_unmark_block_bitmap(fs->block_map, blk);
|
ext2fs_block_alloc_stats(fs, blk, -1);
|
||||||
fs->group_desc[ext2fs_group_of_blk(fs, blk)].bg_free_blocks_count++;
|
|
||||||
fs->super->s_free_blocks_count++;
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,9 +165,10 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
struct ext2_inode *inode, char *block_buf,
|
struct ext2_inode *inode, char *block_buf,
|
||||||
struct problem_context *pctx)
|
struct problem_context *pctx)
|
||||||
{
|
{
|
||||||
|
struct process_block_struct pb;
|
||||||
ext2_filsys fs = ctx->fs;
|
ext2_filsys fs = ctx->fs;
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
struct process_block_struct pb;
|
__u32 count;
|
||||||
|
|
||||||
if (!ext2fs_inode_has_valid_blocks(inode))
|
if (!ext2fs_inode_has_valid_blocks(inode))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -211,7 +209,23 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
inode->i_blocks -= pb.truncated_blocks *
|
inode->i_blocks -= pb.truncated_blocks *
|
||||||
(fs->blocksize / 512);
|
(fs->blocksize / 512);
|
||||||
|
|
||||||
ext2fs_mark_bb_dirty(fs);
|
if (inode->i_file_acl) {
|
||||||
|
retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
|
||||||
|
block_buf, -1, &count);
|
||||||
|
if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
|
||||||
|
retval = 0;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
if (retval) {
|
||||||
|
com_err("release_inode_blocks", retval,
|
||||||
|
_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
|
||||||
|
ino);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (count == 0)
|
||||||
|
ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
|
||||||
|
inode->i_file_acl = 0;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +236,6 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
|
||||||
static int release_orphan_inodes(e2fsck_t ctx)
|
static int release_orphan_inodes(e2fsck_t ctx)
|
||||||
{
|
{
|
||||||
ext2_filsys fs = ctx->fs;
|
ext2_filsys fs = ctx->fs;
|
||||||
int group;
|
|
||||||
ext2_ino_t ino, next_ino;
|
ext2_ino_t ino, next_ino;
|
||||||
struct ext2_inode inode;
|
struct ext2_inode inode;
|
||||||
struct problem_context pctx;
|
struct problem_context pctx;
|
||||||
|
@ -281,14 +294,8 @@ static int release_orphan_inodes(e2fsck_t ctx)
|
||||||
goto return_abort;
|
goto return_abort;
|
||||||
|
|
||||||
if (!inode.i_links_count) {
|
if (!inode.i_links_count) {
|
||||||
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
|
ext2fs_inode_alloc_stats2(fs, ino, -1,
|
||||||
ext2fs_mark_ib_dirty(fs);
|
LINUX_S_ISDIR(inode.i_mode));
|
||||||
group = ext2fs_group_of_ino(fs, ino);
|
|
||||||
fs->group_desc[group].bg_free_inodes_count++;
|
|
||||||
fs->super->s_free_inodes_count++;
|
|
||||||
if (LINUX_S_ISDIR(inode.i_mode))
|
|
||||||
fs->group_desc[group].bg_used_dirs_count--;
|
|
||||||
|
|
||||||
inode.i_dtime = time(0);
|
inode.i_dtime = time(0);
|
||||||
} else {
|
} else {
|
||||||
inode.i_dtime = 0;
|
inode.i_dtime = 0;
|
||||||
|
|
|
@ -61,7 +61,8 @@ static void usage(e2fsck_t ctx)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n"
|
_("Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n"
|
||||||
"\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
|
"\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
|
||||||
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal] device\n"),
|
"\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal]\n"
|
||||||
|
"\t\t[-E extended-options] device\n"),
|
||||||
ctx->program_name);
|
ctx->program_name);
|
||||||
|
|
||||||
fprintf(stderr, _("\nEmergency help:\n"
|
fprintf(stderr, _("\nEmergency help:\n"
|
||||||
|
@ -448,6 +449,60 @@ static void signal_cancel(int sig)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void parse_extended_opts(e2fsck_t ctx, const char *opts)
|
||||||
|
{
|
||||||
|
char *buf, *token, *next, *p, *arg;
|
||||||
|
int len, ea_ver;
|
||||||
|
int extended_usage = 0;
|
||||||
|
|
||||||
|
len = strlen(opts);
|
||||||
|
buf = malloc(len+1);
|
||||||
|
if (!buf) {
|
||||||
|
fprintf(stderr, _("Couldn't allocate memory to parse "
|
||||||
|
"extended options!\n"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
strcpy(buf, opts);
|
||||||
|
for (token = buf; token && *token; token = next) {
|
||||||
|
p = strchr(token, ',');
|
||||||
|
next = 0;
|
||||||
|
if (p) {
|
||||||
|
*p = 0;
|
||||||
|
next = p+1;
|
||||||
|
}
|
||||||
|
arg = strchr(token, '=');
|
||||||
|
if (arg) {
|
||||||
|
*arg = 0;
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
if (strcmp(token, "ea_ver") == 0) {
|
||||||
|
if (!arg) {
|
||||||
|
extended_usage++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ea_ver = strtoul(arg, &p, 0);
|
||||||
|
if (*p ||
|
||||||
|
((ea_ver != 1) && (ea_ver != 2))) {
|
||||||
|
fprintf(stderr,
|
||||||
|
_("Invalid EA version.\n"));
|
||||||
|
extended_usage++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ctx->ext_attr_ver = ea_ver;
|
||||||
|
} else
|
||||||
|
extended_usage++;
|
||||||
|
}
|
||||||
|
if (extended_usage) {
|
||||||
|
fprintf(stderr, _("Extended options are separated by commas, "
|
||||||
|
"and may take an argument which\n"
|
||||||
|
"is set off by an equals ('=') sign. "
|
||||||
|
"Valid raid options are:\n"
|
||||||
|
"\tea_ver=<ea_version (1 or 2)\n\n"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
{
|
{
|
||||||
int flush = 0;
|
int flush = 0;
|
||||||
|
@ -460,6 +515,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
#ifdef HAVE_SIGNAL_H
|
#ifdef HAVE_SIGNAL_H
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
#endif
|
#endif
|
||||||
|
char *extended_opts = 0;
|
||||||
|
|
||||||
retval = e2fsck_allocate_context(&ctx);
|
retval = e2fsck_allocate_context(&ctx);
|
||||||
if (retval)
|
if (retval)
|
||||||
|
@ -475,7 +531,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
ctx->program_name = *argv;
|
ctx->program_name = *argv;
|
||||||
else
|
else
|
||||||
ctx->program_name = "e2fsck";
|
ctx->program_name = "e2fsck";
|
||||||
while ((c = getopt (argc, argv, "panyrcC:B:dfvtFVM:b:I:j:P:l:L:N:SsD")) != EOF)
|
while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsD")) != EOF)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'C':
|
case 'C':
|
||||||
ctx->progress = e2fsck_update_progress;
|
ctx->progress = e2fsck_update_progress;
|
||||||
|
@ -497,6 +553,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
case 'D':
|
case 'D':
|
||||||
ctx->options |= E2F_OPT_COMPRESS_DIRS;
|
ctx->options |= E2F_OPT_COMPRESS_DIRS;
|
||||||
break;
|
break;
|
||||||
|
case 'E':
|
||||||
|
extended_opts = optarg;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'a':
|
case 'a':
|
||||||
ctx->options |= E2F_OPT_PREEN;
|
ctx->options |= E2F_OPT_PREEN;
|
||||||
|
@ -602,6 +661,9 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
|
||||||
!cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
|
!cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
|
||||||
ctx->options |= E2F_OPT_READONLY;
|
ctx->options |= E2F_OPT_READONLY;
|
||||||
ctx->filesystem_name = argv[optind];
|
ctx->filesystem_name = argv[optind];
|
||||||
|
if (extended_opts)
|
||||||
|
parse_extended_opts(ctx, extended_opts);
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
fd = open(ctx->filesystem_name, O_RDONLY, 0);
|
fd = open(ctx->filesystem_name, O_RDONLY, 0);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
2002-08-16 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
|
* ext2_err.et.in (EXT2_ET_BAD_EA_BLOCK_NUM): New error code
|
||||||
|
|
||||||
|
* ext2fs.h (ext2fs_inode_data_blocks): New function which returns
|
||||||
|
the number of data blocks used by an inode exclusive of
|
||||||
|
the EA block.
|
||||||
|
|
||||||
|
* ext_attr.c (ext2fs_adjust_ea_refcount): New function which
|
||||||
|
adjusts the reference count in an extended attribute block.
|
||||||
|
|
||||||
|
* valid_blk.c (ext2fs_inode_has_valid_blocks): Add code to
|
||||||
|
correctly deal with extended attribute blocks in symbolic
|
||||||
|
links.
|
||||||
|
|
||||||
2002-08-13 <tytso@snap.thunk.org>
|
2002-08-13 <tytso@snap.thunk.org>
|
||||||
|
|
||||||
* Makefile.in: Move dupfs.o and test_io.o from the
|
* Makefile.in: Move dupfs.o and test_io.o from the
|
||||||
|
|
|
@ -278,5 +278,8 @@ ec EXT2_ET_NO_JOURNAL,
|
||||||
ec EXT2_ET_DIRHASH_UNSUPP,
|
ec EXT2_ET_DIRHASH_UNSUPP,
|
||||||
"Directory hash unsupported"
|
"Directory hash unsupported"
|
||||||
|
|
||||||
|
ec EXT2_ET_BAD_EA_BLOCK_NUM,
|
||||||
|
"Illegal extended attribute block number"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -663,7 +663,12 @@ extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
|
||||||
/* ext_attr.c */
|
/* ext_attr.c */
|
||||||
void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from);
|
void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from);
|
||||||
extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
|
extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
|
||||||
extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *buf);
|
extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
|
||||||
|
void *buf);
|
||||||
|
extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
|
||||||
|
char *block_buf,
|
||||||
|
int adjust, __u32 *newcount);
|
||||||
|
|
||||||
/* fileio.c */
|
/* fileio.c */
|
||||||
extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
|
extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
|
||||||
int flags, ext2_file_t *ret);
|
int flags, ext2_file_t *ret);
|
||||||
|
@ -873,6 +878,8 @@ extern int ext2fs_test_ib_dirty(ext2_filsys fs);
|
||||||
extern int ext2fs_test_bb_dirty(ext2_filsys fs);
|
extern int ext2fs_test_bb_dirty(ext2_filsys fs);
|
||||||
extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
|
extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
|
||||||
extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
|
extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
|
||||||
|
extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
|
||||||
|
struct ext2_inode *inode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The actual inlined functions definitions themselves...
|
* The actual inlined functions definitions themselves...
|
||||||
|
@ -1025,6 +1032,13 @@ _INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
|
||||||
{
|
{
|
||||||
return (ino - 1) / fs->super->s_inodes_per_group;
|
return (ino - 1) / fs->super->s_inodes_per_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
|
||||||
|
struct ext2_inode *inode)
|
||||||
|
{
|
||||||
|
return inode->i_blocks -
|
||||||
|
(inode->i_file_acl ? fs->blocksize >> 9 : 0);
|
||||||
|
}
|
||||||
#undef _INLINE_
|
#undef _INLINE_
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* ext_attr.c --- extended attribute blocks
|
* ext_attr.c --- extended attribute blocks
|
||||||
*
|
*
|
||||||
* Copyright (C) Andreas Gruenbacher, <a.gruenbacher@computer.org>
|
* Copyright (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 Theodore Ts'o.
|
||||||
*
|
*
|
||||||
* %Begin-Header%
|
* %Begin-Header%
|
||||||
* This file may be redistributed under the terms of the GNU Public
|
* This file may be redistributed under the terms of the GNU Public
|
||||||
|
@ -96,3 +98,44 @@ errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
|
||||||
ext2fs_mark_changed(fs);
|
ext2fs_mark_changed(fs);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function adjusts the reference count of the EA block.
|
||||||
|
*/
|
||||||
|
errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
|
||||||
|
char *block_buf, int adjust,
|
||||||
|
__u32 *newcount)
|
||||||
|
{
|
||||||
|
errcode_t retval;
|
||||||
|
struct ext2_ext_attr_header *header;
|
||||||
|
char *buf = 0;
|
||||||
|
|
||||||
|
if ((blk >= fs->super->s_blocks_count) ||
|
||||||
|
(blk < fs->super->s_first_data_block))
|
||||||
|
return EXT2_ET_BAD_EA_BLOCK_NUM;
|
||||||
|
|
||||||
|
if (!block_buf) {
|
||||||
|
retval = ext2fs_get_mem(fs->blocksize, (void **) &buf);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
block_buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = ext2fs_read_ext_attr(fs, blk, block_buf);
|
||||||
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
header = (struct ext2_ext_attr_header *) block_buf;
|
||||||
|
header->h_refcount += adjust;
|
||||||
|
if (newcount)
|
||||||
|
*newcount = header->h_refcount;
|
||||||
|
|
||||||
|
retval = ext2fs_write_ext_attr(fs, blk, block_buf);
|
||||||
|
if (retval)
|
||||||
|
goto errout;
|
||||||
|
|
||||||
|
errout:
|
||||||
|
if (buf)
|
||||||
|
ext2fs_free_mem((void **) &buf);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
@ -38,8 +38,19 @@ int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
|
||||||
* If the symbolic link is a "fast symlink", then the symlink
|
* If the symbolic link is a "fast symlink", then the symlink
|
||||||
* target is stored in the block entries.
|
* target is stored in the block entries.
|
||||||
*/
|
*/
|
||||||
if (LINUX_S_ISLNK (inode->i_mode) && inode->i_blocks == 0)
|
if (LINUX_S_ISLNK (inode->i_mode)) {
|
||||||
|
if (inode->i_file_acl == 0) {
|
||||||
|
/* With no EA block, we can rely on i_blocks */
|
||||||
|
if (inode->i_blocks == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* With an EA block, life gets more tricky */
|
||||||
|
if (inode->i_size >= EXT2_N_BLOCKS*4)
|
||||||
|
return 1; /* definitely using i_block[] */
|
||||||
|
if (inode->i_size > 3 && inode->i_block[1] != 0)
|
||||||
|
return 1; /* probably using i_block[] */
|
||||||
|
return 0; /* Probably a fast symlink */
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
2002-08-17 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
|
* f_badinode, f_badroot, f_badsymlinks, f_badtable, f_dupdot,
|
||||||
|
f_filetype, f_illitable, f_imagic, f_imagic_fs, f_lpf,
|
||||||
|
f_lpffile, f_mke2fs2b, f_noroot, f_recnect_bad: Update
|
||||||
|
expect files to deal with changes in the extended
|
||||||
|
attribute block processing, and in how e2fsck updates
|
||||||
|
filesystem statistics when deleting files and creating
|
||||||
|
/lost+found.
|
||||||
|
|
||||||
|
* f_special_ea: New test which checks to make sure e2fsck
|
||||||
|
correctly handles special device files with extended
|
||||||
|
attribute blocks.
|
||||||
|
|
||||||
2002-08-01 Theodore Ts'o <tytso@mit.edu>
|
2002-08-01 Theodore Ts'o <tytso@mit.edu>
|
||||||
|
|
||||||
* f_dup, f_dup2, f_dup3, f_bbfile, f_dupfsblks: Update expect
|
* f_dup, f_dup2, f_dup3, f_bbfile, f_dupfsblks: Update expect
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
Filesystem did not have a UUID; generating one.
|
Filesystem did not have a UUID; generating one.
|
||||||
|
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
Pass 1: Checking inodes, blocks, and sizes
|
||||||
|
Inode 12, i_blocks is 2, should be 0. Fix? yes
|
||||||
|
|
||||||
Pass 2: Checking directory structure
|
Pass 2: Checking directory structure
|
||||||
Inode 12 (/motd) has a bad mode (0110444).
|
Inode 12 (/motd) has a bad mode (0110444).
|
||||||
Clear? yes
|
Clear? yes
|
||||||
|
@ -32,12 +34,6 @@ Fix? yes
|
||||||
Free blocks count wrong (76, counted=77).
|
Free blocks count wrong (76, counted=77).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (16, counted=20).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (16, counted=20).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 12/32 files (0.0% non-contiguous), 23/100 blocks
|
test_filesys: 12/32 files (0.0% non-contiguous), 23/100 blocks
|
||||||
|
|
|
@ -23,21 +23,6 @@ Connect to /lost+found? yes
|
||||||
Inode 12 ref count is 2, should be 1. Fix? yes
|
Inode 12 ref count is 2, should be 1. Fix? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
Free blocks count wrong for group #0 (77, counted=76).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free blocks count wrong (77, counted=76).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (20, counted=19).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Directories count wrong for group #0 (2, counted=3).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (20, counted=19).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 13/32 files (0.0% non-contiguous), 24/100 blocks
|
test_filesys: 13/32 files (0.0% non-contiguous), 24/100 blocks
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
Pass 1: Checking inodes, blocks, and sizes
|
Pass 1: Checking inodes, blocks, and sizes
|
||||||
Inode 16, i_size is 4294967358, should be 1024. Fix? yes
|
|
||||||
|
|
||||||
Special (device/socket/fifo/symlink) file (inode 18) has immutable
|
Special (device/socket/fifo/symlink) file (inode 18) has immutable
|
||||||
or append-only flag set. Clear? yes
|
or append-only flag set. Clear? yes
|
||||||
|
|
||||||
|
@ -51,16 +49,10 @@ Clear? yes
|
||||||
Pass 3: Checking directory connectivity
|
Pass 3: Checking directory connectivity
|
||||||
Pass 4: Checking reference counts
|
Pass 4: Checking reference counts
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
Free blocks count wrong for group #0 (995, counted=1001).
|
Free blocks count wrong for group #0 (1000, counted=1001).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (995, counted=1001).
|
Free blocks count wrong (1000, counted=1001).
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (9, counted=19).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (9, counted=19).
|
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,19 +21,22 @@ Pass 5: Checking group summary information
|
||||||
Block bitmap differences: -(12--20)
|
Block bitmap differences: -(12--20)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong for group #0 (78, counted=87).
|
Free blocks count wrong for group #0 (77, counted=87).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (78, counted=87).
|
Free blocks count wrong (77, counted=87).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Inode bitmap differences: +(12--16) +(25--32)
|
Inode bitmap differences: +(12--16) +(25--32)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (21, counted=7).
|
Free inodes count wrong for group #0 (20, counted=7).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free inodes count wrong (21, counted=7).
|
Directories count wrong for group #0 (3, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (20, counted=7).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,6 @@ Inode 13 ref count is 2, should be 1. Fix? yes
|
||||||
Unattached zero-length inode 14. Clear? yes
|
Unattached zero-length inode 14. Clear? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
Free inodes count wrong for group #0 (2, counted=3).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (2, counted=3).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 13/16 files (0.0% non-contiguous), 22/100 blocks
|
test_filesys: 13/16 files (0.0% non-contiguous), 22/100 blocks
|
||||||
|
|
|
@ -37,6 +37,12 @@ Setting filetype for entry '..' in /dir (13) to 2.
|
||||||
Pass 3: Checking directory connectivity
|
Pass 3: Checking directory connectivity
|
||||||
Pass 4: Checking reference counts
|
Pass 4: Checking reference counts
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
|
Free inodes count wrong for group #0 (50, counted=47).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (50, counted=47).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 17/64 files (0.0% non-contiguous), 27/100 blocks
|
test_filesys: 17/64 files (0.0% non-contiguous), 27/100 blocks
|
||||||
|
|
|
@ -28,10 +28,19 @@ Pass 5: Checking group summary information
|
||||||
Block bitmap differences: -(11--21)
|
Block bitmap differences: -(11--21)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong for group #0 (78, counted=89).
|
Free blocks count wrong for group #0 (77, counted=89).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (78, counted=89).
|
Free blocks count wrong (77, counted=89).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong for group #0 (20, counted=21).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Directories count wrong for group #0 (3, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (20, counted=21).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,19 @@ Pass 5: Checking group summary information
|
||||||
Block bitmap differences: -(9--19)
|
Block bitmap differences: -(9--19)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong for group #0 (76, counted=87).
|
Free blocks count wrong for group #0 (75, counted=87).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (76, counted=87).
|
Free blocks count wrong (75, counted=87).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong for group #0 (1, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Directories count wrong for group #0 (3, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (1, counted=2).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,19 @@ Pass 5: Checking group summary information
|
||||||
Block bitmap differences: -(9--19)
|
Block bitmap differences: -(9--19)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong for group #0 (76, counted=87).
|
Free blocks count wrong for group #0 (75, counted=87).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (76, counted=87).
|
Free blocks count wrong (75, counted=87).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong for group #0 (1, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Directories count wrong for group #0 (3, counted=2).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (1, counted=2).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,22 +27,19 @@ Pass 5: Checking group summary information
|
||||||
Block bitmap differences: +(22--23) +49 +(57--58)
|
Block bitmap differences: +(22--23) +49 +(57--58)
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong for group #0 (25, counted=33).
|
Free blocks count wrong for group #0 (24, counted=33).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free blocks count wrong (39, counted=33).
|
Free blocks count wrong (38, counted=33).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Inode bitmap differences: +13
|
Inode bitmap differences: +13
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (2, counted=0).
|
Free inodes count wrong for group #0 (1, counted=0).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Directories count wrong for group #0 (1, counted=2).
|
Free inodes count wrong (1, counted=0).
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (2, counted=0).
|
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,21 +26,6 @@ Connect to /lost+found? yes
|
||||||
Inode 14 ref count is 2, should be 1. Fix? yes
|
Inode 14 ref count is 2, should be 1. Fix? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
Free blocks count wrong for group #0 (86, counted=85).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free blocks count wrong (86, counted=85).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (18, counted=17).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Directories count wrong for group #0 (1, counted=2).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (18, counted=17).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 15/32 files (0.0% non-contiguous), 15/100 blocks
|
test_filesys: 15/32 files (0.0% non-contiguous), 15/100 blocks
|
||||||
|
|
|
@ -13,6 +13,12 @@ Pass 4: Checking reference counts
|
||||||
Unattached zero-length inode 15. Clear? yes
|
Unattached zero-length inode 15. Clear? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
|
Free inodes count wrong for group #0 (18, counted=17).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (18, counted=17).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 15/32 files (0.0% non-contiguous), 25/100 blocks
|
test_filesys: 15/32 files (0.0% non-contiguous), 25/100 blocks
|
||||||
|
|
|
@ -27,18 +27,9 @@ Inode 12 ref count is 4, should be 3. Fix? yes
|
||||||
Unattached zero-length inode 15. Clear? yes
|
Unattached zero-length inode 15. Clear? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
Free blocks count wrong for group #0 (75, counted=74).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free blocks count wrong (75, counted=74).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong for group #0 (17, counted=16).
|
Free inodes count wrong for group #0 (17, counted=16).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
Directories count wrong for group #0 (4, counted=5).
|
|
||||||
Fix? yes
|
|
||||||
|
|
||||||
Free inodes count wrong (17, counted=16).
|
Free inodes count wrong (17, counted=16).
|
||||||
Fix? yes
|
Fix? yes
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,12 @@ Inode 28 (...) has a bad mode (0177777).
|
||||||
Clear? yes
|
Clear? yes
|
||||||
|
|
||||||
Pass 5: Checking group summary information
|
Pass 5: Checking group summary information
|
||||||
|
Free inodes count wrong for group #0 (18, counted=17).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
Free inodes count wrong (18, counted=17).
|
||||||
|
Fix? yes
|
||||||
|
|
||||||
|
|
||||||
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
|
||||||
test_filesys: 15/32 files (0.0% non-contiguous), 26/100 blocks
|
test_filesys: 15/32 files (0.0% non-contiguous), 26/100 blocks
|
||||||
|
|
|
@ -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: 17/1024 files (0.0% non-contiguous), 1180/4096 blocks
|
||||||
|
Exit status is 1
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Special files with extended attributes
|
|
@ -0,0 +1,2 @@
|
||||||
|
ONE_PASS_ONLY="true"
|
||||||
|
. $cmd_dir/run_e2fsck
|
Loading…
Reference in New Issue