Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7c21177 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

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: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent f9a62d09
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -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),
	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 @@ static int ext4_readdir(struct file *filp,
		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
+8 −7
Original line number Diff line number Diff line
@@ -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,
+5 −5
Original line number Diff line number Diff line
@@ -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;
+16 −12
Original line number Diff line number Diff line
@@ -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);