Skip to content

Commit 24e42e3

Browse files
committed
9p: Use fscache indexing rewrite and reenable caching
Change the 9p filesystem to take account of the changes to fscache's indexing rewrite and reenable caching in 9p. The following changes have been made: (1) The fscache_netfs struct is no more, and there's no need to register the filesystem as a whole. (2) The session cookie is now an fscache_volume cookie, allocated with fscache_acquire_volume(). That takes three parameters: a string representing the "volume" in the index, a string naming the cache to use (or NULL) and a u64 that conveys coherency metadata for the volume. For 9p, I've made it render the volume name string as: "9p,<devname>,<cachetag>" where the cachetag is replaced by the aname if it wasn't supplied. This probably needs rethinking a bit as the aname can have slashes in it. It might be better to hash the cachetag and use the hash or I could substitute commas for the slashes or something. (3) The fscache_cookie_def is no more and needed information is passed directly to fscache_acquire_cookie(). The cache no longer calls back into the filesystem, but rather metadata changes are indicated at other times. fscache_acquire_cookie() is passed the same keying and coherency information as before. (4) The functions to set/reset/flush cookies are removed and fscache_use_cookie() and fscache_unuse_cookie() are used instead. fscache_use_cookie() is passed a flag to indicate if the cookie is opened for writing. fscache_unuse_cookie() is passed updates for the metadata if we changed it (ie. if the file was opened for writing). These are called when the file is opened or closed. (5) wait_on_page_bit[_killable]() is replaced with the specific wait functions for the bits waited upon. (6) I've got rid of some of the 9p-specific cache helper functions and called things like fscache_relinquish_cookie() directly as they'll optimise away if v9fs_inode_cookie() returns an unconditional NULL (which will be the case if CONFIG_9P_FSCACHE=n). (7) v9fs_vfs_setattr() is made to call fscache_resize() to change the size of the cache object. Notes: (A) We should call fscache_invalidate() if we detect that the server's copy of a file got changed by a third party, but I don't know where to do that. We don't need to do that when allocating the cookie as we get a check-and-invalidate when we initially bind to the cache object. (B) The copy-to-cache-on-writeback side of things will be handled in separate patch. Changes ======= ver #3: - Canonicalise the cookie key and coherency data to make them endianness-independent. ver #2: - Use gfpflags_allow_blocking() rather than using flag directly. - fscache_acquire_volume() now returns errors. Signed-off-by: David Howells <[email protected]> Acked-by: Jeff Layton <[email protected]> Tested-by: Dominique Martinet <[email protected]> cc: Eric Van Hensbergen <[email protected]> cc: Latchesar Ionkov <[email protected]> cc: [email protected] cc: [email protected] Link: https://lore.kernel.org/r/163819664645.215744.1555314582005286846.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906975017.143852.3459573173204394039.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967178512.1823006.17377493641569138183.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021573143.640689.3977487095697717967.stgit@warthog.procyon.org.uk/ # v4
1 parent 0770bd4 commit 24e42e3

File tree

10 files changed

+91
-210
lines changed

10 files changed

+91
-210
lines changed

fs/9p/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ config 9P_FS
1414
if 9P_FS
1515
config 9P_FSCACHE
1616
bool "Enable 9P client caching support"
17-
depends on 9P_FS=m && FSCACHE_OLD_API || 9P_FS=y && FSCACHE_OLD_API=y
17+
depends on 9P_FS=m && FSCACHE || 9P_FS=y && FSCACHE=y
1818
help
1919
Choose Y here to enable persistent, read-only local
2020
caching support for 9p clients using FS-Cache

fs/9p/cache.c

Lines changed: 35 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -16,186 +16,61 @@
1616
#include "v9fs.h"
1717
#include "cache.h"
1818

19-
#define CACHETAG_LEN 11
20-
21-
struct fscache_netfs v9fs_cache_netfs = {
22-
.name = "9p",
23-
.version = 0,
24-
};
25-
26-
/*
27-
* v9fs_random_cachetag - Generate a random tag to be associated
28-
* with a new cache session.
29-
*
30-
* The value of jiffies is used for a fairly randomly cache tag.
31-
*/
32-
33-
static
34-
int v9fs_random_cachetag(struct v9fs_session_info *v9ses)
19+
int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses,
20+
const char *dev_name)
3521
{
36-
v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL);
37-
if (!v9ses->cachetag)
38-
return -ENOMEM;
22+
struct fscache_volume *vcookie;
23+
char *name, *p;
3924

