| From dc23dbf57c7b88fc7fd8193ca3bf6caff070e56e Mon Sep 17 00:00:00 2001 |
| From: David Howells <dhowells@redhat.com> |
| Date: Thu, 16 Apr 2020 14:20:32 +0100 |
| Subject: [PATCH] afs: Always include dir in bulk status fetch from |
| afs_do_lookup() |
| |
| commit 13fcc6356a94558a0a4857dc00cd26b3834a1b3e upstream. |
| |
| When a lookup is done in an AFS directory, the filesystem will speculate |
| and fetch up to 49 other statuses for files in the same directory and fetch |
| those as well, turning them into inodes or updating inodes that already |
| exist. |
| |
| However, occasionally, a callback break might go missing due to NAT timing |
| out, but the afs filesystem doesn't then realise that the directory is not |
| up to date. |
| |
| Alleviate this by using one of the status slots to check the directory in |
| which the lookup is being done. |
| |
| Reported-by: Dave Botsch <botsch@cnf.cornell.edu> |
| Suggested-by: Jeffrey Altman <jaltman@auristor.com> |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/afs/dir.c b/fs/afs/dir.c |
| index 02052f5269ae..429698d0a596 100644 |
| --- a/fs/afs/dir.c |
| +++ b/fs/afs/dir.c |
| @@ -659,7 +659,8 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, |
| |
| cookie->ctx.actor = afs_lookup_filldir; |
| cookie->name = dentry->d_name; |
| - cookie->nr_fids = 1; /* slot 0 is saved for the fid we actually want */ |
| + cookie->nr_fids = 2; /* slot 0 is saved for the fid we actually want |
| + * and slot 1 for the directory */ |
| |
| read_seqlock_excl(&dvnode->cb_lock); |
| dcbi = rcu_dereference_protected(dvnode->cb_interest, |
| @@ -710,7 +711,11 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, |
| if (!cookie->inodes) |
| goto out_s; |
| |
| - for (i = 1; i < cookie->nr_fids; i++) { |
| + cookie->fids[1] = dvnode->fid; |
| + cookie->statuses[1].cb_break = afs_calc_vnode_cb_break(dvnode); |
| + cookie->inodes[1] = igrab(&dvnode->vfs_inode); |
| + |
| + for (i = 2; i < cookie->nr_fids; i++) { |
| scb = &cookie->statuses[i]; |
| |
| /* Find any inodes that already exist and get their |
| -- |
| 2.27.0 |
| |