summaryrefslogtreecommitdiffstats
path: root/fs/afs/flock.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-04-25 14:26:50 +0100
committerDavid Howells <dhowells@redhat.com>2019-04-25 14:26:50 +0100
commita690f60a2ba3125a2f08cdde176376f5ec1d8a84 (patch)
treeba05bc0309f660d66acf188c6e25a1689109f2c0 /fs/afs/flock.c
parent0b9bf3812ad1f0d937584e300826285694f53e2b (diff)
downloadlinux-a690f60a2ba3125a2f08cdde176376f5ec1d8a84.tar.bz2
afs: Calculate lock extend timer from set/extend reply reception
Record the timestamp on the first reply DATA packet received in response to a set- or extend-lock operation, then use this to calculate the time remaining till the lock expires rather than using whatever time the requesting process wakes up and finishes processing the operation as a base. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/flock.c')
-rw-r--r--fs/afs/flock.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index e432bd27a2e7..8b02f0056d54 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -40,8 +40,34 @@ void afs_lock_may_be_available(struct afs_vnode *vnode)
*/
static void afs_schedule_lock_extension(struct afs_vnode *vnode)
{
- queue_delayed_work(afs_lock_manager, &vnode->lock_work,
- AFS_LOCKWAIT * HZ / 2);
+ ktime_t expires_at, now, duration;
+ u64 duration_j;
+
+ expires_at = ktime_add_ms(vnode->locked_at, AFS_LOCKWAIT * 1000 / 2);
+ now = ktime_get_real();
+ duration = ktime_sub(expires_at, now);
+ if (duration <= 0)
+ duration_j = 0;
+ else
+ duration_j = nsecs_to_jiffies(ktime_to_ns(duration));
+
+ queue_delayed_work(afs_lock_manager, &vnode->lock_work, duration_j);
+}
+
+/*
+ * In the case of successful completion of a lock operation, record the time
+ * the reply appeared and start the lock extension timer.
+ */
+void afs_lock_op_done(struct afs_call *call)
+{
+ struct afs_vnode *vnode = call->reply[0];
+
+ if (call->error == 0) {
+ spin_lock(&vnode->lock);
+ vnode->locked_at = call->reply_time;
+ afs_schedule_lock_extension(vnode);
+ spin_unlock(&vnode->lock);
+ }
}
/*