Commit 12d8e95a authored by David Howells's avatar David Howells
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
parent 36bb5f49
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ typedef enum {
} afs_callback_type_t;

struct afs_callback {
	time64_t		expires_at;	/* Time at which expires */
	unsigned		version;	/* Callback version */
	unsigned		expiry;		/* Time at which expires */
	afs_callback_type_t	type;		/* Type of callback */
};

+17 −5
Original line number Diff line number Diff line
@@ -287,13 +287,19 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
	*_bp = bp;
}

static void xdr_decode_AFSCallBack_raw(const __be32 **_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->expiry	= ntohl(*bp++);
	cb->expires_at	= xdr_decode_expiry(call, ntohl(*bp++));
	cb->type	= ntohl(*bp++);
	*_bp = bp;
}
@@ -440,6 +446,7 @@ int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsy
	call->reply[0] = vnode;
	call->reply[1] = volsync;
	call->expected_version = new_inode ? 1 : vnode->status.data_version;
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
@@ -627,6 +634,7 @@ static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
	call->reply[1] = NULL; /* volsync */
	call->reply[2] = req;
	call->expected_version = vnode->status.data_version;
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
@@ -672,6 +680,7 @@ int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
	call->reply[1] = NULL; /* volsync */
	call->reply[2] = req;
	call->expected_version = vnode->status.data_version;
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
@@ -714,7 +723,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(&bp, call->reply[3]);
	xdr_decode_AFSCallBack_raw(call, &bp, call->reply[3]);
	/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

	_leave(" = 0 [done]");
@@ -773,6 +782,7 @@ int afs_fs_create(struct afs_fs_cursor *fc,
	call->reply[2] = newstatus;
	call->reply[3] = newcb;
	call->expected_version = current_data_version + 1;
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
@@ -2042,7 +2052,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(&bp, callback);
	xdr_decode_AFSCallBack_raw(call, &bp, callback);
	if (volsync)
		xdr_decode_AFSVolSync(&bp, volsync);

@@ -2088,6 +2098,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
	call->reply[2] = callback;
	call->reply[3] = volsync;
	call->expected_version = 1; /* vnode->status.data_version */
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
@@ -2188,7 +2199,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
		bp = call->buffer;
		callbacks = call->reply[2];
		callbacks[call->count].version	= ntohl(bp[0]);
		callbacks[call->count].expiry	= ntohl(bp[1]);
		callbacks[call->count].expires_at = xdr_decode_expiry(call, ntohl(bp[1]));
		callbacks[call->count].type	= ntohl(bp[2]);
		statuses = call->reply[1];
		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,
	call->reply[2] = callbacks;
	call->reply[3] = volsync;
	call->count2 = nr_fids;
	call->want_reply_time = true;

	/* marshall the parameters */
	bp = call->request;
+2 −2
Original line number Diff line number Diff line
@@ -317,11 +317,11 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
			 * didn't give us a callback) */
			vnode->cb_version = 0;
			vnode->cb_type = 0;
			vnode->cb_expires_at = 0;
			vnode->cb_expires_at = ktime_get();
		} else {
			vnode->cb_version = cb->version;
			vnode->cb_type = cb->type;
			vnode->cb_expires_at = cb->expiry;
			vnode->cb_expires_at = cb->expires_at;
			vnode->cb_interest = afs_get_cb_interest(cbi);
			set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
		}
+2 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ struct afs_call {
	bool			async;		/* T if asynchronous */
	bool			ret_reply0;	/* T if should return reply[0] on success */
	bool			upgrade;	/* T to request service upgrade */
	bool			want_reply_time;	/* T if want reply_time */
	u16			service_id;	/* Actual service ID (after upgrade) */
	unsigned int		debug_id;	/* Trace ID */
	u32			operation_ID;	/* operation ID for an incoming call */
@@ -144,6 +145,7 @@ struct afs_call {
	};
	afs_dataversion_t	expected_version; /* Updated version expected from store */
	afs_dataversion_t	expected_version_2; /* 2nd updated version expected from store */
	ktime_t			reply_time;	/* Time of first reply packet */
};

struct afs_call_type {
+6 −0
Original line number Diff line number Diff line
@@ -499,6 +499,12 @@ static void afs_deliver_to_call(struct afs_call *call)
			return;
		}

		if (call->want_reply_time &&
		    rxrpc_kernel_get_reply_time(call->net->socket,
						call->rxcall,
						&call->reply_time))
			call->want_reply_time = false;

		ret = call->type->deliver(call);
		state = READ_ONCE(call->state);
		switch (ret) {