From 3efcc87413ab51293f127fb9015ec3947975c2b3 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 26 Apr 2018 10:32:44 -0700 Subject: [PATCH] scoutfs: add corruption messages for namei Add scoutfs_corruption() calls for corruption associated with mapping names to inodes. Signed-off-by: Zach Brown --- kmod/src/counters.h | 6 ++++++ kmod/src/dir.c | 36 ++++++++++++++++++++++++++++++------ kmod/src/format.h | 6 ++++++ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/kmod/src/counters.h b/kmod/src/counters.h index f552617a..a919b191 100644 --- a/kmod/src/counters.h +++ b/kmod/src/counters.h @@ -23,6 +23,12 @@ EXPAND_COUNTER(compact_stale_error) \ EXPAND_COUNTER(compact_sticky_upper) \ EXPAND_COUNTER(compact_sticky_written) \ + EXPAND_COUNTER(corrupt_dirent_backref_name_len) \ + EXPAND_COUNTER(corrupt_dirent_name_len) \ + EXPAND_COUNTER(corrupt_dirent_readdir_name_len) \ + EXPAND_COUNTER(corrupt_symlink_inode_size) \ + EXPAND_COUNTER(corrupt_symlink_missing_item) \ + EXPAND_COUNTER(corrupt_symlink_not_null_term) \ EXPAND_COUNTER(data_end_writeback_page) \ EXPAND_COUNTER(data_invalidatepage) \ EXPAND_COUNTER(data_readpage) \ diff --git a/kmod/src/dir.c b/kmod/src/dir.c index bf2c052a..292df2d5 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -258,8 +258,11 @@ static int lookup_dirent(struct super_block *sb, u64 dir_ino, const char *name, break; ret -= sizeof(struct scoutfs_dirent); - /* XXX corruption */ if (ret < 1 || ret > SCOUTFS_NAME_LEN) { + scoutfs_corruption(sb, SC_DIRENT_NAME_LEN, + corrupt_dirent_name_len, + "dir_ino %llu hash %llu key "SK_FMT" len %d", + dir_ino, hash, SK_ARG(&key), ret); ret = -EIO; goto out; } @@ -504,8 +507,12 @@ static int scoutfs_readdir(struct file *file, void *dirent, filldir_t filldir) } name_len = ret - sizeof(struct scoutfs_dirent); - /* XXX corruption */ if (name_len < 1 || name_len > SCOUTFS_NAME_LEN) { + scoutfs_corruption(sb, SC_DIRENT_READDIR_NAME_LEN, + corrupt_dirent_readdir_name_len, + "dir_ino %llu pos %llu key "SK_FMT" len %d", + scoutfs_ino(inode), file->f_pos, + SK_ARG(&key), name_len); ret = -EIO; goto out; } @@ -1034,8 +1041,11 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd) size = i_size_read(inode); - /* XXX corruption */ if (size == 0 || size > SCOUTFS_SYMLINK_MAX_SIZE) { + scoutfs_corruption(sb, SC_SYMLINK_INODE_SIZE, + corrupt_symlink_inode_size, + "ino %llu size %llu", + scoutfs_ino(inode), (u64)size); ret = -EIO; goto out; } @@ -1055,10 +1065,21 @@ static void *scoutfs_follow_link(struct dentry *dentry, struct nameidata *nd) ret = symlink_item_ops(sb, SYM_LOOKUP, scoutfs_ino(inode), inode_lock, path, size); - /* XXX corruption: missing items or not null term */ - if (ret == -ENOENT || (ret == 0 && path[size - 1])) + if (ret == -ENOENT) { + scoutfs_corruption(sb, SC_SYMLINK_MISSING_ITEM, + corrupt_symlink_missing_item, + "ino %llu size %llu", scoutfs_ino(inode), + size); ret = -EIO; + } else if (ret == 0 && path[size - 1]) { + scoutfs_corruption(sb, SC_SYMLINK_NOT_NULL_TERM, + corrupt_symlink_not_null_term, + "ino %llu last %u", + scoutfs_ino(inode), path[size - 1]); + ret = -EIO; + } + out: if (ret < 0) { kfree(path); @@ -1229,8 +1250,11 @@ int scoutfs_dir_add_next_linkref(struct super_block *sb, u64 ino, goto out; len = ret - sizeof(struct scoutfs_dirent); - /* XXX corruption */ if (len < 1 || len > SCOUTFS_NAME_LEN) { + scoutfs_corruption(sb, SC_DIRENT_BACKREF_NAME_LEN, + corrupt_dirent_backref_name_len, + "ino %llu dir_ino %llu pos %llu key "SK_FMT" len %d", + ino, dir_ino, dir_pos, SK_ARG(&key), len); ret = -EIO; goto out; } diff --git a/kmod/src/format.h b/kmod/src/format.h index 8022f36a..54857d24 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -649,6 +649,12 @@ struct scoutfs_fid { * Identifiers for sources of corruption that can generate messages. */ enum { + SC_DIRENT_NAME_LEN = 0, + SC_DIRENT_BACKREF_NAME_LEN, + SC_DIRENT_READDIR_NAME_LEN, + SC_SYMLINK_INODE_SIZE, + SC_SYMLINK_MISSING_ITEM, + SC_SYMLINK_NOT_NULL_TERM, SC_NR_SOURCES, };