40-
return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies);
41-
}
42-
43-
const struct fscache_cookie_def v9fs_cache_session_index_def = {
44-
.name = "9P.session",
45-
.type = FSCACHE_COOKIE_TYPE_INDEX,
46-
};
25+
name = kasprintf(GFP_KERNEL, "9p,%s,%s",
26+
dev_name, v9ses->cachetag ?: v9ses->aname);
27+
if (!name)
28+
return -ENOMEM;
4729

48-
void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
49-
{
50-
/* If no cache session tag was specified, we generate a random one. */
51-
if (!v9ses->cachetag) {
52-
if (v9fs_random_cachetag(v9ses) < 0) {
53-
v9ses->fscache = NULL;
54-
kfree(v9ses->cachetag);
55-
v9ses->cachetag = NULL;
56-
return;
30+
for (p = name; *p; p++)
31+
if (*p == '/')
32+
*p = ';';
33+
34+
vcookie = fscache_acquire_volume(name, NULL, NULL, 0);
35+
p9_debug(P9_DEBUG_FSC, "session %p get volume %p (%s)\n",
36+
v9ses, vcookie, name);
37+
if (IS_ERR(vcookie)) {
38+
if (vcookie != ERR_PTR(-EBUSY)) {
39+
kfree(name);
40+
return PTR_ERR(vcookie);
5741
}
42+
pr_err("Cache volume key already in use (%s)\n", name);
43+
vcookie = NULL;
5844
}
59-
60-
v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
61-
&v9fs_cache_session_index_def,
62-
v9ses->cachetag,
63-
strlen(v9ses->cachetag),
64-
NULL, 0,
65-
v9ses, 0, true);
66-
p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
67-
v9ses, v9ses->fscache);
68-
}
69-
70-
void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
71-
{
72-
p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n",
73-
v9ses, v9ses->fscache);
74-
fscache_relinquish_cookie(v9ses->fscache, NULL, false);
75-
v9ses->fscache = NULL;
76-
}
77-
78-
static enum
79-
fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
80-
const void *buffer,
81-
uint16_t buflen,
82-
loff_t object_size)
83-
{
84-
const struct v9fs_inode *v9inode = cookie_netfs_data;
85-
86-
if (buflen != sizeof(v9inode->qid.version))
87-
return FSCACHE_CHECKAUX_OBSOLETE;
88-
89-
if (memcmp(buffer, &v9inode->qid.version,
90-
sizeof(v9inode->qid.version)))
91-
return FSCACHE_CHECKAUX_OBSOLETE;
92-
93-
return FSCACHE_CHECKAUX_OKAY;
45+
v9ses->fscache = vcookie;
46+
kfree(name);
47+
return 0;
9448
}
9549

96-
const struct fscache_cookie_def v9fs_cache_inode_index_def = {
97-
.name = "9p.inode",
98-
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
99-
.check_aux = v9fs_cache_inode_check_aux,
100-
};
101-
10250
void v9fs_cache_inode_get_cookie(struct inode *inode)
10351
{
10452
struct v9fs_inode *v9inode;
10553
struct v9fs_session_info *v9ses;
54+
__le32 version;
55+
__le64 path;
10656

10757
if (!S_ISREG(inode->i_mode))
10858
return;
10959

11060
v9inode = V9FS_I(inode);
111-
if (v9inode->fscache)
61+
if (WARN_ON(v9inode->fscache))
11262
return;
11363

64+
version = cpu_to_le32(v9inode->qid.version);
65+
path = cpu_to_le64(v9inode->qid.path);
11466
v9ses = v9fs_inode2v9ses(inode);
115-
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
116-
&v9fs_cache_inode_index_def,
117-
&v9inode->qid.path,
118-
sizeof(v9inode->qid.path),
119-
&v9inode->qid.version,
120-
sizeof(v9inode->qid.version),
121-
v9inode,
122-
i_size_read(&v9inode->vfs_inode),
123-
true);
67+
v9inode->fscache =
68+
fscache_acquire_cookie(v9fs_session_cache(v9ses),
69+
0,
70+
&path, sizeof(path),
71+
&version, sizeof(version),
72+
i_size_read(&v9inode->vfs_inode));
12473

