xref: /freebsd/sys/fs/p9fs/p9_client.h (revision e97ad33a89a78f55280b0485b3249ee9b907a718)
1*e97ad33aSDoug Rabson /*-
2*e97ad33aSDoug Rabson  * Copyright (c) 2017 Juniper Networks, Inc.
3*e97ad33aSDoug Rabson  * All rights reserved.
4*e97ad33aSDoug Rabson  *
5*e97ad33aSDoug Rabson  * Redistribution and use in source and binary forms, with or without
6*e97ad33aSDoug Rabson  * modification, are permitted provided that the following conditions
7*e97ad33aSDoug Rabson  * are met:
8*e97ad33aSDoug Rabson  * 1. Redistributions of source code must retain the above copyright
9*e97ad33aSDoug Rabson  *	notice, this list of conditions and the following disclaimer.
10*e97ad33aSDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
11*e97ad33aSDoug Rabson  *	notice, this list of conditions and the following disclaimer in the
12*e97ad33aSDoug Rabson  *	documentation and/or other materials provided with the distribution.
13*e97ad33aSDoug Rabson  *
14*e97ad33aSDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*e97ad33aSDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*e97ad33aSDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*e97ad33aSDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*e97ad33aSDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*e97ad33aSDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*e97ad33aSDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*e97ad33aSDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*e97ad33aSDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*e97ad33aSDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*e97ad33aSDoug Rabson  * SUCH DAMAGE.
25*e97ad33aSDoug Rabson  */
26*e97ad33aSDoug Rabson 
27*e97ad33aSDoug Rabson /* 9P client definitions */
28*e97ad33aSDoug Rabson 
29*e97ad33aSDoug Rabson #ifndef FS_P9FS_P9_CLIENT_H
30*e97ad33aSDoug Rabson #define FS_P9FS_P9_CLIENT_H
31*e97ad33aSDoug Rabson 
32*e97ad33aSDoug Rabson #include <sys/errno.h>
33*e97ad33aSDoug Rabson #include <sys/types.h>
34*e97ad33aSDoug Rabson #include <sys/_unrhdr.h>
35*e97ad33aSDoug Rabson #include <sys/lock.h>
36*e97ad33aSDoug Rabson #include <sys/mutex.h>
37*e97ad33aSDoug Rabson #include <sys/condvar.h>
38*e97ad33aSDoug Rabson #include <sys/systm.h>
39*e97ad33aSDoug Rabson #include <sys/mount.h>
40*e97ad33aSDoug Rabson #include <sys/malloc.h>
41*e97ad33aSDoug Rabson #include <sys/kernel.h>
42*e97ad33aSDoug Rabson #include <sys/proc.h>
43*e97ad33aSDoug Rabson #include <sys/dirent.h>
44*e97ad33aSDoug Rabson #include <machine/stdarg.h>
45*e97ad33aSDoug Rabson 
46*e97ad33aSDoug Rabson #include <fs/p9fs/p9_protocol.h>
47*e97ad33aSDoug Rabson 
48*e97ad33aSDoug Rabson /* 9P protocol versions */
49*e97ad33aSDoug Rabson enum p9_proto_versions {
50*e97ad33aSDoug Rabson 	p9_proto_legacy,	/* legacy version */
51*e97ad33aSDoug Rabson 	p9_proto_2000u,		/* Unix version */
52*e97ad33aSDoug Rabson 	p9_proto_2000L,		/* Linux version */
53*e97ad33aSDoug Rabson };
54*e97ad33aSDoug Rabson 
55*e97ad33aSDoug Rabson /* P9 Request exchanged between Host and Guest */
56*e97ad33aSDoug Rabson struct p9_req_t {
57*e97ad33aSDoug Rabson 	struct p9_buffer *tc;	/* request buffer */
58*e97ad33aSDoug Rabson 	struct p9_buffer *rc;	/* response buffer */
59*e97ad33aSDoug Rabson };
60*e97ad33aSDoug Rabson 
61*e97ad33aSDoug Rabson /* 9P transport status */
62*e97ad33aSDoug Rabson enum transport_status {
63*e97ad33aSDoug Rabson 	P9FS_CONNECT,		/* transport is connected */
64*e97ad33aSDoug Rabson 	P9FS_BEGIN_DISCONNECT,/* transport has begun to disconnect */
65*e97ad33aSDoug Rabson 	P9FS_DISCONNECT,	/* transport has been dosconnected */
66*e97ad33aSDoug Rabson };
67*e97ad33aSDoug Rabson 
68*e97ad33aSDoug Rabson /* This is set by QEMU so we will oblige */
69*e97ad33aSDoug Rabson #define P9FS_MTU 8192
70*e97ad33aSDoug Rabson 
71*e97ad33aSDoug Rabson /*
72*e97ad33aSDoug Rabson  * Even though we have a 8k buffer, Qemu is typically doing 8168
73*e97ad33aSDoug Rabson  * because of a HDR of 24. Use that amount for transfers so that we dont
74*e97ad33aSDoug Rabson  * drop anything.
75*e97ad33aSDoug Rabson  */
76*e97ad33aSDoug Rabson #define P9FS_IOUNIT (P9FS_MTU - 24)
77*e97ad33aSDoug Rabson #define P9FS_DIRENT_LEN 256
78*e97ad33aSDoug Rabson #define P9_NOTAG 0
79*e97ad33aSDoug Rabson 
80*e97ad33aSDoug Rabson /* Client state information */
81*e97ad33aSDoug Rabson struct p9_client {
82*e97ad33aSDoug Rabson 	struct p9_trans_module *ops;		/* module API instantiated with this client */
83*e97ad33aSDoug Rabson 	void *handle;				/* module-specific client handle */
84*e97ad33aSDoug Rabson 	struct mtx clnt_mtx;			/* mutex to lock the client */
85*e97ad33aSDoug Rabson 	struct mtx req_mtx;			/* mutex to lock the request buffer */
86*e97ad33aSDoug Rabson 	struct cv req_cv;			/* condition variable on which to wake up thread */
87*e97ad33aSDoug Rabson 	unsigned int msize;			/* maximum data size */
88*e97ad33aSDoug Rabson 	unsigned char proto_version;		/* 9P version to use */
89*e97ad33aSDoug Rabson 	struct unrhdr fidpool;			/* fid handle accounting for session */
90*e97ad33aSDoug Rabson 	struct unrhdr tagpool;			/* transaction id accounting for session */
91*e97ad33aSDoug Rabson 	enum transport_status trans_status;	/* tranport instance state */
92*e97ad33aSDoug Rabson };
93*e97ad33aSDoug Rabson 
94*e97ad33aSDoug Rabson /* The main fid structure which keeps track of the file.*/
95*e97ad33aSDoug Rabson struct p9_fid {
96*e97ad33aSDoug Rabson 	struct p9_client *clnt;	/* the instatntiating 9P client */
97*e97ad33aSDoug Rabson 	uint32_t fid;		/* numeric identifier */
98*e97ad33aSDoug Rabson 	int mode;		/* current mode of this fid */
99*e97ad33aSDoug Rabson 	struct p9_qid qid;	/* server identifier */
100*e97ad33aSDoug Rabson 	uint32_t mtu;		/* max transferrable unit at a time */
101*e97ad33aSDoug Rabson 	uid_t uid;		/* numeric uid of the local user who owns this handle */
102*e97ad33aSDoug Rabson 	int v_opens;		/* keep count on the number of opens called with this fiel handle */
103*e97ad33aSDoug Rabson 	STAILQ_ENTRY(p9_fid) fid_next;	/* points to next fid in the list */
104*e97ad33aSDoug Rabson };
105*e97ad33aSDoug Rabson 
106*e97ad33aSDoug Rabson /* Directory entry structure */
107*e97ad33aSDoug Rabson struct p9_dirent {
108*e97ad33aSDoug Rabson 	struct p9_qid qid;		/* 9P server qid for this dirent */
109*e97ad33aSDoug Rabson 	uint64_t d_off;			/* offset to the next dirent */
110*e97ad33aSDoug Rabson 	unsigned char d_type;		/* file type */
111*e97ad33aSDoug Rabson 	char d_name[P9FS_DIRENT_LEN];	/* file name */
112*e97ad33aSDoug Rabson 	int len;
113*e97ad33aSDoug Rabson };
114*e97ad33aSDoug Rabson 
115*e97ad33aSDoug Rabson void p9_init_zones(void);
116*e97ad33aSDoug Rabson void p9_destroy_zones(void);
117*e97ad33aSDoug Rabson 
118*e97ad33aSDoug Rabson /* Session and client Init Ops */
119*e97ad33aSDoug Rabson struct p9_client *p9_client_create(struct mount *mp, int *error,
120*e97ad33aSDoug Rabson     const char *mount_tag);
121*e97ad33aSDoug Rabson void p9_client_destroy(struct p9_client *clnt);
122*e97ad33aSDoug Rabson struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *fid,
123*e97ad33aSDoug Rabson     const char *uname, uid_t n_uname, const char *aname, int *error);
124*e97ad33aSDoug Rabson 
125*e97ad33aSDoug Rabson /* FILE OPS - These are individually called from the specific vop function */
126*e97ad33aSDoug Rabson 
127*e97ad33aSDoug Rabson int p9_client_open(struct p9_fid *fid, int mode);
128*e97ad33aSDoug Rabson int p9_client_close(struct p9_fid *fid);
129*e97ad33aSDoug Rabson struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwnames,
130*e97ad33aSDoug Rabson     char **wnames, int clone, int *error);
131*e97ad33aSDoug Rabson struct p9_fid *p9_fid_create(struct p9_client *clnt);
132*e97ad33aSDoug Rabson void p9_fid_destroy(struct p9_fid *fid);
133*e97ad33aSDoug Rabson uint16_t p9_tag_create(struct p9_client *clnt);
134*e97ad33aSDoug Rabson void p9_tag_destroy(struct p9_client *clnt, uint16_t tag);
135*e97ad33aSDoug Rabson int p9_client_clunk(struct p9_fid *fid);
136*e97ad33aSDoug Rabson int p9_client_version(struct p9_client *clnt);
137*e97ad33aSDoug Rabson int p9_client_readdir(struct p9_fid *fid, char *data, uint64_t offset, uint32_t count);
138*e97ad33aSDoug Rabson int p9_client_read(struct p9_fid *fid, uint64_t offset, uint32_t count, char *data);
139*e97ad33aSDoug Rabson int p9_client_write(struct p9_fid *fid, uint64_t offset, uint32_t count, char *data);
140*e97ad33aSDoug Rabson int p9_client_file_create(struct p9_fid *fid, char *name, uint32_t perm, int mode,
141*e97ad33aSDoug Rabson     char *extension);
142*e97ad33aSDoug Rabson int p9_client_remove(struct p9_fid *fid);
143*e97ad33aSDoug Rabson int p9_dirent_read(struct p9_client *clnt, char *buf, int start, int len,
144*e97ad33aSDoug Rabson     struct p9_dirent *dirent);
145*e97ad33aSDoug Rabson int p9_client_statfs(struct p9_fid *fid, struct p9_statfs *stat);
146*e97ad33aSDoug Rabson int p9_client_statread(struct p9_client *clnt, char *data, size_t len, struct p9_wstat *st);
147*e97ad33aSDoug Rabson int p9_is_proto_dotu(struct p9_client *clnt);
148*e97ad33aSDoug Rabson int p9_is_proto_dotl(struct p9_client *clnt);
149*e97ad33aSDoug Rabson void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
150*e97ad33aSDoug Rabson int p9stat_read(struct p9_client *clnt, char *data, size_t len, struct p9_wstat *st);
151*e97ad33aSDoug Rabson void p9_client_disconnect(struct p9_client *clnt);
152*e97ad33aSDoug Rabson void p9_client_begin_disconnect(struct p9_client *clnt);
153*e97ad33aSDoug Rabson int p9_create_symlink(struct p9_fid *fid, char *name, char *symtgt, gid_t gid);
154*e97ad33aSDoug Rabson int p9_create_hardlink(struct p9_fid *dfid, struct p9_fid *oldfid, char *name);
155*e97ad33aSDoug Rabson int p9_readlink(struct p9_fid *fid, char **target);
156*e97ad33aSDoug Rabson int p9_client_renameat(struct p9_fid *oldfid, char *oldname, struct p9_fid *newfid, char *newname);
157*e97ad33aSDoug Rabson int p9_client_getattr(struct p9_fid *fid, struct p9_stat_dotl *stat_dotl,
158*e97ad33aSDoug Rabson     uint64_t request_mask);
159*e97ad33aSDoug Rabson int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr);
160*e97ad33aSDoug Rabson 
161*e97ad33aSDoug Rabson int p9_buf_vwritef(struct p9_buffer *buf, int proto_version, const char *fmt,
162*e97ad33aSDoug Rabson     va_list ap);
163*e97ad33aSDoug Rabson int p9_buf_readf(struct p9_buffer *buf, int proto_version, const char *fmt, ...);
164*e97ad33aSDoug Rabson int p9_buf_prepare(struct p9_buffer *buf, int8_t type);
165*e97ad33aSDoug Rabson int p9_buf_finalize(struct p9_client *clnt, struct p9_buffer *buf);
166*e97ad33aSDoug Rabson void p9_buf_reset(struct p9_buffer *buf);
167*e97ad33aSDoug Rabson 
168*e97ad33aSDoug Rabson #endif /* FS_P9FS_P9_CLIENT_H */
169