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
	
	Block a user