aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2011-01-10 12:10:55 -0500
committerTheodore Ts'o <tytso@mit.edu>2011-01-10 12:10:55 -0500
commitf7c21177af0b32a2cd9ee36189637f0c1f0e1e17 (patch)
treeba83d4ddcd4b7e15ff575f0b75013ba9ed62f249
parentf9a62d090cf47fae2fe6f6bd8eb9f24482573fd8 (diff)
ext4: Use ext4_error_file() to print the pathname to the corrupted inode
Where the file pointer is available, use ext4_error_file() instead of ext4_error_inode(). Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/dir.c30
-rw-r--r--fs/ext4/ext4.h15
-rw-r--r--fs/ext4/namei.c10
-rw-r--r--fs/ext4/super.c28
4 files changed, 49 insertions, 34 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index bd5d74d06399..164c56092e58 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -66,7 +66,7 @@ static unsigned char get_dtype(struct super_block *sb, int filetype)
66 * Note: this is the opposite of what ext2 and ext3 historically returned... 66 * Note: this is the opposite of what ext2 and ext3 historically returned...
67 */ 67 */
68int __ext4_check_dir_entry(const char *function, unsigned int line, 68int __ext4_check_dir_entry(const char *function, unsigned int line,
69 struct inode *dir, 69 struct inode *dir, struct file *filp,
70 struct ext4_dir_entry_2 *de, 70 struct ext4_dir_entry_2 *de,
71 struct buffer_head *bh, 71 struct buffer_head *bh,
72 unsigned int offset) 72 unsigned int offset)
@@ -90,12 +90,21 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
90 else 90 else
91 return 0; 91 return 0;
92 92
93 ext4_error_inode(dir, function, line, bh->b_blocknr, 93 if (filp)
94 "bad entry in directory: %s - " 94 ext4_error_file(filp, function, line, bh ? bh->b_blocknr : 0,
95 "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d", 95 "bad entry in directory: %s - offset=%u(%u), "
96 error_msg, (unsigned) (offset%bh->b_size), offset, 96 "inode=%u, rec_len=%d, name_len=%d",
97 le32_to_cpu(de->inode), 97 error_msg, (unsigned) (offset%bh->b_size),
98 rlen, de->name_len); 98 offset, le32_to_cpu(de->inode),
99 rlen, de->name_len);
100 else
101 ext4_error_inode(dir, function, line, bh ? bh->b_blocknr : 0,
102 "bad entry in directory: %s - offset=%u(%u), "
103 "inode=%u, rec_len=%d, name_len=%d",
104 error_msg, (unsigned) (offset%bh->b_size),
105 offset, le32_to_cpu(de->inode),
106 rlen, de->name_len);
107
99 return 1; 108 return 1;
100} 109}
101 110
@@ -158,8 +167,9 @@ static int ext4_readdir(struct file *filp,
158 */ 167 */
159 if (!bh) { 168 if (!bh) {
160 if (!dir_has_error) { 169 if (!dir_has_error) {
161 EXT4_ERROR_INODE(inode, "directory " 170 EXT4_ERROR_FILE(filp, 0,
162 "contains a hole at offset %Lu", 171 "directory contains a "
172 "hole at offset %llu",
163 (unsigned long long) filp->f_pos); 173 (unsigned long long) filp->f_pos);
164 dir_has_error = 1; 174 dir_has_error = 1;
165 } 175 }
@@ -200,7 +210,7 @@ revalidate:
200 while (!error && filp->f_pos < inode->i_size 210 while (!error && filp->f_pos < inode->i_size
201 && offset < sb->s_blocksize) { 211 && offset < sb->s_blocksize) {
202 de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); 212 de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
203 if (ext4_check_dir_entry(inode, de, 213 if (ext4_check_dir_entry(inode, filp, de,
204 bh, offset)) { 214 bh, offset)) {
205 /* 215 /*
206 * On error, skip the f_pos to the next block 216 * On error, skip the f_pos to the next block
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 8104ab7eb7d4..2a739255ee05 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -62,8 +62,8 @@
62#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \ 62#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \
63 ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a) 63 ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a)
64 64
65#define EXT4_ERROR_FILE(file, fmt, a...) \ 65#define EXT4_ERROR_FILE(file, block, fmt, a...) \
66 ext4_error_file(__func__, __LINE__, (file), (fmt), ## a) 66 ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
67 67
68/* data type for block offset of block group */ 68/* data type for block offset of block group */
69typedef int ext4_grpblk_t; 69typedef int ext4_grpblk_t;
@@ -1640,11 +1640,12 @@ extern unsigned ext4_init_block_bitmap(struct super_block *sb,
1640 1640
1641/* dir.c */ 1641/* dir.c */
1642extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, 1642extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
1643 struct file *,
1643 struct ext4_dir_entry_2 *, 1644 struct ext4_dir_entry_2 *,
1644 struct buffer_head *, unsigned int); 1645 struct buffer_head *, unsigned int);
1645#define ext4_check_dir_entry(dir, de, bh, offset) \ 1646#define ext4_check_dir_entry(dir, filp, de, bh, offset) \
1646 unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (de), \ 1647 unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (filp), \
1647 (bh), (offset))) 1648 (de), (bh), (offset)))
1648extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, 1649extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
1649 __u32 minor_hash, 1650 __u32 minor_hash,
1650 struct ext4_dir_entry_2 *dirent); 1651 struct ext4_dir_entry_2 *dirent);
@@ -1751,8 +1752,8 @@ extern void ext4_error_inode(struct inode *, const char *, unsigned int,
1751 ext4_fsblk_t, const char *, ...) 1752 ext4_fsblk_t, const char *, ...)
1752 __attribute__ ((format (printf, 5, 6))); 1753 __attribute__ ((format (printf, 5, 6)));
1753extern void ext4_error_file(struct file *, const char *, unsigned int, 1754extern void ext4_error_file(struct file *, const char *, unsigned int,
1754 const char *, ...) 1755 ext4_fsblk_t, const char *, ...)
1755 __attribute__ ((format (printf, 4, 5))); 1756 __attribute__ ((format (printf, 5, 6)));
1756extern void __ext4_std_error(struct super_block *, const char *, 1757extern void __ext4_std_error(struct super_block *, const char *,
1757 unsigned int, int); 1758 unsigned int, int);
1758extern void __ext4_abort(struct super_block *, const char *, unsigned int, 1759extern void __ext4_abort(struct super_block *, const char *, unsigned int,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index e275464f7754..96a594d86a19 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -581,7 +581,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
581 dir->i_sb->s_blocksize - 581 dir->i_sb->s_blocksize -
582 EXT4_DIR_REC_LEN(0)); 582 EXT4_DIR_REC_LEN(0));
583 for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { 583 for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) {
584 if (ext4_check_dir_entry(dir, de, bh, 584 if (ext4_check_dir_entry(dir, NULL, de, bh,
585 (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) 585 (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
586 + ((char *)de - bh->b_data))) { 586 + ((char *)de - bh->b_data))) {
587 /* On error, skip the f_pos to the next block. */ 587 /* On error, skip the f_pos to the next block. */
@@ -820,7 +820,7 @@ static inline int search_dirblock(struct buffer_head *bh,
820 if ((char *) de + namelen <= dlimit && 820 if ((char *) de + namelen <= dlimit &&
821 ext4_match (namelen, name, de)) { 821 ext4_match (namelen, name, de)) {
822 /* found a match - just to be sure, do a full check */ 822 /* found a match - just to be sure, do a full check */
823 if (ext4_check_dir_entry(dir, de, bh, offset)) 823 if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
824 return -1; 824 return -1;
825 *res_dir = de; 825 *res_dir = de;
826 return 1; 826 return 1;
@@ -1269,7 +1269,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
1269 de = (struct ext4_dir_entry_2 *)bh->b_data; 1269 de = (struct ext4_dir_entry_2 *)bh->b_data;
1270 top = bh->b_data + blocksize - reclen; 1270 top = bh->b_data + blocksize - reclen;
1271 while ((char *) de <= top) { 1271 while ((char *) de <= top) {
1272 if (ext4_check_dir_entry(dir, de, bh, offset)) 1272 if (ext4_check_dir_entry(dir, NULL, de, bh, offset))
1273 return -EIO; 1273 return -EIO;
1274 if (ext4_match(namelen, name, de)) 1274 if (ext4_match(namelen, name, de))
1275 return -EEXIST; 1275 return -EEXIST;
@@ -1636,7 +1636,7 @@ static int ext4_delete_entry(handle_t *handle,
1636 pde = NULL; 1636 pde = NULL;
1637 de = (struct ext4_dir_entry_2 *) bh->b_data; 1637 de = (struct ext4_dir_entry_2 *) bh->b_data;
1638 while (i < bh->b_size) { 1638 while (i < bh->b_size) {
1639 if (ext4_check_dir_entry(dir, de, bh, i)) 1639 if (ext4_check_dir_entry(dir, NULL, de, bh, i))
1640 return -EIO; 1640 return -EIO;
1641 if (de == de_del) { 1641 if (de == de_del) {
1642 BUFFER_TRACE(bh, "get_write_access"); 1642 BUFFER_TRACE(bh, "get_write_access");
@@ -1919,7 +1919,7 @@ static int empty_dir(struct inode *inode)
1919 } 1919 }
1920 de = (struct ext4_dir_entry_2 *) bh->b_data; 1920 de = (struct ext4_dir_entry_2 *) bh->b_data;
1921 } 1921 }
1922 if (ext4_check_dir_entry(inode, de, bh, offset)) { 1922 if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) {
1923 de = (struct ext4_dir_entry_2 *)(bh->b_data + 1923 de = (struct ext4_dir_entry_2 *)(bh->b_data +
1924 sb->s_blocksize); 1924 sb->s_blocksize);
1925 offset = (offset | (sb->s_blocksize - 1)) + 1; 1925 offset = (offset | (sb->s_blocksize - 1)) + 1;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d49e3b1ec41e..7728a4ca3d6c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -406,28 +406,31 @@ void ext4_error_inode(struct inode *inode, const char *function,
406 const char *fmt, ...) 406 const char *fmt, ...)
407{ 407{
408 va_list args; 408 va_list args;
409 struct va_format vaf;
409 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; 410 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
410 411
411 es->s_last_error_ino = cpu_to_le32(inode->i_ino); 412 es->s_last_error_ino = cpu_to_le32(inode->i_ino);
412 es->s_last_error_block = cpu_to_le64(block); 413 es->s_last_error_block = cpu_to_le64(block);
413 save_error_info(inode->i_sb, function, line); 414 save_error_info(inode->i_sb, function, line);
414 va_start(args, fmt); 415 va_start(args, fmt);
416 vaf.fmt = fmt;
417 vaf.va = &args;
415 printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ", 418 printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
416 inode->i_sb->s_id, function, line, inode->i_ino); 419 inode->i_sb->s_id, function, line, inode->i_ino);
417 if (block) 420 if (block)
418 printk("block %llu: ", block); 421 printk(KERN_CONT "block %llu: ", block);
419 printk("comm %s: ", current->comm); 422 printk(KERN_CONT "comm %s: %pV\n", current->comm, &vaf);
420 vprintk(fmt, args);
421 printk("\n");
422 va_end(args); 423 va_end(args);
423 424
424 ext4_handle_error(inode->i_sb); 425 ext4_handle_error(inode->i_sb);
425} 426}
426 427
427void ext4_error_file(struct file *file, const char *function, 428void ext4_error_file(struct file *file, const char *function,
428 unsigned int line, const char *fmt, ...) 429 unsigned int line, ext4_fsblk_t block,
430 const char *fmt, ...)
429{ 431{
430 va_list args; 432 va_list args;
433 struct va_format vaf;
431 struct ext4_super_block *es; 434 struct ext4_super_block *es;
432 struct inode *inode = file->f_dentry->d_inode; 435 struct inode *inode = file->f_dentry->d_inode;
433 char pathname[80], *path; 436 char pathname[80], *path;
@@ -435,17 +438,18 @@ void ext4_error_file(struct file *file, const char *function,
435 es = EXT4_SB(inode->i_sb)->s_es; 438 es = EXT4_SB(inode->i_sb)->s_es;
436 es->s_last_error_ino = cpu_to_le32(inode->i_ino); 439 es->s_last_error_ino = cpu_to_le32(inode->i_ino);
437 save_error_info(inode->i_sb, function, line); 440 save_error_info(inode->i_sb, function, line);
438 va_start(args, fmt);
439 path = d_path(&(file->f_path), pathname, sizeof(pathname)); 441 path = d_path(&(file->f_path), pathname, sizeof(pathname));
440 if (IS_ERR(path)) 442 if (IS_ERR(path))
441 path = "(unknown)"; 443 path = "(unknown)";
442 printk(KERN_CRIT 444 printk(KERN_CRIT
443 "EXT4-fs error (device %s): %s:%d: inode #%lu " 445 "EXT4-fs error (device %s): %s:%d: inode #%lu: ",
444 "(comm %s path %s): ", 446 inode->i_sb->s_id, function, line, inode->i_ino);
445 inode->i_sb->s_id, function, line, inode->i_ino, 447 if (block)
446 current->comm, path); 448 printk(KERN_CONT "block %llu: ", block);
447 vprintk(fmt, args); 449 va_start(args, fmt);
448 printk("\n"); 450 vaf.fmt = fmt;
451 vaf.va = &args;
452 printk(KERN_CONT "comm %s: path %s: %pV\n", current->comm, path, &vaf);
449 va_end(args); 453 va_end(args);
450 454
451 ext4_handle_error(inode->i_sb); 455 ext4_handle_error(inode->i_sb);