Skip to content

Commit

Permalink
afs: Calc callback expiry in op reply delivery
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
dhowells committed Oct 23, 2018
1 parent 36bb5f4 commit 12d8e95
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
2 changes: 1 addition & 1 deletion fs/afs/afs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};

Expand Down
22 changes: 17 additions & 5 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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]");
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions fs/afs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 {
Expand Down
6 changes: 6 additions & 0 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 12d8e95

Please sign in to comment.