By this point we have two ways to test for inode reuse - qid and qid+path. By default, uncached mode uses qid+path and cached mode uses qid (and in fact does not support qid+path). This patch adds the option to control the behaviour for uncached mode. In a future version, if we can negotiate with the server and be sure that it won't give us duplicate qid.path, the default for those cases can be qid-based. Signed-off-by: Tingmao Wang <m@xxxxxxxxxx> Cc: "Mickaël Salaün" <mic@xxxxxxxxxxx> Cc: "Günther Noack" <gnoack@xxxxxxxxxx> --- Changes since v1: - Removed inodeident=none and instead supports inodeident=qid. This means that there is no longer an option to not re-use inodes at all. - No longer supports inodeident=path on cached mode, checks added at option init time. - Added explicit bits for both V9FS_INODE_IDENT_PATH and V9FS_INODE_IDENT_QID, in order to set a default based on cache bits when neither are set explicitly by the user. fs/9p/v9fs.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++- fs/9p/v9fs.h | 3 +++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 77e9c4387c1d..f87d6680b85a 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -36,7 +36,7 @@ enum { /* Options that take integer arguments */ Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid, /* String options */ - Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag, + Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag, Opt_inodeident, /* Options that take no arguments */ Opt_nodevmap, Opt_noxattr, Opt_directio, Opt_ignoreqv, /* Access options */ @@ -63,6 +63,7 @@ static const match_table_t tokens = { {Opt_access, "access=%s"}, {Opt_posixacl, "posixacl"}, {Opt_locktimeout, "locktimeout=%u"}, + {Opt_inodeident, "inodeident=%s"}, {Opt_err, NULL} }; @@ -149,6 +150,21 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) if (v9ses->flags & V9FS_NO_XATTR) seq_puts(m, ",noxattr"); + switch (v9ses->flags & V9FS_INODE_IDENT_MASK) { + case V9FS_INODE_IDENT_QID: + seq_puts(m, ",inodeident=qid"); + break; + case V9FS_INODE_IDENT_PATH: + seq_puts(m, ",inodeident=path"); + break; + default: + /* + * Unspecified, will be set later in v9fs_session_init depending on + * cache setting + */ + break; + } + return p9_show_client_options(m, v9ses->clnt); } @@ -369,6 +385,26 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) v9ses->session_lock_timeout = (long)option * HZ; break; + case Opt_inodeident: + s = match_strdup(&args[0]); + if (!s) { + ret = -ENOMEM; + p9_debug(P9_DEBUG_ERROR, + "problem allocating copy of inodeident arg\n"); + goto free_and_return; + } + v9ses->flags &= ~V9FS_INODE_IDENT_MASK; + if (strcmp(s, "qid") == 0) { + v9ses->flags |= V9FS_INODE_IDENT_QID; + } else if (strcmp(s, "path") == 0) { + v9ses->flags |= V9FS_INODE_IDENT_PATH; + } else { + ret = -EINVAL; + p9_debug(P9_DEBUG_ERROR, "Unknown inodeident argument %s\n", s); + } + kfree(s); + break; + default: continue; } @@ -393,6 +429,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, { struct p9_fid *fid; int rc = -ENOMEM; + bool cached; v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL); if (!v9ses->uname) @@ -427,6 +464,26 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, if (rc < 0) goto err_clnt; + cached = v9ses->cache & (CACHE_META | CACHE_LOOSE); + + if (cached && v9ses->flags & V9FS_INODE_IDENT_PATH) { + rc = -EINVAL; + p9_debug(P9_DEBUG_ERROR, + "inodeident=path not supported in cached mode\n"); + goto err_clnt; + } + + if (!(v9ses->flags & V9FS_INODE_IDENT_MASK)) { + /* Unspecified - use default */ + if (cached) { + /* which is qid in cached mode (path not supported) */ + v9ses->flags |= V9FS_INODE_IDENT_QID; + } else { + /* ...or path in uncached mode */ + v9ses->flags |= V9FS_INODE_IDENT_PATH; + } + } + v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; if (!v9fs_proto_dotl(v9ses) && diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 134b55a605be..b4e738c1bba5 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -43,8 +43,11 @@ enum p9_session_flags { V9FS_DIRECT_IO = 0x100, V9FS_SYNC = 0x200, V9FS_INODE_IDENT_PATH = 0x400, + V9FS_INODE_IDENT_QID = 0x800, }; +#define V9FS_INODE_IDENT_MASK (V9FS_INODE_IDENT_PATH | V9FS_INODE_IDENT_QID) + /** * enum p9_cache_shortcuts - human readable cache preferences * @CACHE_SC_NONE: disable all caches -- 2.51.0