12574
p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
12675
inode, v9inode->fscache);
12776
}
128-
129-
void v9fs_cache_inode_put_cookie(struct inode *inode)
130-
{
131-
struct v9fs_inode *v9inode = V9FS_I(inode);
132-
133-
if (!v9inode->fscache)
134-
return;
135-
p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n",
136-
inode, v9inode->fscache);
137-
138-
fscache_relinquish_cookie(v9inode->fscache, &v9inode->qid.version,
139-
false);
140-
v9inode->fscache = NULL;
141-
}
142-
143-
void v9fs_cache_inode_flush_cookie(struct inode *inode)
144-
{
145-
struct v9fs_inode *v9inode = V9FS_I(inode);
146-
147-
if (!v9inode->fscache)
148-
return;
149-
p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n",
150-
inode, v9inode->fscache);
151-
152-
fscache_relinquish_cookie(v9inode->fscache, NULL, true);
153-
v9inode->fscache = NULL;
154-
}
155-
156-
void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
157-
{
158-
struct v9fs_inode *v9inode = V9FS_I(inode);
159-
160-
if (!v9inode->fscache)
161-
return;
162-
163-
mutex_lock(&v9inode->fscache_lock);
164-
165-
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
166-
v9fs_cache_inode_flush_cookie(inode);
167-
else
168-
v9fs_cache_inode_get_cookie(inode);
169-
170-
mutex_unlock(&v9inode->fscache_lock);
171-
}
172-
173-
void v9fs_cache_inode_reset_cookie(struct inode *inode)
174-
{
175-
struct v9fs_inode *v9inode = V9FS_I(inode);
176-
struct v9fs_session_info *v9ses;
177-
struct fscache_cookie *old;
178-
179-
if (!v9inode->fscache)
180-
return;
181-
182-
old = v9inode->fscache;
183-
184-
mutex_lock(&v9inode->fscache_lock);
185-
fscache_relinquish_cookie(v9inode->fscache, NULL, true);
186-
187-
v9ses = v9fs_inode2v9ses(inode);
188-
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
189-
&v9fs_cache_inode_index_def,
190-
&v9inode->qid.path,
191-
sizeof(v9inode->qid.path),
192-
&v9inode->qid.version,
193-
sizeof(v9inode->qid.version),
194-
v9inode,
195-
i_size_read(&v9inode->vfs_inode),
196-
true);
197-
p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
198-
inode, old, v9inode->fscache);
199-
200-
mutex_unlock(&v9inode->fscache_lock);
201-
}

fs/9p/cache.h

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,21 @@
77

88
#ifndef _9P_CACHE_H
99
#define _9P_CACHE_H
10-
#define FSCACHE_USE_NEW_IO_API
10+
1111
#include <linux/fscache.h>
1212

1313
#ifdef CONFIG_9P_FSCACHE
1414

15-
extern struct fscache_netfs v9fs_cache_netfs;
16-
extern const struct fscache_cookie_def v9fs_cache_session_index_def;
17-
extern const struct fscache_cookie_def v9fs_cache_inode_index_def;
18-
19-
extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses);
20-
extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses);
15+
extern int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses,
16+
const char *dev_name);
2117

2218
extern void v9fs_cache_inode_get_cookie(struct inode *inode);
23-
extern void v9fs_cache_inode_put_cookie(struct inode *inode);
24-
extern void v9fs_cache_inode_flush_cookie(struct inode *inode);
25-
extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp);
26-
extern void v9fs_cache_inode_reset_cookie(struct inode *inode);
27-
28-
extern int __v9fs_cache_register(void);
29-
extern void __v9fs_cache_unregister(void);
3019

3120
#else /* CONFIG_9P_FSCACHE */
3221

3322
static inline void v9fs_cache_inode_get_cookie(struct inode *inode)
3423
{
3524
}
3625

37-
static inline void v9fs_cache_inode_put_cookie(struct inode *inode)
38-
{
39-
}
40-
41-
static inline void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *file)
42-
{
43-
}
44-
4526
#endif /* CONFIG_9P_FSCACHE */
4627
#endif /* _9P_CACHE_H */

fs/9p/v9fs.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,11 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
469469

