xref: /dflybsd-src/sys/vfs/dirfs/dirfs.h (revision 66bce8a2f622f39f5e46cc522aa5edb634b9895a)
1509bc517SAntonio Huete Jimenez /*
2509bc517SAntonio Huete Jimenez  * Copyright (c) 2013 The DragonFly Project.  All rights reserved.
3509bc517SAntonio Huete Jimenez  *
4509bc517SAntonio Huete Jimenez  * This code is derived from software contributed to The DragonFly Project
5509bc517SAntonio Huete Jimenez  * by Antonio Huete Jimenez <tuxillo@quantumachine.net>
6509bc517SAntonio Huete Jimenez  * by Matthew Dillon <dillon@dragonflybsd.org>
7509bc517SAntonio Huete Jimenez  *
8509bc517SAntonio Huete Jimenez  * Redistribution and use in source and binary forms, with or without
9509bc517SAntonio Huete Jimenez  * modification, are permitted provided that the following conditions
10509bc517SAntonio Huete Jimenez  * are met:
11509bc517SAntonio Huete Jimenez  *
12509bc517SAntonio Huete Jimenez  * 1. Redistributions of source code must retain the above copyright
13509bc517SAntonio Huete Jimenez  *    notice, this list of conditions and the following disclaimer.
14509bc517SAntonio Huete Jimenez  * 2. Redistributions in binary form must reproduce the above copyright
15509bc517SAntonio Huete Jimenez  *    notice, this list of conditions and the following disclaimer in
16509bc517SAntonio Huete Jimenez  *    the documentation and/or other materials provided with the
17509bc517SAntonio Huete Jimenez  *    distribution.
18509bc517SAntonio Huete Jimenez  * 3. Neither the name of The DragonFly Project nor the names of its
19509bc517SAntonio Huete Jimenez  *    contributors may be used to endorse or promote products derived
20509bc517SAntonio Huete Jimenez  *    from this software without specific, prior written permission.
21509bc517SAntonio Huete Jimenez  *
22509bc517SAntonio Huete Jimenez  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23509bc517SAntonio Huete Jimenez  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24509bc517SAntonio Huete Jimenez  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25509bc517SAntonio Huete Jimenez  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
26509bc517SAntonio Huete Jimenez  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27509bc517SAntonio Huete Jimenez  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28509bc517SAntonio Huete Jimenez  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29509bc517SAntonio Huete Jimenez  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30509bc517SAntonio Huete Jimenez  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31509bc517SAntonio Huete Jimenez  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32509bc517SAntonio Huete Jimenez  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33509bc517SAntonio Huete Jimenez  * SUCH DAMAGE.
34509bc517SAntonio Huete Jimenez  *
35509bc517SAntonio Huete Jimenez  */
36509bc517SAntonio Huete Jimenez 
37509bc517SAntonio Huete Jimenez #ifndef _SYS_VFS_DIRFS_DIRFS_H_
38509bc517SAntonio Huete Jimenez #define _SYS_VFS_DIRFS_DIRFS_H_
39509bc517SAntonio Huete Jimenez 
40509bc517SAntonio Huete Jimenez #include <unistd.h>
41509bc517SAntonio Huete Jimenez 
42509bc517SAntonio Huete Jimenez #include <sys/lockf.h>
43509bc517SAntonio Huete Jimenez #include <sys/stat.h>
44509bc517SAntonio Huete Jimenez #include <sys/vnode.h>
45509bc517SAntonio Huete Jimenez 
46509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS);
47509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS_NODE);
48509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS_MISC);
49509bc517SAntonio Huete Jimenez 
50509bc517SAntonio Huete Jimenez #ifndef KTR_DIRFS
51509bc517SAntonio Huete Jimenez #define KTR_DIRFS KTR_ALL
52509bc517SAntonio Huete Jimenez #endif
53509bc517SAntonio Huete Jimenez 
54509bc517SAntonio Huete Jimenez #define DIRFS_NOFD	-1	/* No fd present */
55509bc517SAntonio Huete Jimenez 
56509bc517SAntonio Huete Jimenez #define DIRFS_ROOT	0x00000001
57509bc517SAntonio Huete Jimenez #define DIRFS_PASVFD	0x00000002
5883837cefSAntonio Huete Jimenez #define DIRFS_NODE_RD	0x00000004
5983837cefSAntonio Huete Jimenez #define DIRFS_NODE_WR	0x00000008
6083837cefSAntonio Huete Jimenez #define DIRFS_NODE_EXE	0x00000010
61509bc517SAntonio Huete Jimenez 
62509bc517SAntonio Huete Jimenez #define DIRFS_TXTFLG "pasvfd"
63509bc517SAntonio Huete Jimenez 
64509bc517SAntonio Huete Jimenez /* Used for buffer cache operations */
65509bc517SAntonio Huete Jimenez #define BSIZE	16384
66509bc517SAntonio Huete Jimenez #define BMASK	(BSIZE - 1)
67509bc517SAntonio Huete Jimenez 
68509bc517SAntonio Huete Jimenez /*
69509bc517SAntonio Huete Jimenez  * XXX This should be temporary. A semi-proper solution would be to expose
70509bc517SAntonio Huete Jimenez  * below prototypes in the _KERNEL_VIRTUAL case.
71509bc517SAntonio Huete Jimenez  */
72509bc517SAntonio Huete Jimenez extern int getdirentries(int, char *, int, long *);
73509bc517SAntonio Huete Jimenez extern int statfs(const char *, struct statfs *);
74509bc517SAntonio Huete Jimenez 
75509bc517SAntonio Huete Jimenez /*
76509bc517SAntonio Huete Jimenez  * Debugging macros. The impact should be determined and in case it has a
77509bc517SAntonio Huete Jimenez  * considerable performance penalty, it should be enclosed in a DEBUG #ifdef.
78509bc517SAntonio Huete Jimenez  */
79509bc517SAntonio Huete Jimenez #define debug_called() do {					\
80509bc517SAntonio Huete Jimenez 		dbg(9, "called\n", __func__);			\
81509bc517SAntonio Huete Jimenez } while(0)
82509bc517SAntonio Huete Jimenez 
83509bc517SAntonio Huete Jimenez #define dbg(lvl, fmt, ...) do {					\
84509bc517SAntonio Huete Jimenez 		debug(lvl, "%s: " fmt, __func__, ##__VA_ARGS__);	\
85509bc517SAntonio Huete Jimenez } while(0)
86509bc517SAntonio Huete Jimenez 
87509bc517SAntonio Huete Jimenez #define debug_node(s) do {						\
88509bc517SAntonio Huete Jimenez 		dbg(5, "mode=%u flags=%u dn_name=%s "			\
89509bc517SAntonio Huete Jimenez 		    "uid=%u gid=%u objtype=%u nlinks=%d "		\
90509bc517SAntonio Huete Jimenez 		    "size=%jd ctime=%ju atime=%ju mtime=%ju\n",		\
91509bc517SAntonio Huete Jimenez 		    s->dn_mode, s->dn_flags, s->dn_name,		\
92509bc517SAntonio Huete Jimenez 		    s->dn_uid, s->dn_gid, s->dn_type,			\
93509bc517SAntonio Huete Jimenez 		    s->dn_links, s->dn_size,				\
94509bc517SAntonio Huete Jimenez 		    s->dn_ctime, s->dn_atime,				\
95509bc517SAntonio Huete Jimenez 		    s->dn_mtime);					\
96509bc517SAntonio Huete Jimenez } while(0)
97509bc517SAntonio Huete Jimenez 
98509bc517SAntonio Huete Jimenez #define debug_node2(n) do {						\
99509bc517SAntonio Huete Jimenez 		dbg(5, "dnp=%p name=%s fd=%d parent=%p vnode=%p "	\
100509bc517SAntonio Huete Jimenez 		    "refcnt=%d state=%s\n",				\
101509bc517SAntonio Huete Jimenez 		    n, n->dn_name, n->dn_fd, n->dn_parent, n->dn_vnode,	\
102509bc517SAntonio Huete Jimenez 		    n->dn_refcnt, dirfs_flag2str(n));			\
103509bc517SAntonio Huete Jimenez } while(0)
104509bc517SAntonio Huete Jimenez 
105509bc517SAntonio Huete Jimenez /*
106509bc517SAntonio Huete Jimenez  * Locking macros
107509bc517SAntonio Huete Jimenez  */
108509bc517SAntonio Huete Jimenez #define dirfs_node_islocked(n)	(lockstatus(&(n)->dn_lock,curthread) == LK_EXCLUSIVE)
109509bc517SAntonio Huete Jimenez #define dirfs_node_lock(n)	lockmgr(&(n)->dn_lock, LK_EXCLUSIVE|LK_RETRY)
110509bc517SAntonio Huete Jimenez #define dirfs_node_unlock(n) 	lockmgr(&(n)->dn_lock, LK_RELEASE)
111509bc517SAntonio Huete Jimenez #define dirfs_mount_lock(m)	lockmgr(&(m)->dm_lock, LK_EXCLUSIVE|LK_RETRY)
112509bc517SAntonio Huete Jimenez #define dirfs_mount_unlock(m)	lockmgr(&(m)->dm_lock, LK_RELEASE)
113509bc517SAntonio Huete Jimenez #define dirfs_mount_gettoken(m)	lwkt_gettoken(&(m)->dm_token)
114509bc517SAntonio Huete Jimenez #define dirfs_mount_reltoken(m)	lwkt_reltoken(&(m)->dm_token)
115509bc517SAntonio Huete Jimenez 
11683837cefSAntonio Huete Jimenez /*
11783837cefSAntonio Huete Jimenez  * Misc macros
11883837cefSAntonio Huete Jimenez  */
119509bc517SAntonio Huete Jimenez #define dirfs_node_isroot(n)	(n->dn_state & DIRFS_ROOT)
120509bc517SAntonio Huete Jimenez 
121509bc517SAntonio Huete Jimenez /*
122509bc517SAntonio Huete Jimenez  * Main in-memory node structure which will represent a host file when active.
123509bc517SAntonio Huete Jimenez  * Upon VOP_NRESOLVE() an attempt to initialize its generic fields will be made
124509bc517SAntonio Huete Jimenez  * via a fstatat(2)/lstat(2) call.
125509bc517SAntonio Huete Jimenez  */
126509bc517SAntonio Huete Jimenez struct dirfs_node {
127509bc517SAntonio Huete Jimenez 	enum vtype		dn_type;	/* Node type. Same as vnode
128509bc517SAntonio Huete Jimenez 						   type for simplicty */
129509bc517SAntonio Huete Jimenez 
130509bc517SAntonio Huete Jimenez 	int			dn_state;	/* Node state flags */
131509bc517SAntonio Huete Jimenez 
132509bc517SAntonio Huete Jimenez 	TAILQ_ENTRY(dirfs_node)	dn_fdentry;	/* Passive fd cache */
133509bc517SAntonio Huete Jimenez 	RB_ENTRY(dirfs_node)	dn_rbentry;	/* Inode no. lookup */
134509bc517SAntonio Huete Jimenez 
135509bc517SAntonio Huete Jimenez 	int			dn_refcnt;	/* Refs from children */
136509bc517SAntonio Huete Jimenez 	int			dn_fd;		/* File des. for open(2) */
137509bc517SAntonio Huete Jimenez 
138509bc517SAntonio Huete Jimenez 	struct dirfs_node *	dn_parent;	/* Pointer to parent node */
139509bc517SAntonio Huete Jimenez 
140509bc517SAntonio Huete Jimenez 	struct vnode *          dn_vnode;	/* Reference to its vnode on
141509bc517SAntonio Huete Jimenez 						   the vkernel scope */
142509bc517SAntonio Huete Jimenez 	char *			dn_name;
143509bc517SAntonio Huete Jimenez 	int			dn_namelen;
144509bc517SAntonio Huete Jimenez 
145509bc517SAntonio Huete Jimenez         struct lockf            dn_advlock;
146509bc517SAntonio Huete Jimenez 	struct lock		dn_lock;
147509bc517SAntonio Huete Jimenez 
148509bc517SAntonio Huete Jimenez 	uint32_t		dn_st_dev;	/* Device number */
149509bc517SAntonio Huete Jimenez 
150509bc517SAntonio Huete Jimenez 	/* Generic attributes */
151509bc517SAntonio Huete Jimenez 	ino_t			dn_ino;
152509bc517SAntonio Huete Jimenez 	long			dn_blocksize;
153509bc517SAntonio Huete Jimenez 	uid_t			dn_uid;
154509bc517SAntonio Huete Jimenez 	gid_t			dn_gid;
155509bc517SAntonio Huete Jimenez 	mode_t			dn_mode;
156509bc517SAntonio Huete Jimenez 	int			dn_flags;
157509bc517SAntonio Huete Jimenez 	nlink_t			dn_links;
158509bc517SAntonio Huete Jimenez 	int32_t			dn_atime;
159509bc517SAntonio Huete Jimenez 	int32_t			dn_atimensec;
160509bc517SAntonio Huete Jimenez 	int32_t			dn_mtime;
161509bc517SAntonio Huete Jimenez 	int32_t			dn_mtimensec;
162509bc517SAntonio Huete Jimenez 	int32_t			dn_ctime;
163509bc517SAntonio Huete Jimenez 	int32_t			dn_ctimensec;
164509bc517SAntonio Huete Jimenez 	unsigned long		dn_gen;
165509bc517SAntonio Huete Jimenez 	off_t			dn_size;
166509bc517SAntonio Huete Jimenez };
167509bc517SAntonio Huete Jimenez typedef struct dirfs_node *dirfs_node_t;
168509bc517SAntonio Huete Jimenez 
169509bc517SAntonio Huete Jimenez /*
170509bc517SAntonio Huete Jimenez  * In-memory dirfs mount structure. It corresponds to a mounted
171509bc517SAntonio Huete Jimenez  * dirfs filesystem.
172509bc517SAntonio Huete Jimenez  */
173509bc517SAntonio Huete Jimenez struct dirfs_mount {
174509bc517SAntonio Huete Jimenez 	RB_HEAD(, dn_rbentry) dm_inotree;
175509bc517SAntonio Huete Jimenez 	TAILQ_HEAD(, dirfs_node) dm_fdlist;
176509bc517SAntonio Huete Jimenez 
177509bc517SAntonio Huete Jimenez 	struct lock	 	dm_lock;
178509bc517SAntonio Huete Jimenez 	struct lwkt_token	dm_token;
179509bc517SAntonio Huete Jimenez 	dirfs_node_t		dm_root;	/* Root dirfs node */
180509bc517SAntonio Huete Jimenez 	struct mount *		dm_mount;
181509bc517SAntonio Huete Jimenez 	int			dm_rdonly;
182509bc517SAntonio Huete Jimenez 
183509bc517SAntonio Huete Jimenez 	int			dm_fd_used;	/* Opened file descriptors */
184509bc517SAntonio Huete Jimenez 
18583837cefSAntonio Huete Jimenez 	uid_t			dm_uid;	/* User running the vkernel */
18683837cefSAntonio Huete Jimenez 	gid_t			dm_gid;
18783837cefSAntonio Huete Jimenez 
188509bc517SAntonio Huete Jimenez 	char			dm_path[MAXPATHLEN];
189509bc517SAntonio Huete Jimenez };
190509bc517SAntonio Huete Jimenez typedef struct dirfs_mount *dirfs_mount_t;
191509bc517SAntonio Huete Jimenez 
192509bc517SAntonio Huete Jimenez /*
193509bc517SAntonio Huete Jimenez  * VFS <-> DIRFS conversion macros
194509bc517SAntonio Huete Jimenez  */
195509bc517SAntonio Huete Jimenez #define VFS_TO_DIRFS(mp)	((dirfs_mount_t)((mp)->mnt_data))
196509bc517SAntonio Huete Jimenez #define DIRFS_TO_VFS(dmp)	((struct mount *)((dmp)->dm_mount))
197509bc517SAntonio Huete Jimenez #define VP_TO_NODE(vp)		((dirfs_node_t)((vp)->v_data))
198509bc517SAntonio Huete Jimenez #define NODE_TO_VP(dnp)		((dnp)->dn_vnode)
199509bc517SAntonio Huete Jimenez 
200509bc517SAntonio Huete Jimenez /* Misc stuff */
201509bc517SAntonio Huete Jimenez extern int debuglvl;
202509bc517SAntonio Huete Jimenez extern int dirfs_fd_limit;
203509bc517SAntonio Huete Jimenez extern int dirfs_fd_used;
204509bc517SAntonio Huete Jimenez extern long passive_fd_list_miss;
205509bc517SAntonio Huete Jimenez extern long passive_fd_list_hits;
206509bc517SAntonio Huete Jimenez 
207509bc517SAntonio Huete Jimenez extern struct vop_ops dirfs_vnode_vops;
208509bc517SAntonio Huete Jimenez 
209*66bce8a2SMatthew Dillon #ifdef _KERNEL
210509bc517SAntonio Huete Jimenez /*
21183837cefSAntonio Huete Jimenez  * Misc functions for node operations
212509bc517SAntonio Huete Jimenez  */
213509bc517SAntonio Huete Jimenez static __inline void
214509bc517SAntonio Huete Jimenez dirfs_node_ref(dirfs_node_t dnp)
215509bc517SAntonio Huete Jimenez {
216509bc517SAntonio Huete Jimenez 	atomic_add_int(&dnp->dn_refcnt, 1);
217509bc517SAntonio Huete Jimenez }
218509bc517SAntonio Huete Jimenez 
219509bc517SAntonio Huete Jimenez static __inline int
220509bc517SAntonio Huete Jimenez dirfs_node_unref(dirfs_node_t dnp)
221509bc517SAntonio Huete Jimenez {
222509bc517SAntonio Huete Jimenez 	/*
223509bc517SAntonio Huete Jimenez 	 * Returns non-zero on last unref.
224509bc517SAntonio Huete Jimenez 	 */
225509bc517SAntonio Huete Jimenez 	KKASSERT(dnp->dn_refcnt > 0);
226509bc517SAntonio Huete Jimenez 	return (atomic_fetchadd_int(&dnp->dn_refcnt, -1) == 1);
227509bc517SAntonio Huete Jimenez }
228509bc517SAntonio Huete Jimenez 
229509bc517SAntonio Huete Jimenez static __inline void
230509bc517SAntonio Huete Jimenez dirfs_node_setflags(dirfs_node_t dnp, int flags)
231509bc517SAntonio Huete Jimenez {
232509bc517SAntonio Huete Jimenez 	atomic_set_int(&dnp->dn_state, flags);
233509bc517SAntonio Huete Jimenez }
234509bc517SAntonio Huete Jimenez 
235509bc517SAntonio Huete Jimenez static __inline void
236509bc517SAntonio Huete Jimenez dirfs_node_clrflags(dirfs_node_t dnp, int flags)
237509bc517SAntonio Huete Jimenez {
238509bc517SAntonio Huete Jimenez 	atomic_clear_int(&dnp->dn_state, flags);
239509bc517SAntonio Huete Jimenez }
240509bc517SAntonio Huete Jimenez 
241*66bce8a2SMatthew Dillon #endif
242509bc517SAntonio Huete Jimenez 
243509bc517SAntonio Huete Jimenez /*
244509bc517SAntonio Huete Jimenez  * Prototypes
245509bc517SAntonio Huete Jimenez  */
246509bc517SAntonio Huete Jimenez dirfs_node_t dirfs_node_alloc(struct mount *);
247509bc517SAntonio Huete Jimenez int dirfs_node_stat(int, const char *, dirfs_node_t);
248509bc517SAntonio Huete Jimenez int dirfs_nodetype(struct stat *);
249509bc517SAntonio Huete Jimenez void dirfs_node_setname(dirfs_node_t, const char *, int);
250509bc517SAntonio Huete Jimenez char *dirfs_node_fullpath(dirfs_mount_t, const char *);
251509bc517SAntonio Huete Jimenez int dirfs_node_free(dirfs_mount_t, dirfs_node_t);
252509bc517SAntonio Huete Jimenez void dirfs_node_drop(dirfs_mount_t dmp, dirfs_node_t dnp);
253509bc517SAntonio Huete Jimenez void dirfs_node_setpassive(dirfs_mount_t dmp, dirfs_node_t dnp, int state);
254509bc517SAntonio Huete Jimenez void dirfs_alloc_vp(struct mount *, struct vnode **, int, dirfs_node_t);
255509bc517SAntonio Huete Jimenez void dirfs_free_vp(dirfs_mount_t, dirfs_node_t);
256509bc517SAntonio Huete Jimenez int dirfs_alloc_file(dirfs_mount_t, dirfs_node_t *, dirfs_node_t,
257509bc517SAntonio Huete Jimenez     struct namecache *, struct vnode **, struct vattr *, int);
258509bc517SAntonio Huete Jimenez dirfs_node_t dirfs_findfd(dirfs_mount_t dmp, dirfs_node_t cur,
259509bc517SAntonio Huete Jimenez 			char **pathto, char **pathfree);
260509bc517SAntonio Huete Jimenez void dirfs_dropfd(dirfs_mount_t dmp, dirfs_node_t dnp1, char *pathfree);
261509bc517SAntonio Huete Jimenez char *dirfs_node_absolute_path(dirfs_mount_t, dirfs_node_t, char **);
262509bc517SAntonio Huete Jimenez char *dirfs_node_absolute_path_plus(dirfs_mount_t, dirfs_node_t,
263509bc517SAntonio Huete Jimenez 			char *, char **);
264509bc517SAntonio Huete Jimenez int dirfs_open_helper(dirfs_mount_t, dirfs_node_t, int, char *);
265509bc517SAntonio Huete Jimenez int dirfs_close_helper(dirfs_node_t);
266509bc517SAntonio Huete Jimenez int dirfs_node_refcnt(dirfs_node_t);
267509bc517SAntonio Huete Jimenez char *dirfs_flag2str(dirfs_node_t);
26883837cefSAntonio Huete Jimenez int dirfs_node_getperms(dirfs_node_t, int *);
269509bc517SAntonio Huete Jimenez int dirfs_node_chflags(dirfs_node_t, int, struct ucred *);
270509bc517SAntonio Huete Jimenez int dirfs_node_chtimes(dirfs_node_t);
271509bc517SAntonio Huete Jimenez int dirfs_node_chmod(dirfs_mount_t, dirfs_node_t, mode_t cur_mode);
272509bc517SAntonio Huete Jimenez int dirfs_node_chown(dirfs_mount_t, dirfs_node_t,
273509bc517SAntonio Huete Jimenez 			uid_t cur_uid, uid_t cur_gid, mode_t cur_mode);
274509bc517SAntonio Huete Jimenez int dirfs_node_chsize(dirfs_node_t, off_t);
275509bc517SAntonio Huete Jimenez void debug(int, const char *, ...);
276509bc517SAntonio Huete Jimenez 
277509bc517SAntonio Huete Jimenez #endif /* _SYS_VFS_DIRFS_DIRFS_H_ */
278