Skip to content

Commit 64e64e6

Browse files
committed
netfs, cachefiles: Implement helpers for new write code
Implement the helpers for the new write code in cachefiles. There's now an optional ->prepare_write() that allows the filesystem to set the parameters for the next write, such as maximum size and maximum segment count, and an ->issue_write() that is called to initiate an (asynchronous) write operation. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: netfs@lists.linux.dev cc: linux-erofs@lists.ozlabs.org cc: linux-fsdevel@vger.kernel.org
1 parent 5fb70e7 commit 64e64e6

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

fs/cachefiles/io.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/slab.h>
1010
#include <linux/file.h>
1111
#include <linux/uio.h>
12+
#include <linux/bio.h>
1213
#include <linux/falloc.h>
1314
#include <linux/sched/mm.h>
1415
#include <trace/events/fscache.h>
@@ -622,6 +623,77 @@ static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
622623
return ret;
623624
}
624625

626+
static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)
627+
{
628+
struct netfs_io_request *wreq = subreq->rreq;
629+
struct netfs_cache_resources *cres = &wreq->cache_resources;
630+
631+
_enter("W=%x[%x] %llx", wreq->debug_id, subreq->debug_index, subreq->start);
632+
633+
subreq->max_len = ULONG_MAX;
634+
subreq->max_nr_segs = BIO_MAX_VECS;
635+
636+
if (!cachefiles_cres_file(cres)) {
637+
if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE))
638+
return netfs_prepare_write_failed(subreq);
639+
if (!cachefiles_cres_file(cres))
640+
return netfs_prepare_write_failed(subreq);
641+
}
642+
}
643+
644+
static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
645+
{
646+
struct netfs_io_request *wreq = subreq->rreq;
647+
struct netfs_cache_resources *cres = &wreq->cache_resources;
648+
struct cachefiles_object *object = cachefiles_cres_object(cres);
649+
struct cachefiles_cache *cache = object->volume->cache;
650+
const struct cred *saved_cred;
651+
size_t off, pre, post, len = subreq->len;
652+
loff_t start = subreq->start;
653+
int ret;
654+
655+
_enter("W=%x[%x] %llx-%llx",
656+
wreq->debug_id, subreq->debug_index, start, start + len - 1);
657+
658+
/* We need to start on the cache granularity boundary */
659+
off = start & (CACHEFILES_DIO_BLOCK_SIZE - 1);
660+
if (off) {
661+
pre = CACHEFILES_DIO_BLOCK_SIZE - off;
662+
if (pre >= len) {
663+
netfs_write_subrequest_terminated(subreq, len, false);
664+
return;
665+
}
666+
subreq->transferred += pre;
667+
start += pre;
668+
len -= pre;
669+
iov_iter_advance(&subreq->io_iter, pre);
670+
}
671+
672+
/* We also need to end on the cache granularity boundary */
673+
post = len & (CACHEFILES_DIO_BLOCK_SIZE - 1);
674+
if (post) {
675+
len -= post;
676+
if (len == 0) {
677+
netfs_write_subrequest_terminated(subreq, post, false);
678+
return;
679+
}
680+
iov_iter_truncate(&subreq->io_iter, len);
681+
}
682+
683+
cachefiles_begin_secure(cache, &saved_cred);
684+
ret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres),
685+
&start, &len, len, true);
686+
cachefiles_end_secure(cache, saved_cred);
687+
if (ret < 0) {
688+
netfs_write_subrequest_terminated(subreq, ret, false);
689+
return;
690+
}
691+
692+
cachefiles_write(&subreq->rreq->cache_resources,
693+
subreq->start, &subreq->io_iter,
694+
netfs_write_subrequest_terminated, subreq);
695+
}
696+
625697
/*
626698
* Clean up an operation.
627699
*/
@@ -638,8 +710,10 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
638710
.end_operation = cachefiles_end_operation,
639711
.read = cachefiles_read,
640712
.write = cachefiles_write,
713+
.issue_write = cachefiles_issue_write,
641714
.prepare_read = cachefiles_prepare_read,
642715
.prepare_write = cachefiles_prepare_write,
716+
.prepare_write_subreq = cachefiles_prepare_write_subreq,
643717
.prepare_ondemand_read = cachefiles_prepare_ondemand_read,
644718
.query_occupancy = cachefiles_query_occupancy,
645719
};

0 commit comments

Comments
 (0)