Commit 287fd611 authored by David Howells's avatar David Howells

cachefiles: Implement begin and end I/O operation

Implement the methods for beginning and ending an I/O operation.

When called to begin an I/O operation, we are guaranteed that the cookie
has reached a certain stage (we're called by fscache after it has done a
suitable wait).

If a file is available, we paste a ref over into the cache resources for
the I/O routines to use.  This means that the object can be invalidated
whilst the I/O is ongoing without the need to synchronise as the file
pointer in the object is replaced, but the file pointer in the cache
resources is unaffected.

Ending the operation just requires ditching any refs we have and dropping
the access guarantee that fscache got for us on the cookie.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
cc: linux-cachefs@redhat.com
Link: https://lore.kernel.org/r/163819645033.215744.2199344081658268312.stgit@warthog.procyon.org.uk/ # v1
Link: https://lore.kernel.org/r/163906951916.143852.9531384743995679857.stgit@warthog.procyon.org.uk/ # v2
Link: https://lore.kernel.org/r/163967161222.1823006.4461476204800357263.stgit@warthog.procyon.org.uk/ # v3
Link: https://lore.kernel.org/r/164021559030.640689.3684291785218094142.stgit@warthog.procyon.org.uk/ # v4
parent 1f08c925
......@@ -7,6 +7,7 @@ cachefiles-y := \
cache.o \
daemon.o \
interface.o \
io.o \
key.o \
main.o \
namei.o \
......
......@@ -362,5 +362,6 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
.lookup_cookie = cachefiles_lookup_cookie,
.withdraw_cookie = cachefiles_withdraw_cookie,
.invalidate_cookie = cachefiles_invalidate_cookie,
.begin_operation = cachefiles_begin_operation,
.prepare_to_write = cachefiles_prepare_to_write,
};
......@@ -105,6 +105,18 @@ struct cachefiles_cache {
#include <trace/events/cachefiles.h>
static inline
struct file *cachefiles_cres_file(struct netfs_cache_resources *cres)
{
return cres->cache_priv2;
}
static inline
struct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres)
{
return fscache_cres_cookie(cres)->cache_priv;
}
/*
* note change of state for daemon
*/
......@@ -177,6 +189,12 @@ extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object
extern void cachefiles_put_object(struct cachefiles_object *object,
enum cachefiles_obj_ref_trace why);
/*
* io.c
*/
extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
enum fscache_want_state want_state);
/*
* key.c
*/
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* kiocb-using read/write
*
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <linux/mount.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/uio.h>
#include <linux/falloc.h>
#include <linux/sched/mm.h>
#include <trace/events/fscache.h>
#include "internal.h"
/*
* Clean up an operation.
*/
static void cachefiles_end_operation(struct netfs_cache_resources *cres)
{
struct file *file = cachefiles_cres_file(cres);
if (file)
fput(file);
fscache_end_cookie_access(fscache_cres_cookie(cres), fscache_access_io_end);
}
static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
.end_operation = cachefiles_end_operation,
};
/*
* Open the cache file when beginning a cache operation.
*/
bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
enum fscache_want_state want_state)
{
struct cachefiles_object *object = cachefiles_cres_object(cres);
if (!cachefiles_cres_file(cres)) {
cres->ops = &cachefiles_netfs_cache_ops;
if (object->file) {
spin_lock(&object->lock);
if (!cres->cache_priv2 && object->file)
cres->cache_priv2 = get_file(object->file);
spin_unlock(&object->lock);
}
}
if (!cachefiles_cres_file(cres) && want_state != FSCACHE_WANT_PARAMS) {
pr_err("failed to get cres->file\n");
return false;
}
return true;
}
......@@ -78,6 +78,7 @@ enum fscache_access_trace {
fscache_access_cache_unpin,
fscache_access_invalidate_cookie,
fscache_access_invalidate_cookie_end,
fscache_access_io_end,
fscache_access_io_not_live,
fscache_access_io_read,
fscache_access_io_resize,
......@@ -152,6 +153,7 @@ enum fscache_access_trace {
EM(fscache_access_cache_unpin, "UNPIN cache ") \
EM(fscache_access_invalidate_cookie, "BEGIN inval ") \
EM(fscache_access_invalidate_cookie_end,"END inval ") \
EM(fscache_access_io_end, "END io ") \
EM(fscache_access_io_not_live, "END io_notl") \
EM(fscache_access_io_read, "BEGIN io_read") \
EM(fscache_access_io_resize, "BEGIN io_resz") \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment