Skip to content

Commit 8e15605

Browse files
committed
Merge tag '9p-6.4-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull 9p updates from Eric Van Hensbergen: "This includes a number of patches that didn't quite make the cut last merge window while we addressed some outstanding issues and review comments. It includes some new caching modes for those that only want readahead caches and reworks how we do writeback caching so we are not keeping extra references around which both causes performance problems and uses lots of additional resources on the server. It also includes a new flag to force disabling of xattrs which can also cause major performance issues, particularly if the underlying filesystem on the server doesn't support them. Finally it adds a couple of additional mount options to better support directio and enabling caches when the server doesn't support qid.version. There was one late-breaking bug report that has also been included as its own patch where I forgot to propagate an embarassing bit-logic fix to the various variations of open" * tag '9p-6.4-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs: fs/9p: Fix bit operation logic error fs/9p: Rework cache modes and add new options to Documentation fs/9p: remove writeback fid and fix per-file modes fs/9p: Add new mount modes 9p: Add additional debug flags and open modes fs/9p: allow disable of xattr support on mount fs/9p: Remove unnecessary superblock flags fs/9p: Consolidate file operations and add readahead and writeback
2 parents a1fd058 + 21e26d5 commit 8e15605

15 files changed

Lines changed: 368 additions & 416 deletions

File tree

Documentation/filesystems/9p.rst

Lines changed: 39 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,12 @@ 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+
164+
noxattr do not offer xattr functions on this mount.
165+
140166
access there are four access modes.
141167
user
142168
if a user tries to access a file on v9fs

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.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,24 @@ void v9fs_fid_add(struct dentry *dentry, struct p9_fid **pfid)
4141
*pfid = NULL;
4242
}
4343

44+
static bool v9fs_is_writeable(int mode)
45+
{
46+
if (mode & (P9_OWRITE|P9_ORDWR))
47+
return true;
48+
else
49+
return false;
50+
}
51+
4452
/**
4553
* v9fs_fid_find_inode - search for an open fid off of the inode list
4654
* @inode: return a fid pointing to a specific inode
55+
* @want_writeable: only consider fids which are writeable
4756
* @uid: return a fid belonging to the specified user
57+
* @any: ignore uid as a selection criteria
4858
*
4959
*/
50-
51-
static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
60+
struct p9_fid *v9fs_fid_find_inode(struct inode *inode, bool want_writeable,
61+
kuid_t uid, bool any)
5262
{
5363
struct hlist_head *h;
5464
struct p9_fid *fid, *ret = NULL;
@@ -58,7 +68,12 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
5868
spin_lock(&inode->i_lock);
5969
h = (struct hlist_head *)&inode->i_private;
6070
hlist_for_each_entry(fid, h, ilist) {
61-
if (uid_eq(fid->uid, uid)) {
71+
if (any || uid_eq(fid->uid, uid)) {
72+
if (want_writeable && !v9fs_is_writeable(fid->mode)) {
73+
p9_debug(P9_DEBUG_VFS, " mode: %x not writeable?\n",
74+
fid->mode);
75+
continue;
76+
}
6277
p9_fid_get(fid);
6378
ret = fid;
6479
break;
@@ -118,7 +133,7 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
118133
spin_unlock(&dentry->d_lock);
119134
} else {
120135
if (dentry->d_inode)
121-
ret = v9fs_fid_find_inode(dentry->d_inode, uid);
136+
ret = v9fs_fid_find_inode(dentry->d_inode, false, uid, any);
122137
}
123138

124139
return ret;
@@ -299,28 +314,3 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
299314
return v9fs_fid_lookup_with_uid(dentry, uid, any);
300315
}
301316

302-
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
303-
{
304-
int err;
305-
struct p9_fid *fid, *ofid;
306-
307-
ofid = v9fs_fid_lookup_with_uid(dentry, GLOBAL_ROOT_UID, 0);
308-
fid = clone_fid(ofid);
309-
if (IS_ERR(fid))
310-
goto error_out;
311-
p9_fid_put(ofid);
312-
/*
313-
* writeback fid will only be used to write back the
314-
* dirty pages. We always request for the open fid in read-write
315-
* mode so that a partial page write which result in page
316-
* read can work.
317-
*/
318-
err = p9_client_open(fid, O_RDWR);
319-
if (err < 0) {
320-
p9_fid_put(fid);
321-
fid = ERR_PTR(err);
322-
goto error_out;
323-
}
324-
error_out:
325-
return fid;
326-
}

fs/9p/fid.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77
#ifndef FS_9P_FID_H
88
#define FS_9P_FID_H
99
#include <linux/list.h>
10+
#include "v9fs.h"
1011

12+
struct p9_fid *v9fs_fid_find_inode(struct inode *inode, bool want_writeable,
13+
kuid_t uid, bool any);
1114
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
1215
static inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
1316
{
1417
return v9fs_fid_lookup(dentry->d_parent);
1518
}
1619
void v9fs_fid_add(struct dentry *dentry, struct p9_fid **fid);
17-
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
1820
void v9fs_open_fid_add(struct inode *inode, struct p9_fid **fid);
1921
static inline struct p9_fid *clone_fid(struct p9_fid *fid)
2022
{
@@ -32,4 +34,31 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
3234
p9_fid_put(fid);
3335
return nfid;
3436
}
37+
/**
38+
* v9fs_fid_addmodes - add cache flags to fid mode (for client use only)
39+
* @fid: fid to augment
40+
* @s_flags: session info mount flags
41+
* @s_cache: session info cache flags
42+
* @f_flags: unix open flags
43+
*
44+
* make sure mode reflects flags of underlying mounts
45+
* also qid.version == 0 reflects a synthetic or legacy file system
46+
* NOTE: these are set after open so only reflect 9p client not
47+
* underlying file system on server.
48+
*/
49+
static inline void v9fs_fid_add_modes(struct p9_fid *fid, int s_flags,
50+
int s_cache, unsigned int f_flags)
51+
{
52+
if (fid->qid.type != P9_QTFILE)
53+
return;
54+
55+
if ((!s_cache) ||
56+
((fid->qid.version == 0) && !(s_flags & V9FS_IGNORE_QV)) ||
57+
(s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) {
58+
fid->mode |= P9L_DIRECT; /* no read or write cache */
59+
} else if ((!(s_cache & CACHE_WRITEBACK)) ||
60+
(f_flags & O_DSYNC) | (s_flags & V9FS_SYNC)) {
61+
fid->mode |= P9L_NOWRITECACHE;
62+
}
63+
}
3564
#endif

fs/9p/v9fs.c

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ enum {
3838
/* String options */
3939
Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag,
4040
/* Options that take no arguments */
41-
Opt_nodevmap,
42-
/* Cache options */
43-
Opt_cache_loose, Opt_fscache, Opt_mmap,
41+
Opt_nodevmap, Opt_noxattr, Opt_directio, Opt_ignoreqv,
4442
/* Access options */
4543
Opt_access, Opt_posixacl,
4644
/* Lock timeout option */
@@ -57,43 +55,41 @@ static const match_table_t tokens = {
5755
{Opt_uname, "uname=%s"},
5856
{Opt_remotename, "aname=%s"},
5957
{Opt_nodevmap, "nodevmap"},
58+
{Opt_noxattr, "noxattr"},
59+
{Opt_directio, "directio"},
60+
{Opt_ignoreqv, "ignoreqv"},
6061
{Opt_cache, "cache=%s"},
61-
{Opt_cache_loose, "loose"},
62-
{Opt_fscache, "fscache"},
63-
{Opt_mmap, "mmap"},
6462
{Opt_cachetag, "cachetag=%s"},
6563
{Opt_access, "access=%s"},
6664
{Opt_posixacl, "posixacl"},
6765
{Opt_locktimeout, "locktimeout=%u"},
6866
{Opt_err, NULL}
6967
};
7068

71-
static const char *const v9fs_cache_modes[nr__p9_cache_modes] = {
72-
[CACHE_NONE] = "none",
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");
83+
} else if (!strcmp(s, "readahead")) {
84+
version = CACHE_SC_READAHEAD;
85+
p9_debug(P9_DEBUG_9P, "Cache mode: readahead\n");
9286
} else if (!strcmp(s, "none")) {
93-
version = CACHE_NONE;
87+
version = CACHE_SC_NONE;
9488
p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
95-
} else
96-
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+
}
9793
return version;
9894
}
9995

@@ -121,9 +117,9 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root)
121117
if (v9ses->nodev)
122118
seq_puts(m, ",nodevmap");
123119
if (v9ses->cache)
124-
seq_printf(m, ",%s", v9fs_cache_modes[v9ses->cache]);
120+
seq_printf(m, ",cache=%x", v9ses->cache);
125121
#ifdef CONFIG_9P_FSCACHE
126-
if (v9ses->cachetag && v9ses->cache == CACHE_FSCACHE)
122+
if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE))
127123
seq_printf(m, ",cachetag=%s", v9ses->cachetag);
128124
#endif
129125

