summaryrefslogtreecommitdiff
path: root/e2fsck/pass1b.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>1997-04-29 17:48:10 +0000
committerTheodore Ts'o <tytso@mit.edu>1997-04-29 17:48:10 +0000
commit521e36857227b21e7ab47b0a97f788d2af9f9717 (patch)
tree21ca3452b25bd1310df4c2d8cebbbc8ed8a7b217 /e2fsck/pass1b.c
parent24757fa0468170e1420087eef36219650dba8c07 (diff)
downloade2fsprogs-521e36857227b21e7ab47b0a97f788d2af9f9717.tar.gz
Many files:
Checked in e2fsprogs 1.08.
Diffstat (limited to 'e2fsck/pass1b.c')
-rw-r--r--e2fsck/pass1b.c31
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);