linux/fs/afs
David Howells 2105c2820d afs: Fix race between post-modification dir edit and readdir/d_revalidate
AFS directories are retained locally as a structured file, with lookup
being effected by a local search of the file contents.  When a modification
(such as mkdir) happens, the dir file content is modified locally rather
than redownloading the directory.

The directory contents are accessed in a number of ways, with a number of
different locks schemes:

 (1) Download of contents - dvnode->validate_lock/write in afs_read_dir().

 (2) Lookup and readdir - dvnode->validate_lock/read in afs_dir_iterate(),
     downgrading from (1) if necessary.

 (3) d_revalidate of child dentry - dvnode->validate_lock/read in
     afs_do_lookup_one() downgrading from (1) if necessary.

 (4) Edit of dir after modification - page locks on individual dir pages.

Unfortunately, because (4) uses different locking scheme to (1) - (3),
nothing protects against the page being scanned whilst the edit is
underway.  Even download is not safe as it doesn't lock the pages - relying
instead on the validate_lock to serialise as a whole (the theory being that
directory contents are treated as a block and always downloaded as a
block).

Fix this by write-locking dvnode->validate_lock around the edits.  Care
must be taken in the rename case as there may be two different dirs - but
they need not be locked at the same time.  In any case, once the lock is
taken, the directory version must be rechecked, and the edit skipped if a
later version has been downloaded by revalidation (there can't have been
any local changes because the VFS holds the inode lock, but there can have
been remote changes).

Fixes: 63a4681ff3 ("afs: Locally edit directory data for mkdir/create/unlink/...")
Signed-off-by: David Howells <dhowells@redhat.com>
2020-04-13 15:09:01 +01:00
..
addr_list.c afs: Use kfree_rcu() instead of casting kfree() to rcu_callback_t 2020-03-13 10:47:33 -07:00
afs_cm.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
afs_fs.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
afs_vl.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
afs.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
cache.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
callback.c afs: Fix possible assert with callbacks from yfs servers 2019-11-22 14:19:26 -08:00
cell.c afs: Fix characters allowed into cell names 2020-01-26 08:54:04 -08:00
cmservice.c afs: Fix handling of an abort from a service handler 2020-03-13 23:04:35 +00:00
dir_edit.c afs: Remove set but not used variables 'before', 'after' 2019-11-21 20:36:00 +00:00
dir_silly.c afs: Fix race between post-modification dir edit and readdir/d_revalidate 2020-04-13 15:09:01 +01:00
dir.c afs: Fix race between post-modification dir edit and readdir/d_revalidate 2020-04-13 15:09:01 +01:00
dynroot.c afs: Fix creation calls in the dynamic root to fail with EOPNOTSUPP 2019-12-11 17:47:51 +00:00
file.c afs: Rename desc -> req in afs_fetch_data() 2019-11-21 09:12:17 +00:00
flock.c fs: afs: Use pr_warn instead of pr_warning 2019-10-18 15:01:55 +02:00
fs_probe.c afs: Fix unpinned address list during probing 2020-03-26 16:04:29 -07:00
fsclient.c afs: Fix rename operation status delivery 2020-04-13 15:09:01 +01:00
inode.c Printk changes for 5.5 2019-11-25 19:40:40 -08:00
internal.h Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2020-03-25 13:58:05 -07:00
Kconfig treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
main.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
Makefile afs: do not send list of client addresses 2019-06-02 18:06:26 -07:00
misc.c AFS development 2019-07-10 20:55:33 -07:00
mntpt.c afs: Fix mountpoint parsing 2019-12-11 16:56:54 +00:00
proc.c afs: Show volume name in /proc/net/afs/<cell>/volumes 2019-12-11 17:48:20 +00:00
protocol_uae.h afs: Add support for the UAE error table 2019-06-28 18:37:53 +01:00
protocol_yfs.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
rotate.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
rxrpc.c afs: Fix client call Rx-phase signal handling 2020-03-13 23:04:35 +00:00
security.c afs: Support RCU pathwalk 2019-09-02 11:43:54 +01:00
server_list.c AFS development 2019-07-10 20:55:33 -07:00
server.c afs: Fix afs_find_server lookups for ipv4 peers 2019-12-09 15:04:43 +00:00
super.c fs_parse: fold fs_parameter_desc/fs_parameter_spec 2020-02-07 14:48:37 -05:00
vl_list.c fs/afs: Replace rcu_swap_protected() with rcu_replace_pointer() 2019-10-30 08:44:27 -07:00
vl_probe.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
vl_rotate.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
vlclient.c afs: Switch the naming of call->iter and call->_iter 2019-11-21 09:12:17 +00:00
volume.c afs: remove unused variable 'afs_voltypes' 2019-09-02 11:43:54 +01:00
write.c AFS development 2019-07-10 20:55:33 -07:00
xattr.c afs: xattr: use scnprintf 2019-11-21 09:12:17 +00:00
xdr_fs.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36 2019-05-24 17:27:11 +02:00
yfsclient.c afs: Fix length of dump of bad YFSFetchStatus record 2020-04-13 15:09:01 +01:00