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>
4508905fc5SAntonio Huete Jimenez #include <sys/file.h>
46509bc517SAntonio Huete Jimenez
47*7ea34faaSzrj #ifdef MALLOC_DECLARE
48509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS);
49509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS_NODE);
50509bc517SAntonio Huete Jimenez MALLOC_DECLARE(M_DIRFS_MISC);
51*7ea34faaSzrj #endif
52509bc517SAntonio Huete Jimenez
53509bc517SAntonio Huete Jimenez #ifndef KTR_DIRFS
54509bc517SAntonio Huete Jimenez #define KTR_DIRFS KTR_ALL
55509bc517SAntonio Huete Jimenez #endif
56509bc517SAntonio Huete Jimenez
57509bc517SAntonio Huete Jimenez #define DIRFS_NOFD -1 /* No fd present */
58509bc517SAntonio Huete Jimenez
59509bc517SAntonio Huete Jimenez #define DIRFS_ROOT 0x00000001
60509bc517SAntonio Huete Jimenez #define DIRFS_PASVFD 0x00000002
6183837cefSAntonio Huete Jimenez #define DIRFS_NODE_RD 0x00000004
6283837cefSAntonio Huete Jimenez #define DIRFS_NODE_WR 0x00000008
6383837cefSAntonio Huete Jimenez #define DIRFS_NODE_EXE 0x00000010
64509bc517SAntonio Huete Jimenez
65509bc517SAntonio Huete Jimenez #define DIRFS_TXTFLG "pasvfd"
66509bc517SAntonio Huete Jimenez
67509bc517SAntonio Huete Jimenez /* Used for buffer cache operations */
68509bc517SAntonio Huete Jimenez #define BSIZE 16384
69509bc517SAntonio Huete Jimenez #define BMASK (BSIZE - 1)
70509bc517SAntonio Huete Jimenez
71509bc517SAntonio Huete Jimenez /*
72509bc517SAntonio Huete Jimenez * XXX This should be temporary. A semi-proper solution would be to expose
73509bc517SAntonio Huete Jimenez * below prototypes in the _KERNEL_VIRTUAL case.
74509bc517SAntonio Huete Jimenez */
75509bc517SAntonio Huete Jimenez extern int getdirentries(int, char *, int, long *);
76509bc517SAntonio Huete Jimenez extern int statfs(const char *, struct statfs *);
77509bc517SAntonio Huete Jimenez
78509bc517SAntonio Huete Jimenez /*
7926ec059cSAntonio Huete Jimenez * Debugging macros.
8026ec059cSAntonio Huete Jimenez *
8126ec059cSAntonio Huete Jimenez * LEVEL USED FOR
8226ec059cSAntonio Huete Jimenez *
8326ec059cSAntonio Huete Jimenez * 1 Calls to VFS operations (mount, umount, ...)
8426ec059cSAntonio Huete Jimenez * 3 Calls to VN operations (open, close, read, ...)
8526ec059cSAntonio Huete Jimenez * 5 Calls to subroutines
8626ec059cSAntonio Huete Jimenez * 9 Everything
8726ec059cSAntonio Huete Jimenez *
88509bc517SAntonio Huete Jimenez */
89509bc517SAntonio Huete Jimenez #define dbg(lvl, fmt, ...) do { \
90509bc517SAntonio Huete Jimenez debug(lvl, "%s: " fmt, __func__, ##__VA_ARGS__); \
91509bc517SAntonio Huete Jimenez } while(0)
92509bc517SAntonio Huete Jimenez
93509bc517SAntonio Huete Jimenez #define debug_node(s) do { \
9426ec059cSAntonio Huete Jimenez dbg(9, "mode=%u flags=%u dn_name=%s " \
95509bc517SAntonio Huete Jimenez "uid=%u gid=%u objtype=%u nlinks=%d " \
96509bc517SAntonio Huete Jimenez "size=%jd ctime=%ju atime=%ju mtime=%ju\n", \
97509bc517SAntonio Huete Jimenez s->dn_mode, s->dn_flags, s->dn_name, \
98509bc517SAntonio Huete Jimenez s->dn_uid, s->dn_gid, s->dn_type, \
99509bc517SAntonio Huete Jimenez s->dn_links, s->dn_size, \
100509bc517SAntonio Huete Jimenez s->dn_ctime, s->dn_atime, \
101509bc517SAntonio Huete Jimenez s->dn_mtime); \
102509bc517SAntonio Huete Jimenez } while(0)
103509bc517SAntonio Huete Jimenez
104509bc517SAntonio Huete Jimenez #define debug_node2(n) do { \
10526ec059cSAntonio Huete Jimenez dbg(9, "dnp=%p name=%s fd=%d parent=%p vnode=%p " \
106509bc517SAntonio Huete Jimenez "refcnt=%d state=%s\n", \
107509bc517SAntonio Huete Jimenez n, n->dn_name, n->dn_fd, n->dn_parent, n->dn_vnode, \
108509bc517SAntonio Huete Jimenez n->dn_refcnt, dirfs_flag2str(n)); \
109509bc517SAntonio Huete Jimenez } while(0)
110509bc517SAntonio Huete Jimenez
111509bc517SAntonio Huete Jimenez /*
112509bc517SAntonio Huete Jimenez * Locking macros
113509bc517SAntonio Huete Jimenez */
114509bc517SAntonio Huete Jimenez #define dirfs_node_islocked(n) (lockstatus(&(n)->dn_lock,curthread) == LK_EXCLUSIVE)
115509bc517SAntonio Huete Jimenez #define dirfs_node_lock(n) lockmgr(&(n)->dn_lock, LK_EXCLUSIVE|LK_RETRY)
116509bc517SAntonio Huete Jimenez #define dirfs_node_unlock(n) lockmgr(&(n)->dn_lock, LK_RELEASE)
117509bc517SAntonio Huete Jimenez #define dirfs_mount_lock(m) lockmgr(&(m)->dm_lock, LK_EXCLUSIVE|LK_RETRY)
118509bc517SAntonio Huete Jimenez #define dirfs_mount_unlock(m) lockmgr(&(m)->dm_lock, LK_RELEASE)
119509bc517SAntonio Huete Jimenez #define dirfs_mount_gettoken(m) lwkt_gettoken(&(m)->dm_token)
120509bc517SAntonio Huete Jimenez #define dirfs_mount_reltoken(m) lwkt_reltoken(&(m)->dm_token)
121509bc517SAntonio Huete Jimenez
12283837cefSAntonio Huete Jimenez /*
12383837cefSAntonio Huete Jimenez * Misc macros
12483837cefSAntonio Huete Jimenez */
125509bc517SAntonio Huete Jimenez #define dirfs_node_isroot(n) (n->dn_state & DIRFS_ROOT)
126509bc517SAntonio Huete Jimenez
127509bc517SAntonio Huete Jimenez /*
128509bc517SAntonio Huete Jimenez * Main in-memory node structure which will represent a host file when active.
129509bc517SAntonio Huete Jimenez * Upon VOP_NRESOLVE() an attempt to initialize its generic fields will be made
130509bc517SAntonio Huete Jimenez * via a fstatat(2)/lstat(2) call.
131509bc517SAntonio Huete Jimenez */
132509bc517SAntonio Huete Jimenez struct dirfs_node {
133509bc517SAntonio Huete Jimenez enum vtype dn_type; /* Node type. Same as vnode
134509bc517SAntonio Huete Jimenez type for simplicty */
135509bc517SAntonio Huete Jimenez
136509bc517SAntonio Huete Jimenez int dn_state; /* Node state flags */
137509bc517SAntonio Huete Jimenez
138509bc517SAntonio Huete Jimenez TAILQ_ENTRY(dirfs_node) dn_fdentry; /* Passive fd cache */
139509bc517SAntonio Huete Jimenez RB_ENTRY(dirfs_node) dn_rbentry; /* Inode no. lookup */
140509bc517SAntonio Huete Jimenez
141509bc517SAntonio Huete Jimenez int dn_refcnt; /* Refs from children */
142509bc517SAntonio Huete Jimenez int dn_fd; /* File des. for open(2) */
143509bc517SAntonio Huete Jimenez
144509bc517SAntonio Huete Jimenez struct dirfs_node * dn_parent; /* Pointer to parent node */
145509bc517SAntonio Huete Jimenez
146509bc517SAntonio Huete Jimenez struct vnode * dn_vnode; /* Reference to its vnode on
147509bc517SAntonio Huete Jimenez the vkernel scope */
148509bc517SAntonio Huete Jimenez char * dn_name;
149509bc517SAntonio Huete Jimenez int dn_namelen;
150509bc517SAntonio Huete Jimenez
151509bc517SAntonio Huete Jimenez struct lockf dn_advlock;
152509bc517SAntonio Huete Jimenez struct lock dn_lock;
153509bc517SAntonio Huete Jimenez
154509bc517SAntonio Huete Jimenez uint32_t dn_st_dev; /* Device number */
155509bc517SAntonio Huete Jimenez
156509bc517SAntonio Huete Jimenez /* Generic attributes */
157509bc517SAntonio Huete Jimenez ino_t dn_ino;
158509bc517SAntonio Huete Jimenez long dn_blocksize;
159509bc517SAntonio Huete Jimenez uid_t dn_uid;
160509bc517SAntonio Huete Jimenez gid_t dn_gid;
161509bc517SAntonio Huete Jimenez mode_t dn_mode;
162513a5bc4Szrj u_int dn_flags;
163509bc517SAntonio Huete Jimenez nlink_t dn_links;
164509bc517SAntonio Huete Jimenez int32_t dn_atime;
165509bc517SAntonio Huete Jimenez int32_t dn_atimensec;
166509bc517SAntonio Huete Jimenez int32_t dn_mtime;
167509bc517SAntonio Huete Jimenez int32_t dn_mtimensec;
168509bc517SAntonio Huete Jimenez int32_t dn_ctime;
169509bc517SAntonio Huete Jimenez int32_t dn_ctimensec;
170509bc517SAntonio Huete Jimenez unsigned long dn_gen;
171509bc517SAntonio Huete Jimenez off_t dn_size;
172509bc517SAntonio Huete Jimenez };
173509bc517SAntonio Huete Jimenez typedef struct dirfs_node *dirfs_node_t;
174509bc517SAntonio Huete Jimenez
175509bc517SAntonio Huete Jimenez /*
176509bc517SAntonio Huete Jimenez * In-memory dirfs mount structure. It corresponds to a mounted
177509bc517SAntonio Huete Jimenez * dirfs filesystem.
178509bc517SAntonio Huete Jimenez */
179509bc517SAntonio Huete Jimenez struct dirfs_mount {
180509bc517SAntonio Huete Jimenez RB_HEAD(, dn_rbentry) dm_inotree;
181509bc517SAntonio Huete Jimenez TAILQ_HEAD(, dirfs_node) dm_fdlist;
182509bc517SAntonio Huete Jimenez
183509bc517SAntonio Huete Jimenez struct lock dm_lock;
184509bc517SAntonio Huete Jimenez struct lwkt_token dm_token;
185509bc517SAntonio Huete Jimenez dirfs_node_t dm_root; /* Root dirfs node */
186509bc517SAntonio Huete Jimenez struct mount * dm_mount;
187509bc517SAntonio Huete Jimenez int dm_rdonly;
188509bc517SAntonio Huete Jimenez
189509bc517SAntonio Huete Jimenez int dm_fd_used; /* Opened file descriptors */
190509bc517SAntonio Huete Jimenez
19183837cefSAntonio Huete Jimenez uid_t dm_uid; /* User running the vkernel */
19283837cefSAntonio Huete Jimenez gid_t dm_gid;
19383837cefSAntonio Huete Jimenez
194509bc517SAntonio Huete Jimenez char dm_path[MAXPATHLEN];
195509bc517SAntonio Huete Jimenez };
196509bc517SAntonio Huete Jimenez typedef struct dirfs_mount *dirfs_mount_t;
197509bc517SAntonio Huete Jimenez
198509bc517SAntonio Huete Jimenez /*
199509bc517SAntonio Huete Jimenez * VFS <-> DIRFS conversion macros
200509bc517SAntonio Huete Jimenez */
201509bc517SAntonio Huete Jimenez #define VFS_TO_DIRFS(mp) ((dirfs_mount_t)((mp)->mnt_data))
202509bc517SAntonio Huete Jimenez #define DIRFS_TO_VFS(dmp) ((struct mount *)((dmp)->dm_mount))
203509bc517SAntonio Huete Jimenez #define VP_TO_NODE(vp) ((dirfs_node_t)((vp)->v_data))
204509bc517SAntonio Huete Jimenez #define NODE_TO_VP(dnp) ((dnp)->dn_vnode)
205509bc517SAntonio Huete Jimenez
206509bc517SAntonio Huete Jimenez /* Misc stuff */
207509bc517SAntonio Huete Jimenez extern int debuglvl;
208509bc517SAntonio Huete Jimenez extern int dirfs_fd_limit;
209509bc517SAntonio Huete Jimenez extern int dirfs_fd_used;
210509bc517SAntonio Huete Jimenez extern long passive_fd_list_miss;
211509bc517SAntonio Huete Jimenez extern long passive_fd_list_hits;
212509bc517SAntonio Huete Jimenez
213509bc517SAntonio Huete Jimenez extern struct vop_ops dirfs_vnode_vops;
214509bc517SAntonio Huete Jimenez
21566bce8a2SMatthew Dillon #ifdef _KERNEL
216509bc517SAntonio Huete Jimenez /*
21783837cefSAntonio Huete Jimenez * Misc functions for node operations
218509bc517SAntonio Huete Jimenez */
219509bc517SAntonio Huete Jimenez static __inline void
dirfs_node_ref(dirfs_node_t dnp)220509bc517SAntonio Huete Jimenez dirfs_node_ref(dirfs_node_t dnp)
221509bc517SAntonio Huete Jimenez {
222509bc517SAntonio Huete Jimenez atomic_add_int(&dnp->dn_refcnt, 1);
223509bc517SAntonio Huete Jimenez }
224509bc517SAntonio Huete Jimenez
225509bc517SAntonio Huete Jimenez static __inline int
dirfs_node_unref(dirfs_node_t dnp)226509bc517SAntonio Huete Jimenez dirfs_node_unref(dirfs_node_t dnp)
227509bc517SAntonio Huete Jimenez {
228509bc517SAntonio Huete Jimenez /*
229509bc517SAntonio Huete Jimenez * Returns non-zero on last unref.
230509bc517SAntonio Huete Jimenez */
231509bc517SAntonio Huete Jimenez KKASSERT(dnp->dn_refcnt > 0);
232509bc517SAntonio Huete Jimenez return (atomic_fetchadd_int(&dnp->dn_refcnt, -1) == 1);
233509bc517SAntonio Huete Jimenez }
234509bc517SAntonio Huete Jimenez
235509bc517SAntonio Huete Jimenez static __inline void
dirfs_node_setflags(dirfs_node_t dnp,int flags)236509bc517SAntonio Huete Jimenez dirfs_node_setflags(dirfs_node_t dnp, int flags)
237509bc517SAntonio Huete Jimenez {
238509bc517SAntonio Huete Jimenez atomic_set_int(&dnp->dn_state, flags);
239509bc517SAntonio Huete Jimenez }
240509bc517SAntonio Huete Jimenez
241509bc517SAntonio Huete Jimenez static __inline void
dirfs_node_clrflags(dirfs_node_t dnp,int flags)242509bc517SAntonio Huete Jimenez dirfs_node_clrflags(dirfs_node_t dnp, int flags)
243509bc517SAntonio Huete Jimenez {
244509bc517SAntonio Huete Jimenez atomic_clear_int(&dnp->dn_state, flags);
245509bc517SAntonio Huete Jimenez }
246509bc517SAntonio Huete Jimenez
24766bce8a2SMatthew Dillon #endif
248509bc517SAntonio Huete Jimenez
249509bc517SAntonio Huete Jimenez /*
250509bc517SAntonio Huete Jimenez * Prototypes
251509bc517SAntonio Huete Jimenez */
252509bc517SAntonio Huete Jimenez dirfs_node_t dirfs_node_alloc(struct mount *);
253509bc517SAntonio Huete Jimenez int dirfs_node_stat(int, const char *, dirfs_node_t);
254509bc517SAntonio Huete Jimenez int dirfs_nodetype(struct stat *);
255509bc517SAntonio Huete Jimenez void dirfs_node_setname(dirfs_node_t, const char *, int);
256509bc517SAntonio Huete Jimenez char *dirfs_node_fullpath(dirfs_mount_t, const char *);
257509bc517SAntonio Huete Jimenez int dirfs_node_free(dirfs_mount_t, dirfs_node_t);
258509bc517SAntonio Huete Jimenez void dirfs_node_drop(dirfs_mount_t dmp, dirfs_node_t dnp);
259509bc517SAntonio Huete Jimenez void dirfs_node_setpassive(dirfs_mount_t dmp, dirfs_node_t dnp, int state);
260509bc517SAntonio Huete Jimenez void dirfs_alloc_vp(struct mount *, struct vnode **, int, dirfs_node_t);
261509bc517SAntonio Huete Jimenez void dirfs_free_vp(dirfs_mount_t, dirfs_node_t);
262509bc517SAntonio Huete Jimenez int dirfs_alloc_file(dirfs_mount_t, dirfs_node_t *, dirfs_node_t,
263509bc517SAntonio Huete Jimenez struct namecache *, struct vnode **, struct vattr *, int);
264509bc517SAntonio Huete Jimenez dirfs_node_t dirfs_findfd(dirfs_mount_t dmp, dirfs_node_t cur,
265509bc517SAntonio Huete Jimenez char **pathto, char **pathfree);
266509bc517SAntonio Huete Jimenez void dirfs_dropfd(dirfs_mount_t dmp, dirfs_node_t dnp1, char *pathfree);
267509bc517SAntonio Huete Jimenez char *dirfs_node_absolute_path(dirfs_mount_t, dirfs_node_t, char **);
268509bc517SAntonio Huete Jimenez char *dirfs_node_absolute_path_plus(dirfs_mount_t, dirfs_node_t,
269509bc517SAntonio Huete Jimenez char *, char **);
270509bc517SAntonio Huete Jimenez int dirfs_open_helper(dirfs_mount_t, dirfs_node_t, int, char *);
271509bc517SAntonio Huete Jimenez int dirfs_close_helper(dirfs_node_t);
272509bc517SAntonio Huete Jimenez int dirfs_node_refcnt(dirfs_node_t);
273509bc517SAntonio Huete Jimenez char *dirfs_flag2str(dirfs_node_t);
27483837cefSAntonio Huete Jimenez int dirfs_node_getperms(dirfs_node_t, int *);
275513a5bc4Szrj int dirfs_node_chflags(dirfs_node_t, u_long, struct ucred *);
276509bc517SAntonio Huete Jimenez int dirfs_node_chtimes(dirfs_node_t);
277509bc517SAntonio Huete Jimenez int dirfs_node_chmod(dirfs_mount_t, dirfs_node_t, mode_t cur_mode);
278509bc517SAntonio Huete Jimenez int dirfs_node_chown(dirfs_mount_t, dirfs_node_t,
279509bc517SAntonio Huete Jimenez uid_t cur_uid, uid_t cur_gid, mode_t cur_mode);
280509bc517SAntonio Huete Jimenez int dirfs_node_chsize(dirfs_node_t, off_t);
281509bc517SAntonio Huete Jimenez void debug(int, const char *, ...);
282509bc517SAntonio Huete Jimenez
283509bc517SAntonio Huete Jimenez #endif /* _SYS_VFS_DIRFS_DIRFS_H_ */
284