1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * V9FS definitions.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
6*4882a593Smuzhiyun * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun #ifndef FS_9P_V9FS_H
9*4882a593Smuzhiyun #define FS_9P_V9FS_H
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/backing-dev.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun /**
14*4882a593Smuzhiyun * enum p9_session_flags - option flags for each 9P session
15*4882a593Smuzhiyun * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
16*4882a593Smuzhiyun * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
17*4882a593Smuzhiyun * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
18*4882a593Smuzhiyun * @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
19*4882a593Smuzhiyun * @V9FS_ACCESS_CLIENT: Just like user, but access check is performed on client.
20*4882a593Smuzhiyun * @V9FS_ACCESS_ANY: use a single attach for all users
21*4882a593Smuzhiyun * @V9FS_ACCESS_MASK: bit mask of different ACCESS options
22*4882a593Smuzhiyun * @V9FS_POSIX_ACL: POSIX ACLs are enforced
23*4882a593Smuzhiyun *
24*4882a593Smuzhiyun * Session flags reflect options selected by users at mount time
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun #define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \
27*4882a593Smuzhiyun V9FS_ACCESS_USER | \
28*4882a593Smuzhiyun V9FS_ACCESS_CLIENT)
29*4882a593Smuzhiyun #define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
30*4882a593Smuzhiyun #define V9FS_ACL_MASK V9FS_POSIX_ACL
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun enum p9_session_flags {
33*4882a593Smuzhiyun V9FS_PROTO_2000U = 0x01,
34*4882a593Smuzhiyun V9FS_PROTO_2000L = 0x02,
35*4882a593Smuzhiyun V9FS_ACCESS_SINGLE = 0x04,
36*4882a593Smuzhiyun V9FS_ACCESS_USER = 0x08,
37*4882a593Smuzhiyun V9FS_ACCESS_CLIENT = 0x10,
38*4882a593Smuzhiyun V9FS_POSIX_ACL = 0x20
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /* possible values of ->cache */
42*4882a593Smuzhiyun /**
43*4882a593Smuzhiyun * enum p9_cache_modes - user specified cache preferences
44*4882a593Smuzhiyun * @CACHE_NONE: do not cache data, dentries, or directory contents (default)
45*4882a593Smuzhiyun * @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
46*4882a593Smuzhiyun *
47*4882a593Smuzhiyun * eventually support loose, tight, time, session, default always none
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun enum p9_cache_modes {
51*4882a593Smuzhiyun CACHE_NONE,
52*4882a593Smuzhiyun CACHE_MMAP,
53*4882a593Smuzhiyun CACHE_LOOSE,
54*4882a593Smuzhiyun CACHE_FSCACHE,
55*4882a593Smuzhiyun nr__p9_cache_modes
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /**
59*4882a593Smuzhiyun * struct v9fs_session_info - per-instance session information
60*4882a593Smuzhiyun * @flags: session options of type &p9_session_flags
61*4882a593Smuzhiyun * @nodev: set to 1 to disable device mapping
62*4882a593Smuzhiyun * @debug: debug level
63*4882a593Smuzhiyun * @afid: authentication handle
64*4882a593Smuzhiyun * @cache: cache mode of type &p9_cache_modes
65*4882a593Smuzhiyun * @cachetag: the tag of the cache associated with this session
66*4882a593Smuzhiyun * @fscache: session cookie associated with FS-Cache
67*4882a593Smuzhiyun * @uname: string user name to mount hierarchy as
68*4882a593Smuzhiyun * @aname: mount specifier for remote hierarchy
69*4882a593Smuzhiyun * @maxdata: maximum data to be sent/recvd per protocol message
70*4882a593Smuzhiyun * @dfltuid: default numeric userid to mount hierarchy as
71*4882a593Smuzhiyun * @dfltgid: default numeric groupid to mount hierarchy as
72*4882a593Smuzhiyun * @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
73*4882a593Smuzhiyun * @clnt: reference to 9P network client instantiated for this session
74*4882a593Smuzhiyun * @slist: reference to list of registered 9p sessions
75*4882a593Smuzhiyun *
76*4882a593Smuzhiyun * This structure holds state for each session instance established during
77*4882a593Smuzhiyun * a sys_mount() .
78*4882a593Smuzhiyun *
79*4882a593Smuzhiyun * Bugs: there seems to be a lot of state which could be condensed and/or
80*4882a593Smuzhiyun * removed.
81*4882a593Smuzhiyun */
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun struct v9fs_session_info {
84*4882a593Smuzhiyun /* options */
85*4882a593Smuzhiyun unsigned char flags;
86*4882a593Smuzhiyun unsigned char nodev;
87*4882a593Smuzhiyun unsigned short debug;
88*4882a593Smuzhiyun unsigned int afid;
89*4882a593Smuzhiyun unsigned int cache;
90*4882a593Smuzhiyun #ifdef CONFIG_9P_FSCACHE
91*4882a593Smuzhiyun char *cachetag;
92*4882a593Smuzhiyun struct fscache_cookie *fscache;
93*4882a593Smuzhiyun #endif
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun char *uname; /* user name to mount as */
96*4882a593Smuzhiyun char *aname; /* name of remote hierarchy being mounted */
97*4882a593Smuzhiyun unsigned int maxdata; /* max data for client interface */
98*4882a593Smuzhiyun kuid_t dfltuid; /* default uid/muid for legacy support */
99*4882a593Smuzhiyun kgid_t dfltgid; /* default gid for legacy support */
100*4882a593Smuzhiyun kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
101*4882a593Smuzhiyun struct p9_client *clnt; /* 9p client */
102*4882a593Smuzhiyun struct list_head slist; /* list of sessions registered with v9fs */
103*4882a593Smuzhiyun struct rw_semaphore rename_sem;
104*4882a593Smuzhiyun long session_lock_timeout; /* retry interval for blocking locks */
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /* cache_validity flags */
108*4882a593Smuzhiyun #define V9FS_INO_INVALID_ATTR 0x01
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun struct v9fs_inode {
111*4882a593Smuzhiyun #ifdef CONFIG_9P_FSCACHE
112*4882a593Smuzhiyun struct mutex fscache_lock;
113*4882a593Smuzhiyun struct fscache_cookie *fscache;
114*4882a593Smuzhiyun #endif
115*4882a593Smuzhiyun struct p9_qid qid;
116*4882a593Smuzhiyun unsigned int cache_validity;
117*4882a593Smuzhiyun struct p9_fid *writeback_fid;
118*4882a593Smuzhiyun struct mutex v_mutex;
119*4882a593Smuzhiyun struct inode vfs_inode;
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun
V9FS_I(const struct inode * inode)122*4882a593Smuzhiyun static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun return container_of(inode, struct v9fs_inode, vfs_inode);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun extern int v9fs_show_options(struct seq_file *m, struct dentry *root);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
130*4882a593Smuzhiyun char *);
131*4882a593Smuzhiyun extern void v9fs_session_close(struct v9fs_session_info *v9ses);
132*4882a593Smuzhiyun extern void v9fs_session_cancel(struct v9fs_session_info *v9ses);
133*4882a593Smuzhiyun extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
134*4882a593Smuzhiyun extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
135*4882a593Smuzhiyun unsigned int flags);
136*4882a593Smuzhiyun extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
137*4882a593Smuzhiyun extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
138*4882a593Smuzhiyun extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
139*4882a593Smuzhiyun struct inode *new_dir, struct dentry *new_dentry,
140*4882a593Smuzhiyun unsigned int flags);
141*4882a593Smuzhiyun extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
142*4882a593Smuzhiyun struct p9_fid *fid,
143*4882a593Smuzhiyun struct super_block *sb, int new);
144*4882a593Smuzhiyun extern const struct inode_operations v9fs_dir_inode_operations_dotl;
145*4882a593Smuzhiyun extern const struct inode_operations v9fs_file_inode_operations_dotl;
146*4882a593Smuzhiyun extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
147*4882a593Smuzhiyun extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
148*4882a593Smuzhiyun struct p9_fid *fid,
149*4882a593Smuzhiyun struct super_block *sb, int new);
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /* other default globals */
152*4882a593Smuzhiyun #define V9FS_PORT 564
153*4882a593Smuzhiyun #define V9FS_DEFUSER "nobody"
154*4882a593Smuzhiyun #define V9FS_DEFANAME ""
155*4882a593Smuzhiyun #define V9FS_DEFUID KUIDT_INIT(-2)
156*4882a593Smuzhiyun #define V9FS_DEFGID KGIDT_INIT(-2)
157*4882a593Smuzhiyun
v9fs_inode2v9ses(struct inode * inode)158*4882a593Smuzhiyun static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun return (inode->i_sb->s_fs_info);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
v9fs_dentry2v9ses(struct dentry * dentry)163*4882a593Smuzhiyun static inline struct v9fs_session_info *v9fs_dentry2v9ses(struct dentry *dentry)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun return dentry->d_sb->s_fs_info;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
v9fs_proto_dotu(struct v9fs_session_info * v9ses)168*4882a593Smuzhiyun static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun return v9ses->flags & V9FS_PROTO_2000U;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun
v9fs_proto_dotl(struct v9fs_session_info * v9ses)173*4882a593Smuzhiyun static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun return v9ses->flags & V9FS_PROTO_2000L;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun /**
179*4882a593Smuzhiyun * v9fs_get_inode_from_fid - Helper routine to populate an inode by
180*4882a593Smuzhiyun * issuing a attribute request
181*4882a593Smuzhiyun * @v9ses: session information
182*4882a593Smuzhiyun * @fid: fid to issue attribute request for
183*4882a593Smuzhiyun * @sb: superblock on which to create inode
184*4882a593Smuzhiyun *
185*4882a593Smuzhiyun */
186*4882a593Smuzhiyun static inline struct inode *
v9fs_get_inode_from_fid(struct v9fs_session_info * v9ses,struct p9_fid * fid,struct super_block * sb)187*4882a593Smuzhiyun v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
188*4882a593Smuzhiyun struct super_block *sb)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun if (v9fs_proto_dotl(v9ses))
191*4882a593Smuzhiyun return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
192*4882a593Smuzhiyun else
193*4882a593Smuzhiyun return v9fs_inode_from_fid(v9ses, fid, sb, 0);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /**
197*4882a593Smuzhiyun * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
198*4882a593Smuzhiyun * issuing a attribute request
199*4882a593Smuzhiyun * @v9ses: session information
200*4882a593Smuzhiyun * @fid: fid to issue attribute request for
201*4882a593Smuzhiyun * @sb: superblock on which to create inode
202*4882a593Smuzhiyun *
203*4882a593Smuzhiyun */
204*4882a593Smuzhiyun static inline struct inode *
v9fs_get_new_inode_from_fid(struct v9fs_session_info * v9ses,struct p9_fid * fid,struct super_block * sb)205*4882a593Smuzhiyun v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
206*4882a593Smuzhiyun struct super_block *sb)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun if (v9fs_proto_dotl(v9ses))
209*4882a593Smuzhiyun return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
210*4882a593Smuzhiyun else
211*4882a593Smuzhiyun return v9fs_inode_from_fid(v9ses, fid, sb, 1);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #endif
215