From b134d687dd9369bb2407a23c6ecc9e0a15d8bb20 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 25 Apr 2019 14:26:52 +0100 Subject: afs: Log more information for "kAFS: AFS vnode with undefined type\n" Log more information when "kAFS: AFS vnode with undefined type\n" is displayed due to a vnode record being retrieved from the server that appears to have a duff file type (usually 0). This prints more information to try and help pin down the problem. Signed-off-by: David Howells --- fs/afs/dir.c | 4 ++-- fs/afs/inode.c | 35 +++++++++++++++++++++++++++++++---- fs/afs/internal.h | 3 ++- fs/afs/super.c | 2 +- 4 files changed, 36 insertions(+), 8 deletions(-) (limited to 'fs/afs') diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 48706eefc63b..9a466be583d2 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -776,7 +776,7 @@ success: ti = afs_iget(dir->i_sb, key, &cookie->fids[i], &cookie->statuses[i], &cookie->callbacks[i], - cbi); + cbi, dvnode); if (i == 0) { inode = ti; } else { @@ -1125,7 +1125,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc, return; inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key, - newfid, newstatus, newcb, fc->cbi); + newfid, newstatus, newcb, fc->cbi, fc->vnode); if (IS_ERR(inode)) { /* ENOMEM or EINTR at a really inconvenient time - just abandon * the new directory on the server. diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 3eef20ff285b..0362cc7e1c7c 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -29,10 +29,36 @@ static const struct inode_operations afs_symlink_inode_operations = { .listxattr = afs_listxattr, }; +static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *parent_vnode) +{ + static unsigned long once_only; + + pr_warn("kAFS: AFS vnode with undefined type %u\n", + vnode->status.type); + pr_warn("kAFS: A=%d m=%o s=%llx v=%llx\n", + vnode->status.abort_code, + vnode->status.mode, + vnode->status.size, + vnode->status.data_version); + pr_warn("kAFS: vnode %llx:%llx:%x\n", + vnode->fid.vid, + vnode->fid.vnode, + vnode->fid.unique); + if (parent_vnode) + pr_warn("kAFS: dir %llx:%llx:%x\n", + parent_vnode->fid.vid, + parent_vnode->fid.vnode, + parent_vnode->fid.unique); + + if (!test_and_set_bit(0, &once_only)) + dump_stack(); +} + /* * Initialise an inode from the vnode status. */ -static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key) +static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key, + struct afs_vnode *parent_vnode) { struct inode *inode = AFS_VNODE_TO_I(vnode); @@ -80,7 +106,7 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key) inode_nohighmem(inode); break; default: - printk("kAFS: AFS vnode with undefined type\n"); + dump_vnode(vnode, parent_vnode); read_sequnlock_excl(&vnode->cb_lock); return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type); } @@ -270,7 +296,8 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) */ struct inode *afs_iget(struct super_block *sb, struct key *key, struct afs_fid *fid, struct afs_file_status *status, - struct afs_callback *cb, struct afs_cb_interest *cbi) + struct afs_callback *cb, struct afs_cb_interest *cbi, + struct afs_vnode *parent_vnode) { struct afs_iget_data data = { .fid = *fid }; struct afs_super_info *as; @@ -327,7 +354,7 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, vnode->cb_expires_at += ktime_get_real_seconds(); } - ret = afs_inode_init_from_status(vnode, key); + ret = afs_inode_init_from_status(vnode, key, parent_vnode); if (ret < 0) goto bad_inode; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 91204e1428f2..585a5952f608 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -993,7 +993,8 @@ extern struct inode *afs_iget_pseudo_dir(struct super_block *, bool); extern struct inode *afs_iget(struct super_block *, struct key *, struct afs_fid *, struct afs_file_status *, struct afs_callback *, - struct afs_cb_interest *); + struct afs_cb_interest *, + struct afs_vnode *); extern void afs_zap_data(struct afs_vnode *); extern int afs_validate(struct afs_vnode *, struct key *); extern int afs_getattr(const struct path *, struct kstat *, u32, unsigned int); diff --git a/fs/afs/super.c b/fs/afs/super.c index 18334fa1a0d2..df5b0d8ef049 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -453,7 +453,7 @@ static int afs_fill_super(struct super_block *sb, struct afs_fs_context *ctx) fid.vnode = 1; fid.vnode_hi = 0; fid.unique = 1; - inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL); + inode = afs_iget(sb, ctx->key, &fid, NULL, NULL, NULL, NULL); } if (IS_ERR(inode)) -- cgit v1.2.3