Skip to content

Commit 4eb3117

Browse files
committed
fs/9p: Rework cache modes and add new options to Documentation
Switch cache modes to a bit-mask and use legacy cache names as shortcuts. Update documentation to include information on both shortcuts and bitmasks. This patch also fixes missing guards related to fscache. Update the documentation for new mount flags and cache modes. Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
1 parent 1543b4c commit 4eb3117

10 files changed

Lines changed: 153 additions & 107 deletions

File tree

Documentation/filesystems/9p.rst

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,39 @@ Options
7878
offering several exported file systems.
7979

8080
cache=mode specifies a caching policy. By default, no caches are used.
81-
82-
none
83-
default no cache policy, metadata and data
84-
alike are synchronous.
85-
loose
86-
no attempts are made at consistency,
87-
intended for exclusive, read-only mounts
88-
fscache
89-
use FS-Cache for a persistent, read-only
90-
cache backend.
91-
mmap
92-
minimal cache that is only used for read-write
93-
mmap. Northing else is cached, like cache=none
81+
The mode can be specified as a bitmask or by using one of the
82+
prexisting common 'shortcuts'.
83+
The bitmask is described below: (unspecified bits are reserved)
84+
85+
========== ====================================================
86+
0b00000000 all caches disabled, mmap disabled
87+
0b00000001 file caches enabled
88+
0b00000010 meta-data caches enabled
89+
0b00000100 writeback behavior (as opposed to writethrough)
90+
0b00001000 loose caches (no explicit consistency with server)
91+
0b10000000 fscache enabled for persistent caching
92+
========== ====================================================
93+
94+
The current shortcuts and their associated bitmask are:
95+
96+
========= ====================================================
97+
none 0b00000000 (no caching)
98+
readahead 0b00000001 (only read-ahead file caching)
99+
mmap 0b00000101 (read-ahead + writeback file cache)
100+
loose 0b00001111 (non-coherent file and meta-data caches)
101+
fscache 0b10001111 (persistent loose cache)
102+
========= ====================================================
103+
104+
NOTE: only these shortcuts are tested modes of operation at the
105+
moment, so using other combinations of bit-patterns is not
106+
known to work. Work on better cache support is in progress.
107+
108+
IMPORTANT: loose caches (and by extension at the moment fscache)
109+
do not necessarily validate cached values on the server. In other
110+
words changes on the server are not guaranteed to be reflected
111+
on the client system. Only use this mode of operation if you
112+
have an exclusive mount and the server will modify the filesystem
113+
underneath you.
94114

95115
debug=n specifies debug level. The debug level is a bitmask.
96116

@@ -137,6 +157,10 @@ Options
137157
This can be used to share devices/named pipes/sockets between
138158
hosts. This functionality will be expanded in later versions.
139159

160+
directio bypass page cache on all read/write operations
161+
162+
ignoreqv ignore qid.version==0 as a marker to ignore cache
163+
140164
noxattr do not offer xattr functions on this mount.
141165

142166
access there are four access modes.

fs/9p/cache.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
#ifndef _9P_CACHE_H
99
#define _9P_CACHE_H
1010

11-
#include <linux/fscache.h>
12-
1311
#ifdef CONFIG_9P_FSCACHE
12+
#include <linux/fscache.h>
1413

1514
extern int v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses,
1615
const char *dev_name);

fs/9p/fid.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,9 @@ static inline void v9fs_fid_add_modes(struct p9_fid *fid, int s_flags,
5656
((fid->qid.version == 0) && !(s_flags & V9FS_IGNORE_QV)) ||
5757
(s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) {
5858
fid->mode |= P9L_DIRECT; /* no read or write cache */
59-
} else if ((s_cache < CACHE_WRITEBACK) ||
59+
} else if ((!(s_cache & CACHE_WRITEBACK)) ||
6060
(f_flags & O_DSYNC) | (s_flags & V9FS_SYNC)) {
6161
fid->mode |= P9L_NOWRITECACHE;
62-
} else if (s_cache == CACHE_LOOSE) {
63-
fid->mode |= P9L_LOOSE; /* noncoherent cache */
6462
}
6563
}
6664
#endif

fs/9p/v9fs.c

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -66,40 +66,30 @@ static const match_table_t tokens = {
6666
{Opt_err, NULL}
6767
};
6868