@@ -143,9 +139,16 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root)
143139
break;
144140
}
145141

142+
if (v9ses->flags & V9FS_IGNORE_QV)
143+
seq_puts(m, ",ignoreqv");
144+
if (v9ses->flags & V9FS_DIRECT_IO)
145+
seq_puts(m, ",directio");
146146
if (v9ses->flags & V9FS_POSIX_ACL)
147147
seq_puts(m, ",posixacl");
148148

149+
if (v9ses->flags & V9FS_NO_XATTR)
150+
seq_puts(m, ",noxattr");
151+
149152
return p9_show_client_options(m, v9ses->clnt);
150153
}
151154

@@ -266,14 +269,14 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
266269
case Opt_nodevmap:
267270
v9ses->nodev = 1;
268271
break;
269-
case Opt_cache_loose:
270-
v9ses->cache = CACHE_LOOSE;
272+
case Opt_noxattr:
273+
v9ses->flags |= V9FS_NO_XATTR;
271274
break;
272-
case Opt_fscache:
273-
v9ses->cache = CACHE_FSCACHE;
275+
case Opt_directio:
276+
v9ses->flags |= V9FS_DIRECT_IO;
274277
break;
275-
case Opt_mmap:
276-
v9ses->cache = CACHE_MMAP;
278+
case Opt_ignoreqv:
279+
v9ses->flags |= V9FS_IGNORE_QV;
277280
break;
278281
case Opt_cachetag:
279282
#ifdef CONFIG_9P_FSCACHE
@@ -468,7 +471,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
468471

469472
#ifdef CONFIG_9P_FSCACHE
470473
/* register the session for caching */
471-
if (v9ses->cache == CACHE_FSCACHE) {
474+
if (v9ses->cache & CACHE_FSCACHE) {
472475
rc = v9fs_cache_session_get_cookie(v9ses, dev_name);
473476
if (rc < 0)
474477
goto err_clnt;

0 commit comments

Comments
 (0)