diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 17:00:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-16 17:00:13 -0700 |
commit | 227747fb9eab37aaeb360aeba795362c01889427 (patch) | |
tree | 6bc179332007a270373703c5f04cbc19af242702 /fs/afs/rotate.c | |
parent | 1d9d7cbf28a1c2f84f2a0224466f8eb5f0a62ace (diff) | |
parent | fd711586bb7d63f257da5eff234e68c446ac35ea (diff) | |
download | linux-227747fb9eab37aaeb360aeba795362c01889427.tar.bz2 |
Merge tag 'afs-fixes-20190516' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull misc AFS fixes from David Howells:
"This fixes a set of miscellaneous issues in the afs filesystem,
including:
- leak of keys on file close.
- broken error handling in xattr functions.
- missing locking when updating VL server list.
- volume location server DNS lookup whereby preloaded cells may not
ever get a lookup and regular DNS lookups to maintain server lists
consume power unnecessarily.
- incorrect error propagation and handling in the fileserver
iteration code causes operations to sometimes apparently succeed.
- interruption of server record check/update side op during
fileserver iteration causes uninterruptible main operations to fail
unexpectedly.
- callback promise expiry time miscalculation.
- over invalidation of the callback promise on directories.
- double locking on callback break waking up file locking waiters.
- double increment of the vnode callback break counter.
Note that it makes some changes outside of the afs code, including:
- an extra parameter to dns_query() to allow the dns_resolver key
just accessed to be immediately invalidated. AFS is caching the
results itself, so the key can be discarded.
- an interruptible version of wait_var_event().
- an rxrpc function to allow the maximum lifespan to be set on a
call.
- a way for an rxrpc call to be marked as non-interruptible"
* tag 'afs-fixes-20190516' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
afs: Fix double inc of vnode->cb_break
afs: Fix lock-wait/callback-break double locking
afs: Don't invalidate callback if AFS_VNODE_DIR_VALID not set
afs: Fix calculation of callback expiry time
afs: Make dynamic root population wait uninterruptibly for proc_cells_lock
afs: Make some RPC operations non-interruptible
rxrpc: Allow the kernel to mark a call as being non-interruptible
afs: Fix error propagation from server record check/update
afs: Fix the maximum lifespan of VL and probe calls
rxrpc: Provide kernel interface to set max lifespan on a call
afs: Fix "kAFS: AFS vnode with undefined type 0"
afs: Fix cell DNS lookup
Add wait_var_event_interruptible()
dns_resolver: Allow used keys to be invalidated
afs: Fix afs_cell records to always have a VL server list record
afs: Fix missing lock when replacing VL server list
afs: Fix afs_xattr_get_yfs() to not try freeing an error value
afs: Fix incorrect error handling in afs_xattr_get_acl()
afs: Fix key leak in afs_release() and afs_evict_inode()
Diffstat (limited to 'fs/afs/rotate.c')
-rw-r--r-- | fs/afs/rotate.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c index c3ae324781f8..52f3a9910f0d 100644 --- a/fs/afs/rotate.c +++ b/fs/afs/rotate.c @@ -25,7 +25,7 @@ * them here also using the io_lock. */ bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode, - struct key *key) + struct key *key, bool intr) { memset(fc, 0, sizeof(*fc)); fc->vnode = vnode; @@ -33,10 +33,15 @@ bool afs_begin_vnode_operation(struct afs_fs_cursor *fc, struct afs_vnode *vnode fc->ac.error = SHRT_MAX; fc->error = -EDESTADDRREQ; - if (mutex_lock_interruptible(&vnode->io_lock) < 0) { - fc->error = -EINTR; - fc->flags |= AFS_FS_CURSOR_STOP; - return false; + if (intr) { + fc->flags |= AFS_FS_CURSOR_INTR; + if (mutex_lock_interruptible(&vnode->io_lock) < 0) { + fc->error = -EINTR; + fc->flags |= AFS_FS_CURSOR_STOP; + return false; + } + } else { + mutex_lock(&vnode->io_lock); } if (vnode->lock_state != AFS_VNODE_LOCK_NONE) @@ -118,10 +123,14 @@ static void afs_busy(struct afs_volume *volume, u32 abort_code) */ static bool afs_sleep_and_retry(struct afs_fs_cursor *fc) { - msleep_interruptible(1000); - if (signal_pending(current)) { - fc->error = -ERESTARTSYS; - return false; + if (fc->flags & AFS_FS_CURSOR_INTR) { + msleep_interruptible(1000); + if (signal_pending(current)) { + fc->error = -ERESTARTSYS; + return false; + } + } else { + msleep(1000); } return true; @@ -459,6 +468,8 @@ no_more_servers: s->probe.abort_code); } + error = e.error; + failed_set_error: fc->error = error; failed: |