Skip to content

Commit 3956e72

Browse files
committed
Merge branch 'netfs-writeback' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into vfs.netfs
Merge patch series "netfs: Read/write improvements" from David Howells <[email protected]>. * 'netfs-writeback' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: (25 commits) cifs: Don't support ITER_XARRAY cifs: Switch crypto buffer to use a folio_queue rather than an xarray cifs: Use iterate_and_advance*() routines directly for hashing netfs: Cancel dirty folios that have no storage destination cachefiles, netfs: Fix write to partial block at EOF netfs: Remove fs/netfs/io.c netfs: Speed up buffered reading afs: Make read subreqs async netfs: Simplify the writeback code netfs: Provide an iterator-reset function netfs: Use new folio_queue data type and iterator instead of xarray iter cifs: Provide the capability to extract from ITER_FOLIOQ to RDMA SGEs iov_iter: Provide copy_folio_from_iter() mm: Define struct folio_queue and ITER_FOLIOQ to handle a sequence of folios netfs: Use bh-disabling spinlocks for rreq->lock netfs: Set the request work function upon allocation netfs: Remove NETFS_COPY_TO_CACHE netfs: Reserve netfs_sreq_source 0 as unset/unknown netfs: Move max_len/max_nr_segs from netfs_io_subrequest to netfs_io_stream netfs, cifs: Move CIFS_INO_MODIFIED_ATTR to netfs_inode ... Signed-off-by: Christian Brauner <[email protected]>
2 parents 4356ab3 + 4aa571d commit 3956e72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3519
-1983
lines changed

fs/9p/vfs_addr.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,22 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
6868
{
6969
struct netfs_io_request *rreq = subreq->rreq;
7070
struct p9_fid *fid = rreq->netfs_priv;
71+
unsigned long long pos = subreq->start + subreq->transferred;
7172
int total, err;
7273

73-
total = p9_client_read(fid, subreq->start + subreq->transferred,
74-
&subreq->io_iter, &err);
74+
total = p9_client_read(fid, pos, &subreq->io_iter, &err);
7575

7676
/* if we just extended the file size, any portion not in
7777
* cache won't be on server and is zeroes */
7878
if (subreq->rreq->origin != NETFS_DIO_READ)
7979
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
80+
if (pos + total >= i_size_read(rreq->inode))
81+
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
8082

81-
netfs_subreq_terminated(subreq, err ?: total, false);
83+
if (!err)
84+
subreq->transferred += total;
85+
86+
netfs_read_subreq_terminated(subreq, err, false);
8287
}
8388

