[PATCH] afs: Fix afs_do_lookup() to call correct fetch-status op variant
From: David Howells
Date: Thu Jun 18 2020 - 19:01:39 EST
Fix afs_do_lookup()'s fallback case for when FS.InlineBulkStatus isn't
supported by the server. In the fallback, it calls FS.FetchStatus for the
specific vnode it's meant to be looking up. Commit b6489a49f7b7 broke this
by renaming one of the two identically-named afs_fetch_status_operation
descriptors to something else so that one of them could be made non-static.
The site that used the renamed one, however, wasn't renamed and didn't
produce any warning because the other was declared in a header.
Fix this by making afs_do_lookup() use the renamed variant.
Note that there are two variants of the success method because one is
called from ->lookup() where we may or may not have an inode, but can't
call iget until after we've talked to the server - whereas the other is
called from within iget where we have an inode, but it may or may not be
initialised.
The latter variant expects there to be an inode, but because it's being
called from there former case, there might not be - resulting in an oops
like the following:
BUG: kernel NULL pointer dereference, address: 00000000000000b0
...
RIP: 0010:afs_fetch_status_success+0x27/0x7e
...
Call Trace:
? rxrpc_cleanup_call+0xb5/0xc5
afs_wait_for_operation+0xda/0x234
afs_do_lookup+0x2fe/0x3c1
afs_lookup+0x3c5/0x4bd
__lookup_slow+0xcd/0x10f
walk_component+0xa2/0x10c
? path_init+0x101/0x2eb
path_lookupat.isra.0+0x80/0x110
filename_lookup+0x81/0x104
? slab_post_alloc_hook.isra.0+0xa/0x1a
? kmem_cache_alloc+0xc3/0x129
vfs_statx+0x76/0x109
? touch_atime+0x33/0xac
__do_sys_newlstat+0x39/0x6b
? ksys_getdents64+0xb9/0xe0
? vtime_delta.isra.0+0xe/0x24
? vtime_delta.isra.0+0xe/0x24
? get_vtime_delta+0x12/0x20
? vtime_user_exit+0x21/0x61
? __context_tracking_exit+0x3a/0x87
do_syscall_64+0x4c/0x78
entry_SYSCALL_64_after_hwframe+0x44/0xa9
Fixes: b6489a49f7b7 ("afs: Fix silly rename")
Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---
fs/afs/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 3e3c2bf0a722..96757f3abd74 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -845,7 +845,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
* to FS.FetchStatus for op->file[1].
*/
op->fetch_status.which = 1;
- op->ops = &afs_fetch_status_operation;
+ op->ops = &afs_lookup_fetch_status_operation;
afs_begin_vnode_operation(op);
afs_wait_for_operation(op);
}