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