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