mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
afs: Use a bvec rather than a kvec in afs_send_pages()
Use a bvec rather than a kvec in afs_send_pages() as we don't then have to call kmap() in advance. This allows us to pass the array of contiguous pages that we extracted through to rxrpc in one go rather than passing a single page at a time. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
6a0e3999e5
commit
2f5705a5c8
@ -259,67 +259,74 @@ void afs_flat_call_destructor(struct afs_call *call)
|
||||
call->buffer = NULL;
|
||||
}
|
||||
|
||||
#define AFS_BVEC_MAX 8
|
||||
|
||||
/*
|
||||
* Load the given bvec with the next few pages.
|
||||
*/
|
||||
static void afs_load_bvec(struct afs_call *call, struct msghdr *msg,
|
||||
struct bio_vec *bv, pgoff_t first, pgoff_t last,
|
||||
unsigned offset)
|
||||
{
|
||||
struct page *pages[AFS_BVEC_MAX];
|
||||
unsigned int nr, n, i, to, bytes = 0;
|
||||
|
||||
nr = min_t(pgoff_t, last - first + 1, AFS_BVEC_MAX);
|
||||
n = find_get_pages_contig(call->mapping, first, nr, pages);
|
||||
ASSERTCMP(n, ==, nr);
|
||||
|
||||
msg->msg_flags |= MSG_MORE;
|
||||
for (i = 0; i < nr; i++) {
|
||||
to = PAGE_SIZE;
|
||||
if (first + i >= last) {
|
||||
to = call->last_to;
|
||||
msg->msg_flags &= ~MSG_MORE;
|
||||
}
|
||||
bv[i].bv_page = pages[i];
|
||||
bv[i].bv_len = to - offset;
|
||||
bv[i].bv_offset = offset;
|
||||
bytes += to - offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC, bv, nr, bytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* attach the data from a bunch of pages on an inode to a call
|
||||
*/
|
||||
static int afs_send_pages(struct afs_call *call, struct msghdr *msg)
|
||||
{
|
||||
struct page *pages[8];
|
||||
unsigned count, n, loop, offset, to;
|
||||
struct bio_vec bv[AFS_BVEC_MAX];
|
||||
unsigned int bytes, nr, loop, offset;
|
||||
pgoff_t first = call->first, last = call->last;
|
||||
int ret;
|
||||
|
||||
_enter("");
|
||||
|
||||
offset = call->first_offset;
|
||||
call->first_offset = 0;
|
||||
|
||||
do {
|
||||
_debug("attach %lx-%lx", first, last);
|
||||
afs_load_bvec(call, msg, bv, first, last, offset);
|
||||
offset = 0;
|
||||
bytes = msg->msg_iter.count;
|
||||
nr = msg->msg_iter.nr_segs;
|
||||
|
||||
count = last - first + 1;
|
||||
if (count > ARRAY_SIZE(pages))
|
||||
count = ARRAY_SIZE(pages);
|
||||
n = find_get_pages_contig(call->mapping, first, count, pages);
|
||||
ASSERTCMP(n, ==, count);
|
||||
|
||||
loop = 0;
|
||||
do {
|
||||
struct bio_vec bvec = {.bv_page = pages[loop],
|
||||
.bv_offset = offset};
|
||||
msg->msg_flags = 0;
|
||||
to = PAGE_SIZE;
|
||||
if (first + loop >= last)
|
||||
to = call->last_to;
|
||||
else
|
||||
msg->msg_flags = MSG_MORE;
|
||||
bvec.bv_len = to - offset;
|
||||
offset = 0;
|
||||
|
||||
_debug("- range %u-%u%s",
|
||||
offset, to, msg->msg_flags ? " [more]" : "");
|
||||
iov_iter_bvec(&msg->msg_iter, WRITE | ITER_BVEC,
|
||||
&bvec, 1, to - offset);
|
||||
|
||||
/* have to change the state *before* sending the last
|
||||
* packet as RxRPC might give us the reply before it
|
||||
* returns from sending the request */
|
||||
if (first + loop >= last)
|
||||
call->state = AFS_CALL_AWAIT_REPLY;
|
||||
ret = rxrpc_kernel_send_data(afs_socket, call->rxcall,
|
||||
msg, to - offset);
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (++loop < count);
|
||||
first += count;
|
||||
|
||||
for (loop = 0; loop < count; loop++)
|
||||
put_page(pages[loop]);
|
||||
/* Have to change the state *before* sending the last
|
||||
* packet as RxRPC might give us the reply before it
|
||||
* returns from sending the request.
|
||||
*/
|
||||
if (first + nr >= last)
|
||||
call->state = AFS_CALL_AWAIT_REPLY;
|
||||
ret = rxrpc_kernel_send_data(afs_socket, call->rxcall,
|
||||
msg, bytes);
|
||||
for (loop = 0; loop < nr; loop++)
|
||||
put_page(bv[loop].bv_page);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
first += nr;
|
||||
} while (first <= last);
|
||||
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user