ext4: Use ext4_error_file() to print the pathname to the corrupted inode
authorTheodore Ts'o <tytso@mit.edu>
Mon, 10 Jan 2011 17:10:55 +0000 (12:10 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 10 Jan 2011 17:10:55 +0000 (12:10 -0500)
Where the file pointer is available, use ext4_error_file() instead of
ext4_error_inode().

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>

fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/namei.c
fs/ext4/super.c

index bd5d74d..164c560 100644 (file)
@@ -66,7 +66,7 @@ static unsigned char get_dtype(struct super_block *sb, int filetype)
  * Note: this is the opposite of what ext2 and ext3 historically returned...
  */
 int __ext4_check_dir_entry(const char *function, unsigned int line,
-                          struct inode *dir,
+                          struct inode *dir, struct file *filp,
                           struct ext4_dir_entry_2 *de,
                           struct buffer_head *bh,
                           unsigned int offset)
@@ -90,12 +90,21 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
        else
                return 0;
 
-       ext4_error_inode(dir, function, line, bh->b_blocknr,
-                        "bad entry in directory: %s - "
-                        "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d",
-                        error_msg, (unsigned) (offset%bh->b_size), offset,
-                        le32_to_cpu(de->inode),
-                        rlen, de->name_len);
+       if (filp)
+               ext4_error_file(filp, function, line, bh ? bh->b_blocknr : 0,
+                               "bad entry in directory: %s - offset=%u(%u), "
+                               "inode=%u, rec_len=%d, name_len=%d",
+                               error_msg, (unsigned) (offset%bh->b_size),
+                               offset, le32_to_cpu(de->inode),
+                               rlen, de->name_len);
+       else
+               ext4_error_inode(dir, function, line, bh ? bh->b_blocknr : 0,
+                               "bad entry in directory: %s - offset=%u(%u), "
+                               "inode=%u, rec_len=%d, name_len=%d",
+                               error_msg, (unsigned) (offset%bh->b_size),
+                               offset, le32_to_cpu(de->inode),
+                               rlen, de->name_len);
+
        return 1;
 }
 
