Pull AFS updates from David Howells:
"A set of fix and development patches for AFS for 5.2.
Summary:
- Fix the AFS file locking so that sqlite can run on an AFS mount and
also so that firefox and gnome can use a homedir that's mounted
through AFS.
This required emulation of fine-grained locking when the server
will only support whole-file locks and no upgrade/downgrade. Four
modes are provided, settable by mount parameter:
"flock=local" - No reference to the server
"flock=openafs" - Fine-grained locks are local-only, whole-file
locks require sufficient server locks
"flock=strict" - All locks require sufficient server locks
"flock=write" - Always get an exclusive server lock
If the volume is a read-only or backup volume, then flock=local for
that volume.
- Log extra information for a couple of cases where the client mucks
up somehow: AFS vnode with undefined type and dir check failure -
in both cases we seem to end up with unfilled data, but the issues
happen infrequently and are difficult to reproduce at will.
- Implement silly rename for unlink() and rename().
- Set i_blocks so that du can get some information about usage.
- Fix xattr handlers to return the right amount of data and to not
overflow buffers.
- Implement getting/setting raw AFS and YFS ACLs as xattrs"
* tag 'afs-next-
20190507' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
afs: Implement YFS ACL setting
afs: Get YFS ACLs and information through xattrs
afs: implement acl setting
afs: Get an AFS3 ACL as an xattr
afs: Fix getting the afs.fid xattr
afs: Fix the afs.cell and afs.volume xattr handlers
afs: Calculate i_blocks based on file size
afs: Log more information for "kAFS: AFS vnode with undefined type\n"
afs: Provide mount-time configurable byte-range file locking emulation
afs: Add more tracepoints
afs: Implement sillyrename for unlink and rename
afs: Add directory reload tracepoint
afs: Handle lock rpc ops failing on a file that got deleted
afs: Improve dir check failure reports
afs: Add file locking tracepoints
afs: Further fix file locking
afs: Fix AFS file locking to allow fine grained locks
afs: Calculate lock extend timer from set/extend reply reception
afs: Split wait from afs_make_call()
_leave(" [ext]");
return;
- /* If we don't have a granted lock, then we must've been called
- * back by the server, and so if might be possible to get a
- * lock we're currently waiting for.
- */
+ /* If we're waiting for a callback to indicate lock release, we can't
+ * actually rely on this, so need to recheck at regular intervals. The
+ * problem is that the server might not notify us if the lock just
+ * expires (say because a client died) rather than being explicitly
+ * released.
+ */
case AFS_VNODE_LOCK_WAITING_FOR_CB:
- _debug("get");
-
- key = key_get(vnode->lock_key);
- type = vnode->lock_type;
- vnode->lock_state = AFS_VNODE_LOCK_SETTING;
+ _debug("retry");
+ afs_next_locker(vnode, 0);
spin_unlock(&vnode->lock);
+ return;
- ret = afs_set_lock(vnode, key, type); /* RPC */
- key_put(key);
-
- spin_lock(&vnode->lock);
- switch (ret) {
- case -EWOULDBLOCK:
- _debug("blocked");
- break;
- case 0:
- _debug("acquired");
- vnode->lock_state = AFS_VNODE_LOCK_GRANTED;
- /* Fall through */
- default:
- /* Pass the lock or the error onto the first locker in
- * the list - if they're looking for this type of lock.
- * If they're not, we assume that whoever asked for it
- * took a signal.
- */
- if (list_empty(&vnode->pending_locks)) {
- _debug("withdrawn");
- vnode->lock_state = AFS_VNODE_LOCK_NEED_UNLOCK;
- goto again;
- }
-
- fl = list_entry(vnode->pending_locks.next,
- struct file_lock, fl_u.afs.link);
- type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
- if (vnode->lock_type != type) {
- _debug("changed");
- vnode->lock_state = AFS_VNODE_LOCK_NEED_UNLOCK;
- goto again;
- }
-
- fl->fl_u.afs.state = ret;
- if (ret == 0)
- afs_grant_locks(vnode, fl);
- else
- list_del_init(&fl->fl_u.afs.link);
- wake_up(&fl->fl_wait);
- spin_unlock(&vnode->lock);
- _leave(" [granted]");
- return;
- }
+ case AFS_VNODE_LOCK_DELETED:
+ afs_kill_lockers_enoent(vnode);
+ spin_unlock(&vnode->lock);
+ return;
+ /* Fall through */
default:
/* Looks like a lock request was withdrawn. */
spin_unlock(&vnode->lock);