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>
This commit is contained in:
parent
0b9bf3812a
commit
a690f60a2b
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue