summaryrefslogtreecommitdiff
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@dilger.ca>2015-06-15 14:50:26 -0400
committerTheodore Ts'o <tytso@mit.edu>2015-06-15 14:50:26 -0400
commitb03a2f7eb21cc06b541142684abf7eed6aaccf3e (patch)
tree0d16b5c10f1cb7228febb67e37b86ef1aabbc1d6 /fs/ext4/namei.c
parent6f6a6fda294506dfe0e3e0a253bb2d2923f28f0a (diff)
ext4: improve warning directory handling messages
Several ext4_warning() messages in the directory handling code do not report the inode number of the (potentially corrupt) directory where a problem is seen, and others report this in an ad-hoc manner. Add an ext4_warning_inode() helper to print the inode number and command name consistent with ext4_error_inode(). Consolidate the place in ext4.h that these macros are defined. Clean up some other directory error and warning messages to print the calling function name. Minor code style fixes in nearby lines. Signed-off-by: Andreas Dilger <adilger@dilger.ca> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c125
1 files changed, 67 insertions, 58 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index bda4a5d6f5a5..5e7676f1e82f 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -84,12 +84,13 @@ typedef enum {
} dirblock_type_t;
#define ext4_read_dirblock(inode, block, type) \
- __ext4_read_dirblock((inode), (block), (type), __LINE__)
+ __ext4_read_dirblock((inode), (block), (type), __func__, __LINE__)
static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
- ext4_lblk_t block,
- dirblock_type_t type,
- unsigned int line)
+ ext4_lblk_t block,
+ dirblock_type_t type,
+ const char *func,
+ unsigned int line)
{
struct buffer_head *bh;
struct ext4_dir_entry *dirent;
@@ -97,15 +98,17 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
bh = ext4_bread(NULL, inode, block, 0);
if (IS_ERR(bh)) {
- __ext4_warning(inode->i_sb, __func__, line,
- "error %ld reading directory block "
- "(ino %lu, block %lu)", PTR_ERR(bh), inode->i_ino,
- (unsigned long) block);
+ __ext4_warning(inode->i_sb, func, line,
+ "inode #%lu: lblock %lu: comm %s: "
+ "error %ld reading directory block",
+ inode->i_ino, (unsigned long)block,
+ current->comm, PTR_ERR(bh));
return bh;
}
if (!bh) {
- ext4_error_inode(inode, __func__, line, block, "Directory hole found");
+ ext4_error_inode(inode, func, line, block,
+ "Directory hole found");
return ERR_PTR(-EIO);
}
dirent = (struct ext4_dir_entry *) bh->b_data;
@@ -119,7 +122,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
is_dx_block = 1;
}
if (!is_dx_block && type == INDEX) {
- ext4_error_inode(inode, __func__, line, block,
+ ext4_error_inode(inode, func, line, block,
"directory leaf block found instead of index block");
return ERR_PTR(-EIO);
}
@@ -136,8 +139,8 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
if (ext4_dx_csum_verify(inode, dirent))
set_buffer_verified(bh);
else {
- ext4_error_inode(inode, __func__, line, block,
- "Directory index failed checksum");
+ ext4_error_inode(inode, func, line, block,
+ "Directory index failed checksum");
brelse(bh);
return ERR_PTR(-EIO);
}
@@ -146,8 +149,8 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
if (ext4_dirent_csum_verify(inode, dirent))
set_buffer_verified(bh);
else {
- ext4_error_inode(inode, __func__, line, block,
- "Directory block failed checksum");
+ ext4_error_inode(inode, func, line, block,
+ "Directory block failed checksum");
brelse(bh);
return ERR_PTR(-EIO);
}
@@ -327,10 +330,14 @@ static __le32 ext4_dirent_csum(struct inode *inode,
return cpu_to_le32(csum);
}
-static void warn_no_space_for_csum(struct inode *inode)
+#define warn_no_space_for_csum(inode) \
+ __warn_no_space_for_csum((inode), __func__, __LINE__)
+
+static void __warn_no_space_for_csum(struct inode *inode, const char *func,
+ unsigned int line)
{
- ext4_warning(inode->i_sb, "no space in directory inode %lu leaf for "
- "checksum. Please run e2fsck -D.", inode->i_ino);
+ __ext4_warning_inode(inode, func, line,
+ "No space for directory leaf checksum. Please run e2fsck -D.");
}
int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
@@ -738,8 +745,8 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
if (root->info.hash_version != DX_HASH_TEA &&
root->info.hash_version != DX_HASH_HALF_MD4 &&
root->info.hash_version != DX_HASH_LEGACY) {
- ext4_warning(dir->i_sb, "Unrecognised inode hash code %d",
- root->info.hash_version);
+ ext4_warning_inode(dir, "Unrecognised inode hash code %u",
+ root->info.hash_version);
goto fail;
}
if (fname)
@@ -753,23 +760,26 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
hash = hinfo->hash;
if (root->info.unused_flags & 1) {
- ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
- root->info.unused_flags);
+ ext4_warning_inode(dir, "Unimplemented hash flags: %#06x",
+ root->info.unused_flags);
goto fail;
}
- if ((indirect = root->info.indirect_levels) > 1) {
- ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
- root->info.indirect_levels);
+ indirect = root->info.indirect_levels;
+ if (indirect > 1) {
+ ext4_warning_inode(dir, "Unimplemented hash depth: %#06x",
+ root->info.indirect_levels);
goto fail;
}
- entries = (struct dx_entry *) (((char *)&root->info) +
- root->info.info_length);
+ entries = (struct dx_entry *)(((char *)&root->info) +
+ root->info.info_length);
if (dx_get_limit(entries) != dx_root_limit(dir,
root->info.info_length)) {
- ext4_warning(dir->i_sb, "dx entry: limit != root limit");
+ ext4_warning_inode(dir, "dx entry: limit %u != root limit %u",
+ dx_get_limit(entries),
+ dx_root_limit(dir, root->info.info_length));
goto fail;
}
@@ -777,15 +787,16 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
while (1) {
count = dx_get_count(entries);
if (!count || count > dx_get_limit(entries)) {
- ext4_warning(dir->i_sb,
- "dx entry: no count or count > limit");
+ ext4_warning_inode(dir,
+ "dx entry: count %u beyond limit %u",
+ count, dx_get_limit(entries));
goto fail;
}
p = entries + 1;
q = entries + count - 1;
while (p <= q) {
- m = p + (q - p)/2;
+ m = p + (q - p) / 2;
dxtrace(printk("."));
if (dx_get_hash(m) > hash)
q = m - 1;
@@ -809,7 +820,8 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
}
at = p - 1;
- dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
+ dxtrace(printk(" %x->%u\n", at == entries ? 0 : dx_get_hash(at),
+ dx_get_block(at)));
frame->entries = entries;
frame->at = at;
if (!indirect--)
@@ -823,9 +835,10 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
}
entries = ((struct dx_node *) frame->bh->b_data)->entries;
- if (dx_get_limit(entries) != dx_node_limit (dir)) {
- ext4_warning(dir->i_sb,
- "dx entry: limit != node limit");
+ if (dx_get_limit(entries) != dx_node_limit(dir)) {
+ ext4_warning_inode(dir,
+ "dx entry: limit %u != node limit %u",
+ dx_get_limit(entries), dx_node_limit(dir));
goto fail;
}
}
@@ -836,18 +849,17 @@ fail:
}
if (ret_err == ERR_PTR(ERR_BAD_DX_DIR))
- ext4_warning(dir->i_sb,
- "Corrupt dir inode %lu, running e2fsck is "
- "recommended.", dir->i_ino);
+ ext4_warning_inode(dir,
+ "Corrupt directory, running e2fsck is recommended");
return ret_err;
}
-static void dx_release (struct dx_frame *frames)
+static void dx_release(struct dx_frame *frames)
{
if (frames[0].bh == NULL)
return;
- if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
+ if (((struct dx_root *)frames[0].bh->b_data)->info.indirect_levels)
brelse(frames[1].bh);
brelse(frames[0].bh);
}
@@ -1524,9 +1536,9 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
retval = ext4_htree_next_block(dir, fname->hinfo.hash, frame,
frames, NULL);
if (retval < 0) {
- ext4_warning(sb,
- "error %d reading index page in directory #%lu",
- retval, dir->i_ino);
+ ext4_warning_inode(dir,
+ "error %d reading directory index block",
+ retval);
bh = ERR_PTR(retval);
goto errout;
}
@@ -2187,7 +2199,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
if (levels && (dx_get_count(frames->entries) ==
dx_get_limit(frames->entries))) {
- ext4_warning(sb, "Directory index full!");
+ ext4_warning_inode(dir, "Directory index full!");
err = -ENOSPC;
goto cleanup;
}
@@ -2678,12 +2690,9 @@ int ext4_empty_dir(struct inode *inode)
de = (struct ext4_dir_entry_2 *) bh->b_data;
de1 = ext4_next_entry(de, sb->s_blocksize);
if (le32_to_cpu(de->inode) != inode->i_ino ||
- !le32_to_cpu(de1->inode) ||
- strcmp(".", de->name) ||
- strcmp("..", de1->name)) {
- ext4_warning(inode->i_sb,
- "bad directory (dir #%lu) - no `.' or `..'",
- inode->i_ino);
+ le32_to_cpu(de1->inode) == 0 ||
+ strcmp(".", de->name) || strcmp("..", de1->name)) {
+ ext4_warning_inode(inode, "directory missing '.' and/or '..'");
brelse(bh);
return 1;
}
@@ -2936,8 +2945,9 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
if (retval)
goto end_rmdir;
if (!EXT4_DIR_LINK_EMPTY(inode))
- ext4_warning(inode->i_sb,
- "empty directory has too many links (%d)",
+ ext4_warning_inode(inode,
+ "empty directory '%.*s' has too many links (%u)",
+ dentry->d_name.len, dentry->d_name.name,
inode->i_nlink);
inode->i_version++;
clear_nlink(inode);
@@ -2997,10 +3007,9 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);
- if (!inode->i_nlink) {
- ext4_warning(inode->i_sb,
- "Deleting nonexistent file (%lu), %d",
- inode->i_ino, inode->i_nlink);
+ if (inode->i_nlink == 0) {
+ ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
+ dentry->d_name.len, dentry->d_name.name);
set_nlink(inode, 1);
}
retval = ext4_delete_entry(handle, dir, de, bh);
@@ -3385,9 +3394,9 @@ static void ext4_rename_delete(handle_t *handle, struct ext4_renament *ent,
}
if (retval) {
- ext4_warning(ent->dir->i_sb,
- "Deleting old file (%lu), %d, error=%d",
- ent->dir->i_ino, ent->dir->i_nlink, retval);
+ ext4_warning_inode(ent->dir,
+ "Deleting old file: nlink %d, error=%d",
+ ent->dir->i_nlink, retval);
}
}