Home | History | Annotate | Download | only in fs
      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 #include <sys/taskq.h>
     39 
     40 struct	hs_direntry {
     41 	uint_t		ext_lbn;	/* LBN of start of extent */
     42 	uint_t		ext_size;    	/* no. of data bytes in extent */
     43 	struct timeval	cdate;		/* creation date */
     44 	struct timeval	mdate;		/* last modification date */
     45 	struct timeval	adate;		/* last access date */
     46 	enum vtype	type;		/* file type */
     47 	mode_t		mode;		/* mode and type of file (UNIX) */
     48 	uint_t		nlink;		/* no. of links to file */
     49 	uid_t		uid;		/* owner's user id */
     50 	gid_t		gid;		/* owner's group id */
     51 	ino64_t		inode;		/* inode number from rrip data */
     52 	dev_t		r_dev;		/* major/minor device numbers */
     53 	uint_t		xar_prot :1;	/* 1 if protection in XAR */
     54 	uchar_t		xar_len;	/* no. of Logical blocks in XAR */
     55 	uchar_t		intlf_sz;	/* intleaving size */
     56 	uchar_t		intlf_sk;	/* intleaving skip factor */
     57 	ushort_t	sym_link_flag;	/* flags for sym link */
     58 	char		*sym_link; 	/* path of sym link for readlink() */
     59 };
     60 
     61 struct	ptable {
     62 	uchar_t	filler[7];		/* filler */
     63 	uchar_t	dname_len;		/* length of directory name */
     64 	uchar_t	dname[HS_DIR_NAMELEN+1];	/* directory name */
     65 };
     66 
     67 struct ptable_idx {
     68 	struct ptable_idx *idx_pptbl_idx; /* parent's path table index entry */
     69 	struct ptable	*idx_mptbl;	/* path table entry for myself */
     70 	ushort_t idx_nochild;		/* no. of children */
     71 	ushort_t idx_childid;		/* directory no of first child */
     72 };
     73 
     74 /*
     75  * hsnode structure:
     76  *
     77  * hs_offset, hs_ptbl_idx, base  apply to VDIR type only
     78  *
     79  * nodeid uniquely identifies an hsnode, ISO9660 means
     80  * nodeid can be very big.
     81  * For directories it is the disk address of
     82  * the data extent of the dir (the directory itself,
     83  * ".", and ".." all point to same data extent).
     84  * For non-directories, it is the disk address of the
     85  * directory entry for the file; note that this does
     86  * not permit hard links, as it assumes a single dir
     87  * entry per file.
     88  */
     89 
     90 struct  hsnode {
     91 	struct hsnode	*hs_hash;	/* next hsnode in hash list */
     92 	struct hsnode	*hs_freef;	/* next hsnode in free list */
     93 	struct hsnode	*hs_freeb;	/* previous hsnode in free list */
     94 	struct vnode	*hs_vnode;	/* the real vnode for the file */
     95 	struct hs_direntry hs_dirent;	/* the directory entry for this file */
     96 	ino64_t		hs_nodeid;	/* "inode" number for hsnode */
     97 	uint_t		hs_dir_lbn;	/* LBN of directory entry */
     98 	uint_t		hs_dir_off;	/* offset in LBN of directory entry */
     99 	struct ptable_idx	*hs_ptbl_idx;	/* path table index */
    100 	uint_t		hs_offset;	/* start offset in dir for searching */
    101 	long		hs_mapcnt;	/* mappings to file pages */
    102 	uint_t		hs_seq;		/* sequence number */
    103 	uint_t		hs_flags;	/* (see below) */
    104 	u_offset_t	hs_prev_offset; /* Last read end offset (readahead) */
    105 	int		hs_num_contig;  /* Count of contiguous reads */
    106 	int		hs_ra_bytes;    /* Bytes to readahead */
    107 	kmutex_t	hs_contents_lock;	/* protects hsnode contents */
    108 						/* 	except hs_offset */
    109 };
    110 
    111 /* hs_flags */
    112 #define	HREF	1			/* hsnode is referenced */
    113 
    114 /* hs_modes */
    115 
    116 #define	HFDIR	0040000			/* directory */
    117 #define	HFREG	0100000			/* regular file */
    118 
    119 struct  hsfid {
    120 	ushort_t	hf_len;		/* length of fid */
    121 	ushort_t	hf_dir_off;	/* offset in LBN of directory entry */
    122 	uint_t		hf_dir_lbn;	/* LBN of directory */
    123 	uint32_t	hf_ino;		/* The inode number or HS_DUMMY_INO */
    124 };
    125 
    126 
    127 /*
    128  * All of the fields in the hs_volume are read-only once they have been
    129  * initialized.
    130  */
    131 struct	hs_volume {
    132 	ulong_t		vol_size; 	/* no. of Logical blocks in Volume */
    133 	uint_t		lbn_size;	/* no. of bytes in a block */
    134 	uint_t		lbn_shift;	/* shift to convert lbn to bytes */
    135 	uint_t		lbn_secshift;	/* shift to convert lbn to sec */
    136 	uint_t		lbn_maxoffset;	/* max lbn-relative offset and mask */
    137 	uchar_t		file_struct_ver; /* version of directory structure */
    138 	uid_t		vol_uid;	/* uid of volume */
    139 	gid_t		vol_gid;	/* gid of volume */
    140 	uint_t		vol_prot;	/* protection (mode) of volume */
    141 	struct timeval	cre_date;	/* volume creation time */
    142 	struct timeval	mod_date;	/* volume modification time */
    143 	struct	hs_direntry root_dir;	/* dir entry for Root Directory */
    144 	ushort_t	ptbl_len;	/* number of bytes in Path Table */
    145 	uint_t		ptbl_lbn;	/* logical block no of Path Table */
    146 	ushort_t	vol_set_size;	/* number of CD in this vol set */
    147 	ushort_t	vol_set_seq;	/* the sequence number of this CD */
    148 	char		vol_id[32];		/* volume id in PVD */
    149 };
    150 
    151 /*
    152  * The hsnode table is no longer fixed in size but grows
    153  * and shrinks dynamically. However a cache of nodes is still maintained
    154  * for efficiency. This cache size (nhsnode) is a tunable which
    155  * is either specified in /etc/system or calculated as the number
    156  * that will fit into the number of bytes defined by HS_HSNODESPACE (below).
    157  */
    158 #define	HS_HASHSIZE	32		/* hsnode hash table size */
    159 #define	HS_HSNODESPACE	16384		/* approx. space used for hsnodes */
    160 
    161 /*
    162  * We usually use the starting extent LBA for the inode numbers of files and
    163  * directories. As this will not work for zero sized files, we assign a dummy
    164  * inode number to all zero sized files. We use the number 16 as this is the
    165  * LBA for the PVD, this number cannot be a valid starting extent LBA for a
    166  * file. In case that the node number is the HS_DUMMY_INO, we use the LBA and
    167  * offset of the directory entry of this file (which is what we used before
    168  * we started to support correct hard links).
    169  */
    170 #define	HS_DUMMY_INO	16	/* dummy inode number for empty files */
    171 
    172 /*
    173  * Hsfs I/O Scheduling parameters and data structures.
    174  * Deadline for reads is set at 5000 usec.
    175  */
    176 #define	HSFS_READ_DEADLINE 5000
    177 #define	HSFS_NORMAL 0x0
    178 
    179 /*
    180  * This structure holds information for a read request that is enqueued
    181  * for processing by the scheduling function. An AVL tree is used to
    182  * access the read requests in a sorted manner.
    183  */
    184 struct hio {
    185 	struct buf	*bp;		/* The buf for this read */
    186 	struct hio	*contig_chain;  /* Next adjacent read if any */
    187 	offset_t	io_lblkno;	/* Starting disk block of io */
    188 	u_offset_t	nblocks;	/* # disk blocks */
    189 	uint64_t	io_timestamp;	/* usec timestamp for deadline */
    190 	ksema_t		*sema;		/* Completion flag */
    191 	avl_node_t	io_offset_node; /* Avl tree requirements */
    192 	avl_node_t	io_deadline_node;
    193 };
    194 
    195 /*
    196  * This structure holds information about all the read requests issued
    197  * during a read-ahead invocation. This is then enqueued on a task-queue
    198  * for processing by a background thread that takes this read-ahead to
    199  * completion and cleans up.
    200  */
    201 struct hio_info {
    202 	struct buf	*bufs;	/* array of bufs issued for this R/A */
    203 	caddr_t		*vas;	/* The kmem_alloced chunk for the bufs */
    204 	ksema_t		*sema;	/* Semaphores used in the bufs */
    205 	uint_t		bufsused; /* # of bufs actually used */
    206 	uint_t		bufcnt;   /* Tot bufs allocated. */
    207 	struct page	*pp;	  /* The list of I/O locked pages */
    208 	struct hsfs	*fsp; /* The filesystem structure */
    209 };
    210 
    211 /*
    212  * This is per-filesystem structure that stores toplevel data structures for
    213  * the I/O scheduler.
    214  */
    215 struct hsfs_queue {
    216 	/*
    217 	 * A dummy hio holding the LBN of the last read processed. Easy
    218 	 * to use in AVL_NEXT for Circular Look behavior.
    219 	 */
    220 	struct hio	*next;
    221 
    222 	/*
    223 	 * A pre-allocated buf for issuing coalesced reads. The scheduling
    224 	 * function is mostly single threaded by necessity.
    225 	 */
    226 	struct buf	*nbuf;
    227 	kmutex_t	hsfs_queue_lock; /* Protects the AVL trees */
    228 
    229 	/*
    230 	 * Makes most of the scheduling function Single-threaded.
    231 	 */
    232 	kmutex_t	strategy_lock;
    233 	avl_tree_t	read_tree;	 /* Reads ordered by LBN */
    234 	avl_tree_t	deadline_tree;	 /* Reads ordered by timestamp */
    235 	taskq_t		*ra_task;	 /* Read-ahead Q */
    236 	int		max_ra_bytes;	 /* Max read-ahead quantum */
    237 
    238 	/* Device Max Transfer size in DEV_BSIZE */
    239 	uint_t		dev_maxtransfer;
    240 };
    241 
    242 /*
    243  * High Sierra filesystem structure.
    244  * There is one of these for each mounted High Sierra filesystem.
    245  */
    246 enum hs_vol_type {
    247 	HS_VOL_TYPE_HS = 0, HS_VOL_TYPE_ISO = 1, HS_VOL_TYPE_ISO_V2 = 2,
    248 	HS_VOL_TYPE_JOLIET = 3
    249 };
    250 #define	HSFS_MAGIC 0x03095500
    251 struct hsfs {
    252 	struct hsfs	*hsfs_next;	/* ptr to next entry in linked list */
    253 	long		hsfs_magic;	/* should be HSFS_MAGIC */
    254 	struct vfs	*hsfs_vfs;	/* vfs for this fs */
    255 	struct vnode	*hsfs_rootvp;	/* vnode for root of filesystem */
    256 	struct vnode	*hsfs_devvp;	/* device mounted on */
    257 	enum hs_vol_type hsfs_vol_type; /* see above */
    258 	struct hs_volume hsfs_vol;	/* File Structure Volume Descriptor */
    259 	struct ptable	*hsfs_ptbl;	/* pointer to incore Path Table */
    260 	int		hsfs_ptbl_size;	/* size of incore path table */
    261 	struct ptable_idx *hsfs_ptbl_idx; /* pointer to path table index */
    262 	int		hsfs_ptbl_idx_size;	/* no. of path table index */
    263 	ulong_t		hsfs_ext_impl;	/* ext. information bits */
    264 	ushort_t	hsfs_sua_off;	/* the SUA offset */
    265 	ushort_t	hsfs_namemax;	/* maximum file name length */
    266 	ushort_t	hsfs_namelen;	/* "official" max. file name length */
    267 	ulong_t		hsfs_err_flags;	/* ways in which fs is non-conformant */
    268 	char		*hsfs_fsmnt;	/* name mounted on */
    269 	ulong_t		hsfs_flags;	/* hsfs-specific mount flags */
    270 	krwlock_t	hsfs_hash_lock;	/* protect hash table & hst_nohsnode */
    271 	struct hsnode	*hsfs_hash[HS_HASHSIZE]; /* head of hash lists */
    272 	uint32_t	hsfs_nohsnode;	/* no. of allocated hsnodes */
    273 	kmutex_t	hsfs_free_lock;	/* protects free list */
    274 	struct hsnode	*hsfs_free_f;	/* first entry of free list */
    275 	struct hsnode	*hsfs_free_b;	/* last entry of free list */
    276 
    277 	/*
    278 	 * Counters exported through kstats.
    279 	 */
    280 	uint64_t	physical_read_bytes;
    281 	uint64_t	cache_read_pages;
    282 	uint64_t	readahead_bytes;
    283 	uint64_t	coalesced_bytes;
    284 	uint64_t	total_pages_requested;
    285 	kstat_t		*hsfs_kstats;
    286 
    287 	struct hsfs_queue *hqueue;	/* I/O Scheduling parameters */
    288 };
    289 
    290 /*
    291  * Error types: bit offsets into hsfs_err_flags.
    292  * Also serves as index into hsfs_error[], so must be
    293  * kept in sync with that data structure.
    294  */
    295 #define	HSFS_ERR_TRAILING_JUNK		0
    296 #define	HSFS_ERR_LOWER_CASE_NM		1
    297 #define	HSFS_ERR_BAD_ROOT_DIR		2
    298 #define	HSFS_ERR_UNSUP_TYPE		3
    299 #define	HSFS_ERR_BAD_FILE_LEN		4
    300 #define	HSFS_ERR_BAD_JOLIET_FILE_LEN	5
    301 #define	HSFS_ERR_TRUNC_JOLIET_FILE_LEN	6
    302 #define	HSFS_ERR_BAD_DIR_ENTRY		7
    303 #define	HSFS_ERR_NEG_SUA_LEN		8
    304 #define	HSFS_ERR_BAD_SUA_LEN		9
    305 
    306 #define	HSFS_HAVE_LOWER_CASE(fsp) \
    307 	((fsp)->hsfs_err_flags & (1 << HSFS_ERR_LOWER_CASE_NM))
    308 
    309 
    310 /*
    311  * File system parameter macros
    312  */
    313 #define	hs_blksize(HSFS, HSP, OFF)	/* file system block size */ \
    314 	((HSP)->hs_vn.v_flag & VROOT ? \
    315 	    ((OFF) >= \
    316 		((HSFS)->hsfs_rdirsec & ~((HSFS)->hsfs_spcl - 1))*HS_SECSIZE ?\
    317 		((HSFS)->hsfs_rdirsec & ((HSFS)->hsfs_spcl - 1))*HS_SECSIZE :\
    318 		(HSFS)->hsfs_clsize): \
    319 	    (HSFS)->hsfs_clsize)
    320 #define	hs_blkoff(OFF)		/* offset within block */ \
    321 	((OFF) & (HS_SECSIZE - 1))
    322 
    323 /*
    324  * Conversion macros
    325  */
    326 #define	VFS_TO_HSFS(VFSP)	((struct hsfs *)(VFSP)->vfs_data)
    327 #define	HSFS_TO_VFS(FSP)	((FSP)->hsfs_vfs)
    328 
    329 #define	VTOH(VP)		((struct hsnode *)(VP)->v_data)
    330 #define	HTOV(HP)		(((HP)->hs_vnode))
    331 
    332 /*
    333  * Convert between Logical Block Number and Sector Number.
    334  */
    335 #define	LBN_TO_SEC(lbn, vfsp)	((lbn)>>((struct hsfs *)((vfsp)->vfs_data))->  \
    336 				hsfs_vol.lbn_secshift)
    337 
    338 #define	SEC_TO_LBN(sec, vfsp)	((sec)<<((struct hsfs *)((vfsp)->vfs_data))->  \
    339 				hsfs_vol.lbn_secshift)
    340 
    341 #define	LBN_TO_BYTE(lbn, vfsp)	((lbn)<<((struct hsfs *)((vfsp)->vfs_data))->  \
    342 				hsfs_vol.lbn_shift)
    343 #define	BYTE_TO_LBN(boff, vfsp)	((boff)>>((struct hsfs *)((vfsp)->vfs_data))-> \
    344 				hsfs_vol.lbn_shift)
    345 
    346 #ifdef	__cplusplus
    347 }
    348 #endif
    349 
    350 #endif	/* _SYS_FS_HSFS_NODE_H */
    351