xref: /freebsd-src/sys/fs/p9fs/p9fs.h (revision e97ad33a89a78f55280b0485b3249ee9b907a718)
1*e97ad33aSDoug Rabson /*-
2*e97ad33aSDoug Rabson  * Copyright (c) 2017-2020 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 ``AS IS'' AND ANY EXPRESS OR
15*e97ad33aSDoug Rabson  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*e97ad33aSDoug Rabson  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*e97ad33aSDoug Rabson  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18*e97ad33aSDoug Rabson  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*e97ad33aSDoug Rabson  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*e97ad33aSDoug Rabson  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*e97ad33aSDoug Rabson  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*e97ad33aSDoug Rabson  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*e97ad33aSDoug Rabson  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*e97ad33aSDoug Rabson  *
25*e97ad33aSDoug Rabson  */
26*e97ad33aSDoug Rabson 
27*e97ad33aSDoug Rabson /* This file has prototypes specific to the p9fs file system */
28*e97ad33aSDoug Rabson 
29*e97ad33aSDoug Rabson #ifndef FS_P9FS_P9FS_H
30*e97ad33aSDoug Rabson #define FS_P9FS_P9FS_H
31*e97ad33aSDoug Rabson 
32*e97ad33aSDoug Rabson struct p9fs_session;
33*e97ad33aSDoug Rabson 
34*e97ad33aSDoug Rabson /* QID: Unique identification for the file being accessed */
35*e97ad33aSDoug Rabson struct p9fs_qid {
36*e97ad33aSDoug Rabson 	uint8_t qid_mode;	/* file mode specifiying file type */
37*e97ad33aSDoug Rabson 	uint32_t qid_version;	/* version of the file */
38*e97ad33aSDoug Rabson 	uint64_t qid_path;	/* unique integer among all files in hierarchy */
39*e97ad33aSDoug Rabson };
40*e97ad33aSDoug Rabson 
41*e97ad33aSDoug Rabson /*
42*e97ad33aSDoug Rabson  * The in memory representation of the on disk inode. Save the current
43*e97ad33aSDoug Rabson  * fields to write it back later.
44*e97ad33aSDoug Rabson  */
45*e97ad33aSDoug Rabson struct p9fs_inode {
46*e97ad33aSDoug Rabson         /* Make it simple first, Add more fields later */
47*e97ad33aSDoug Rabson 	uint64_t i_size;	/* size of the inode */
48*e97ad33aSDoug Rabson 	uint16_t i_type;	/* type of inode */
49*e97ad33aSDoug Rabson 	uint32_t i_dev;		/* type of device */
50*e97ad33aSDoug Rabson 	uint32_t i_mode;	/* mode of the inode */
51*e97ad33aSDoug Rabson 	uint32_t i_atime;	/* time of last access */
52*e97ad33aSDoug Rabson 	uint32_t i_mtime;	/* time of last modification */
53*e97ad33aSDoug Rabson 	uint32_t i_ctime;	/* time of last status change */
54*e97ad33aSDoug Rabson 	uint32_t i_atime_nsec;	/* times of last access in nanoseconds resolution */
55*e97ad33aSDoug Rabson 	uint32_t i_mtime_nsec;	/* time of last modification in nanoseconds resolution */
56*e97ad33aSDoug Rabson 	uint32_t i_ctime_nsec;	/* time of last status change in nanoseconds resolution */
57*e97ad33aSDoug Rabson 	uint64_t i_length;
58*e97ad33aSDoug Rabson 	char *i_name;		/* inode name */
59*e97ad33aSDoug Rabson 	char *i_uid;		/* inode user id */
60*e97ad33aSDoug Rabson 	char *i_gid;		/* inode group id */
61*e97ad33aSDoug Rabson 	char *i_muid;
62*e97ad33aSDoug Rabson 	char *i_extension;       /* 9p2000.u extensions */
63*e97ad33aSDoug Rabson 	uid_t n_uid;            /* 9p2000.u extensions */
64*e97ad33aSDoug Rabson 	gid_t n_gid;            /* 9p2000.u extensions */
65*e97ad33aSDoug Rabson 	uid_t n_muid;           /* 9p2000.u extensions */
66*e97ad33aSDoug Rabson 	/* bookkeeping info on the client. */
67*e97ad33aSDoug Rabson 	uint16_t i_links_count;  /*number of references to the inode*/
68*e97ad33aSDoug Rabson 	uint64_t i_qid_path;    /* using inode number for reference. */
69*e97ad33aSDoug Rabson 	uint64_t i_flags;
70*e97ad33aSDoug Rabson 	uint64_t blksize;	/* block size for file system */
71*e97ad33aSDoug Rabson 	uint64_t blocks;	/* number of 512B blocks allocated */
72*e97ad33aSDoug Rabson 	uint64_t gen;		/* reserved for future use */
73*e97ad33aSDoug Rabson 	uint64_t data_version;	/* reserved for future use */
74*e97ad33aSDoug Rabson 
75*e97ad33aSDoug Rabson };
76*e97ad33aSDoug Rabson 
77*e97ad33aSDoug Rabson #define P9FS_VFID_MTX(_sc) (&(_sc)->vfid_mtx)
78*e97ad33aSDoug Rabson #define P9FS_VFID_LOCK(_sc) mtx_lock(P9FS_VFID_MTX(_sc))
79*e97ad33aSDoug Rabson #define P9FS_VFID_UNLOCK(_sc) mtx_unlock(P9FS_VFID_MTX(_sc))
80*e97ad33aSDoug Rabson #define P9FS_VFID_LOCK_INIT(_sc) mtx_init(P9FS_VFID_MTX(_sc), \
81*e97ad33aSDoug Rabson     "VFID List lock", NULL, MTX_DEF)
82*e97ad33aSDoug Rabson #define P9FS_VFID_LOCK_DESTROY(_sc) mtx_destroy(P9FS_VFID_MTX(_sc))
83*e97ad33aSDoug Rabson 
84*e97ad33aSDoug Rabson #define P9FS_VOFID_MTX(_sc) (&(_sc)->vofid_mtx)
85*e97ad33aSDoug Rabson #define P9FS_VOFID_LOCK(_sc) mtx_lock(P9FS_VOFID_MTX(_sc))
86*e97ad33aSDoug Rabson #define P9FS_VOFID_UNLOCK(_sc) mtx_unlock(P9FS_VOFID_MTX(_sc))
87*e97ad33aSDoug Rabson #define P9FS_VOFID_LOCK_INIT(_sc) mtx_init(P9FS_VOFID_MTX(_sc), \
88*e97ad33aSDoug Rabson     "VOFID List lock", NULL, MTX_DEF)
89*e97ad33aSDoug Rabson #define P9FS_VOFID_LOCK_DESTROY(_sc) mtx_destroy(P9FS_VOFID_MTX(_sc))
90*e97ad33aSDoug Rabson 
91*e97ad33aSDoug Rabson #define VFID	0x01
92*e97ad33aSDoug Rabson #define VOFID	0x02
93*e97ad33aSDoug Rabson 
94*e97ad33aSDoug Rabson /* A Plan9 node. */
95*e97ad33aSDoug Rabson struct p9fs_node {
96*e97ad33aSDoug Rabson 	STAILQ_HEAD( ,p9_fid) vfid_list;	/* vfid related to uid */
97*e97ad33aSDoug Rabson 	struct mtx vfid_mtx;			/* mutex for vfid list */
98*e97ad33aSDoug Rabson 	STAILQ_HEAD( ,p9_fid) vofid_list;	/* vofid related to uid */
99*e97ad33aSDoug Rabson 	struct mtx vofid_mtx;			/* mutex for vofid list */
100*e97ad33aSDoug Rabson 	struct p9fs_node *parent;		/* pointer to parent p9fs node */
101*e97ad33aSDoug Rabson 	struct p9fs_qid vqid;			/* the server qid, will be from the host */
102*e97ad33aSDoug Rabson 	struct vnode *v_node;			/* vnode for this fs_node. */
103*e97ad33aSDoug Rabson 	struct p9fs_inode inode;		/* in memory representation of ondisk information*/
104*e97ad33aSDoug Rabson 	struct p9fs_session *p9fs_ses;	/*  Session_ptr for this node */
105*e97ad33aSDoug Rabson 	STAILQ_ENTRY(p9fs_node) p9fs_node_next;
106*e97ad33aSDoug Rabson 	uint64_t flags;
107*e97ad33aSDoug Rabson };
108*e97ad33aSDoug Rabson 
109*e97ad33aSDoug Rabson #define P9FS_VTON(vp) ((struct p9fs_node *)(vp)->v_data)
110*e97ad33aSDoug Rabson #define P9FS_NTOV(node) ((node)->v_node)
111*e97ad33aSDoug Rabson #define	VFSTOP9(mp) ((struct p9fs_mount *)(mp)->mnt_data)
112*e97ad33aSDoug Rabson #define QEMU_DIRENTRY_SZ	25
113*e97ad33aSDoug Rabson #define P9FS_NODE_MODIFIED	0x1  /* indicating file change */
114*e97ad33aSDoug Rabson #define P9FS_ROOT		0x2  /* indicating root p9fs node */
115*e97ad33aSDoug Rabson #define P9FS_NODE_DELETED	0x4  /* indicating file or directory delete */
116*e97ad33aSDoug Rabson #define P9FS_NODE_IN_SESSION	0x8  /* p9fs_node is in the session - virt_node_list */
117*e97ad33aSDoug Rabson #define IS_ROOT(node)	(node->flags & P9FS_ROOT)
118*e97ad33aSDoug Rabson 
119*e97ad33aSDoug Rabson #define P9FS_SET_LINKS(inode) do {	\
120*e97ad33aSDoug Rabson 	(inode)->i_links_count = 1;	\
121*e97ad33aSDoug Rabson } while (0)				\
122*e97ad33aSDoug Rabson 
123*e97ad33aSDoug Rabson #define P9FS_INCR_LINKS(inode) do {	\
124*e97ad33aSDoug Rabson 	(inode)->i_links_count++;	\
125*e97ad33aSDoug Rabson } while (0)				\
126*e97ad33aSDoug Rabson 
127*e97ad33aSDoug Rabson #define P9FS_DECR_LINKS(inode) do {	\
128*e97ad33aSDoug Rabson 	(inode)->i_links_count--;	\
129*e97ad33aSDoug Rabson } while (0)				\
130*e97ad33aSDoug Rabson 
131*e97ad33aSDoug Rabson #define P9FS_CLR_LINKS(inode) do {	\
132*e97ad33aSDoug Rabson 	(inode)->i_links_count = 0;	\
133*e97ad33aSDoug Rabson } while (0)				\
134*e97ad33aSDoug Rabson 
135*e97ad33aSDoug Rabson #define P9FS_MTX(_sc) (&(_sc)->p9fs_mtx)
136*e97ad33aSDoug Rabson #define P9FS_LOCK(_sc) mtx_lock(P9FS_MTX(_sc))
137*e97ad33aSDoug Rabson #define P9FS_UNLOCK(_sc) mtx_unlock(P9FS_MTX(_sc))
138*e97ad33aSDoug Rabson #define P9FS_LOCK_INIT(_sc) mtx_init(P9FS_MTX(_sc), \
139*e97ad33aSDoug Rabson     "P9FS session chain lock", NULL, MTX_DEF)
140*e97ad33aSDoug Rabson #define P9FS_LOCK_DESTROY(_sc) mtx_destroy(P9FS_MTX(_sc))
141*e97ad33aSDoug Rabson 
142*e97ad33aSDoug Rabson /* Session structure for the FS */
143*e97ad33aSDoug Rabson struct p9fs_session {
144*e97ad33aSDoug Rabson 	unsigned char flags;				/* these flags for the session */
145*e97ad33aSDoug Rabson 	struct mount *p9fs_mount;			/* mount point */
146*e97ad33aSDoug Rabson 	struct p9fs_node rnp;				/* root p9fs node for this session */
147*e97ad33aSDoug Rabson 	uid_t uid;					/* the uid that has access */
148*e97ad33aSDoug Rabson 	const char *uname;				/* user name to mount as */
149*e97ad33aSDoug Rabson 	const char *aname;				/* name of remote file tree being mounted */
150*e97ad33aSDoug Rabson 	struct p9_client *clnt;				/* 9p client */
151*e97ad33aSDoug Rabson 	struct mtx p9fs_mtx;				/* mutex used for guarding the chain.*/
152*e97ad33aSDoug Rabson 	STAILQ_HEAD( ,p9fs_node) virt_node_list;	/* list of p9fs nodes in this session*/
153*e97ad33aSDoug Rabson 	struct p9_fid *mnt_fid;				/* to save nobody 's fid for unmounting as root user */
154*e97ad33aSDoug Rabson };
155*e97ad33aSDoug Rabson 
156*e97ad33aSDoug Rabson struct p9fs_mount {
157*e97ad33aSDoug Rabson 	struct p9fs_session p9fs_session;		/* per instance session information */
158*e97ad33aSDoug Rabson 	struct mount *p9fs_mountp;			/* mount point */
159*e97ad33aSDoug Rabson 	int mount_tag_len;				/* length of the mount tag */
160*e97ad33aSDoug Rabson 	char *mount_tag;				/* mount tag used */
161*e97ad33aSDoug Rabson };
162*e97ad33aSDoug Rabson 
163*e97ad33aSDoug Rabson /* All session flags based on 9p versions  */
164*e97ad33aSDoug Rabson enum virt_session_flags {
165*e97ad33aSDoug Rabson 	P9FS_PROTO_2000U	= 0x01,
166*e97ad33aSDoug Rabson 	P9FS_PROTO_2000L	= 0x02,
167*e97ad33aSDoug Rabson };
168*e97ad33aSDoug Rabson 
169*e97ad33aSDoug Rabson /* Session access flags */
170*e97ad33aSDoug Rabson #define P9_ACCESS_ANY		0x04	/* single attach for all users */
171*e97ad33aSDoug Rabson #define P9_ACCESS_SINGLE	0x08	/* access to only the user who mounts */
172*e97ad33aSDoug Rabson #define P9_ACCESS_USER		0x10	/* new attach established for every user */
173*e97ad33aSDoug Rabson #define P9_ACCESS_MASK	(P9_ACCESS_ANY|P9_ACCESS_SINGLE|P9_ACCESS_USER)
174*e97ad33aSDoug Rabson 
175*e97ad33aSDoug Rabson u_quad_t p9fs_round_filesize_to_bytes(uint64_t filesize, uint64_t bsize);
176*e97ad33aSDoug Rabson u_quad_t p9fs_pow2_filesize_to_bytes(uint64_t filesize, uint64_t bsize);
177*e97ad33aSDoug Rabson 
178*e97ad33aSDoug Rabson /* These are all the P9FS specific vops */
179*e97ad33aSDoug Rabson int p9fs_stat_vnode_l(void);
180*e97ad33aSDoug Rabson int p9fs_stat_vnode_dotl(struct p9_stat_dotl *st, struct vnode *vp);
181*e97ad33aSDoug Rabson int p9fs_reload_stats_dotl(struct vnode *vp, struct ucred *cred);
182*e97ad33aSDoug Rabson int p9fs_proto_dotl(struct p9fs_session *vses);
183*e97ad33aSDoug Rabson struct p9_fid *p9fs_init_session(struct mount *mp, int *error);
184*e97ad33aSDoug Rabson void p9fs_close_session(struct mount *mp);
185*e97ad33aSDoug Rabson void p9fs_prepare_to_close(struct mount *mp);
186*e97ad33aSDoug Rabson void p9fs_complete_close(struct mount *mp);
187*e97ad33aSDoug Rabson int p9fs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp);
188*e97ad33aSDoug Rabson int p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags,
189*e97ad33aSDoug Rabson     struct p9fs_node *parent, struct p9_fid *fid, struct vnode **vpp,
190*e97ad33aSDoug Rabson     char *name);
191*e97ad33aSDoug Rabson int p9fs_node_cmp(struct vnode *vp, void *arg);
192*e97ad33aSDoug Rabson void p9fs_destroy_node(struct p9fs_node **npp);
193*e97ad33aSDoug Rabson void p9fs_dispose_node(struct p9fs_node **npp);
194*e97ad33aSDoug Rabson void p9fs_cleanup(struct p9fs_node *vp);
195*e97ad33aSDoug Rabson void p9fs_fid_remove_all(struct p9fs_node *np, int leave_ofids);
196*e97ad33aSDoug Rabson void p9fs_fid_remove(struct p9fs_node *np, struct p9_fid *vfid,
197*e97ad33aSDoug Rabson     int fid_type);
198*e97ad33aSDoug Rabson void p9fs_fid_add(struct p9fs_node *np, struct p9_fid *fid,
199*e97ad33aSDoug Rabson     int fid_type);
200*e97ad33aSDoug Rabson struct p9_fid *p9fs_get_fid(struct p9_client *clnt,
201*e97ad33aSDoug Rabson     struct p9fs_node *np, struct ucred *cred, int fid_type, int mode, int *error);
202*e97ad33aSDoug Rabson 
203*e97ad33aSDoug Rabson #endif /* FS_P9FS_P9FS_H */
204