470470
#ifdef CONFIG_9P_FSCACHE
471471
/* register the session for caching */
472-
v9fs_cache_session_get_cookie(v9ses);
472+
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
473+
rc = v9fs_cache_session_get_cookie(v9ses, dev_name);
474+
if (rc < 0)
475+
goto err_clnt;
476+
}
473477
#endif
474478
spin_lock(&v9fs_sessionlist_lock);
475479
list_add(&v9ses->slist, &v9fs_sessionlist);
@@ -502,8 +506,7 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
502506
}
503507

504508
#ifdef CONFIG_9P_FSCACHE
505-
if (v9ses->fscache)
506-
v9fs_cache_session_put_cookie(v9ses);
509+
fscache_relinquish_volume(v9fs_session_cache(v9ses), NULL, false);
507510
kfree(v9ses->cachetag);
508511
#endif
509512
kfree(v9ses->uname);
@@ -665,20 +668,12 @@ static int v9fs_cache_register(void)
665668
ret = v9fs_init_inode_cache();
666669
if (ret < 0)
667670
return ret;
668-
#ifdef CONFIG_9P_FSCACHE
669-
ret = fscache_register_netfs(&v9fs_cache_netfs);
670-
if (ret < 0)
671-
v9fs_destroy_inode_cache();
672-
#endif
673671
return ret;
674672
}
675673

676674
static void v9fs_cache_unregister(void)
677675
{
678676
v9fs_destroy_inode_cache();
679-
#ifdef CONFIG_9P_FSCACHE
680-
fscache_unregister_netfs(&v9fs_cache_netfs);
681-
#endif
682677
}
683678

684679
/**

fs/9p/v9fs.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct v9fs_session_info {
8989
unsigned int cache;
9090
#ifdef CONFIG_9P_FSCACHE
9191
char *cachetag;
92-
struct fscache_cookie *fscache;
92+
struct fscache_volume *fscache;
9393
#endif
9494

9595
char *uname; /* user name to mount as */
@@ -109,7 +109,6 @@ struct v9fs_session_info {
109109

110110
struct v9fs_inode {
111111
#ifdef CONFIG_9P_FSCACHE
112-
struct mutex fscache_lock;
113112
struct fscache_cookie *fscache;
114113
#endif
115114
struct p9_qid qid;
@@ -133,6 +132,16 @@ static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inod
133132
#endif
134133
}
135134

135+
static inline struct fscache_volume *v9fs_session_cache(struct v9fs_session_info *v9ses)
136+
{
137+
#ifdef CONFIG_9P_FSCACHE
138+
return v9ses->fscache;
139+
#else
140+
return NULL;
141+
#endif
142+
}
143+
144+
136145
extern int v9fs_show_options(struct seq_file *m, struct dentry *root);
137146

138147
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,

fs/9p/vfs_addr.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ static void v9fs_req_cleanup(struct address_space *mapping, void *priv)
7676
*/
7777
static bool v9fs_is_cache_enabled(struct inode *inode)
7878
{
79-
return fscache_cookie_enabled(v9fs_inode_cookie(V9FS_I(inode)));
79+
struct fscache_cookie *cookie = v9fs_inode_cookie(V9FS_I(inode));
80+
81+
return fscache_cookie_enabled(cookie) && cookie->cache_priv;
8082
}
8183

8284
/**
@@ -88,7 +90,7 @@ static int v9fs_begin_cache_operation(struct netfs_read_request *rreq)
8890
#ifdef CONFIG_9P_FSCACHE
8991
struct fscache_cookie *cookie = v9fs_inode_cookie(V9FS_I(rreq->inode));
9092

91-
return fscache_begin_read_operation(rreq, cookie);
93+
return fscache_begin_read_operation(&rreq->cache_resources, cookie);
9294
#else
9395
return -ENOBUFS;
9496
#endif
@@ -140,7 +142,7 @@ static int v9fs_release_page(struct page *page, gfp_t gfp)
140142
return 0;
141143
#ifdef CONFIG_9P_FSCACHE
142144
if (folio_test_fscache(folio)) {
143-
if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS))
145+
if (!gfpflags_allow_blocking(gfp) || !(gfp & __GFP_FS))
144146
return 0;
145147
folio_wait_fscache(folio);
146148
}

0 commit comments

Comments
 (0)