mirror of https://github.com/vitalif/e2fsprogs
pass1b.c (clone_file_block): Fix bugs when cloning extended attribute
blocks. Moved free of block_buf to after the code which clones the extattr block, and fixed logic for changing pointers to the extended attribute field in the inodes which were affected. (decrement_badcount): New function which is used whenever we need to decrement the number of files which claim a particular bad block. Fixed bug where delete_file wasn't checking check_if_fs_block() before clearing the entry in block_dup_map. This could cause a block which was claimed by multiple files as well as the filesystem metadata to not be completely fixed.bitmap-optimize
parent
e8a3ee628a
commit
7abb2bdcd6
|
@ -1,5 +1,18 @@
|
||||||
2001-07-07 Theodore Tso <tytso@valinux.com>
|
2001-07-07 Theodore Tso <tytso@valinux.com>
|
||||||
|
|
||||||
|
* pass1b.c (clone_file_block): Fix bugs when cloning extended
|
||||||
|
attribute blocks. Moved free of block_buf to after the
|
||||||
|
code which clones the extattr block, and fixed logic for
|
||||||
|
changing pointers to the extended attribute field in the
|
||||||
|
inodes which were affected.
|
||||||
|
(decrement_badcount): New function which is used whenever
|
||||||
|
we need to decrement the number of files which claim a
|
||||||
|
particular bad block. Fixed bug where delete_file wasn't
|
||||||
|
checking check_if_fs_block() before clearing the entry in
|
||||||
|
block_dup_map. This could cause a block which was claimed
|
||||||
|
by multiple files as well as the filesystem metadata to
|
||||||
|
not be completely fixed.
|
||||||
|
|
||||||
* pass1.c (adjust_extattr_refcount): Add new function which
|
* pass1.c (adjust_extattr_refcount): Add new function which
|
||||||
adjusts the reference counts of extended attribute blocks
|
adjusts the reference counts of extended attribute blocks
|
||||||
if needed, both up and down.
|
if needed, both up and down.
|
||||||
|
|
|
@ -492,6 +492,18 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
|
||||||
ext2fs_free_mem((void **) &shared);
|
ext2fs_free_mem((void **) &shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop the refcount on the dup_block structure, and clear the entry
|
||||||
|
* in the block_dup_map if appropriate.
|
||||||
|
*/
|
||||||
|
static void decrement_badcount(e2fsck_t ctx, struct dup_block *p)
|
||||||
|
{
|
||||||
|
p->num_bad--;
|
||||||
|
if (p->num_bad <= 0 ||
|
||||||
|
(p->num_bad == 1 && !check_if_fs_block(ctx, p->block)))
|
||||||
|
ext2fs_unmark_block_bitmap(ctx->block_dup_map, p->block);
|
||||||
|
}
|
||||||
|
|
||||||
static int delete_file_block(ext2_filsys fs,
|
static int delete_file_block(ext2_filsys fs,
|
||||||
blk_t *block_nr,
|
blk_t *block_nr,
|
||||||
e2_blkcnt_t blockcnt,
|
e2_blkcnt_t blockcnt,
|
||||||
|
@ -514,10 +526,7 @@ static int delete_file_block(ext2_filsys fs,
|
||||||
if (p->block == *block_nr)
|
if (p->block == *block_nr)
|
||||||
break;
|
break;
|
||||||
if (p) {
|
if (p) {
|
||||||
p->num_bad--;
|
decrement_badcount(ctx, p);
|
||||||
if (p->num_bad == 1)
|
|
||||||
ext2fs_unmark_block_bitmap(ctx->block_dup_map,
|
|
||||||
*block_nr);
|
|
||||||
} else
|
} else
|
||||||
com_err("delete_file_block", 0,
|
com_err("delete_file_block", 0,
|
||||||
_("internal error; can't find dup_blk for %d\n"),
|
_("internal error; can't find dup_blk for %d\n"),
|
||||||
|
@ -619,11 +628,7 @@ static int clone_file_block(ext2_filsys fs,
|
||||||
cs->errcode = retval;
|
cs->errcode = retval;
|
||||||
return BLOCK_ABORT;
|
return BLOCK_ABORT;
|
||||||
}
|
}
|
||||||
p->num_bad--;
|
decrement_badcount(ctx, p);
|
||||||
if (p->num_bad == 1 &&
|
|
||||||
!check_if_fs_block(ctx, *block_nr))
|
|
||||||
ext2fs_unmark_block_bitmap(ctx->block_dup_map,
|
|
||||||
*block_nr);
|
|
||||||
*block_nr = new_block;
|
*block_nr = new_block;
|
||||||
ext2fs_mark_block_bitmap(ctx->block_found_map,
|
ext2fs_mark_block_bitmap(ctx->block_found_map,
|
||||||
new_block);
|
new_block);
|
||||||
|
@ -643,6 +648,7 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
|
||||||
errcode_t retval;
|
errcode_t retval;
|
||||||
struct clone_struct cs;
|
struct clone_struct cs;
|
||||||
struct problem_context pctx;
|
struct problem_context pctx;
|
||||||
|
blk_t blk;
|
||||||
|
|
||||||
clear_problem_context(&pctx);
|
clear_problem_context(&pctx);
|
||||||
cs.errcode = 0;
|
cs.errcode = 0;
|
||||||
|
@ -660,22 +666,23 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
|
||||||
pctx.errcode = ext2fs_block_iterate2(fs, dp->ino, 0, block_buf,
|
pctx.errcode = ext2fs_block_iterate2(fs, dp->ino, 0, block_buf,
|
||||||
clone_file_block, &cs);
|
clone_file_block, &cs);
|
||||||
ext2fs_mark_bb_dirty(fs);
|
ext2fs_mark_bb_dirty(fs);
|
||||||
ext2fs_free_mem((void **) &cs.buf);
|
|
||||||
if (pctx.errcode) {
|
if (pctx.errcode) {
|
||||||
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
|
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
|
||||||
return pctx.errcode;
|
retval = pctx.errcode;
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
if (cs.errcode) {
|
if (cs.errcode) {
|
||||||
com_err("clone_file", cs.errcode,
|
com_err("clone_file", cs.errcode,
|
||||||
_("returned from clone_file_block"));
|
_("returned from clone_file_block"));
|
||||||
return cs.errcode;
|
retval = cs.errcode;
|
||||||
|
goto errout;
|
||||||
}
|
}
|
||||||
if (dp->inode.i_file_acl &&
|
blk = dp->inode.i_file_acl;
|
||||||
(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) ==
|
||||||
BLOCK_CHANGED)) {
|
BLOCK_CHANGED)) {
|
||||||
struct dup_block *p;
|
struct dup_block *p, *q;
|
||||||
struct dup_inode *q;
|
struct dup_inode *r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we cloned the EA block, find all other inodes
|
* If we cloned the EA block, find all other inodes
|
||||||
|
@ -683,20 +690,28 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
|
||||||
* them to point to the new EA block.
|
* them to point to the new EA block.
|
||||||
*/
|
*/
|
||||||
for (p = dup_blk; p; p = p->next_block) {
|
for (p = dup_blk; p; p = p->next_block) {
|
||||||
if (!(p->flags & FLAG_EXTATTR))
|
if (p->block == blk)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (q = p; q ; q = q->next_inode) {
|
||||||
|
if (!(q->flags & FLAG_EXTATTR))
|
||||||
continue;
|
continue;
|
||||||
for (q = dup_ino; q; q = q->next)
|
for (r = dup_ino; r; r = r->next)
|
||||||
if (p->ino == q->ino)
|
if (r->ino == q->ino)
|
||||||
break;
|
break;
|
||||||
if (!q)
|
if (r) {
|
||||||
continue; /* Should never happen */
|
r->inode.i_file_acl = dp->inode.i_file_acl;
|
||||||
q->inode.i_file_acl = dp->inode.i_file_acl;
|
e2fsck_write_inode(ctx, q->ino, &r->inode,
|
||||||
e2fsck_write_inode(ctx, q->ino, &q->inode,
|
"clone file EA");
|
||||||
"clone file EA");
|
}
|
||||||
|
q->ino = 0; /* Should free the structure... */
|
||||||
|
decrement_badcount(ctx, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
retval = 0;
|
||||||
return 0;
|
errout:
|
||||||
|
ext2fs_free_mem((void **) &cs.buf);
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue