*/
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);
+ }
}
/*
.name = "FS.SetLock",
.op = afs_FS_SetLock,
.deliver = afs_deliver_fs_xxxx_lock,
+ .done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
.name = "FS.ExtendLock",
.op = afs_FS_ExtendLock,
.deliver = afs_deliver_fs_xxxx_lock,
+ .done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
call->key = fc->key;
call->reply[0] = vnode;
+ call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;
call->key = fc->key;
call->reply[0] = vnode;
+ call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;
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;
*/
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 *);
.name = "YFS.SetLock",
.op = yfs_FS_SetLock,
.deliver = yfs_deliver_fs_xxxx_lock,
+ .done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
.name = "YFS.ExtendLock",
.op = yfs_FS_ExtendLock,
.deliver = yfs_deliver_fs_xxxx_lock,
+ .done = afs_lock_op_done,
.destructor = afs_flat_call_destructor,
};
call->key = fc->key;
call->reply[0] = vnode;
+ call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;
call->key = fc->key;
call->reply[0] = vnode;
+ call->want_reply_time = true;
/* marshall the parameters */
bp = call->request;