aboutsummaryrefslogtreecommitdiffstats
path: root/e2fsck/pass1b.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2002-08-17 10:19:44 -0400
committerTheodore Ts'o <tytso@mit.edu>2002-08-17 10:19:44 -0400
commit0684a4f33b5c268fe12f57fcbc77a880c79ab282 (patch)
treebc9dc324c0bd760d48f9d5be378f094811989908 /e2fsck/pass1b.c
parent0ccd488a764c14b27983b92435deca5e1adf9061 (diff)
downloadandroid_external_e2fsprogs-0684a4f33b5c268fe12f57fcbc77a880c79ab282.tar.gz
android_external_e2fsprogs-0684a4f33b5c268fe12f57fcbc77a880c79ab282.tar.bz2
android_external_e2fsprogs-0684a4f33b5c268fe12f57fcbc77a880c79ab282.zip
Overhaul extended attribute handling. Should now be correct with
respect to the latest V2 bestbits ACL code.
Diffstat (limited to 'e2fsck/pass1b.c')
-rw-r--r--e2fsck/pass1b.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index 8549a655..c370601e 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -259,15 +259,17 @@ static void pass1b(e2fsck_t ctx, char *block_buf)
while (ino) {
pctx.ino = ctx->stashed_ino = ino;
if ((ino != EXT2_BAD_INO) &&
- (!ext2fs_test_inode_bitmap(ctx->inode_used_map, ino) ||
- !ext2fs_inode_has_valid_blocks(&inode)))
+ !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
goto next;
pb.ino = ino;
pb.dup_blocks = 0;
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)
process_pass1b_block(fs, &inode.i_file_acl,
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
@@ -543,7 +545,7 @@ static int delete_file_block(ext2_filsys fs,
*block_nr);
} else {
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;
@@ -556,6 +558,7 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
struct process_block_struct pb;
struct ext2_inode inode;
struct problem_context pctx;
+ unsigned int count;
clear_problem_context(&pctx);
pctx.ino = pb.ino = ino;
@@ -563,23 +566,47 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
pb.ctx = ctx;
pctx.str = "delete_file";
- pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
- delete_file_block, &pb);
+ 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,
+ delete_file_block, &pb);
if (pctx.errcode)
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
if (ctx->inode_bad_map)
ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
- ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
- ext2fs_mark_ib_dirty(fs);
- ext2fs_mark_bb_dirty(fs);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
+
+ /* Inode may have changed by block_iterate, so reread it */
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
inode.i_links_count = 0;
inode.i_dtime = time(0);
- if (inode.i_file_acl)
- delete_file_block(fs, &inode.i_file_acl,
- BLOCK_COUNT_EXTATTR, 0, 0, &pb);
+ 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,
+ BLOCK_COUNT_EXTATTR, 0, 0, &pb);
+ }
e2fsck_write_inode(ctx, ino, &inode, "delete_file");
}
@@ -683,8 +710,9 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
pctx.ino = ino;
pctx.str = "clone_file";
- pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
- clone_file_block, &cs);
+ if (ext2fs_inode_has_valid_blocks(&dp->inode))
+ pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
+ clone_file_block, &cs);
ext2fs_mark_bb_dirty(fs);
if (pctx.errcode) {
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
@@ -697,6 +725,8 @@ static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
retval = cs.errcode;
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;
if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
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) {
di->inode.i_file_acl = dp->inode.i_file_acl;
e2fsck_write_inode(ctx, ino_el->inode,
- &dp->inode, "clone file EA");
+ &di->inode, "clone file EA");
decrement_badcount(ctx, blk, db);
}
}