Commit | Line | Data |
---|---|---|
1f327613 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
bd238fb4 LI |
2 | /* |
3 | * include/net/9p/client.h | |
4 | * | |
5 | * 9P Client Definitions | |
6 | * | |
8a0dc95f | 7 | * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com> |
bd238fb4 | 8 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> |
bd238fb4 LI |
9 | */ |
10 | ||
11 | #ifndef NET_9P_CLIENT_H | |
12 | #define NET_9P_CLIENT_H | |
13 | ||
50192abe | 14 | #include <linux/utsname.h> |
f28cdf04 | 15 | #include <linux/idr.h> |
50192abe | 16 | |
fea511a6 EVH |
17 | /* Number of requests per row */ |
18 | #define P9_ROW_MAXTAG 255 | |
19 | ||
0fb80abd SK |
20 | /** enum p9_proto_versions - 9P protocol versions |
21 | * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u | |
22 | * @p9_proto_2000u: 9P2000.u extension | |
45bc21ed | 23 | * @p9_proto_2000L: 9P2000.L extension |
0fb80abd SK |
24 | */ |
25 | ||
26 | enum p9_proto_versions{ | |
4d63055f PK |
27 | p9_proto_legacy, |
28 | p9_proto_2000u, | |
29 | p9_proto_2000L, | |
0fb80abd SK |
30 | }; |
31 | ||
32 | ||
8b81ef58 EVH |
33 | /** |
34 | * enum p9_trans_status - different states of underlying transports | |
35 | * @Connected: transport is connected and healthy | |
36 | * @Disconnected: transport has been disconnected | |
37 | * @Hung: transport is connected by wedged | |
38 | * | |
39 | * This enumeration details the various states a transport | |
40 | * instatiation can be in. | |
41 | */ | |
42 | ||
43 | enum p9_trans_status { | |
44 | Connected, | |
6d96d3ab | 45 | BeginDisconnect, |
8b81ef58 EVH |
46 | Disconnected, |
47 | Hung, | |
48 | }; | |
49 | ||
fea511a6 | 50 | /** |
aca00763 | 51 | * enum p9_req_status_t - status of a request |
fea511a6 | 52 | * @REQ_STATUS_ALLOC: request has been allocated but not sent |
673d62cd | 53 | * @REQ_STATUS_UNSENT: request waiting to be sent |
fea511a6 | 54 | * @REQ_STATUS_SENT: request sent to server |
fea511a6 EVH |
55 | * @REQ_STATUS_RCVD: response received from server |
56 | * @REQ_STATUS_FLSHD: request has been flushed | |
673d62cd | 57 | * @REQ_STATUS_ERROR: request encountered an error on the client side |
fea511a6 EVH |
58 | */ |
59 | ||
60 | enum p9_req_status_t { | |
fea511a6 | 61 | REQ_STATUS_ALLOC, |
673d62cd | 62 | REQ_STATUS_UNSENT, |
fea511a6 | 63 | REQ_STATUS_SENT, |
fea511a6 EVH |
64 | REQ_STATUS_RCVD, |
65 | REQ_STATUS_FLSHD, | |
66 | REQ_STATUS_ERROR, | |
67 | }; | |
68 | ||
69 | /** | |
70 | * struct p9_req_t - request slots | |
71 | * @status: status of this request slot | |
72 | * @t_err: transport error | |
73 | * @wq: wait_queue for the client to block on for this request | |
74 | * @tc: the request fcall structure | |
75 | * @rc: the response fcall structure | |
673d62cd | 76 | * @req_list: link for higher level objects to chain requests |
fea511a6 | 77 | */ |
fea511a6 EVH |
78 | struct p9_req_t { |
79 | int status; | |
80 | int t_err; | |
728356de | 81 | struct kref refcount; |
2557d0c5 | 82 | wait_queue_head_t wq; |
523adb6c DM |
83 | struct p9_fcall tc; |
84 | struct p9_fcall rc; | |
673d62cd | 85 | struct list_head req_list; |
fea511a6 EVH |
86 | }; |
87 | ||
ee443996 EVH |
88 | /** |
89 | * struct p9_client - per client instance state | |
996d5b4d | 90 | * @lock: protect @fids and @reqs |
ee443996 | 91 | * @msize: maximum data size negotiated by protocol |
0fb80abd | 92 | * @proto_version: 9P protocol version to use |
ee443996 | 93 | * @trans_mod: module API instantiated with this client |
996d5b4d | 94 | * @status: connection state |
ee443996 | 95 | * @trans: tranport instance state and API |
f28cdf04 | 96 | * @fids: All active FID handles |
996d5b4d MW |
97 | * @reqs: All active requests. |
98 | * @name: node name used as client id | |
ee443996 EVH |
99 | * |
100 | * The client structure is used to keep track of various per-client | |
101 | * state that has been instantiated. | |
ee443996 | 102 | */ |
bd238fb4 | 103 | struct p9_client { |
996d5b4d | 104 | spinlock_t lock; |
ef6b0807 | 105 | unsigned int msize; |
0fb80abd | 106 | unsigned char proto_version; |
8a0dc95f | 107 | struct p9_trans_module *trans_mod; |
8b81ef58 EVH |
108 | enum p9_trans_status status; |
109 | void *trans; | |
91a76be3 | 110 | struct kmem_cache *fcall_cache; |
bd238fb4 | 111 | |
c4fac910 DH |
112 | union { |
113 | struct { | |
114 | int rfd; | |
115 | int wfd; | |
116 | } fd; | |
117 | struct { | |
118 | u16 port; | |
119 | bool privport; | |
120 | ||
121 | } tcp; | |
122 | } trans_opts; | |
123 | ||
f28cdf04 | 124 | struct idr fids; |
996d5b4d | 125 | struct idr reqs; |
50192abe WD |
126 | |
127 | char name[__NEW_UTS_LEN + 1]; | |
bd238fb4 LI |
128 | }; |
129 | ||
ee443996 EVH |
130 | /** |
131 | * struct p9_fid - file system entity handle | |
132 | * @clnt: back pointer to instantiating &p9_client | |
133 | * @fid: numeric identifier for this handle | |
134 | * @mode: current mode of this fid (enum?) | |
135 | * @qid: the &p9_qid server identifier this handle points to | |
136 | * @iounit: the server reported maximum transaction size for this file | |
137 | * @uid: the numeric uid of the local user who owns this handle | |
3e2796a9 | 138 | * @rdir: readdir accounting structure (allocated on demand) |
ee443996 EVH |
139 | * @dlist: per-dentry fid tracking |
140 | * | |
141 | * TODO: This needs lots of explanation. | |
142 | */ | |
143 | ||
bd238fb4 LI |
144 | struct p9_fid { |
145 | struct p9_client *clnt; | |
146 | u32 fid; | |
147 | int mode; | |
148 | struct p9_qid qid; | |
149 | u32 iounit; | |
b4642556 | 150 | kuid_t uid; |
bd238fb4 | 151 | |
3e2796a9 EVH |
152 | void *rdir; |
153 | ||
c4d30967 | 154 | struct hlist_node dlist; /* list of all fids attached to a dentry */ |
987a6485 | 155 | struct hlist_node ilist; |
bd238fb4 LI |
156 | }; |
157 | ||
7751bdb3 SK |
158 | /** |
159 | * struct p9_dirent - directory entry structure | |
160 | * @qid: The p9 server qid for this dirent | |
161 | * @d_off: offset to the next dirent | |
162 | * @d_type: type of file | |
163 | * @d_name: file name | |
164 | */ | |
165 | ||
166 | struct p9_dirent { | |
167 | struct p9_qid qid; | |
168 | u64 d_off; | |
169 | unsigned char d_type; | |
170 | char d_name[256]; | |
171 | }; | |
172 | ||
070b3656 AV |
173 | struct iov_iter; |
174 | ||
c4fac910 | 175 | int p9_show_client_options(struct seq_file *m, struct p9_client *clnt); |
bda8e775 | 176 | int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); |
9e8fb38e AK |
177 | int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, |
178 | const char *name); | |
179 | int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name, | |
180 | struct p9_fid *newdirfid, const char *new_name); | |
8a0dc95f | 181 | struct p9_client *p9_client_create(const char *dev_name, char *options); |
bd238fb4 LI |
182 | void p9_client_destroy(struct p9_client *clnt); |
183 | void p9_client_disconnect(struct p9_client *clnt); | |
6d96d3ab | 184 | void p9_client_begin_disconnect(struct p9_client *clnt); |
bd238fb4 | 185 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, |
7880b43b | 186 | const char *uname, kuid_t n_uname, const char *aname); |
b76225e2 | 187 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, |
7880b43b | 188 | const unsigned char * const *wnames, int clone); |
bd238fb4 | 189 | int p9_client_open(struct p9_fid *fid, int mode); |
7880b43b | 190 | int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode, |
bd238fb4 | 191 | char *extension); |
7880b43b AV |
192 | int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, const char *newname); |
193 | int p9_client_symlink(struct p9_fid *fid, const char *name, const char *symname, | |
194 | kgid_t gid, struct p9_qid *qid); | |
195 | int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 mode, | |
f791f7c5 | 196 | kgid_t gid, struct p9_qid *qid); |
bd238fb4 | 197 | int p9_client_clunk(struct p9_fid *fid); |
b165d601 | 198 | int p9_client_fsync(struct p9_fid *fid, int datasync); |
bd238fb4 | 199 | int p9_client_remove(struct p9_fid *fid); |
48e370ff | 200 | int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags); |
e1200fe6 | 201 | int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err); |
388f6966 SA |
202 | int p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, |
203 | int *err); | |
070b3656 | 204 | int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err); |
7751bdb3 | 205 | int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset); |
348b5901 AK |
206 | int p9dirent_read(struct p9_client *clnt, char *buf, int len, |
207 | struct p9_dirent *dirent); | |
51a87c55 | 208 | struct p9_wstat *p9_client_stat(struct p9_fid *fid); |
bd238fb4 | 209 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); |
87d7845a | 210 | int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr); |
bd238fb4 | 211 | |
f0853122 SK |
212 | struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, |
213 | u64 request_mask); | |
214 | ||
7880b43b | 215 | int p9_client_mknod_dotl(struct p9_fid *oldfid, const char *name, int mode, |
f791f7c5 | 216 | dev_t rdev, kgid_t gid, struct p9_qid *); |
7880b43b | 217 | int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode, |
f791f7c5 | 218 | kgid_t gid, struct p9_qid *); |
a099027c | 219 | int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); |
1d769cd1 | 220 | int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); |
523adb6c | 221 | void p9_fcall_fini(struct p9_fcall *fc); |
fea511a6 | 222 | struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); |
728356de TB |
223 | |
224 | static inline void p9_req_get(struct p9_req_t *r) | |
225 | { | |
226 | kref_get(&r->refcount); | |
227 | } | |
228 | ||
229 | static inline int p9_req_try_get(struct p9_req_t *r) | |
230 | { | |
231 | return kref_get_unless_zero(&r->refcount); | |
232 | } | |
233 | ||
234 | int p9_req_put(struct p9_req_t *r); | |
235 | ||
2b6e72ed | 236 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); |
fea511a6 | 237 | |
fc79d4b1 | 238 | int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); |
348b5901 | 239 | int p9stat_read(struct p9_client *, char *, int, struct p9_wstat *); |
51a87c55 EVH |
240 | void p9stat_free(struct p9_wstat *); |
241 | ||
342fee1d SK |
242 | int p9_is_proto_dotu(struct p9_client *clnt); |
243 | int p9_is_proto_dotl(struct p9_client *clnt); | |
0ef63f34 | 244 | struct p9_fid *p9_client_xattrwalk(struct p9_fid *, const char *, u64 *); |
eda25e46 | 245 | int p9_client_xattrcreate(struct p9_fid *, const char *, u64, int); |
329176cc | 246 | int p9_client_readlink(struct p9_fid *fid, char **target); |
02da398b | 247 | |
996d5b4d MW |
248 | int p9_client_init(void); |
249 | void p9_client_exit(void); | |
250 | ||
bd238fb4 | 251 | #endif /* NET_9P_CLIENT_H */ |