Add an extra option to control the inode identification behaviour, and make path-based default. The reasoning for this default is that the current 9pfs already does not re-use inodes even for same qid.path, but because of the dcache, a file kept open by a process (by e.g. open, or having the directory as CWD) means that other processes will re-use that inode. If we identify inode by path by default, this behaviour is consistent regardless of whether files are kept open or not. 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 (possibly re-merging commit 724a08450f74 ("fs/9p: simplify iget to remove unnecessary paths")...?) Signed-off-by: Tingmao Wang <m@xxxxxxxxxx> --- fs/9p/v9fs.c | 33 ++++++++++++++++++++++++++++++++- fs/9p/v9fs.h | 2 ++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 77e9c4387c1d..487532295a98 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,15 @@ 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 0: + seq_puts(m, ",inodeident=none"); + break; + case V9FS_INODE_IDENT_PATH: + seq_puts(m, ",inodeident=path"); + break; + } + return p9_show_client_options(m, v9ses->clnt); } @@ -369,6 +379,25 @@ 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; + } + if (strcmp(s, "none") == 0) { + v9ses->flags &= ~V9FS_INODE_IDENT_MASK; + } 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; } @@ -423,6 +452,8 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, v9ses->flags |= V9FS_PROTO_2000U; } + v9ses->flags |= V9FS_INODE_IDENT_PATH; + rc = v9fs_parse_options(v9ses, data); if (rc < 0) goto err_clnt; diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 5c85923aa2dd..b4874fdd925e 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -31,6 +31,8 @@ #define V9FS_ACCESS_MASK V9FS_ACCESS_ANY #define V9FS_ACL_MASK V9FS_POSIX_ACL +#define V9FS_INODE_IDENT_MASK (V9FS_INODE_IDENT_PATH) + enum p9_session_flags { V9FS_PROTO_2000U = 0x01, V9FS_PROTO_2000L = 0x02, -- 2.39.5