xref: /illumos-gate/usr/src/uts/common/sys/fs/hsfs_node.h (revision f48205be61a214698b763ff550ab9e657525104c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * High Sierra filesystem structure definitions
23  */
24 /*
25  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #ifndef	_SYS_FS_HSFS_NODE_H
30 #define	_SYS_FS_HSFS_NODE_H
31 
32 #pragma ident	"%Z%%M%	%I%	%E% SMI"
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 struct	hs_direntry {
39 	uint_t		ext_lbn;	/* LBN of start of extent */
40 	uint_t		ext_size;    	/* no. of data bytes in extent */
41 	struct timeval	cdate;		/* creation date */
42 	struct timeval	mdate;		/* last modification date */
43 	struct timeval	adate;		/* last access date */
44 	enum vtype	type;		/* file type */
45 	mode_t		mode;		/* mode and type of file (UNIX) */
46 	uint_t		nlink;		/* no. of links to file */
47 	uid_t		uid;		/* owner's user id */
48 	gid_t		gid;		/* owner's group id */
49 	ino64_t		inode;		/* inode number from rrip data */
50 	dev_t		r_dev;		/* major/minor device numbers */
51 	uint_t		xar_prot :1;	/* 1 if protection in XAR */
52 	uchar_t		xar_len;	/* no. of Logical blocks in XAR */
53 	uchar_t		intlf_sz;	/* intleaving size */
54 	uchar_t		intlf_sk;	/* intleaving skip factor */
55 	ushort_t	sym_link_flag;	/* flags for sym link */
56 	char		*sym_link; 	/* path of sym link for readlink() */
57 };
58 
59 struct	ptable {
60 	uchar_t	filler[7];		/* filler */
61 	uchar_t	dname_len;		/* length of directory name */
62 	uchar_t	dname[HS_DIR_NAMELEN+1];	/* directory name */
63 };
64 
65 struct ptable_idx {
66 	struct ptable_idx *idx_pptbl_idx; /* parent's path table index entry */
67 	struct ptable	*idx_mptbl;	/* path table entry for myself */
68 	ushort_t idx_nochild;		/* no. of children */
69 	ushort_t idx_childid;		/* directory no of first child */
70 };
71 
72 /*
73  * hsnode structure:
74  *
75  * hs_offset, hs_ptbl_idx, base  apply to VDIR type only
76  *
77  * nodeid uniquely identifies an hsnode, ISO9660 means
78  * nodeid can be very big.
79  * For directories it is the disk address of
80  * the data extent of the dir (the directory itself,
81  * ".", and ".." all point to same data extent).
82  * For non-directories, it is the disk address of the
83  * directory entry for the file; note that this does
84  * not permit hard links, as it assumes a single dir
85  * entry per file.
86  */
87 
88 struct  hsnode {
89 	struct hsnode	*hs_hash;	/* next hsnode in hash list */
90 	struct hsnode	*hs_freef;	/* next hsnode in free list */
91 	struct hsnode	*hs_freeb;	/* previous hsnode in free list */
92 	struct vnode	*hs_vnode;	/* the real vnode for the file */
93 	struct hs_direntry hs_dirent;	/* the directory entry for this file */
94 	ino64_t		hs_nodeid;	/* "inode" number for hsnode */
95 	uint_t		hs_dir_lbn;	/* LBN of directory entry */
96 	uint_t		hs_dir_off;	/* offset in LBN of directory entry */
97 	struct ptable_idx	*hs_ptbl_idx;	/* path table index */
98 	uint_t		hs_offset;	/* start offset in dir for searching */
99 	long		hs_mapcnt;	/* mappings to file pages */
100 	uint_t		hs_seq;		/* sequence number */
101 	uint_t		hs_flags;	/* (see below) */
102 	kmutex_t	hs_contents_lock;	/* protects hsnode contents */
103 						/* 	except hs_offset */
104 };
105 
106 /* hs_flags */
107 #define	HREF	1			/* hsnode is referenced */
108 
109 /* hs_modes */
110 
111 #define	HFDIR	0040000			/* directory */
112 #define	HFREG	0100000			/* regular file */
113 
114 struct  hsfid {
115 	ushort_t	hf_len;		/* length of fid */
116 	ushort_t	hf_dir_off;	/* offset in LBN of directory entry */
117 	uint_t		hf_dir_lbn;	/* LBN of directory */
118 	uint32_t	hf_ino;		/* The inode number or HS_DUMMY_INO */
119 };
120 
121 
122 /*
123  * All of the fields in the hs_volume are read-only once they have been
124  * initialized.
125  */
126 struct	hs_volume {
127 	ulong_t		vol_size; 	/* no. of Logical blocks in Volume */
128 	uint_t		lbn_size;	/* no. of bytes in a block */
129 	uint_t		lbn_shift;	/* shift to convert lbn to bytes */
130 	uint_t		lbn_secshift;	/* shift to convert lbn to sec */
131 	uint_t		lbn_maxoffset;	/* max lbn-relative offset and mask */
132 	uchar_t		file_struct_ver; /* version of directory structure */
133 	uid_t		vol_uid;	/* uid of volume */
134 	gid_t		vol_gid;	/* gid of volume */
135 	uint_t		vol_prot;	/* protection (mode) of volume */
136 	struct timeval	cre_date;	/* volume creation time */
137 	struct timeval	mod_date;	/* volume modification time */
138 	struct	hs_direntry root_dir;	/* dir entry for Root Directory */
139 	ushort_t	ptbl_len;	/* number of bytes in Path Table */
140 	uint_t		ptbl_lbn;	/* logical block no of Path Table */
141 	ushort_t	vol_set_size;	/* number of CD in this vol set */
142 	ushort_t	vol_set_seq;	/* the sequence number of this CD */
143 	char		vol_id[32];		/* volume id in PVD */
144 };
145 
146 /*
147  * The hsnode table is no longer fixed in size but grows
148  * and shrinks dynamically. However a cache of nodes is still maintained
149  * for efficiency. This cache size (nhsnode) is a tunable which
150  * is either specified in /etc/system or calculated as the number
151  * that will fit into the number of bytes defined by HS_HSNODESPACE (below).
152  */
153 #define	HS_HASHSIZE	32		/* hsnode hash table size */
154 #define	HS_HSNODESPACE	16384		/* approx. space used for hsnodes */
155 
156 /*
157  * We usually use the starting extent LBA for the inode numbers of files and
158  * directories. As this will not work for zero sized files, we assign a dummy
159  * inode number to all zero sized files. We use the number 16 as this is the
160  * LBA for the PVD, this number cannot be a valid starting extent LBA for a
161  * file. In case that the node number is the HS_DUMMY_INO, we use the LBA and
162  * offset of the directory entry of this file (which is what we used before
163  * we started to support correct hard links).
164  */
165 #define	HS_DUMMY_INO	16	/* dummy inode number for empty files */
166 
167 /*
168  * High Sierra filesystem structure.
169  * There is one of these for each mounted High Sierra filesystem.
170  */
171 enum hs_vol_type {
172 	HS_VOL_TYPE_HS = 0, HS_VOL_TYPE_ISO = 1, HS_VOL_TYPE_ISO_V2 = 2,
173 	HS_VOL_TYPE_JOLIET = 3
174 };
175 #define	HSFS_MAGIC 0x03095500
176 struct hsfs {
177 	struct hsfs	*hsfs_next;	/* ptr to next entry in linked list */
178 	long		hsfs_magic;	/* should be HSFS_MAGIC */
179 	struct vfs	*hsfs_vfs;	/* vfs for this fs */
180 	struct vnode	*hsfs_rootvp;	/* vnode for root of filesystem */
181 	struct vnode	*hsfs_devvp;	/* device mounted on */
182 	enum hs_vol_type hsfs_vol_type; /* see above */
183 	struct hs_volume hsfs_vol;	/* File Structure Volume Descriptor */
184 	struct ptable	*hsfs_ptbl;	/* pointer to incore Path Table */
185 	int		hsfs_ptbl_size;	/* size of incore path table */
186 	struct ptable_idx *hsfs_ptbl_idx; /* pointer to path table index */
187 	int		hsfs_ptbl_idx_size;	/* no. of path table index */
188 	ulong_t		hsfs_ext_impl;	/* ext. information bits */
189 	ushort_t	hsfs_sua_off;	/* the SUA offset */
190 	ushort_t	hsfs_namemax;	/* maximum file name length */
191 	ushort_t	hsfs_namelen;	/* "official" max. file name length */
192 	ulong_t		hsfs_err_flags;	/* ways in which fs is non-conformant */
193 	char		*hsfs_fsmnt;	/* name mounted on */
194 	ulong_t		hsfs_flags;	/* hsfs-specific mount flags */
195 	krwlock_t	hsfs_hash_lock;	/* protect hash table & hst_nohsnode */
196 	struct hsnode	*hsfs_hash[HS_HASHSIZE]; /* head of hash lists */
197 	uint32_t	hsfs_nohsnode;	/* no. of allocated hsnodes */
198 	kmutex_t	hsfs_free_lock;	/* protects free list */
199 	struct hsnode	*hsfs_free_f;	/* first entry of free list */
200 	struct hsnode	*hsfs_free_b;	/* last entry of free list */
201 };
202 
203 /*
204  * Error types: bit offsets into hsfs_err_flags.
205  * Also serves as index into hsfs_error[], so must be
206  * kept in sync with that data structure.
207  */
208 #define	HSFS_ERR_TRAILING_JUNK		0
209 #define	HSFS_ERR_LOWER_CASE_NM		1
210 #define	HSFS_ERR_BAD_ROOT_DIR		2
211 #define	HSFS_ERR_UNSUP_TYPE		3
212 #define	HSFS_ERR_BAD_FILE_LEN		4
213 #define	HSFS_ERR_BAD_JOLIET_FILE_LEN	5
214 #define	HSFS_ERR_TRUNC_JOLIET_FILE_LEN	6
215 #define	HSFS_ERR_BAD_DIR_ENTRY		7
216 #define	HSFS_ERR_NEG_SUA_LEN		8
217 #define	HSFS_ERR_BAD_SUA_LEN		9
218 
219 #define	HSFS_HAVE_LOWER_CASE(fsp) \
220 	((fsp)->hsfs_err_flags & (1 << HSFS_ERR_LOWER_CASE_NM))
221 
222 
223 /*
224  * File system parameter macros
225  */
226 #define	hs_blksize(HSFS, HSP, OFF)	/* file system block size */ \
227 	((HSP)->hs_vn.v_flag & VROOT ? \
228 	    ((OFF) >= \
229 		((HSFS)->hsfs_rdirsec & ~((HSFS)->hsfs_spcl - 1))*HS_SECSIZE ?\
230 		((HSFS)->hsfs_rdirsec & ((HSFS)->hsfs_spcl - 1))*HS_SECSIZE :\
231 		(HSFS)->hsfs_clsize): \
232 	    (HSFS)->hsfs_clsize)
233 #define	hs_blkoff(OFF)		/* offset within block */ \
234 	((OFF) & (HS_SECSIZE - 1))
235 
236 /*
237  * Conversion macros
238  */
239 #define	VFS_TO_HSFS(VFSP)	((struct hsfs *)(VFSP)->vfs_data)
240 #define	HSFS_TO_VFS(FSP)	((FSP)->hsfs_vfs)
241 
242 #define	VTOH(VP)		((struct hsnode *)(VP)->v_data)
243 #define	HTOV(HP)		(((HP)->hs_vnode))
244 
245 /*
246  * Convert between Logical Block Number and Sector Number.
247  */
248 #define	LBN_TO_SEC(lbn, vfsp)	((lbn)>>((struct hsfs *)((vfsp)->vfs_data))->  \
249 				hsfs_vol.lbn_secshift)
250 
251 #define	SEC_TO_LBN(sec, vfsp)	((sec)<<((struct hsfs *)((vfsp)->vfs_data))->  \
252 				hsfs_vol.lbn_secshift)
253 
254 #define	LBN_TO_BYTE(lbn, vfsp)	((lbn)<<((struct hsfs *)((vfsp)->vfs_data))->  \
255 				hsfs_vol.lbn_shift)
256 #define	BYTE_TO_LBN(boff, vfsp)	((boff)>>((struct hsfs *)((vfsp)->vfs_data))-> \
257 				hsfs_vol.lbn_shift)
258 
259 #ifdef	__cplusplus
260 }
261 #endif
262 
263 #endif	/* _SYS_FS_HSFS_NODE_H */
264