69-
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
70-
[CACHE_NONE] = "none",
71-
[CACHE_READAHEAD] = "readahead",
72-
[CACHE_WRITEBACK] = "writeback",
73-
[CACHE_MMAP] = "mmap",
74-
[CACHE_LOOSE] = "loose",
75-
[CACHE_FSCACHE] = "fscache",
76-
};
77-
7869
/* Interpret mount options for cache mode */
7970
static int get_cache_mode(char *s)
8071
{
8172
int version = -EINVAL;
8273

8374
if (!strcmp(s, "loose")) {
84-
version = CACHE_LOOSE;
75+
version = CACHE_SC_LOOSE;
8576
p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
8677
} else if (!strcmp(s, "fscache")) {
87-
version = CACHE_FSCACHE;
78+
version = CACHE_SC_FSCACHE;
8879
p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
8980
} else if (!strcmp(s, "mmap")) {
90-
version = CACHE_MMAP;
81+
version = CACHE_SC_MMAP;
9182
p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
92-
} else if (!strcmp(s, "writeback")) {
93-
version = CACHE_WRITEBACK;
94-
p9_debug(P9_DEBUG_9P, "Cache mode: writeback\n");
9583
} else if (!strcmp(s, "readahead")) {
96-
version = CACHE_READAHEAD;
84+
version = CACHE_SC_READAHEAD;
9785
p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n");
9886
} else if (!strcmp(s, "none")) {
99-
version = CACHE_NONE;
87+
version = CACHE_SC_NONE;
10088
p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
101-
} else
102-
pr_info("Unknown Cache mode %s\n", s);
89+
} else if (kstrtoint(s, 0, &version) != 0) {
90+
version = -EINVAL;
91+
pr_info("Unknown Cache mode or invalid value %s\n", s);
92+
}
10393
return version;
10494
}
10595

@@ -127,9 +117,9 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root)
127117
if (v9ses->nodev)
128118
seq_puts(m, ",nodevmap");
129119
if (v9ses->cache)
130-
seq_printf(m, ",cache=%s", v9fs_cache_modes[v9ses->cache]);
120+
seq_printf(m, ",cache=%x", v9ses->cache);
131121
#ifdef CONFIG_9P_FSCACHE
132-
if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE)
122+
if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE))
133123
seq_printf(m, ",cachetag=%s", v9ses->cachetag);
134124
#endif
135125

@@ -481,7 +471,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
481471

