OSDN Git Service

avoid semi-infinite loop when mounting bad ext2
authordann frazier <dannf@debian.org>
Tue, 22 Jan 2008 00:14:49 +0000 (17:14 -0700)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Feb 2008 15:37:45 +0000 (16:37 +0100)
This is a 2.4 backport of a linux-2.6 change by Andries Brouwer
(old-2.6-bkcvs commit c279c5343b1796bf1db4c0b4af2c99479a6575fe)

Commit log from 2.6 follows.

  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.

  [no doubt a similar patch is appropriate for ext3]

Signed-off-by: dann frazier <dannf@hp.com>
fs/ext2/dir.c

index b158e60..0cbb8f9 100644 (file)
@@ -246,6 +246,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
        unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
        unsigned char *types = NULL;
        int need_revalidate = (filp->f_version != inode->i_version);
+       int ret = 0;
 
        if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
                goto done;
@@ -263,7 +264,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
                                   "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) {
@@ -296,7 +298,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
 done:
        filp->f_version = inode->i_version;
        UPDATE_ATIME(inode);
-       return 0;
+       return ret;
 }
 
 /*