]>
Commit | Line | Data |
---|---|---|
bd238fb4 LI |
1 | /* |
2 | * include/net/9p/client.h | |
3 | * | |
4 | * 9P Client Definitions | |
5 | * | |
8a0dc95f | 6 | * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com> |
bd238fb4 LI |
7 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License version 2 | |
11 | * as published by the Free Software Foundation. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to: | |
20 | * Free Software Foundation | |
21 | * 51 Franklin Street, Fifth Floor | |
22 | * Boston, MA 02111-1301 USA | |
23 | * | |
24 | */ | |
25 | ||
26 | #ifndef NET_9P_CLIENT_H | |
27 | #define NET_9P_CLIENT_H | |
28 | ||
50192abe WD |
29 | #include <linux/utsname.h> |
30 | ||
fea511a6 EVH |
31 | /* Number of requests per row */ |
32 | #define P9_ROW_MAXTAG 255 | |
33 | ||
0fb80abd SK |
34 | /** enum p9_proto_versions - 9P protocol versions |
35 | * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u | |
36 | * @p9_proto_2000u: 9P2000.u extension | |
45bc21ed | 37 | * @p9_proto_2000L: 9P2000.L extension |
0fb80abd SK |
38 | */ |
39 | ||
40 | enum p9_proto_versions{ | |
4d63055f PK |
41 | p9_proto_legacy, |
42 | p9_proto_2000u, | |
43 | p9_proto_2000L, | |
0fb80abd SK |
44 | }; |
45 | ||
46 | ||
8b81ef58 EVH |
47 | /** |
48 | * enum p9_trans_status - different states of underlying transports | |
49 | * @Connected: transport is connected and healthy | |
50 | * @Disconnected: transport has been disconnected | |
51 | * @Hung: transport is connected by wedged | |
52 | * | |
53 | * This enumeration details the various states a transport | |
54 | * instatiation can be in. | |
55 | */ | |
56 | ||
57 | enum p9_trans_status { | |
58 | Connected, | |
6d96d3ab | 59 | BeginDisconnect, |
8b81ef58 EVH |
60 | Disconnected, |
61 | Hung, | |
62 | }; | |
63 | ||
fea511a6 | 64 | /** |
aca00763 | 65 | * enum p9_req_status_t - status of a request |
fea511a6 EVH |
66 | * @REQ_STATUS_IDLE: request slot unused |
67 | * @REQ_STATUS_ALLOC: request has been allocated but not sent | |
673d62cd | 68 | * @REQ_STATUS_UNSENT: request waiting to be sent |
fea511a6 | 69 | * @REQ_STATUS_SENT: request sent to server |
fea511a6 EVH |
70 | * @REQ_STATUS_RCVD: response received from server |
71 | * @REQ_STATUS_FLSHD: request has been flushed | |
673d62cd | 72 | * @REQ_STATUS_ERROR: request encountered an error on the client side |
fea511a6 EVH |
73 | * |
74 | * The @REQ_STATUS_IDLE state is used to mark a request slot as unused | |
75 | * but use is actually tracked by the idpool structure which handles tag | |
76 | * id allocation. | |
77 | * | |
78 | */ | |
79 | ||
80 | enum p9_req_status_t { | |
81 | REQ_STATUS_IDLE, | |
82 | REQ_STATUS_ALLOC, | |
673d62cd | 83 | REQ_STATUS_UNSENT, |
fea511a6 | 84 | REQ_STATUS_SENT, |
fea511a6 EVH |
85 | REQ_STATUS_RCVD, |
86 | REQ_STATUS_FLSHD, | |
87 | REQ_STATUS_ERROR, | |
88 | }; | |
89 | ||
90 | /** | |
91 | * struct p9_req_t - request slots | |
92 | * @status: status of this request slot | |
93 | * @t_err: transport error | |
51a87c55 | 94 | * @flush_tag: tag of request being flushed (for flush requests) |
fea511a6 EVH |
95 | * @wq: wait_queue for the client to block on for this request |
96 | * @tc: the request fcall structure | |
97 | * @rc: the response fcall structure | |
98 | * @aux: transport specific data (provided for trans_fd migration) | |
673d62cd | 99 | * @req_list: link for higher level objects to chain requests |
fea511a6 EVH |
100 | * |
101 | * Transport use an array to track outstanding requests | |
102 | * instead of a list. While this may incurr overhead during initial | |
103 | * allocation or expansion, it makes request lookup much easier as the | |
25985edc | 104 | * tag id is a index into an array. (We use tag+1 so that we can accommodate |
fea511a6 EVH |
105 | * the -1 tag for the T_VERSION request). |
106 | * This also has the nice effect of only having to allocate wait_queues | |
107 | * once, instead of constantly allocating and freeing them. Its possible | |
108 | * other resources could benefit from this scheme as well. | |
109 | * | |
110 | */ | |
111 | ||
112 | struct p9_req_t { | |
113 | int status; | |
114 | int t_err; | |
115 | wait_queue_head_t *wq; | |
116 | struct p9_fcall *tc; | |
117 | struct p9_fcall *rc; | |
fea511a6 | 118 | void *aux; |
673d62cd | 119 | |
673d62cd | 120 | struct list_head req_list; |
fea511a6 EVH |
121 | }; |
122 | ||
ee443996 EVH |
123 | /** |
124 | * struct p9_client - per client instance state | |
125 | * @lock: protect @fidlist | |
126 | * @msize: maximum data size negotiated by protocol | |
127 | * @dotu: extension flags negotiated by protocol | |
0fb80abd | 128 | * @proto_version: 9P protocol version to use |
ee443996 EVH |
129 | * @trans_mod: module API instantiated with this client |
130 | * @trans: tranport instance state and API | |
ee443996 EVH |
131 | * @fidpool: fid handle accounting for session |
132 | * @fidlist: List of active fid handles | |
fea511a6 EVH |
133 | * @tagpool - transaction id accounting for session |
134 | * @reqs - 2D array of requests | |
135 | * @max_tag - current maximum tag id allocated | |
50192abe | 136 | * @name - node name used as client id |
ee443996 EVH |
137 | * |
138 | * The client structure is used to keep track of various per-client | |
139 | * state that has been instantiated. | |
fea511a6 EVH |
140 | * In order to minimize per-transaction overhead we use a |
141 | * simple array to lookup requests instead of a hash table | |
142 | * or linked list. In order to support larger number of | |
143 | * transactions, we make this a 2D array, allocating new rows | |
144 | * when we need to grow the total number of the transactions. | |
145 | * | |
146 | * Each row is 256 requests and we'll support up to 256 rows for | |
147 | * a total of 64k concurrent requests per session. | |
ee443996 EVH |
148 | * |
149 | * Bugs: duplicated data and potentially unnecessary elements. | |
150 | */ | |
151 | ||
bd238fb4 LI |
152 | struct p9_client { |
153 | spinlock_t lock; /* protect client structure */ | |
ef6b0807 | 154 | unsigned int msize; |
0fb80abd | 155 | unsigned char proto_version; |
8a0dc95f | 156 | struct p9_trans_module *trans_mod; |
8b81ef58 EVH |
157 | enum p9_trans_status status; |
158 | void *trans; | |
bd238fb4 | 159 | |
c4fac910 DH |
160 | union { |
161 | struct { | |
162 | int rfd; | |
163 | int wfd; | |
164 | } fd; | |
165 | struct { | |
166 | u16 port; | |
167 | bool privport; | |
168 | ||
169 | } tcp; | |
170 | } trans_opts; | |
171 | ||
bd238fb4 LI |
172 | struct p9_idpool *fidpool; |
173 | struct list_head fidlist; | |
fea511a6 EVH |
174 | |
175 | struct p9_idpool *tagpool; | |
176 | struct p9_req_t *reqs[P9_ROW_MAXTAG]; | |
177 | int max_tag; | |
50192abe WD |
178 | |
179 | char name[__NEW_UTS_LEN + 1]; | |
bd238fb4 LI |
180 | }; |
181 | ||
ee443996 EVH |
182 | /** |
183 | * struct p9_fid - file system entity handle | |
184 | * @clnt: back pointer to instantiating &p9_client | |
185 | * @fid: numeric identifier for this handle | |
186 | * @mode: current mode of this fid (enum?) | |
187 | * @qid: the &p9_qid server identifier this handle points to | |
188 | * @iounit: the server reported maximum transaction size for this file | |
189 | * @uid: the numeric uid of the local user who owns this handle | |
3e2796a9 | 190 | * @rdir: readdir accounting structure (allocated on demand) |
ee443996 EVH |
191 | * @flist: per-client-instance fid tracking |
192 | * @dlist: per-dentry fid tracking | |
193 | * | |
194 | * TODO: This needs lots of explanation. | |
195 | */ | |
196 | ||
bd238fb4 LI |
197 | struct p9_fid { |
198 | struct p9_client *clnt; | |
199 | u32 fid; | |
200 | int mode; | |
201 | struct p9_qid qid; | |
202 | u32 iounit; | |
b4642556 | 203 | kuid_t uid; |
bd238fb4 | 204 | |
3e2796a9 EVH |
205 | void *rdir; |
206 | ||
bd238fb4 | 207 | struct list_head flist; |
c4d30967 | 208 | struct hlist_node dlist; /* list of all fids attached to a dentry */ |
bd238fb4 LI |
209 | }; |
210 | ||
7751bdb3 SK |
211 | /** |
212 | * struct p9_dirent - directory entry structure | |
213 | * @qid: The p9 server qid for this dirent | |
214 | * @d_off: offset to the next dirent | |
215 | * @d_type: type of file | |
216 | * @d_name: file name | |
217 | */ | |
218 | ||
219 | struct p9_dirent { | |
220 | struct p9_qid qid; | |
221 | u64 d_off; | |
222 | unsigned char d_type; | |
223 | char d_name[256]; | |
224 | }; | |
225 | ||
070b3656 AV |
226 | struct iov_iter; |
227 | ||
c4fac910 | 228 | int p9_show_client_options(struct seq_file *m, struct p9_client *clnt); |
bda8e775 | 229 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); |
9e8fb38e AK |
230 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, |
231 | const char *name); | |
232 | int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name, | |
233 | struct p9_fid *newdirfid, const char *new_name); | |
8a0dc95f | 234 | struct p9_client *p9_client_create(const char *dev_name, char *options); |
bd238fb4 LI |
235 | void p9_client_destroy(struct p9_client *clnt); |
236 | void p9_client_disconnect(struct p9_client *clnt); | |
6d96d3ab | 237 | void p9_client_begin_disconnect(struct p9_client *clnt); |
bd238fb4 | 238 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, |
7880b43b | 239 | const char *uname, kuid_t n_uname, const char *aname); |
b76225e2 | 240 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, |
7880b43b | 241 | const unsigned char * const *wnames, int clone); |
bd238fb4 | 242 | int p9_client_open(struct p9_fid *fid, int mode); |
7880b43b | 243 | int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, |
bd238fb4 | 244 | char *extension); |
7880b43b AV |
245 | int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, const char *newname); |
246 | int p9_client_symlink(struct p9_fid *fid, const char *name, const char *symname, | |
247 | kgid_t gid, struct p9_qid *qid); | |
248 | int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 mode, | |
f791f7c5 | 249 | kgid_t gid, struct p9_qid *qid); |
bd238fb4 | 250 | int p9_client_clunk(struct p9_fid *fid); |
b165d601 | 251 | int p9_client_fsync(struct p9_fid *fid, int datasync); |
bd238fb4 | 252 | int p9_client_remove(struct p9_fid *fid); |
48e370ff | 253 | int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags); |
e1200fe6 | 254 | int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err); |
070b3656 | 255 | int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err); |
7751bdb3 | 256 | int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset); |
348b5901 AK |
257 | int p9dirent_read(struct p9_client *clnt, char *buf, int len, |
258 | struct p9_dirent *dirent); | |
51a87c55 | 259 | struct p9_wstat *p9_client_stat(struct p9_fid *fid); |
bd238fb4 | 260 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); |
87d7845a | 261 | int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr); |
bd238fb4 | 262 | |
f0853122 SK |
263 | struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, |
264 | u64 request_mask); | |
265 | ||
7880b43b | 266 | int p9_client_mknod_dotl(struct p9_fid *oldfid, const char *name, int mode, |
f791f7c5 | 267 | dev_t rdev, kgid_t gid, struct p9_qid *); |
7880b43b | 268 | int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode, |
f791f7c5 | 269 | kgid_t gid, struct p9_qid *); |
a099027c | 270 | int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); |
1d769cd1 | 271 | int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); |
fea511a6 | 272 | struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); |
2b6e72ed | 273 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); |
fea511a6 | 274 | |
fc79d4b1 | 275 | int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); |
348b5901 | 276 | int p9stat_read(struct p9_client *, char *, int, struct p9_wstat *); |
51a87c55 EVH |
277 | void p9stat_free(struct p9_wstat *); |
278 | ||
342fee1d SK |
279 | int p9_is_proto_dotu(struct p9_client *clnt); |
280 | int p9_is_proto_dotl(struct p9_client *clnt); | |
0ef63f34 | 281 | struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *); |
eda25e46 | 282 | int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int); |
329176cc | 283 | int p9_client_readlink(struct p9_fid *fid, char **target); |
02da398b | 284 | |
bd238fb4 | 285 | #endif /* NET_9P_CLIENT_H */ |