8489
/**

fs/afs/file.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/mm.h>
1717
#include <linux/swap.h>
1818
#include <linux/netfs.h>
19+
#include <trace/events/netfs.h>
1920
#include "internal.h"
2021

2122
static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
@@ -242,9 +243,10 @@ static void afs_fetch_data_notify(struct afs_operation *op)
242243

243244
req->error = error;
244245
if (subreq) {
245-
if (subreq->rreq->origin != NETFS_DIO_READ)
246-
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
247-
netfs_subreq_terminated(subreq, error ?: req->actual_len, false);
246+
subreq->rreq->i_size = req->file_size;
247+
if (req->pos + req->actual_len >= req->file_size)
248+
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
249+
netfs_read_subreq_terminated(subreq, error, false);
248250
req->subreq = NULL;
249251
} else if (req->done) {
250252
req->done(req);
@@ -262,6 +264,12 @@ static void afs_fetch_data_success(struct afs_operation *op)
262264
afs_fetch_data_notify(op);
263265
}
264266

267+
static void afs_fetch_data_aborted(struct afs_operation *op)
268+
{
269+
afs_check_for_remote_deletion(op);
270+
afs_fetch_data_notify(op);
271+
}
272+
265273
static void afs_fetch_data_put(struct afs_operation *op)
266274
{
267275
op->fetch.req->error = afs_op_error(op);
@@ -272,7 +280,7 @@ static const struct afs_operation_ops afs_fetch_data_operation = {
272280
.issue_afs_rpc = afs_fs_fetch_data,
273281
.issue_yfs_rpc = yfs_fs_fetch_data,
274282
.success = afs_fetch_data_success,
275-
.aborted = afs_check_for_remote_deletion,
283+
.aborted = afs_fetch_data_aborted,
276284
.failed = afs_fetch_data_notify,
277285
.put = afs_fetch_data_put,
278286
};
@@ -294,7 +302,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
294302
op = afs_alloc_operation(req->key, vnode->volume);
295303
if (IS_ERR(op)) {
296304
if (req->subreq)
297-
netfs_subreq_terminated(req->subreq, PTR_ERR(op), false);
305+
netfs_read_subreq_terminated(req->subreq, PTR_ERR(op), false);
298306
return PTR_ERR(op);
299307
}
300308

@@ -305,14 +313,15 @@ int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
305313
return afs_do_sync_operation(op);
306314
}
307315

308-
static void afs_issue_read(struct netfs_io_subrequest *subreq)
316+
static void afs_read_worker(struct work_struct *work)
309317
{
318+
struct netfs_io_subrequest *subreq = container_of(work, struct netfs_io_subrequest, work);
310319
struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
311320
struct afs_read *fsreq;
312321

313322
fsreq = afs_alloc_read(GFP_NOFS);
314323
if (!fsreq)
315-
return netfs_subreq_terminated(subreq, -ENOMEM, false);
324+
return netfs_read_subreq_terminated(subreq, -ENOMEM, false);
316325

317326
fsreq->subreq = subreq;
318327
fsreq->pos = subreq->start + subreq->transferred;
@@ -321,10 +330,17 @@ static void afs_issue_read(struct netfs_io_subrequest *subreq)
321330
fsreq->vnode = vnode;
322331
fsreq->iter = &subreq->io_iter;
323332

333+
trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
324334
afs_fetch_data(fsreq->vnode, fsreq);
325335
afs_put_read(fsreq);
326336
}
327337

338+
static void afs_issue_read(struct netfs_io_subrequest *subreq)
339+
{
340+
INIT_WORK(&subreq->work, afs_read_worker);
341+
queue_work(system_long_wq, &subreq->work);
342+
}
343+
328344
static int afs_symlink_read_folio(struct file *file, struct folio *folio)
329345
{
330346
struct afs_vnode *vnode = AFS_FS_I(folio->mapping->host);

fs/afs/fsclient.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
304304
struct afs_vnode_param *vp = &op->file[0];
305305
struct afs_read *req = op->fetch.req;
306306
const __be32 *bp;
307+
size_t count_before;
307308
int ret;
308309

309310
_enter("{%u,%zu,%zu/%llu}",
@@ -345,10 +346,14 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
345346

346347
/* extract the returned data */
347348
case 2:
348-
_debug("extract data %zu/%llu",
349-
iov_iter_count(call->iter), req->actual_len);
349+
count_before = call->iov_len;
350+
_debug("extract data %zu/%llu", count_before, req->actual_len);
350351

351352
ret = afs_extract_data(call, true);
353+
if (req->subreq) {
354+
req->subreq->transferred += count_before - call->iov_len;
355+
netfs_read_subreq_progress(req->subreq, false);
356+
}
352357
if (ret < 0)
353358
return ret;
354359

fs/afs/write.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,12 @@ static const struct afs_operation_ops afs_store_data_operation = {
8989
*/
9090
void afs_prepare_write(struct netfs_io_subrequest *subreq)
9191
{
92+
struct netfs_io_stream *stream = &subreq->rreq->io_streams[subreq->stream_nr];
93+
9294
//if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
9395
// subreq->max_len = 512 * 1024;
9496
//else
95-
subreq->max_len = 256 * 1024 * 1024;
97+
stream->sreq_max_len = 256 * 1024 * 1024;
9698
}
9799

98100
/*

fs/afs/yfsclient.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
355355
struct afs_vnode_param *vp = &op->file[0];
356356
struct afs_read *req = op->fetch.req;
357357
const __be32 *bp;
358+
size_t count_before;
358359
int ret;
359360

360361
_enter("{%u,%zu, %zu/%llu}",
@@ -391,10 +392,14 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
391392

392393
/* extract the returned data */
393394
case 2:
394-
_debug("extract data %zu/%llu",
395-
iov_iter_count(call->iter), req->actual_len);
395+
count_before = call->iov_len;
396+
_debug("extract data %zu/%llu", count_before, req->actual_len);
396397

397398
ret = afs_extract_data(call, true);
399+
if (req->subreq) {
400+
req->subreq->transferred += count_before - call->iov_len;
401+
netfs_read_subreq_progress(req->subreq, false);
402+
}
398403
if (ret < 0)
399404
return ret;
400405

fs/cachefiles/io.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,11 +627,12 @@ static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)
627627
{
628628
struct netfs_io_request *wreq = subreq->rreq;
629629
struct netfs_cache_resources *cres = &wreq->cache_resources;
630+
struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
630631

631632
_enter("W=%x[%x] %llx", wreq->debug_id, subreq->debug_index, subreq->start);
632633

633-
subreq->max_len = MAX_RW_COUNT;
634-
subreq->max_nr_segs = BIO_MAX_VECS;
634+
stream->sreq_max_len = MAX_RW_COUNT;
635+
stream->sreq_max_segs = BIO_MAX_VECS;
635636

636637
if (!cachefiles_cres_file(cres)) {
637638
if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE))
@@ -647,6 +648,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
647648
struct netfs_cache_resources *cres = &wreq->cache_resources;
648649
struct cachefiles_object *object = cachefiles_cres_object(cres);
649650
struct cachefiles_cache *cache = object->volume->cache;
651+
struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
650652
const struct cred *saved_cred;
651653
size_t off, pre, post, len = subreq->len;
652654
loff_t start = subreq->start;
@@ -660,6 +662,7 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
660662
if (off) {
661663
pre = CACHEFILES_DIO_BLOCK_SIZE - off;
662664
if (pre >= len) {
665+
fscache_count_dio_misfit();
663666
netfs_write_subrequest_terminated(subreq, len, false);
664667
return;
665668
}
@@ -670,10 +673,22 @@ static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
670673
}
671674

