Skip to contentSkip to conversation

avoid semi-infinite loop when mounting bad ext2

PATCH In review Andries Brouwer 2 participants 2 messages Nov 3, 2004 – Nov 4, 2004 ext2 file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 avoid semi-infinite loop when mounting bad ext2

The routine ext2_readdir() will, when reading a directory page returns an error, try the next page, without reporting the error to user space. That is bad, and the patch below changes that.

In my case the filesystem was damaged, and ext2_readdir wanted to read 60000+ pages and wrote as many error messages to syslog ("attempt to access beyond end"), not what one wants.

Andries

[no doubt a similar patch is appropriate for ext3]

fs/ext2/dir.c +2 -1
diff -uprN -X /linux/dontdiff a/fs/ext2/dir.c b/fs/ext2/dir.c
@@ -275,7 +275,8 @@ ext2_readdir (struct file * filp, void *
 				   "bad page in #%lu",
 				   inode->i_ino);
 			filp->f_pos += PAGE_CACHE_SIZE - offset;
-			continue;
+			ret = -EIO;
+			goto done;
 		}
 		kaddr = page_address(page);
 		if (need_revalidate) {
#1 lore raw
Quoted 2 lines · Andries Brouwer

[no doubt a similar patch is appropriate for ext3]

ext3 is different here, and uses the old-style buffer cache rather than page cache. It has the equivalent case for a hole and/or IO error, and like ext2, it just continues with the next block.

I _think_ that case should be updated to do the same thing you did for ext2, but I'll leave it up to Andrew, since he is the ext3 master anyway.

Andrew?

Linus

Quoted 14 lines

diff -uprN -X /linux/dontdiff a/fs/ext2/dir.c b/fs/ext2/dir.c

fs/ext2/dir.c +2 -1
@@ -275,7 +275,8 @@ ext2_readdir (struct file * filp, void *
 				   "bad page in #%lu",
 				   inode->i_ino);
 			filp->f_pos += PAGE_CACHE_SIZE - offset;
-			continue;
+			ret = -EIO;
+			goto done;
 		}
 		kaddr = page_address(page);
 		if (need_revalidate) {