diff options
author | David Howells <dhowells@redhat.com> | 2019-04-25 16:26:50 +0300 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-04-25 16:26:50 +0300 |
commit | a690f60a2ba3125a2f08cdde176376f5ec1d8a84 (patch) | |
tree | ba05bc0309f660d66acf188c6e25a1689109f2c0 /fs/afs/flock.c | |
parent | 0b9bf3812ad1f0d937584e300826285694f53e2b (diff) | |
download | linux-a690f60a2ba3125a2f08cdde176376f5ec1d8a84.tar.xz |
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.c | 30 |
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); + } } /* |