672675
/* We also need to end on the cache granularity boundary */
676+
if (start + len == wreq->i_size) {
677+
size_t part = len % CACHEFILES_DIO_BLOCK_SIZE;
678+
size_t need = CACHEFILES_DIO_BLOCK_SIZE - part;
679+
680+
if (part && stream->submit_extendable_to >= need) {
681+
len += need;
682+
subreq->len += need;
683+
subreq->io_iter.count += need;
684+
}
685+
}
686+
673687
post = len & (CACHEFILES_DIO_BLOCK_SIZE - 1);
674688
if (post) {
675689
len -= post;
676690
if (len == 0) {
691+
fscache_count_dio_misfit();
677692
netfs_write_subrequest_terminated(subreq, post, false);
678693
return;
679694
}

fs/cachefiles/xattr.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,15 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
6464
memcpy(buf->data, fscache_get_aux(object->cookie), len);
6565

6666
ret = cachefiles_inject_write_error();
67-
if (ret == 0)
68-
ret = vfs_setxattr(&nop_mnt_idmap, dentry, cachefiles_xattr_cache,
69-
buf, sizeof(struct cachefiles_xattr) + len, 0);
67+
if (ret == 0) {
68+
ret = mnt_want_write_file(file);
69+
if (ret == 0) {
70+
ret = vfs_setxattr(&nop_mnt_idmap, dentry,
71+
cachefiles_xattr_cache, buf,
72+
sizeof(struct cachefiles_xattr) + len, 0);
73+
mnt_drop_write_file(file);
74+
}
75+
}
7076
if (ret < 0) {
7177
trace_cachefiles_vfs_error(object, file_inode(file), ret,
7278
cachefiles_trace_setxattr_error);
@@ -151,8 +157,14 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
151157
int ret;
152158

153159
ret = cachefiles_inject_remove_error();
154-
if (ret == 0)
155-
ret = vfs_removexattr(&nop_mnt_idmap, dentry, cachefiles_xattr_cache);
160+
if (ret == 0) {
161+
ret = mnt_want_write(cache->mnt);
162+
if (ret == 0) {
163+
ret = vfs_removexattr(&nop_mnt_idmap, dentry,
164+
cachefiles_xattr_cache);
165+
mnt_drop_write(cache->mnt);
166+
}
167+
}
156168
if (ret < 0) {
157169
trace_cachefiles_vfs_error(object, d_inode(dentry), ret,
158170
cachefiles_trace_remxattr_error);
@@ -208,9 +220,15 @@ bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume)
208220
memcpy(buf->data, p, volume->vcookie->coherency_len);
209221

210222
ret = cachefiles_inject_write_error();
211-
if (ret == 0)
212-
ret = vfs_setxattr(&nop_mnt_idmap, dentry, cachefiles_xattr_cache,
213-
buf, len, 0);
223+
if (ret == 0) {
224+
ret = mnt_want_write(volume->cache->mnt);
225+
if (ret == 0) {
226+
ret = vfs_setxattr(&nop_mnt_idmap, dentry,
227+
cachefiles_xattr_cache,
228+
buf, len, 0);
229+
mnt_drop_write(volume->cache->mnt);
230+
}
231+
}
214232
if (ret < 0) {
215233
trace_cachefiles_vfs_error(NULL, d_inode(dentry), ret,
216234
cachefiles_trace_setxattr_error);

0 commit comments

Comments
 (0)