afs: Calculate lock extend timer from set/extend reply reception
authorDavid Howells <dhowells@redhat.com>
Thu, 25 Apr 2019 13:26:50 +0000 (14:26 +0100)
committerDavid Howells <dhowells@redhat.com>
Thu, 25 Apr 2019 13:26:50 +0000 (14:26 +0100)
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>
fs/afs/flock.c
fs/afs/fsclient.c
fs/afs/internal.h
fs/afs/yfsclient.c

index e432bd27a2e7b893bf8a1d2480cf2c7efdc17ab8..8b02f0056d54340efc74177ce893a0473f4c1469 100644 (file)
@@ -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);
+       }
 }
 
 /*
index 5eefcf35d73d762c5664a4762878553b26006422..9d405f96cc91baef53743114bb35995d0d2105e5 100644 (file)
@@ -1845,6 +1845,7 @@ static const struct afs_call_type afs_RXFSSetLock = {
        .name           = "FS.SetLock",
        .op             = afs_FS_SetLock,
        .deliver        = afs_deliver_fs_xxxx_lock,
+       .done           = afs_lock_op_done,
        .destructor     = afs_flat_call_destructor,
 };
 
@@ -1855,6 +1856,7 @@ static const struct afs_call_type afs_RXFSExtendLock = {
        .name           = "FS.ExtendLock",
        .op             = afs_FS_ExtendLock,
        .deliver        = afs_deliver_fs_xxxx_lock,
+       .done           = afs_lock_op_done,
        .destructor     = afs_flat_call_destructor,
 };
 
@@ -1889,6 +1891,7 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
 
        call->key = fc->key;
        call->reply[0] = vnode;
+       call->want_reply_time = true;
 
        /* marshall the parameters */
        bp = call->request;
@@ -1925,6 +1928,7 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc)
 
        call->key = fc->key;
        call->reply[0] = vnode;
+       call->want_reply_time = true;
 
        /* marshall the parameters */
        bp = call->request;
index 61e24551574d16ba3701b324e591f38545f37d10..6e680783f59fb8b1ab5f2743e964d9e9ebf28ba3 100644 (file)
@@ -638,6 +638,7 @@ struct afs_vnode {
        struct list_head        granted_locks;  /* locks granted on this file */
        struct delayed_work     lock_work;      /* work to be done in locking */
        struct key              *lock_key;      /* Key to be used in lock ops */
+       ktime_t                 locked_at;      /* Time at which lock obtained */
        enum afs_lock_state     lock_state : 8;
        afs_lock_type_t         lock_type : 8;
 
@@ -905,6 +906,7 @@ extern void afs_put_read(struct afs_read *);
  */
 extern struct workqueue_struct *afs_lock_manager;
 
+extern void afs_lock_op_done(struct afs_call *);
 extern void afs_lock_work(struct work_struct *);
 extern void afs_lock_may_be_available(struct afs_vnode *);
 extern int afs_lock(struct file *, int, struct file_lock *);
index 95b04cb76c8c493dd2c28ccbe702901dc9eab086..73546c2d89ee5bb74536189b7dc7d29dc59c2b1b 100644 (file)
@@ -1801,6 +1801,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = {
        .name           = "YFS.SetLock",
        .op             = yfs_FS_SetLock,
        .deliver        = yfs_deliver_fs_xxxx_lock,
+       .done           = afs_lock_op_done,
        .destructor     = afs_flat_call_destructor,
 };
 
@@ -1811,6 +1812,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = {
        .name           = "YFS.ExtendLock",
        .op             = yfs_FS_ExtendLock,
        .deliver        = yfs_deliver_fs_xxxx_lock,
+       .done           = afs_lock_op_done,
        .destructor     = afs_flat_call_destructor,
 };
 
@@ -1847,6 +1849,7 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
 
        call->key = fc->key;
        call->reply[0] = vnode;
+       call->want_reply_time = true;
 
        /* marshall the parameters */
        bp = call->request;
@@ -1884,6 +1887,7 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
 
        call->key = fc->key;
        call->reply[0] = vnode;
+       call->want_reply_time = true;
 
        /* marshall the parameters */
        bp = call->request;