diff options
author | David Howells <dhowells@redhat.com> | 2018-10-19 19:57:58 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-23 19:41:08 -0400 |
commit | 12d8e95a911eb3921a1fecf1e4d913654f6f4fb5 (patch) | |
tree | fc9823c56bfaac4b746c3d3f84bd7470b07b7ee4 /fs/afs | |
parent | 36bb5f490a542f230beb982475b56d79d72033de (diff) |
afs: Calc callback expiry in op reply delivery
Calculate the callback expiration time at the point of operation reply
delivery, using the reply time queried from AF_RXRPC on that call as a
base.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs')
-rw-r--r-- | fs/afs/afs.h | 2 | ||||
-rw-r--r-- | fs/afs/fsclient.c | 22 | ||||
-rw-r--r-- | fs/afs/inode.c | 4 | ||||
-rw-r--r-- | fs/afs/internal.h | 2 | ||||
-rw-r--r-- | fs/afs/rxrpc.c | 6 |
5 files changed, 28 insertions, 8 deletions
diff --git a/fs/afs/afs.h b/fs/afs/afs.h index fb9bcb8758ea..417cd23529c5 100644 --- a/fs/afs/afs.h +++ b/fs/afs/afs.h | |||
@@ -68,8 +68,8 @@ typedef enum { | |||
68 | } afs_callback_type_t; | 68 | } afs_callback_type_t; |
69 | 69 | ||
70 | struct afs_callback { | 70 | struct afs_callback { |
71 | time64_t expires_at; /* Time at which expires */ | ||
71 | unsigned version; /* Callback version */ | 72 | unsigned version; /* Callback version */ |
72 | unsigned expiry; /* Time at which expires */ | ||
73 | afs_callback_type_t type; /* Type of callback */ | 73 | afs_callback_type_t type; /* Type of callback */ |
74 | }; | 74 | }; |
75 | 75 | ||
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index f758750e81d8..6105cdb17163 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -287,13 +287,19 @@ static void xdr_decode_AFSCallBack(struct afs_call *call, | |||
287 | *_bp = bp; | 287 | *_bp = bp; |
288 | } | 288 | } |
289 | 289 | ||
290 | static void xdr_decode_AFSCallBack_raw(const __be32 **_bp, | 290 | static ktime_t xdr_decode_expiry(struct afs_call *call, u32 expiry) |
291 | { | ||
292 | return ktime_add_ns(call->reply_time, expiry * NSEC_PER_SEC); | ||
293 | } | ||
294 | |||
295 | static void xdr_decode_AFSCallBack_raw(struct afs_call *call, | ||
296 | const __be32 **_bp, | ||
291 | struct afs_callback *cb) | 297 | struct afs_callback *cb) |
292 | { | 298 | { |
293 | const __be32 *bp = *_bp; | 299 | const __be32 *bp = *_bp; |
294 | 300 | ||
295 | cb->version = ntohl(*bp++); | 301 | cb->version = ntohl(*bp++); |
296 | cb->expiry = ntohl(*bp++); | 302 | cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++)); |
297 | cb->type = ntohl(*bp++); | 303 | cb->type = ntohl(*bp++); |
298 | *_bp = bp; | 304 | *_bp = bp; |
299 | } | 305 | } |
@@ -440,6 +446,7 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy | |||
440 | call->reply[0] = vnode; | 446 | call->reply[0] = vnode; |
441 | call->reply[1] = volsync; | 447 | call->reply[1] = volsync; |
442 | call->expected_version = new_inode ? 1 : vnode->status.data_version; | 448 | call->expected_version = new_inode ? 1 : vnode->status.data_version; |
449 | call->want_reply_time = true; | ||
443 | 450 | ||
444 | /* marshall the parameters */ | 451 | /* marshall the parameters */ |
445 | bp = call->request; | 452 | bp = call->request; |
@@ -627,6 +634,7 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req) | |||
627 | call->reply[1] = NULL; /* volsync */ | 634 | call->reply[1] = NULL; /* volsync */ |
628 | call->reply[2] = req; | 635 | call->reply[2] = req; |
629 | call->expected_version = vnode->status.data_version; | 636 | call->expected_version = vnode->status.data_version; |
637 | call->want_reply_time = true; | ||
630 | 638 | ||
631 | /* marshall the parameters */ | 639 | /* marshall the parameters */ |
632 | bp = call->request; | 640 | bp = call->request; |
@@ -672,6 +680,7 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req) | |||
672 | call->reply[1] = NULL; /* volsync */ | 680 | call->reply[1] = NULL; /* volsync */ |
673 | call->reply[2] = req; | 681 | call->reply[2] = req; |
674 | call->expected_version = vnode->status.data_version; | 682 | call->expected_version = vnode->status.data_version; |
683 | call->want_reply_time = true; | ||
675 | 684 | ||
676 | /* marshall the parameters */ | 685 | /* marshall the parameters */ |
677 | bp = call->request; | 686 | bp = call->request; |
@@ -714,7 +723,7 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call) | |||
714 | &call->expected_version, NULL); | 723 | &call->expected_version, NULL); |
715 | if (ret < 0) | 724 | if (ret < 0) |
716 | return ret; | 725 | return ret; |
717 | xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); | 726 | xdr_decode_AFSCallBack_raw(call, &bp, call->reply[3]); |
718 | /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ | 727 | /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ |
719 | 728 | ||
720 | _leave(" = 0 [done]"); | 729 | _leave(" = 0 [done]"); |
@@ -773,6 +782,7 @@ int afs_fs_create(struct afs_fs_cursor *fc, | |||
773 | call->reply[2] = newstatus; | 782 | call->reply[2] = newstatus; |
774 | call->reply[3] = newcb; | 783 | call->reply[3] = newcb; |
775 | call->expected_version = current_data_version + 1; | 784 | call->expected_version = current_data_version + 1; |
785 | call->want_reply_time = true; | ||
776 | 786 | ||
777 | /* marshall the parameters */ | 787 | /* marshall the parameters */ |
778 | bp = call->request; | 788 | bp = call->request; |
@@ -2042,7 +2052,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call) | |||
2042 | &call->expected_version, NULL); | 2052 | &call->expected_version, NULL); |
2043 | if (ret < 0) | 2053 | if (ret < 0) |
2044 | return ret; | 2054 | return ret; |
2045 | xdr_decode_AFSCallBack_raw(&bp, callback); | 2055 | xdr_decode_AFSCallBack_raw(call, &bp, callback); |
2046 | if (volsync) | 2056 | if (volsync) |
2047 | xdr_decode_AFSVolSync(&bp, volsync); | 2057 | xdr_decode_AFSVolSync(&bp, volsync); |
2048 | 2058 | ||
@@ -2088,6 +2098,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc, | |||
2088 | call->reply[2] = callback; | 2098 | call->reply[2] = callback; |
2089 | call->reply[3] = volsync; | 2099 | call->reply[3] = volsync; |
2090 | call->expected_version = 1; /* vnode->status.data_version */ | 2100 | call->expected_version = 1; /* vnode->status.data_version */ |
2101 | call->want_reply_time = true; | ||
2091 | 2102 | ||
2092 | /* marshall the parameters */ | 2103 | /* marshall the parameters */ |
2093 | bp = call->request; | 2104 | bp = call->request; |
@@ -2188,7 +2199,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call) | |||
2188 | bp = call->buffer; | 2199 | bp = call->buffer; |
2189 | callbacks = call->reply[2]; | 2200 | callbacks = call->reply[2]; |
2190 | callbacks[call->count].version = ntohl(bp[0]); | 2201 | callbacks[call->count].version = ntohl(bp[0]); |
2191 | callbacks[call->count].expiry = ntohl(bp[1]); | 2202 | callbacks[call->count].expires_at = xdr_decode_expiry(call, ntohl(bp[1])); |
2192 | callbacks[call->count].type = ntohl(bp[2]); | 2203 | callbacks[call->count].type = ntohl(bp[2]); |
2193 | statuses = call->reply[1]; | 2204 | statuses = call->reply[1]; |
2194 | if (call->count == 0 && vnode && statuses[0].abort_code == 0) | 2205 | if (call->count == 0 && vnode && statuses[0].abort_code == 0) |
@@ -2261,6 +2272,7 @@ int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc, | |||
2261 | call->reply[2] = callbacks; | 2272 | call->reply[2] = callbacks; |
2262 | call->reply[3] = volsync; | 2273 | call->reply[3] = volsync; |
2263 | call->count2 = nr_fids; | 2274 | call->count2 = nr_fids; |
2275 | call->want_reply_time = true; | ||
2264 | 2276 | ||
2265 | /* marshall the parameters */ | 2277 | /* marshall the parameters */ |
2266 | bp = call->request; | 2278 | bp = call->request; |
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 4ba47efe9668..4c6d8e1112c2 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -317,11 +317,11 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, | |||
317 | * didn't give us a callback) */ | 317 | * didn't give us a callback) */ |
318 | vnode->cb_version = 0; | 318 | vnode->cb_version = 0; |
319 | vnode->cb_type = 0; | 319 | vnode->cb_type = 0; |
320 | vnode->cb_expires_at = 0; | 320 | vnode->cb_expires_at = ktime_get(); |
321 | } else { | 321 | } else { |
322 | vnode->cb_version = cb->version; | 322 | vnode->cb_version = cb->version; |
323 | vnode->cb_type = cb->type; | 323 | vnode->cb_type = cb->type; |
324 | vnode->cb_expires_at = cb->expiry; | 324 | vnode->cb_expires_at = cb->expires_at; |
325 | vnode->cb_interest = afs_get_cb_interest(cbi); | 325 | vnode->cb_interest = afs_get_cb_interest(cbi); |
326 | set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); | 326 | set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); |
327 | } | 327 | } |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 28d08aac515d..78065af05153 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -131,6 +131,7 @@ struct afs_call { | |||
131 | bool async; /* T if asynchronous */ | 131 | bool async; /* T if asynchronous */ |
132 | bool ret_reply0; /* T if should return reply[0] on success */ | 132 | bool ret_reply0; /* T if should return reply[0] on success */ |
133 | bool upgrade; /* T to request service upgrade */ | 133 | bool upgrade; /* T to request service upgrade */ |
134 | bool want_reply_time; /* T if want reply_time */ | ||
134 | u16 service_id; /* Actual service ID (after upgrade) */ | 135 | u16 service_id; /* Actual service ID (after upgrade) */ |
135 | unsigned int debug_id; /* Trace ID */ | 136 | unsigned int debug_id; /* Trace ID */ |
136 | u32 operation_ID; /* operation ID for an incoming call */ | 137 | u32 operation_ID; /* operation ID for an incoming call */ |
@@ -144,6 +145,7 @@ struct afs_call { | |||
144 | }; | 145 | }; |
145 | afs_dataversion_t expected_version; /* Updated version expected from store */ | 146 | afs_dataversion_t expected_version; /* Updated version expected from store */ |
146 | afs_dataversion_t expected_version_2; /* 2nd updated version expected from store */ | 147 | afs_dataversion_t expected_version_2; /* 2nd updated version expected from store */ |
148 | ktime_t reply_time; /* Time of first reply packet */ | ||
147 | }; | 149 | }; |
148 | 150 | ||
149 | struct afs_call_type { | 151 | struct afs_call_type { |
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index ce98e133caa6..444ba0d511ef 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c | |||
@@ -499,6 +499,12 @@ static void afs_deliver_to_call(struct afs_call *call) | |||
499 | return; | 499 | return; |
500 | } | 500 | } |
501 | 501 | ||
502 | if (call->want_reply_time && | ||
503 | rxrpc_kernel_get_reply_time(call->net->socket, | ||
504 | call->rxcall, | ||
505 | &call->reply_time)) | ||
506 | call->want_reply_time = false; | ||
507 | |||
502 | ret = call->type->deliver(call); | 508 | ret = call->type->deliver(call); |
503 | state = READ_ONCE(call->state); | 509 | state = READ_ONCE(call->state); |
504 | switch (ret) { | 510 | switch (ret) { |