@@ -158,8 +167,9 @@ static int ext4_readdir(struct file *filp,
                 */
                if (!bh) {
                        if (!dir_has_error) {
-                               EXT4_ERROR_INODE(inode, "directory "
-                                          "contains a hole at offset %Lu",
+                               EXT4_ERROR_FILE(filp, 0,
+                                               "directory contains a "
+                                               "hole at offset %llu",
                                           (unsigned long long) filp->f_pos);
                                dir_has_error = 1;
                        }
@@ -200,7 +210,7 @@ revalidate:
                while (!error && filp->f_pos < inode->i_size
                       && offset < sb->s_blocksize) {
                        de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
-                       if (ext4_check_dir_entry(inode, de,
+                       if (ext4_check_dir_entry(inode, filp, de,
                                                 bh, offset)) {
                                /*
                                 * On error, skip the f_pos to the next block
index 8104ab7..2a73925 100644 (file)
@@ -62,8 +62,8 @@
 #define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...)                        \
        ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a)
 
-#define EXT4_ERROR_FILE(file, fmt, a...)       \
-       ext4_error_file(__func__, __LINE__, (file), (fmt), ## a)
+#define EXT4_ERROR_FILE(file, block, fmt, a...)                                \
+       ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
 
 /* data type for block offset of block group */
 typedef int ext4_grpblk_t;
@@ -1640,11 +1640,12 @@ extern unsigned ext4_init_block_bitmap(struct super_block *sb,
 
 /* dir.c */
 extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
+                                 struct file *,
                                  struct ext4_dir_entry_2 *,
                                  struct buffer_head *, unsigned int);
-#define ext4_check_dir_entry(dir, de, bh, offset) \
-       unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (de), \
-                                       (bh), (offset)))
+#define ext4_check_dir_entry(dir, filp, de, bh, offset)                        \
+       unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \
+                                       (de), (bh), (offset)))
 extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
                                    __u32 minor_hash,
                                    struct ext4_dir_entry_2 *dirent);
@@ -1751,8 +1752,8 @@ extern void ext4_error_inode(struct inode *, const char *, unsigned int,
                             ext4_fsblk_t, const char *, ...)
        __attribute__ ((format (printf, 5, 6)));
 extern void ext4_error_file(struct file *, const char *, unsigned int,
-                           const char *, ...)
-       __attribute__ ((format (printf, 4, 5)));
+                           ext4_fsblk_t, const char *, ...)
+       __attribute__ ((format (printf, 5, 6)));
 extern void __ext4_std_error(struct super_block *, const char *,
                             unsigned int, int);
 extern void __ext4_abort(struct super_block *, const char *, unsigned int,
index e275464..96a594d 100644 (file)
@@ -581,7 +581,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
                                           dir->i_sb->s_blocksize -
                                           EXT4_DIR_REC_LEN(0));
        for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
-               if (ext4_check_dir_entry(dir, de, bh,
+               if (ext4_check_dir_entry(dir, NULL, de, bh,
                                (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
                                         + ((char *)de - bh->b_data))) {
                        /* On error, skip the f_pos to the next block. */
@@ -820,7 +820,7 @@ static inline int search_dirblock(struct buffer_head *bh,
                if ((char *) de + namelen <= dlimit &&
                    ext4_match (namelen, name, de)) {
                        /* found a match - just to be sure, do a full check */
-                       if (ext4_check_dir_entry(dir, de, bh, offset))
+                       if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
                                return -1;
                        *res_dir = de;
                        return 1;
@@ -1269,7 +1269,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
                de = (struct ext4_dir_entry_2 *)bh->b_data;
                top = bh->b_data + blocksize - reclen;
                while ((char *) de <= top) {
-                       if (ext4_check_dir_entry(dir, de, bh, offset))
+                       if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
                                return -EIO;
                        if (ext4_match(namelen, name, de))
                                return -EEXIST;
@@ -1636,7 +1636,7 @@ static int ext4_delete_entry(handle_t *handle,
        pde = NULL;
        de = (struct ext4_dir_entry_2 *) bh->b_data;
        while (i < bh->b_size) {
-               if (ext4_check_dir_entry(dir, de, bh, i))
+               if (ext4_check_dir_entry(dir, NULL, de, bh, i))
                        return -EIO;
                if (de == de_del)  {
                        BUFFER_TRACE(bh, "get_write_access");
@@ -1919,7 +1919,7 @@ static int empty_dir(struct inode *inode)
                        }
                        de = (struct ext4_dir_entry_2 *) bh->b_data;
                }
-               if (ext4_check_dir_entry(inode, de, bh, offset)) {
+               if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) {
                        de = (struct ext4_dir_entry_2 *)(bh->b_data +
                                                         sb->s_blocksize);
                        offset = (offset | (sb->s_blocksize - 1)) + 1;
index d49e3b1..7728a4c 100644 (file)
@@ -406,28 +406,31 @@ void ext4_error_inode(struct inode *inode, const char *function,
                      const char *fmt, ...)
 {
        va_list args;
+       struct va_format vaf;
        struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
 
        es->s_last_error_ino = cpu_to_le32(inode->i_ino);
        es->s_last_error_block = cpu_to_le64(block);
        save_error_info(inode->i_sb, function, line);
        va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
        printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
               inode->i_sb->s_id, function, line, inode->i_ino);
        if (block)
-               printk("block %llu: ", block);
-       printk("comm %s: ", current->comm);
-       vprintk(fmt, args);
-       printk("\n");
+               printk(KERN_CONT "block %llu: ", block);
+       printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);
 }
 
 void ext4_error_file(struct file *file, const char *function,
-                    unsigned int line, const char *fmt, ...)
+                    unsigned int line, ext4_fsblk_t block,
+                    const char *fmt, ...)
 {
        va_list args;
+       struct va_format vaf;
        struct ext4_super_block *es;
        struct inode *inode = file->f_dentry->d_inode;
        char pathname[80], *path;
@@ -435,17 +438,18 @@ void ext4_error_file(struct file *file, const char *function,
        es = EXT4_SB(inode->i_sb)->s_es;
        es->s_last_error_ino = cpu_to_le32(inode->i_ino);
        save_error_info(inode->i_sb, function, line);
-       va_start(args, fmt);
        path = d_path(&(file->f_path), pathname, sizeof(pathname));
        if (IS_ERR(path))
                path = "(unknown)";
        printk(KERN_CRIT
-              "EXT4-fs error (device %s): %s:%d: inode #%lu "
-              "(comm %s path %s): ",
-              inode->i_sb->s_id, function, line, inode->i_ino,
-              current->comm, path);
-       vprintk(fmt, args);
-       printk("\n");
+              "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
+              inode->i_sb->s_id, function, line, inode->i_ino);
+       if (block)
+               printk(KERN_CONT "block %llu: ", block);
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
        va_end(args);
 
        ext4_handle_error(inode->i_sb);