diff options
author | Theodore Ts'o <tytso@mit.edu> | 1997-04-29 17:48:10 +0000 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 1997-04-29 17:48:10 +0000 |
commit | 521e36857227b21e7ab47b0a97f788d2af9f9717 (patch) | |
tree | 21ca3452b25bd1310df4c2d8cebbbc8ed8a7b217 /e2fsck/pass1b.c | |
parent | 24757fa0468170e1420087eef36219650dba8c07 (diff) | |
download | e2fsprogs-521e36857227b21e7ab47b0a97f788d2af9f9717.tar.gz |
Many files:
Checked in e2fsprogs 1.08.
Diffstat (limited to 'e2fsck/pass1b.c')
-rw-r--r-- | e2fsck/pass1b.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index 27ca98b8..50865c14 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -277,6 +277,7 @@ int process_pass1b_block(ext2_filsys fs, struct search_dir_struct { int count; ino_t first_inode; + ino_t max_inode; }; static int search_dirent_proc(ino_t dir, int entry, @@ -287,6 +288,10 @@ static int search_dirent_proc(ino_t dir, int entry, struct search_dir_struct *sd = private; struct dup_inode *p; + if (dirent->inode > sd->max_inode) + /* Should abort this inode, but not everything */ + return 0; + if (!dirent->inode || (entry < DIRENT_OTHER_FILE) || !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode)) return 0; @@ -332,6 +337,7 @@ void pass1c(ext2_filsys fs, char *block_buf) */ sd.count = inodes_left; sd.first_inode = EXT2_FIRST_INODE(fs->super); + sd.max_inode = fs->super->s_inodes_count; ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf, search_dirent_proc, &sd); } @@ -345,6 +351,7 @@ static void pass1d(ext2_filsys fs, char *block_buf) int i; errcode_t retval; int file_ok; + int meta_data = 0; struct problem_context pctx; printf("Pass 1D: Reconciling duplicate blocks\n"); @@ -376,6 +383,12 @@ static void pass1d(ext2_filsys fs, char *block_buf) continue; if (q->num_bad > 1) file_ok = 0; + if (ext2fs_test_block_bitmap(block_illegal_map, + q->block)) { + file_ok = 0; + meta_data = 1; + } + /* * Add all inodes used by this block to the * shared[] --- which is a unique list, so @@ -402,11 +415,14 @@ static void pass1d(ext2_filsys fs, char *block_buf) pctx.ino = p->ino; pctx.dir = p->dir; pctx.blkcount = p->num_dupblocks; - pctx.num = shared_len; + pctx.num = meta_data ? shared_len+1 : shared_len; fix_problem(fs, PR_1B_DUP_FILE, &pctx); pctx.blkcount = 0; pctx.num = 0; + if (meta_data) + fix_problem(fs, PR_1B_SHARE_METADATA, &pctx); + for (i = 0; i < shared_len; i++) { for (s = dup_ino; s; s = s->next) if (s->ino == shared[i]) @@ -506,6 +522,7 @@ static void delete_file(ext2_filsys fs, struct dup_inode *dp, char* block_buf) struct clone_struct { errcode_t errcode; + ino_t dir; char *buf; }; @@ -533,6 +550,14 @@ static int clone_file_block(ext2_filsys fs, cs->errcode = retval; return BLOCK_ABORT; } + if (cs->dir) { + retval = ext2fs_set_dir_block(fs->dblist, + cs->dir, new_block, blockcnt); + if (retval) { + cs->errcode = retval; + return BLOCK_ABORT; + } + } retval = io_channel_read_blk(fs->io, *block_nr, 1, cs->buf); if (retval) { @@ -569,8 +594,12 @@ static int clone_file(ext2_filsys fs, struct dup_inode *dp, char* block_buf) cs.errcode = 0; cs.buf = malloc(fs->blocksize); + cs.dir = 0; if (!cs.buf) return ENOMEM; + + if (ext2fs_test_inode_bitmap(inode_dir_map, dp->ino)) + cs.dir = dp->ino; retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf, clone_file_block, &cs); |