1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Joyent, Inc.
14 */
15
16 #ifndef _LXD_H
17 #define _LXD_H
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /*
24 * lxd.h: declarations, data structures and macros for lxd (lxd devfs).
25 */
26
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/policy.h>
30 #include <sys/dirent.h>
31 #include <sys/errno.h>
32 #include <sys/kmem.h>
33 #include <sys/pathname.h>
34 #include <sys/systm.h>
35 #include <sys/var.h>
36 #include <sys/sysmacros.h>
37 #include <sys/cred.h>
38 #include <sys/priv.h>
39 #include <sys/vnode.h>
40 #include <sys/vfs.h>
41 #include <sys/statvfs.h>
42 #include <sys/cmn_err.h>
43 #include <sys/zone.h>
44 #include <sys/uio.h>
45 #include <sys/utsname.h>
46 #include <sys/atomic.h>
47 #include <vm/anon.h>
48 #include <sys/lx_types.h>
49
50 #if defined(_KERNEL)
51
52 #include <sys/lx_brand.h>
53
54 /*
55 * It's unlikely that we need to create more than 50-60 subdirs/symlinks
56 * as front files so we size the file system hash for 2x that number.
57 * The back devfs typically has ~80 nodes so this is also a comfortable size
58 * for the back hash table.
59 */
60 #define LXD_HASH_SZ 128
61
62 #define LXD_BACK_HASH(v) ((((intptr_t)(v)) >> 10) & ((LXD_HASH_SZ) - 1))
63
64 #define LXD_NM_HASH(ldn, name, hash) \
65 { \
66 char Xc, *Xcp; \
67 hash = (uint_t)(uintptr_t)(ldn) >> 8; \
68 for (Xcp = (name); (Xc = *Xcp) != 0; Xcp++) \
69 hash = (hash << 4) + hash + (uint_t)Xc; \
70 hash &= (LXD_HASH_SZ - 1); \
71 }
72
73
74 enum lxd_node_type { LXDNT_NONE, LXDNT_BACK, LXDNT_FRONT };
75
76 typedef struct lxd_dev_attr {
77 list_node_t lxda_link;
78 char lxda_name[MAXPATHLEN];
79 uid_t lxda_uid;
80 gid_t lxda_gid;
81 mode_t lxda_mode;
82 } lxd_dev_attr_t;
83
84 /*
85 * lxd per-mount data structure.
86 *
87 * All fields are protected by lxd_contents.
88 * File renames on a specific file system are protected lxdm_renamelck.
89 */
90 typedef struct lxd_mnt {
91 struct vfs *lxdm_vfsp; /* filesystem's vfs struct */
92 struct lxd_node *lxdm_rootnode; /* root lxd_node */
93 char *lxdm_mntpath; /* name of lxd mount point */
94 dev_t lxdm_dev; /* unique dev # of mounted `device' */
95 kmutex_t lxdm_contents; /* per-mount lock */
96 kmutex_t lxdm_renamelck; /* rename lock for this mount */
97 kmutex_t lxdm_attrlck; /* per-mount attr. file lock */
98 list_t lxdm_devattrs; /* list of device attr. settings */
99 uint_t lxdm_gen; /* node ID source for files */
100
101 /* protects buckets in both "dir ent" and "back" hash tables */
102 kmutex_t lxdm_hash_mutex[LXD_HASH_SZ];
103
104 /* per-mount data for "back" vnodes in the fs */
105 uint_t lxdm_back_refcnt; /* # outstanding "back" vnodes */
106 struct lxd_node *lxdm_back_htable[LXD_HASH_SZ];
107
108 /*
109 * Per-mount directory data for "front" nodes in the fs.
110 * Each front node has a directory entry but directory entries can live
111 * on either front or back nodes.
112 */
113 uint_t lxdm_dent_refcnt; /* # outstanding dir ents */
114 struct lxd_dirent *lxdm_dent_htable[LXD_HASH_SZ];
115 } lxd_mnt_t;
116
117 /*
118 * lxd_node is the file system dependent node for lxd.
119 *
120 * The node is used to represent both front and back files. For front files
121 * the node can represent either a directory or symlink.
122 */
123 typedef struct lxd_node {
124 enum lxd_node_type lxdn_type;
125
126 /* Data for "front" nodes */
127 struct lxd_node *lxdn_prev; /* lnked lst of lxd nodes */
128 struct lxd_node *lxdn_next; /* lnked lst of lxd nodes */
129 struct lxd_node *lxdn_parent; /* dir containing this node */
130 krwlock_t lxdn_rwlock; /* serialize mods/dir updates */
131 kmutex_t lxdn_tlock; /* time, flag, and nlink lock */
132
133 /* these could be in a union ala tmpfs but not really necessary */
134 uint_t lxdn_dirents; /* number of dirents */
135 struct lxd_dirent *lxdn_dir; /* dirent list */
136 char *lxdn_symlink; /* pointer to symlink */
137 struct vattr lxdn_attr; /* attributes */
138
139 /* Hash table link */
140 struct lxd_node *lxdn_hnxt; /* link in per-mount entry */
141 /* hash table */
142 vnode_t *lxdn_vnode; /* vnode for this lxd_node */
143
144 vnode_t *lxdn_real_vp; /* back file - real vnode */
145 } lxd_node_t;
146
147 /*
148 * Attributes
149 */
150 #define lxdn_mask lxdn_attr.va_mask
151 #define lxdn_mode lxdn_attr.va_mode
152 #define lxdn_uid lxdn_attr.va_uid
153 #define lxdn_gid lxdn_attr.va_gid
154 #define lxdn_fsid lxdn_attr.va_fsid
155 #define lxdn_nodeid lxdn_attr.va_nodeid
156 #define lxdn_nlink lxdn_attr.va_nlink
157 #define lxdn_size lxdn_attr.va_size
158 #define lxdn_atime lxdn_attr.va_atime
159 #define lxdn_mtime lxdn_attr.va_mtime
160 #define lxdn_ctime lxdn_attr.va_ctime
161 #define lxdn_rdev lxdn_attr.va_rdev
162 #define lxdn_blksize lxdn_attr.va_blksize
163 #define lxdn_nblocks lxdn_attr.va_nblocks
164 #define lxdn_seq lxdn_attr.va_seq
165
166 /*
167 * lx devfs conversion macros
168 */
169 #define VFSTOLXDM(vfsp) ((lxd_mnt_t *)(vfsp)->vfs_data)
170 #define VTOLXDM(vp) ((lxd_mnt_t *)(vp)->v_vfsp->vfs_data)
171 #define VTOLDN(vp) ((lxd_node_t *)(vp)->v_data)
172 #define LDNTOV(ln) ((ln)->lxdn_vnode)
173 #define ldnode_hold(ln) VN_HOLD(LDNTOV(ln))
174 #define ldnode_rele(ln) VN_RELE(LDNTOV(ln))
175
176 #define REALVP(vp) (VTOLDN(vp)->lxdn_real_vp)
177
178 /*
179 * front directories are made up of a linked list of lxd_dirent structures
180 * hanging off directory lxdn_nodes. File names are not fixed length, but are
181 * null terminated.
182 */
183 typedef struct lxd_dirent {
184 lxd_node_t *lddir_node; /* lxd node for this file */
185 struct lxd_dirent *lddir_next; /* next directory entry */
186 struct lxd_dirent *lddir_prev; /* prev directory entry */
187 uint_t lddir_offset; /* "offset" of dir entry */
188 uint_t lddir_hash; /* a hash of lddir_name */
189 struct lxd_dirent *lddir_link; /* linked via hash table */
190 lxd_node_t *lddir_parent; /* parent, dir we are in */
191 char *lddir_name; /* null terminated */
192 } lxd_dirent_t;
193
194 enum de_op { DE_CREATE, DE_MKDIR, DE_RENAME }; /* direnter ops */
195 enum dr_op { DR_REMOVE, DR_RMDIR, DR_RENAME }; /* dirremove ops */
196
197 typedef struct lxd_minor_translator {
198 char *lxd_mt_path; /* illumos minor node path */
199 minor_t lxd_mt_minor; /* illumos minor node number */
200 int lxd_mt_lx_major; /* linux major node number */
201 int lxd_mt_lx_minor; /* linux minor node number */
202 } lxd_minor_translator_t;
203
204 enum lxd_xl_tp { DTT_INVALID, DTT_LIST, DTT_CUSTOM };
205
206 #define xl_list lxd_xl_minor.lxd_xl_list
207 #define xl_custom lxd_xl_minor.lxd_xl_custom
208
209 typedef struct lxd_devt_translator {
210 char *lxd_xl_driver; /* driver name */
211 major_t lxd_xl_major; /* driver number */
212
213 enum lxd_xl_tp lxd_xl_type; /* dictates how we intrep. xl_minor */
214 union {
215 uintptr_t lxd_xl_foo; /* required to compile */
216 lxd_minor_translator_t *lxd_xl_list;
217 void (*lxd_xl_custom)(dev_t, dev_t *);
218 } lxd_xl_minor;
219 } lxd_devt_translator_t;
220
221 extern struct vnodeops *lxd_vnodeops;
222 extern lxd_devt_translator_t lxd_devt_translators[];
223
224 vnode_t *lxd_make_back_node(vnode_t *, lxd_mnt_t *);
225 void lxd_free_back_node(lxd_node_t *);
226 int lxd_dirdelete(lxd_node_t *, lxd_node_t *, char *, enum dr_op, cred_t *);
227 int lxd_direnter(lxd_mnt_t *, lxd_node_t *, char *, enum de_op, lxd_node_t *,
228 lxd_node_t *, struct vattr *, lxd_node_t **, cred_t *);
229 void lxd_dirinit(lxd_node_t *, lxd_node_t *);
230 int lxd_dirlookup(lxd_node_t *, char *, lxd_node_t **, cred_t *);
231 void lxd_dirtrunc(lxd_node_t *);
232 void lxd_node_init(lxd_mnt_t *, lxd_node_t *, vnode_t *, vattr_t *, cred_t *);
233 int lxd_naccess(void *, int, cred_t *);
234
235 void lxd_save_attrs(lxd_mnt_t *, vnode_t *);
236 void lxd_apply_db(lxd_mnt_t *);
237
238 #endif /* KERNEL */
239
240 #ifdef __cplusplus
241 }
242 #endif
243
244 #endif /* _LXD_H */