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>
This commit is contained in:
parent
36bb5f490a
commit
12d8e95a91
|
@ -68,8 +68,8 @@ typedef enum {
|
||||||
} afs_callback_type_t;
|
} afs_callback_type_t;
|
||||||
|
|
||||||
struct afs_callback {
|
struct afs_callback {
|
||||||
|
time64_t expires_at; /* Time at which expires */
|
||||||
unsigned version; /* Callback version */
|
unsigned version; /* Callback version */
|
||||||
unsigned expiry; /* Time at which expires */
|
|
||||||
afs_callback_type_t type; /* Type of callback */
|
afs_callback_type_t type; /* Type of callback */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -287,13 +287,19 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
|
||||||
*_bp = bp;
|
*_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)
|
struct afs_callback *cb)
|
||||||
{
|
{
|
||||||
const __be32 *bp = *_bp;
|
const __be32 *bp = *_bp;
|
||||||
|
|
||||||
cb->version = ntohl(*bp++);
|
cb->version = ntohl(*bp++);
|
||||||
cb->expiry = ntohl(*bp++);
|
cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++));
|
||||||
cb->type = ntohl(*bp++);
|
cb->type = ntohl(*bp++);
|
||||||
*_bp = 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[0] = vnode;
|
||||||
call->reply[1] = volsync;
|
call->reply[1] = volsync;
|
||||||
call->expected_version = new_inode ? 1 : vnode->status.data_version;
|
call->expected_version = new_inode ? 1 : vnode->status.data_version;
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
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[1] = NULL; /* volsync */
|
||||||
call->reply[2] = req;
|
call->reply[2] = req;
|
||||||
call->expected_version = vnode->status.data_version;
|
call->expected_version = vnode->status.data_version;
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
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[1] = NULL; /* volsync */
|
||||||
call->reply[2] = req;
|
call->reply[2] = req;
|
||||||
call->expected_version = vnode->status.data_version;
|
call->expected_version = vnode->status.data_version;
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
bp = call->request;
|
||||||
|
@ -714,7 +723,7 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call)
|
||||||
&call->expected_version, NULL);
|
&call->expected_version, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
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]); */
|
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
|
||||||
|
|
||||||
_leave(" = 0 [done]");
|
_leave(" = 0 [done]");
|
||||||
|
@ -773,6 +782,7 @@ int afs_fs_create(struct afs_fs_cursor *fc,
|
||||||
call->reply[2] = newstatus;
|
call->reply[2] = newstatus;
|
||||||
call->reply[3] = newcb;
|
call->reply[3] = newcb;
|
||||||
call->expected_version = current_data_version + 1;
|
call->expected_version = current_data_version + 1;
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
bp = call->request;
|
||||||
|
@ -2042,7 +2052,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
|
||||||
&call->expected_version, NULL);
|
&call->expected_version, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
xdr_decode_AFSCallBack_raw(&bp, callback);
|
xdr_decode_AFSCallBack_raw(call, &bp, callback);
|
||||||
if (volsync)
|
if (volsync)
|
||||||
xdr_decode_AFSVolSync(&bp, 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[2] = callback;
|
||||||
call->reply[3] = volsync;
|
call->reply[3] = volsync;
|
||||||
call->expected_version = 1; /* vnode->status.data_version */
|
call->expected_version = 1; /* vnode->status.data_version */
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
bp = call->request;
|
||||||
|
@ -2188,7 +2199,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
|
||||||
bp = call->buffer;
|
bp = call->buffer;
|
||||||
callbacks = call->reply[2];
|
callbacks = call->reply[2];
|
||||||
callbacks[call->count].version = ntohl(bp[0]);
|
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]);
|
callbacks[call->count].type = ntohl(bp[2]);
|
||||||
statuses = call->reply[1];
|
statuses = call->reply[1];
|
||||||
if (call->count == 0 && vnode && statuses[0].abort_code == 0)
|
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[2] = callbacks;
|
||||||
call->reply[3] = volsync;
|
call->reply[3] = volsync;
|
||||||
call->count2 = nr_fids;
|
call->count2 = nr_fids;
|
||||||
|
call->want_reply_time = true;
|
||||||
|
|
||||||
/* marshall the parameters */
|
/* marshall the parameters */
|
||||||
bp = call->request;
|
bp = call->request;
|
||||||
|
|
|
@ -317,11 +317,11 @@ struct inode *afs_iget(struct super_block *sb, struct key *key,
|
||||||
* didn't give us a callback) */
|
* didn't give us a callback) */
|
||||||
vnode->cb_version = 0;
|
vnode->cb_version = 0;
|
||||||
vnode->cb_type = 0;
|
vnode->cb_type = 0;
|
||||||
vnode->cb_expires_at = 0;
|
vnode->cb_expires_at = ktime_get();
|
||||||
} else {
|
} else {
|
||||||
vnode->cb_version = cb->version;
|
vnode->cb_version = cb->version;
|
||||||
vnode->cb_type = cb->type;
|
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);
|
vnode->cb_interest = afs_get_cb_interest(cbi);
|
||||||
set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
|
set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ struct afs_call {
|
||||||
bool async; /* T if asynchronous */
|
bool async; /* T if asynchronous */
|
||||||
bool ret_reply0; /* T if should return reply[0] on success */
|
bool ret_reply0; /* T if should return reply[0] on success */
|
||||||
bool upgrade; /* T to request service upgrade */
|
bool upgrade; /* T to request service upgrade */
|
||||||
|
bool want_reply_time; /* T if want reply_time */
|
||||||
u16 service_id; /* Actual service ID (after upgrade) */
|
u16 service_id; /* Actual service ID (after upgrade) */
|
||||||
unsigned int debug_id; /* Trace ID */
|
unsigned int debug_id; /* Trace ID */
|
||||||
u32 operation_ID; /* operation ID for an incoming call */
|
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; /* Updated version expected from store */
|
||||||
afs_dataversion_t expected_version_2; /* 2nd 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 {
|
struct afs_call_type {
|
||||||
|
|
|
@ -499,6 +499,12 @@ static void afs_deliver_to_call(struct afs_call *call)
|
||||||
return;
|
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);
|
ret = call->type->deliver(call);
|
||||||
state = READ_ONCE(call->state);
|
state = READ_ONCE(call->state);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
|
|
Loading…
Reference in New Issue