mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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
This commit is contained in:
parent
5fb70e7275
commit
64e64e6c18
@ -9,6 +9,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/bio.h>
|
||||
#include <linux/falloc.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <trace/events/fscache.h>
|
||||
@ -622,6 +623,77 @@ static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)
|
||||
{
|
||||
struct netfs_io_request *wreq = subreq->rreq;
|
||||
struct netfs_cache_resources *cres = &wreq->cache_resources;
|
||||
|
||||
_enter("W=%x[%x] %llx", wreq->debug_id, subreq->debug_index, subreq->start);
|
||||
|
||||
subreq->max_len = ULONG_MAX;
|
||||
subreq->max_nr_segs = BIO_MAX_VECS;
|
||||
|
||||
if (!cachefiles_cres_file(cres)) {
|
||||
if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE))
|
||||
return netfs_prepare_write_failed(subreq);
|
||||
if (!cachefiles_cres_file(cres))
|
||||
return netfs_prepare_write_failed(subreq);
|
||||
}
|
||||
}
|
||||
|
||||
static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
|
||||
{
|
||||
struct netfs_io_request *wreq = subreq->rreq;
|
||||
struct netfs_cache_resources *cres = &wreq->cache_resources;
|
||||
struct cachefiles_object *object = cachefiles_cres_object(cres);
|
||||
struct cachefiles_cache *cache = object->volume->cache;
|
||||
const struct cred *saved_cred;
|
||||
size_t off, pre, post, len = subreq->len;
|
||||
loff_t start = subreq->start;
|
||||
int ret;
|
||||
|
||||
_enter("W=%x[%x] %llx-%llx",
|
||||
wreq->debug_id, subreq->debug_index, start, start + len - 1);
|
||||
|
||||
/* We need to start on the cache granularity boundary */
|
||||
off = start & (CACHEFILES_DIO_BLOCK_SIZE - 1);
|
||||
if (off) {
|
||||
pre = CACHEFILES_DIO_BLOCK_SIZE - off;
|
||||
if (pre >= len) {
|
||||
netfs_write_subrequest_terminated(subreq, len, false);
|
||||
return;
|
||||
}
|
||||
subreq->transferred += pre;
|
||||
start += pre;
|
||||
len -= pre;
|
||||
iov_iter_advance(&subreq->io_iter, pre);
|
||||
}
|
||||
|
||||
/* We also need to end on the cache granularity boundary */
|
||||
post = len & (CACHEFILES_DIO_BLOCK_SIZE - 1);
|
||||
if (post) {
|
||||
len -= post;
|
||||
if (len == 0) {
|
||||
netfs_write_subrequest_terminated(subreq, post, false);
|
||||
return;
|
||||
}
|
||||
iov_iter_truncate(&subreq->io_iter, len);
|
||||
}
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
ret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres),
|
||||
&start, &len, len, true);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
if (ret < 0) {
|
||||
netfs_write_subrequest_terminated(subreq, ret, false);
|
||||
return;
|
||||
}
|
||||
|
||||
cachefiles_write(&subreq->rreq->cache_resources,
|
||||
subreq->start, &subreq->io_iter,
|
||||
netfs_write_subrequest_terminated, subreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up an operation.
|
||||
*/
|
||||
@ -638,8 +710,10 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
|
||||
.end_operation = cachefiles_end_operation,
|
||||
.read = cachefiles_read,
|
||||
.write = cachefiles_write,
|
||||
.issue_write = cachefiles_issue_write,
|
||||
.prepare_read = cachefiles_prepare_read,
|
||||
.prepare_write = cachefiles_prepare_write,
|
||||
.prepare_write_subreq = cachefiles_prepare_write_subreq,
|
||||
.prepare_ondemand_read = cachefiles_prepare_ondemand_read,
|
||||
.query_occupancy = cachefiles_query_occupancy,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user