]> git.itanic.dy.fi Git - linux-stable/commitdiff
afs: Use the operation issue time instead of the reply time for callbacks
authorDavid Howells <dhowells@redhat.com>
Wed, 31 Aug 2022 12:16:42 +0000 (13:16 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2022 09:30:05 +0000 (11:30 +0200)
[ Upstream commit 7903192c4b4a82d792cb0dc5e2779a2efe60d45b ]

rxrpc and kafs between them try to use the receive timestamp on the first
data packet (ie. the one with sequence number 1) as a base from which to
calculate the time at which callback promise and lock expiration occurs.

However, we don't know how long it took for the server to send us the reply
from it having completed the basic part of the operation - it might then,
for instance, have to send a bunch of a callback breaks, depending on the
particular operation.

Fix this by using the time at which the operation is issued on the client
as a base instead.  That should never be longer than the server's idea of
the expiry time.

Fixes: 781070551c26 ("afs: Fix calculation of callback expiry time")
Fixes: 2070a3e44962 ("rxrpc: Allow the reply time to be obtained on a client call")
Suggested-by: Jeffrey E Altman <jaltman@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/afs/flock.c
fs/afs/fsclient.c
fs/afs/internal.h
fs/afs/rxrpc.c
fs/afs/yfsclient.c

index c4210a3964d8b3df6b5ed38feb2270e5387d95ad..bbcc5afd15760a998aa13172c51dfc986ac63ff8 100644 (file)
@@ -76,7 +76,7 @@ void afs_lock_op_done(struct afs_call *call)
        if (call->error == 0) {
                spin_lock(&vnode->lock);
                trace_afs_flock_ev(vnode, NULL, afs_flock_timestamp, 0);
-               vnode->locked_at = call->reply_time;
+               vnode->locked_at = call->issue_time;
                afs_schedule_lock_extension(vnode);
                spin_unlock(&vnode->lock);
        }
index 4943413d9c5f7ff3011ea2fad230e5a84a6e48e5..7d37f63ef0f092079c207b97cfe059cd77a2ab97 100644 (file)
@@ -131,7 +131,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
 
 static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
 {
-       return ktime_divns(call->reply_time, NSEC_PER_SEC) + expiry;
+       return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry;
 }
 
 static void xdr_decode_AFSCallBack(const __be32 **_bp,
index 0ad97a8fc0d494d9fb40d02b4efaf7d7d8ba0ff8..567e61b553f564763c73f3227950f92942f4cf1a 100644 (file)
@@ -138,7 +138,6 @@ struct afs_call {
        bool                    need_attention; /* T if RxRPC poked us */
        bool                    async;          /* T if asynchronous */
        bool                    upgrade;        /* T to request service upgrade */
-       bool                    have_reply_time; /* T if have got reply_time */
        bool                    intr;           /* T if interruptible */
        bool                    unmarshalling_error; /* T if an unmarshalling error occurred */
        u16                     service_id;     /* Actual service ID (after upgrade) */
@@ -152,7 +151,7 @@ struct afs_call {
                } __attribute__((packed));
                __be64          tmp64;
        };
-       ktime_t                 reply_time;     /* Time of first reply packet */
+       ktime_t                 issue_time;     /* Time of issue of operation */
 };
 
 struct afs_call_type {
index a5434f3e57c689a792b23aa62386bc2e0372b8e4..e3de7fea364357900245464a2c027216e9f99297 100644 (file)
@@ -347,6 +347,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
        if (call->max_lifespan)
                rxrpc_kernel_set_max_life(call->net->socket, rxcall,
                                          call->max_lifespan);
+       call->issue_time = ktime_get_real();
 
        /* send the request */
        iov[0].iov_base = call->request;
@@ -497,12 +498,6 @@ static void afs_deliver_to_call(struct afs_call *call)
                        return;
                }
 
-               if (!call->have_reply_time &&
-                   rxrpc_kernel_get_reply_time(call->net->socket,
-                                               call->rxcall,
-                                               &call->reply_time))
-                       call->have_reply_time = true;
-
                ret = call->type->deliver(call);
                state = READ_ONCE(call->state);
                if (ret == 0 && call->unmarshalling_error)
index 2b35cba8ad62b7f801405643ba1657b654062c2e..88ea20e79ae270ae75c4bf184a9b5041a48fe25a 100644 (file)
@@ -239,8 +239,7 @@ static void xdr_decode_YFSCallBack(const __be32 **_bp,
        struct afs_callback *cb = &scb->callback;
        ktime_t cb_expiry;
 
-       cb_expiry = call->reply_time;
-       cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
+       cb_expiry = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
        cb->expires_at  = ktime_divns(cb_expiry, NSEC_PER_SEC);
        scb->have_cb    = true;
        *_bp += xdr_size(x);