afs: Don't truncate iter during data fetch
Don't truncate the iterator to correspond to the actual data size when fetching the data from the server - rather, pass the length we want to read to rxrpc. This will allow the clear-after-read code in future to simply clear the remaining iterator capacity rather than having to reinitialise the iterator. Signed-off-by: David Howells <dhowells@redhat.com> Tested-By: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/158861249201.340223.13035445866976590375.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/159465825061.1377938.14403904452300909320.stgit@warthog.procyon.org.uk/ Link: https://lore.kernel.org/r/160588531418.3465195.10712005940763063144.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161118148567.1232039.13380313332292947956.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161161044610.2537118.17908520793806837792.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/161340407907.1303470.6501394859511712746.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/161539551721.286939.14655713136572200716.stgit@warthog.procyon.org.uk/ # v4 Link: https://lore.kernel.org/r/161653807790.2770958.14034599989374173734.stgit@warthog.procyon.org.uk/ # v5 Link: https://lore.kernel.org/r/161789090823.6155.15673999934535049102.stgit@warthog.procyon.org.uk/ # v6
This commit is contained in:
Родитель
c69bf479ba
Коммит
f105da1a79
|
@ -305,8 +305,9 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
|
|||
unsigned int size;
|
||||
int ret;
|
||||
|
||||
_enter("{%u,%zu/%llu}",
|
||||
call->unmarshall, iov_iter_count(call->iter), req->actual_len);
|
||||
_enter("{%u,%zu,%zu/%llu}",
|
||||
call->unmarshall, call->iov_len, iov_iter_count(call->iter),
|
||||
req->actual_len);
|
||||
|
||||
switch (call->unmarshall) {
|
||||
case 0:
|
||||
|
@ -343,6 +344,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
|
|||
size = PAGE_SIZE - req->offset;
|
||||
else
|
||||
size = req->remain;
|
||||
call->iov_len = size;
|
||||
call->bvec[0].bv_len = size;
|
||||
call->bvec[0].bv_offset = req->offset;
|
||||
call->bvec[0].bv_page = req->pages[req->index];
|
||||
|
|
|
@ -104,6 +104,7 @@ struct afs_call {
|
|||
struct afs_server *server; /* The fileserver record if fs op (pins ref) */
|
||||
struct afs_vlserver *vlserver; /* The vlserver record if vl op */
|
||||
void *request; /* request data (first part) */
|
||||
size_t iov_len; /* Size of *iter to be used */
|
||||
struct iov_iter def_iter; /* Default buffer/data iterator */
|
||||
struct iov_iter *iter; /* Iterator currently in use */
|
||||
union { /* Convenience for ->def_iter */
|
||||
|
@ -1271,6 +1272,7 @@ static inline void afs_make_op_call(struct afs_operation *op, struct afs_call *c
|
|||
|
||||
static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t size)
|
||||
{
|
||||
call->iov_len = size;
|
||||
call->kvec[0].iov_base = buf;
|
||||
call->kvec[0].iov_len = size;
|
||||
iov_iter_kvec(&call->def_iter, READ, call->kvec, 1, size);
|
||||
|
@ -1278,21 +1280,25 @@ static inline void afs_extract_begin(struct afs_call *call, void *buf, size_t si
|
|||
|
||||
static inline void afs_extract_to_tmp(struct afs_call *call)
|
||||
{
|
||||
call->iov_len = sizeof(call->tmp);
|
||||
afs_extract_begin(call, &call->tmp, sizeof(call->tmp));
|
||||
}
|
||||
|
||||
static inline void afs_extract_to_tmp64(struct afs_call *call)
|
||||
{
|
||||
call->iov_len = sizeof(call->tmp64);
|
||||
afs_extract_begin(call, &call->tmp64, sizeof(call->tmp64));
|
||||
}
|
||||
|
||||
static inline void afs_extract_discard(struct afs_call *call, size_t size)
|
||||
{
|
||||
call->iov_len = size;
|
||||
iov_iter_discard(&call->def_iter, READ, size);
|
||||
}
|
||||
|
||||
static inline void afs_extract_to_buf(struct afs_call *call, size_t size)
|
||||
{
|
||||
call->iov_len = size;
|
||||
afs_extract_begin(call, call->buffer, size);
|
||||
}
|
||||
|
||||
|
|
|
@ -363,6 +363,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
|
|||
struct rxrpc_call *rxcall;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[1];
|
||||
size_t len;
|
||||
s64 tx_total_len;
|
||||
int ret;
|
||||
|
||||
|
@ -466,9 +467,10 @@ error_do_abort:
|
|||
rxrpc_kernel_abort_call(call->net->socket, rxcall,
|
||||
RX_USER_ABORT, ret, "KSD");
|
||||
} else {
|
||||
len = 0;
|
||||
iov_iter_kvec(&msg.msg_iter, READ, NULL, 0, 0);
|
||||
rxrpc_kernel_recv_data(call->net->socket, rxcall,
|
||||
&msg.msg_iter, false,
|
||||
&msg.msg_iter, &len, false,
|
||||
&call->abort_code, &call->service_id);
|
||||
ac->abort_code = call->abort_code;
|
||||
ac->responded = true;
|
||||
|
@ -504,6 +506,7 @@ error_kill_call:
|
|||
static void afs_deliver_to_call(struct afs_call *call)
|
||||
{
|
||||
enum afs_call_state state;
|
||||
size_t len;
|
||||
u32 abort_code, remote_abort = 0;
|
||||
int ret;
|
||||
|
||||
|
@ -516,10 +519,11 @@ static void afs_deliver_to_call(struct afs_call *call)
|
|||
state == AFS_CALL_SV_AWAIT_ACK
|
||||
) {
|
||||
if (state == AFS_CALL_SV_AWAIT_ACK) {
|
||||
len = 0;
|
||||
iov_iter_kvec(&call->def_iter, READ, NULL, 0, 0);
|
||||
ret = rxrpc_kernel_recv_data(call->net->socket,
|
||||
call->rxcall, &call->def_iter,
|
||||
false, &remote_abort,
|
||||
&len, false, &remote_abort,
|
||||
&call->service_id);
|
||||
trace_afs_receive_data(call, &call->def_iter, false, ret);
|
||||
|
||||
|
@ -929,10 +933,11 @@ int afs_extract_data(struct afs_call *call, bool want_more)
|
|||
u32 remote_abort = 0;
|
||||
int ret;
|
||||
|
||||
_enter("{%s,%zu},%d", call->type->name, iov_iter_count(iter), want_more);
|
||||
_enter("{%s,%zu,%zu},%d",
|
||||
call->type->name, call->iov_len, iov_iter_count(iter), want_more);
|
||||
|
||||
ret = rxrpc_kernel_recv_data(net->socket, call->rxcall, iter,
|
||||
want_more, &remote_abort,
|
||||
&call->iov_len, want_more, &remote_abort,
|
||||
&call->service_id);
|
||||
if (ret == 0 || ret == -EAGAIN)
|
||||
return ret;
|
||||
|
|
|
@ -363,8 +363,9 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
|
|||
unsigned int size;
|
||||
int ret;
|
||||
|
||||
_enter("{%u,%zu/%llu}",
|
||||
call->unmarshall, iov_iter_count(call->iter), req->actual_len);
|
||||
_enter("{%u,%zu, %zu/%llu}",
|
||||
call->unmarshall, call->iov_len, iov_iter_count(call->iter),
|
||||
req->actual_len);
|
||||
|
||||
switch (call->unmarshall) {
|
||||
case 0:
|
||||
|
@ -396,6 +397,7 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
|
|||
size = PAGE_SIZE - req->offset;
|
||||
else
|
||||
size = req->remain;
|
||||
call->iov_len = size;
|
||||
call->bvec[0].bv_len = size;
|
||||
call->bvec[0].bv_offset = req->offset;
|
||||
call->bvec[0].bv_page = req->pages[req->index];
|
||||
|
|
|
@ -53,7 +53,7 @@ int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
|
|||
struct msghdr *, size_t,
|
||||
rxrpc_notify_end_tx_t);
|
||||
int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
|
||||
struct iov_iter *, bool, u32 *, u16 *);
|
||||
struct iov_iter *, size_t *, bool, u32 *, u16 *);
|
||||
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
|
||||
u32, int, const char *);
|
||||
void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);
|
||||
|
|
|
@ -669,6 +669,7 @@ wait_error:
|
|||
* @sock: The socket that the call exists on
|
||||
* @call: The call to send data through
|
||||
* @iter: The buffer to receive into
|
||||
* @_len: The amount of data we want to receive (decreased on return)
|
||||
* @want_more: True if more data is expected to be read
|
||||
* @_abort: Where the abort code is stored if -ECONNABORTED is returned
|
||||
* @_service: Where to store the actual service ID (may be upgraded)
|
||||
|
@ -684,7 +685,7 @@ wait_error:
|
|||
* *_abort should also be initialised to 0.
|
||||
*/
|
||||
int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
|
||||
struct iov_iter *iter,
|
||||
struct iov_iter *iter, size_t *_len,
|
||||
bool want_more, u32 *_abort, u16 *_service)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
@ -692,7 +693,7 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
|
|||
|
||||
_enter("{%d,%s},%zu,%d",
|
||||
call->debug_id, rxrpc_call_states[call->state],
|
||||
iov_iter_count(iter), want_more);
|
||||
*_len, want_more);
|
||||
|
||||
ASSERTCMP(call->state, !=, RXRPC_CALL_SERVER_SECURING);
|
||||
|
||||
|
@ -703,8 +704,8 @@ int rxrpc_kernel_recv_data(struct socket *sock, struct rxrpc_call *call,
|
|||
case RXRPC_CALL_SERVER_RECV_REQUEST:
|
||||
case RXRPC_CALL_SERVER_ACK_REQUEST:
|
||||
ret = rxrpc_recvmsg_data(sock, call, NULL, iter,
|
||||
iov_iter_count(iter), 0,
|
||||
&offset);
|
||||
*_len, 0, &offset);
|
||||
*_len -= offset;
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче