Skip to content

Commit 287fd61

Browse files
committed
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: David Howells <[email protected]> Reviewed-by: Jeff Layton <[email protected]> cc: [email protected] 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
1 parent 1f08c92 commit 287fd61

File tree

5 files changed

+79
-0
lines changed

5 files changed

+79
-0
lines changed

fs/cachefiles/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ cachefiles-y := \
77
cache.o \
88
daemon.o \
99
interface.o \
10+
io.o \
1011
key.o \
1112
main.o \
1213
namei.o \

fs/cachefiles/interface.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,5 +362,6 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
362362
.lookup_cookie = cachefiles_lookup_cookie,
363363
.withdraw_cookie = cachefiles_withdraw_cookie,
364364
.invalidate_cookie = cachefiles_invalidate_cookie,
365+
.begin_operation = cachefiles_begin_operation,
365366
.prepare_to_write = cachefiles_prepare_to_write,
366367
};

fs/cachefiles/internal.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ struct cachefiles_cache {
105105

106106
#include <trace/events/cachefiles.h>
107107

108+
static inline
109+
struct file *cachefiles_cres_file(struct netfs_cache_resources *cres)
110+
{
111+
return cres->cache_priv2;
112+
}
113+
114+
static inline
115+
struct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres)
116+
{
117+
return fscache_cres_cookie(cres)->cache_priv;
118+
}
119+
108120
/*
109121
* note change of state for daemon
110122
*/
@@ -177,6 +189,12 @@ extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object
177189
extern void cachefiles_put_object(struct cachefiles_object *object,
178190
enum cachefiles_obj_ref_trace why);
179191

192+
/*
193+
* io.c
194+
*/
195+
extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
196+
enum fscache_want_state want_state);
197+
180198
/*
181199
* key.c
182200
*/

fs/cachefiles/io.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/* kiocb-using read/write
3+
*
4+
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5+
* Written by David Howells ([email protected])
6+
*/
7+
8+
#include <linux/mount.h>
9+
#include <linux/slab.h>
10+
#include <linux/file.h>
11+
#include <linux/uio.h>
12+
#include <linux/falloc.h>
13+
#include <linux/sched/mm.h>
14+
#include <trace/events/fscache.h>
15+
#include "internal.h"
16+
17+
/*
18+
* Clean up an operation.
19+
*/
20+
static void cachefiles_end_operation(struct netfs_cache_resources *cres)
21+
{
22+
struct file *file = cachefiles_cres_file(cres);
23+
24+
if (file)
25+
fput(file);
26+
fscache_end_cookie_access(fscache_cres_cookie(cres), fscache_access_io_end);
27+
}
28+
29+
static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
30+
.end_operation = cachefiles_end_operation,
31+
};
32+
33+
/*
34+
* Open the cache file when beginning a cache operation.
35+
*/
36+
bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
37+
enum fscache_want_state want_state)
38+
{
39+
struct cachefiles_object *object = cachefiles_cres_object(cres);
40+
41+
if (!cachefiles_cres_file(cres)) {
42+
cres->ops = &cachefiles_netfs_cache_ops;
43+
if (object->file) {
44+
spin_lock(&object->lock);
45+
if (!cres->cache_priv2 && object->file)
46+
cres->cache_priv2 = get_file(object->file);
47+
spin_unlock(&object->lock);
48+
}
49+
}
50+
51+
if (!cachefiles_cres_file(cres) && want_state != FSCACHE_WANT_PARAMS) {
52+
pr_err("failed to get cres->file\n");
53+
return false;
54+
}
55+
56+
return true;
57+
}

include/trace/events/fscache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum fscache_access_trace {
7878
fscache_access_cache_unpin,
7979
fscache_access_invalidate_cookie,
8080
fscache_access_invalidate_cookie_end,
81+
fscache_access_io_end,
8182
fscache_access_io_not_live,
8283
fscache_access_io_read,
8384
fscache_access_io_resize,
@@ -152,6 +153,7 @@ enum fscache_access_trace {
152153
EM(fscache_access_cache_unpin, "UNPIN cache ") \
153154
EM(fscache_access_invalidate_cookie, "BEGIN inval ") \
154155
EM(fscache_access_invalidate_cookie_end,"END inval ") \
156+
EM(fscache_access_io_end, "END io ") \
155157
EM(fscache_access_io_not_live, "END io_notl") \
156158
EM(fscache_access_io_read, "BEGIN io_read") \
157159
EM(fscache_access_io_resize, "BEGIN io_resz") \

0 commit comments

Comments
 (0)