diff options
author | David Howells <dhowells@redhat.com> | 2019-04-25 09:26:50 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2019-04-25 09:26:50 -0400 |
commit | a690f60a2ba3125a2f08cdde176376f5ec1d8a84 (patch) | |
tree | ba05bc0309f660d66acf188c6e25a1689109f2c0 /fs/afs | |
parent | 0b9bf3812ad1f0d937584e300826285694f53e2b (diff) |
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')
-rw-r--r-- | fs/afs/flock.c | 30 | ||||
-rw-r--r-- | fs/afs/fsclient.c | 4 | ||||
-rw-r--r-- | fs/afs/internal.h | 2 | ||||
-rw-r--r-- | fs/afs/yfsclient.c | 4 |
4 files changed, 38 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) | |||
40 | */ | 40 | */ |
41 | static void afs_schedule_lock_extension(struct afs_vnode *vnode) | 41 | static void afs_schedule_lock_extension(struct afs_vnode *vnode) |
42 | { | 42 | { |
43 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, | 43 | ktime_t expires_at, now, duration; |
44 | AFS_LOCKWAIT * HZ / 2); | 44 | u64 duration_j; |
45 | |||
46 | expires_at = ktime_add_ms(vnode->locked_at, AFS_LOCKWAIT * 1000 / 2); | ||
47 | now = ktime_get_real(); | ||
48 | duration = ktime_sub(expires_at, now); | ||
49 | if (duration <= 0) | ||
50 | duration_j = 0; | ||
51 | else | ||
52 | duration_j = nsecs_to_jiffies(ktime_to_ns(duration)); | ||
53 | |||
54 | queue_delayed_work(afs_lock_manager, &vnode->lock_work, duration_j); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * In the case of successful completion of a lock operation, record the time | ||
59 | * the reply appeared and start the lock extension timer. | ||
60 | */ | ||
61 | void afs_lock_op_done(struct afs_call *call) | ||
62 | { | ||
63 | struct afs_vnode *vnode = call->reply[0]; | ||
64 | |||
65 | if (call->error == 0) { | ||
66 | spin_lock(&vnode->lock); | ||
67 | vnode->locked_at = call->reply_time; | ||
68 | afs_schedule_lock_extension(vnode); | ||
69 | spin_unlock(&vnode->lock); | ||
70 | } | ||
45 | } | 71 | } |
46 | 72 | ||
47 | /* | 73 | /* |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 5eefcf35d73d..9d405f96cc91 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -1845,6 +1845,7 @@ static const struct afs_call_type afs_RXFSSetLock = { | |||
1845 | .name = "FS.SetLock", | 1845 | .name = "FS.SetLock", |
1846 | .op = afs_FS_SetLock, | 1846 | .op = afs_FS_SetLock, |
1847 | .deliver = afs_deliver_fs_xxxx_lock, | 1847 | .deliver = afs_deliver_fs_xxxx_lock, |
1848 | .done = afs_lock_op_done, | ||
1848 | .destructor = afs_flat_call_destructor, | 1849 | .destructor = afs_flat_call_destructor, |
1849 | }; | 1850 | }; |
1850 | 1851 | ||
@@ -1855,6 +1856,7 @@ static const struct afs_call_type afs_RXFSExtendLock = { | |||
1855 | .name = "FS.ExtendLock", | 1856 | .name = "FS.ExtendLock", |
1856 | .op = afs_FS_ExtendLock, | 1857 | .op = afs_FS_ExtendLock, |
1857 | .deliver = afs_deliver_fs_xxxx_lock, | 1858 | .deliver = afs_deliver_fs_xxxx_lock, |
1859 | .done = afs_lock_op_done, | ||
1858 | .destructor = afs_flat_call_destructor, | 1860 | .destructor = afs_flat_call_destructor, |
1859 | }; | 1861 | }; |
1860 | 1862 | ||
@@ -1889,6 +1891,7 @@ int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1889 | 1891 | ||
1890 | call->key = fc->key; | 1892 | call->key = fc->key; |
1891 | call->reply[0] = vnode; | 1893 | call->reply[0] = vnode; |
1894 | call->want_reply_time = true; | ||
1892 | 1895 | ||
1893 | /* marshall the parameters */ | 1896 | /* marshall the parameters */ |
1894 | bp = call->request; | 1897 | bp = call->request; |
@@ -1925,6 +1928,7 @@ int afs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1925 | 1928 | ||
1926 | call->key = fc->key; | 1929 | call->key = fc->key; |
1927 | call->reply[0] = vnode; | 1930 | call->reply[0] = vnode; |
1931 | call->want_reply_time = true; | ||
1928 | 1932 | ||
1929 | /* marshall the parameters */ | 1933 | /* marshall the parameters */ |
1930 | bp = call->request; | 1934 | bp = call->request; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 61e24551574d..6e680783f59f 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -638,6 +638,7 @@ struct afs_vnode { | |||
638 | struct list_head granted_locks; /* locks granted on this file */ | 638 | struct list_head granted_locks; /* locks granted on this file */ |
639 | struct delayed_work lock_work; /* work to be done in locking */ | 639 | struct delayed_work lock_work; /* work to be done in locking */ |
640 | struct key *lock_key; /* Key to be used in lock ops */ | 640 | struct key *lock_key; /* Key to be used in lock ops */ |
641 | ktime_t locked_at; /* Time at which lock obtained */ | ||
641 | enum afs_lock_state lock_state : 8; | 642 | enum afs_lock_state lock_state : 8; |
642 | afs_lock_type_t lock_type : 8; | 643 | afs_lock_type_t lock_type : 8; |
643 | 644 | ||
@@ -905,6 +906,7 @@ extern void afs_put_read(struct afs_read *); | |||
905 | */ | 906 | */ |
906 | extern struct workqueue_struct *afs_lock_manager; | 907 | extern struct workqueue_struct *afs_lock_manager; |
907 | 908 | ||
909 | extern void afs_lock_op_done(struct afs_call *); | ||
908 | extern void afs_lock_work(struct work_struct *); | 910 | extern void afs_lock_work(struct work_struct *); |
909 | extern void afs_lock_may_be_available(struct afs_vnode *); | 911 | extern void afs_lock_may_be_available(struct afs_vnode *); |
910 | extern int afs_lock(struct file *, int, struct file_lock *); | 912 | extern int afs_lock(struct file *, int, struct file_lock *); |
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c index 95b04cb76c8c..73546c2d89ee 100644 --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c | |||
@@ -1801,6 +1801,7 @@ static const struct afs_call_type yfs_RXYFSSetLock = { | |||
1801 | .name = "YFS.SetLock", | 1801 | .name = "YFS.SetLock", |
1802 | .op = yfs_FS_SetLock, | 1802 | .op = yfs_FS_SetLock, |
1803 | .deliver = yfs_deliver_fs_xxxx_lock, | 1803 | .deliver = yfs_deliver_fs_xxxx_lock, |
1804 | .done = afs_lock_op_done, | ||
1804 | .destructor = afs_flat_call_destructor, | 1805 | .destructor = afs_flat_call_destructor, |
1805 | }; | 1806 | }; |
1806 | 1807 | ||
@@ -1811,6 +1812,7 @@ static const struct afs_call_type yfs_RXYFSExtendLock = { | |||
1811 | .name = "YFS.ExtendLock", | 1812 | .name = "YFS.ExtendLock", |
1812 | .op = yfs_FS_ExtendLock, | 1813 | .op = yfs_FS_ExtendLock, |
1813 | .deliver = yfs_deliver_fs_xxxx_lock, | 1814 | .deliver = yfs_deliver_fs_xxxx_lock, |
1815 | .done = afs_lock_op_done, | ||
1814 | .destructor = afs_flat_call_destructor, | 1816 | .destructor = afs_flat_call_destructor, |
1815 | }; | 1817 | }; |
1816 | 1818 | ||
@@ -1847,6 +1849,7 @@ int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type) | |||
1847 | 1849 | ||
1848 | call->key = fc->key; | 1850 | call->key = fc->key; |
1849 | call->reply[0] = vnode; | 1851 | call->reply[0] = vnode; |
1852 | call->want_reply_time = true; | ||
1850 | 1853 | ||
1851 | /* marshall the parameters */ | 1854 | /* marshall the parameters */ |
1852 | bp = call->request; | 1855 | bp = call->request; |
@@ -1884,6 +1887,7 @@ int yfs_fs_extend_lock(struct afs_fs_cursor *fc) | |||
1884 | 1887 | ||
1885 | call->key = fc->key; | 1888 | call->key = fc->key; |
1886 | call->reply[0] = vnode; | 1889 | call->reply[0] = vnode; |
1890 | call->want_reply_time = true; | ||
1887 | 1891 | ||
1888 | /* marshall the parameters */ | 1892 | /* marshall the parameters */ |
1889 | bp = call->request; | 1893 | bp = call->request; |