afs: Log more information for "kAFS: AFS vnode with undefined type\n"
authorDavid Howells <dhowells@redhat.com>
Thu, 25 Apr 2019 13:26:52 +0000 (14:26 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 7 May 2019 15:48:44 +0000 (16:48 +0100)
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 <dhowells@redhat.com>
fs/afs/dir.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/super.c

index 48706eefc63bd7815edb658df8c1e0882b755d6b..9a466be583d2a9e57ddaec723e9dae8f2be45580 100644 (file)
@@ -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.
index 3eef20ff285bc86e55c33c9ea4c443584875136e..0362cc7e1c7cd5c90491884c7ef61492621f9c2d 100644 (file)
@@ -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;
 
index 91204e1428f2633f28524d9418cdc6df570c0d1b..585a5952f6082dfbbf3bfda8c7ac24d62e41f85a 100644 (file)
@@ -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);
index 18334fa1a0d281308f05a8f682e2ff6014b838b1..df5b0d8ef04988f396a4117fd3abab64f98fc642 100644 (file)
@@ -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))