xref: /OK3568_Linux_fs/kernel/fs/9p/v9fs.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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