Skip to content

Commit

Permalink
afs: Don't truncate iter during data fetch
Browse files Browse the repository at this point in the history
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
  • Loading branch information
David Howells committed Apr 23, 2021
1 parent c69bf47 commit f105da1
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 13 deletions.
6 changes: 4 additions & 2 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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];
Expand Down
6 changes: 6 additions & 0 deletions fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -1271,28 +1272,33 @@ 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);
}

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);
}

Expand Down
13 changes: 9 additions & 4 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -466,9 +467,10 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
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;
Expand Down Expand Up @@ -504,6 +506,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
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;

Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions fs/afs/yfsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion include/net/af_rxrpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
9 changes: 5 additions & 4 deletions net/rxrpc/recvmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
* @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)
Expand All @@ -684,15 +685,15 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
* *_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;
int ret;

_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);

Expand All @@ -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;

Expand Down

0 comments on commit f105da1

Please sign in to comment.