linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: linux-afs@lists.infradead.org
Cc: dhowells@redhat.com, linux-kernel@vger.kernel.org
Subject: [PATCH 12/15] afs: Fix calculation of callback expiry time
Date: Wed, 15 May 2019 17:27:04 +0100	[thread overview]
Message-ID: <155793762485.31671.9601704687231766116.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <155793753724.31671.7034451837854752319.stgit@warthog.procyon.org.uk>

Fix the calculation of the expiry time of a callback promise, as obtained
from operations like FS.FetchStatus and FS.FetchData.

The time should be based on the timestamp of the first DATA packet in the
reply and the calculation needs to turn the ktime_t timestamp into a
time64_t.

Fixes: c435ee34551e ("afs: Overhaul the callback handling")
Signed-off-by: David Howells <dhowells@redhat.com>
---

 fs/afs/fsclient.c  |   57 ++++++++++++++++++++++++----------------------------
 fs/afs/yfsclient.c |   51 +++++++++++++++++++++++------------------------
 2 files changed, 51 insertions(+), 57 deletions(-)

diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index c43301b5eea4..721ff8d04401 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -256,6 +256,23 @@ static int afs_decode_status(struct afs_call *call,
 	return ret;
 }
 
+static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
+{
+	return ktime_divns(call->reply_time, NSEC_PER_SEC) + expiry;
+}
+
+static void xdr_decode_AFSCallBack_raw(struct afs_call *call,
+				       struct afs_callback *cb,
+				       const __be32 **_bp)
+{
+	const __be32 *bp = *_bp;
+
+	cb->version	= ntohl(*bp++);
+	cb->expires_at	= xdr_decode_expiry(call, ntohl(*bp++));
+	cb->type	= ntohl(*bp++);
+	*_bp = bp;
+}
+
 /*
  * decode an AFSCallBack block
  */
@@ -264,46 +281,26 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
 				   const __be32 **_bp)
 {
 	struct afs_cb_interest *old, *cbi = call->cbi;
-	const __be32 *bp = *_bp;
-	u32 cb_expiry;
+	struct afs_callback cb;
+
+	xdr_decode_AFSCallBack_raw(call, &cb, _bp);
 
 	write_seqlock(&vnode->cb_lock);
 
 	if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
-		vnode->cb_version	= ntohl(*bp++);
-		cb_expiry		= ntohl(*bp++);
-		vnode->cb_type		= ntohl(*bp++);
-		vnode->cb_expires_at	= cb_expiry + ktime_get_real_seconds();
+		vnode->cb_version	= cb.version;
+		vnode->cb_type		= cb.type;
+		vnode->cb_expires_at	= cb.expires_at;
 		old = vnode->cb_interest;
 		if (old != call->cbi) {
 			vnode->cb_interest = cbi;
 			cbi = old;
 		}
 		set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
-	} else {
-		bp += 3;
 	}
 
 	write_sequnlock(&vnode->cb_lock);
 	call->cbi = cbi;
-	*_bp = bp;
-}
-
-static ktime_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
-{
-	return ktime_add_ns(call->reply_time, expiry * NSEC_PER_SEC);
-}
-
-static void xdr_decode_AFSCallBack_raw(struct afs_call *call,
-				       const __be32 **_bp,
-				       struct afs_callback *cb)
-{
-	const __be32 *bp = *_bp;
-
-	cb->version	= ntohl(*bp++);
-	cb->expires_at	= xdr_decode_expiry(call, ntohl(*bp++));
-	cb->type	= ntohl(*bp++);
-	*_bp = bp;
 }
 
 /*
@@ -744,7 +741,7 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call)
 				&call->expected_version, NULL);
 	if (ret < 0)
 		return ret;
-	xdr_decode_AFSCallBack_raw(call, &bp, call->reply[3]);
+	xdr_decode_AFSCallBack_raw(call, call->reply[3], &bp);
 	/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
 
 	_leave(" = 0 [done]");
@@ -2167,7 +2164,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
 				&call->expected_version, NULL);
 	if (ret < 0)
 		return ret;
-	xdr_decode_AFSCallBack_raw(call, &bp, callback);
+	xdr_decode_AFSCallBack_raw(call, callback, &bp);
 	xdr_decode_AFSVolSync(&bp, volsync);
 
 	_leave(" = 0 [done]");
@@ -2321,9 +2318,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
 		_debug("unmarshall CB array");
 		bp = call->buffer;
 		callbacks = call->reply[2];
-		callbacks[call->count].version	= ntohl(bp[0]);
-		callbacks[call->count].expires_at = xdr_decode_expiry(call, ntohl(bp[1]));
-		callbacks[call->count].type	= ntohl(bp[2]);
+		xdr_decode_AFSCallBack_raw(call, &callbacks[call->count], &bp);
 		statuses = call->reply[1];
 		if (call->count == 0 && vnode && statuses[0].abort_code == 0)
 			xdr_decode_AFSCallBack(call, vnode, &bp);
diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
index 3ba33d415a74..b42bd412dba1 100644
--- a/fs/afs/yfsclient.c
+++ b/fs/afs/yfsclient.c
@@ -311,6 +311,22 @@ static int yfs_decode_status(struct afs_call *call,
 	return ret;
 }
 
+static void xdr_decode_YFSCallBack_raw(struct afs_call *call,
+				       struct afs_callback *cb,
+				       const __be32 **_bp)
+{
+	struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
+	ktime_t cb_expiry;
+
+	cb_expiry = call->reply_time;
+	cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
+	cb->expires_at	= ktime_divns(cb_expiry, NSEC_PER_SEC);
+	cb->version	= ntohl(x->version);
+	cb->type	= ntohl(x->type);
+
+	*_bp += xdr_size(x);
+}
+
 /*
  * Decode a YFSCallBack block
  */
@@ -318,18 +334,17 @@ static void xdr_decode_YFSCallBack(struct afs_call *call,
 				   struct afs_vnode *vnode,
 				   const __be32 **_bp)
 {
-	struct yfs_xdr_YFSCallBack *xdr = (void *)*_bp;
 	struct afs_cb_interest *old, *cbi = call->cbi;
-	u64 cb_expiry;
+	struct afs_callback cb;
+
+	xdr_decode_YFSCallBack_raw(call, &cb, _bp);
 
 	write_seqlock(&vnode->cb_lock);
 
 	if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
-		cb_expiry = xdr_to_u64(xdr->expiration_time);
-		do_div(cb_expiry, 10 * 1000 * 1000);
-		vnode->cb_version	= ntohl(xdr->version);
-		vnode->cb_type		= ntohl(xdr->type);
-		vnode->cb_expires_at	= cb_expiry + ktime_get_real_seconds();
+		vnode->cb_version	= cb.version;
+		vnode->cb_type		= cb.type;
+		vnode->cb_expires_at	= cb.expires_at;
 		old = vnode->cb_interest;
 		if (old != call->cbi) {
 			vnode->cb_interest = cbi;
@@ -340,22 +355,6 @@ static void xdr_decode_YFSCallBack(struct afs_call *call,
 
 	write_sequnlock(&vnode->cb_lock);
 	call->cbi = cbi;
-	*_bp += xdr_size(xdr);
-}
-
-static void xdr_decode_YFSCallBack_raw(const __be32 **_bp,
-				       struct afs_callback *cb)
-{
-	struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
-	u64 cb_expiry;
-
-	cb_expiry = xdr_to_u64(x->expiration_time);
-	do_div(cb_expiry, 10 * 1000 * 1000);
-	cb->version	= ntohl(x->version);
-	cb->type	= ntohl(x->type);
-	cb->expires_at	= cb_expiry + ktime_get_real_seconds();
-
-	*_bp += xdr_size(x);
 }
 
 /*
@@ -743,7 +742,7 @@ static int yfs_deliver_fs_create_vnode(struct afs_call *call)
 				&call->expected_version, NULL);
 	if (ret < 0)
 		return ret;
-	xdr_decode_YFSCallBack_raw(&bp, call->reply[3]);
+	xdr_decode_YFSCallBack_raw(call, call->reply[3], &bp);
 	xdr_decode_YFSVolSync(&bp, NULL);
 
 	_leave(" = 0 [done]");
@@ -1983,7 +1982,7 @@ static int yfs_deliver_fs_fetch_status(struct afs_call *call)
 				&call->expected_version, NULL);
 	if (ret < 0)
 		return ret;
-	xdr_decode_YFSCallBack_raw(&bp, callback);
+	xdr_decode_YFSCallBack_raw(call, callback, &bp);
 	xdr_decode_YFSVolSync(&bp, volsync);
 
 	_leave(" = 0 [done]");
@@ -2138,7 +2137,7 @@ static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
 		_debug("unmarshall CB array");
 		bp = call->buffer;
 		callbacks = call->reply[2];
-		xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]);
+		xdr_decode_YFSCallBack_raw(call, &callbacks[call->count], &bp);
 		statuses = call->reply[1];
 		if (call->count == 0 && vnode && statuses[0].abort_code == 0) {
 			bp = call->buffer;


  parent reply	other threads:[~2019-05-15 16:27 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-15 16:25 [PATCH 00/15] AFS fixes David Howells
2019-05-15 16:25 ` [PATCH 01/15] afs: Fix key leak in afs_release() and afs_evict_inode() David Howells
2019-05-15 16:25 ` [PATCH 02/15] afs: Fix incorrect error handling in afs_xattr_get_acl() David Howells
2019-05-15 16:26 ` [PATCH 03/15] afs: Fix afs_xattr_get_yfs() to not try freeing an error value David Howells
2019-05-15 16:26 ` [PATCH 04/15] afs: Fix missing lock when replacing VL server list David Howells
2019-05-15 16:26 ` [PATCH 05/15] afs: Fix afs_cell records to always have a VL server list record David Howells
2019-05-15 16:26 ` [PATCH 06/15] dns_resolver: Allow used keys to be invalidated David Howells
2019-05-15 16:26 ` [PATCH 07/15] Add wait_var_event_interruptible() David Howells
2019-05-15 17:30   ` Peter Zijlstra
2019-05-15 16:26 ` [PATCH 08/15] afs: Fix cell DNS lookup David Howells
2019-05-15 16:26 ` [PATCH 09/15] rxrpc: Allow the kernel to mark a call as being non-interruptible David Howells
2019-05-15 16:26 ` [PATCH 10/15] afs: Make some RPC operations non-interruptible David Howells
2019-05-15 16:26 ` [PATCH 11/15] afs: Make dynamic root population wait uninterruptibly for proc_cells_lock David Howells
2019-05-15 16:27 ` David Howells [this message]
2019-05-15 16:27 ` [PATCH 13/15] afs: Don't invalidate callback if AFS_VNODE_DIR_VALID not set David Howells
2019-05-15 16:27 ` [PATCH 14/15] afs: Fix lock-wait/callback-break double locking David Howells
2019-05-15 16:27 ` [PATCH 15/15] afs: Fix double inc of vnode->cb_break David Howells

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=155793762485.31671.9601704687231766116.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).