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