482472
#ifdef CONFIG_9P_FSCACHE
483473
/* register the session for caching */
484-
if (v9ses->cache == CACHE_FSCACHE) {
474+
if (v9ses->cache & CACHE_FSCACHE) {
485475
rc = v9fs_cache_session_get_cookie(v9ses, dev_name);
486476
if (rc < 0)
487477
goto err_clnt;

fs/9p/v9fs.h

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,35 +31,54 @@
3131
#define V9FS_ACL_MASK V9FS_POSIX_ACL
3232

3333
enum p9_session_flags {
34-
V9FS_PROTO_2000U = 0x01,
35-
V9FS_PROTO_2000L = 0x02,
36-
V9FS_ACCESS_SINGLE = 0x04,
37-
V9FS_ACCESS_USER = 0x08,
38-
V9FS_ACCESS_CLIENT = 0x10,
39-
V9FS_POSIX_ACL = 0x20,
40-
V9FS_NO_XATTR = 0x40,
41-
V9FS_IGNORE_QV = 0x80, /* ignore qid.version for cache hints */
42-
V9FS_DIRECT_IO = 0x100,
43-
V9FS_SYNC = 0x200
34+
V9FS_PROTO_2000U = 0x01,
35+
V9FS_PROTO_2000L = 0x02,
36+
V9FS_ACCESS_SINGLE = 0x04,
37+
V9FS_ACCESS_USER = 0x08,
38+
V9FS_ACCESS_CLIENT = 0x10,
39+
V9FS_POSIX_ACL = 0x20,
40+
V9FS_NO_XATTR = 0x40,
41+
V9FS_IGNORE_QV = 0x80, /* ignore qid.version for cache hints */
42+
V9FS_DIRECT_IO = 0x100,
43+
V9FS_SYNC = 0x200
4444
};
4545

46-
/* possible values of ->cache */
4746
/**
48-
* enum p9_cache_modes - user specified cache preferences
49-
* @CACHE_NONE: do not cache data, dentries, or directory contents (default)
50-
* @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
47+
* enum p9_cache_shortcuts - human readable cache preferences
48+
* @CACHE_SC_NONE: disable all caches
49+
* @CACHE_SC_READAHEAD: only provide caching for readahead
50+
* @CACHE_SC_MMAP: provide caching to enable mmap
51+
* @CACHE_SC_LOOSE: non-coherent caching for files and meta data
52+
* @CACHE_SC_FSCACHE: persistent non-coherent caching for files and meta-data
5153
*
52-
* eventually support loose, tight, time, session, default always none
5354
*/
5455

55-
enum p9_cache_modes {
56-
CACHE_NONE,
57-
CACHE_READAHEAD,
58-
CACHE_WRITEBACK,
59-
CACHE_MMAP,
60-
CACHE_LOOSE,
61-
CACHE_FSCACHE,
62-
nr__p9_cache_modes
56+
enum p9_cache_shortcuts {
57+
CACHE_SC_NONE = 0b00000000,
58+
CACHE_SC_READAHEAD = 0b00000001,
59+
CACHE_SC_MMAP = 0b00000101,
60+
CACHE_SC_LOOSE = 0b00001111,
61+
CACHE_SC_FSCACHE = 0b10001111,
62+
};
63+
64+
/**
65+
* enum p9_cache_bits - possible values of ->cache
66+
* @CACHE_NONE: caches disabled
67+
* @CACHE_FILE: file caching (open to close)
68+
* @CACHE_META: meta-data and directory caching
69+
* @CACHE_WRITEBACK: write-back caching for files
70+
* @CACHE_LOOSE: don't check cache consistency
71+
* @CACHE_FSCACHE: local persistent caches
72+
*
73+
*/
74+
75+
enum p9_cache_bits {
76+
CACHE_NONE = 0b00000000,
77+
CACHE_FILE = 0b00000001,
78+
CACHE_META = 0b00000010,
79+
CACHE_WRITEBACK = 0b00000100,
80+
CACHE_LOOSE = 0b00001000,
81+
CACHE_FSCACHE = 0b10000000,
6382
};
6483

6584
/**
@@ -68,7 +87,7 @@ enum p9_cache_modes {
6887
* @nodev: set to 1 to disable device mapping
6988
* @debug: debug level
7089
* @afid: authentication handle
71-
* @cache: cache mode of type &p9_cache_modes
90+
* @cache: cache mode of type &p9_cache_bits
7291
* @cachetag: the tag of the cache associated with this session
7392
* @fscache: session cookie associated with FS-Cache
7493
* @uname: string user name to mount hierarchy as

fs/9p/vfs_addr.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ const struct netfs_request_ops v9fs_req_ops = {
115115

116116
static bool v9fs_release_folio(struct folio *folio, gfp_t gfp)
117117
{
118-
struct inode *inode = folio_inode(folio);
119-
120118
if (folio_test_private(folio))
121119
return false;
122120
#ifdef CONFIG_9P_FSCACHE
@@ -125,8 +123,8 @@ static bool v9fs_release_folio(struct folio *folio, gfp_t gfp)
125123
return false;
126124
folio_wait_fscache(folio);
127125
}
126+
fscache_note_page_release(v9fs_inode_cookie(V9FS_I(folio_inode(folio))));
128127
#endif
129-
fscache_note_page_release(v9fs_inode_cookie(V9FS_I(inode)));
130128
return true;
131129
}
132130

@@ -136,6 +134,7 @@ static void v9fs_invalidate_folio(struct folio *folio, size_t offset,
136134
folio_wait_fscache(folio);
137135
}
138136

137+
#ifdef CONFIG_9P_FSCACHE
139138
static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
140139
bool was_async)
141140
{
@@ -149,18 +148,19 @@ static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error,
149148
i_size_read(&v9inode->netfs.inode), 0);
150149
}
151150
}
151+
#endif
152152

153153
static int v9fs_vfs_write_folio_locked(struct folio *folio)
154154
{
155155
struct inode *inode = folio_inode(folio);
156-
struct v9fs_inode *v9inode = V9FS_I(inode);
157-
struct fscache_cookie *cookie = v9fs_inode_cookie(v9inode);
158156
loff_t start = folio_pos(folio);
159157
loff_t i_size = i_size_read(inode);
160158
struct iov_iter from;
161159
size_t len = folio_size(folio);
162160
struct p9_fid *writeback_fid;
163161
int err;
162+
struct v9fs_inode __maybe_unused *v9inode = V9FS_I(inode);
163+
struct fscache_cookie __maybe_unused *cookie = v9fs_inode_cookie(v9inode);
164164

165165
if (start >= i_size)
166166
return 0; /* Simultaneous truncation occurred */
@@ -181,15 +181,17 @@ static int v9fs_vfs_write_folio_locked(struct folio *folio)
181181

182182
p9_client_write(writeback_fid, start, &from, &err);
183183

184+
#ifdef CONFIG_9P_FSCACHE
184185
if (err == 0 &&
185-
fscache_cookie_enabled(cookie) &&
186-
test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) {
186+
fscache_cookie_enabled(cookie) &&
187+
test_bit(FSCACHE_COOKIE_IS_CACHING, &cookie->flags)) {
187188
folio_start_fscache(folio);
188189
fscache_write_to_cache(v9fs_inode_cookie(v9inode),
189-
folio_mapping(folio), start, len, i_size,
190-
v9fs_write_to_cache_done, v9inode,
191-
true);
190+
folio_mapping(folio), start, len, i_size,
191+
v9fs_write_to_cache_done, v9inode,
192+
true);
192193
}
194+
#endif
193195

194196
folio_end_writeback(folio);
195197
p9_fid_put(writeback_fid);
@@ -300,7 +302,6 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
300302
loff_t last_pos = pos + copied;
301303
struct folio *folio = page_folio(subpage);
302304
struct inode *inode = mapping->host;
303-
struct v9fs_inode *v9inode = V9FS_I(inode);
304305

305306
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
306307

@@ -320,7 +321,10 @@ static int v9fs_write_end(struct file *filp, struct address_space *mapping,
320321
if (last_pos > inode->i_size) {
321322
inode_add_bytes(inode, last_pos - inode->i_size);
322323
i_size_write(inode, last_pos);
323-
fscache_update_cookie(v9fs_inode_cookie(v9inode), NULL, &last_pos);
324+
#ifdef CONFIG_9P_FSCACHE
325+
fscache_update_cookie(v9fs_inode_cookie(V9FS_I(inode)), NULL,
326+
&last_pos);
327+
#endif
324328
}
325329
folio_mark_dirty(folio);
326330
out:

fs/9p/vfs_file.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,11 @@ static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
4141
int v9fs_file_open(struct inode *inode, struct file *file)
4242
{
4343
int err;
44-
struct v9fs_inode *v9inode;
4544
struct v9fs_session_info *v9ses;
4645
struct p9_fid *fid;
4746
int omode;
4847

4948
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
50-
v9inode = V9FS_I(inode);
5149
v9ses = v9fs_inode2v9ses(inode);
5250
if (v9fs_proto_dotl(v9ses))
5351
omode = v9fs_open_to_dotl_flags(file->f_flags);
@@ -60,7 +58,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
6058
if (IS_ERR(fid))
6159
return PTR_ERR(fid);
6260

63-
if ((v9ses->cache >= CACHE_WRITEBACK) && (omode & P9_OWRITE)) {
61+
if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) {
6462
int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR;
6563

6664
p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n");
@@ -85,8 +83,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
8583
}
8684

8785
#ifdef CONFIG_9P_FSCACHE
88-
if (v9ses->cache == CACHE_FSCACHE)
89-
fscache_use_cookie(v9fs_inode_cookie(v9inode),
86+
if (v9ses->cache & CACHE_FSCACHE)
87+
fscache_use_cookie(v9fs_inode_cookie(V9FS_I(inode)),
9088
file->f_mode & FMODE_WRITE);
9189
#endif
9290
v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags);
@@ -485,7 +483,7 @@ v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
485483

486484
p9_debug(P9_DEBUG_MMAP, "filp :%p\n", filp);
487485

488-
if (v9ses->cache < CACHE_MMAP) {
486+
if (!(v9ses->cache & CACHE_WRITEBACK)) {
489487
p9_debug(P9_DEBUG_CACHE, "(no mmap mode)");
490488
if (vma->vm_flags & VM_MAYSHARE)
491489
return -ENODEV;

0 commit comments

Comments
 (0)