xref: /illumos-gate/usr/src/uts/common/sys/fs/udf_inode.h (revision b39a0235)
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  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
26 /*	All Rights Reserved */
27 
28 #ifndef	_SYS_FS_UDF_INODE_H
29 #define	_SYS_FS_UDF_INODE_H
30 
31 #include <sys/note.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 #define	SUN_IMPL_ID	"*SUN SOLARIS UDF"
38 #define	SUN_IMPL_ID_LEN	16
39 #define	SUN_OS_CLASS	4
40 #define	SUN_OS_ID	2
41 
42 /*
43  * Size of each cluster
44  * and bits to be shifted
45  */
46 #define	CLSTR_SIZE	8
47 #define	CLSTR_MASK	7
48 
49 
50 /*
51  * enums
52  */
53 enum de_op { DE_CREATE, DE_MKDIR, DE_LINK, DE_RENAME };	/* direnter ops */
54 enum dr_op { DR_REMOVE, DR_RMDIR, DR_RENAME };		/* dirremove ops */
55 
56 /*
57  * The following macros optimize certain frequently calculated
58  * quantities by using shifts and masks in place of divisions
59  * modulos and multiplications.
60  */
61 
62 #define	blkoff(udfvfsp, loc)	/* calculates (loc % udfcfs->udf_lbsize) */ \
63 		((loc) & (udfvfsp)->udf_lbmask)
64 
65 #define	lblkno(udf_vfsp, loc)	\
66 	((int32_t)((loc) / (udf_vfsp)->udf_lbsize))
67 
68 #define	fsbtodb(udf, blk)	\
69 	((blk) << udf->udf_l2d_shift)
70 
71 
72 struct udf_fid {
73 	uint16_t	udfid_len;	/* Length of data */
74 	uint16_t	udfid_prn;	/* the partition number of icb */
75 	uint32_t	udfid_icb_lbn;	/* file entry block no */
76 	uint32_t	udfid_uinq_lo;	/* uniq id to validate the vnode */
77 };
78 
79 
80 
81 
82 #define	MAXNAMLEN	255
83 
84 
85 
86 
87 struct ud_part {
88 	uint16_t	udp_flags;	/* See below */
89 	uint16_t	udp_number;	/* partition Number */
90 	uint32_t	udp_seqno;	/* to find the prevailaing desc */
91 	uint32_t	udp_access;	/* access type */
92 	uint32_t	udp_start;	/* Starting block no of partition */
93 	uint32_t	udp_length;	/* Lenght of the partition */
94 	uint32_t	udp_unall_loc;	/* unall space tbl or bitmap loc */
95 	uint32_t	udp_unall_len;	/* unall space tbl or bitmap length */
96 	uint32_t	udp_freed_loc;	/* freed space tbl or bitmap loc */
97 	uint32_t	udp_freed_len;	/* freed space tbl or bitmap length */
98 					/* From part desc */
99 
100 	uint32_t	udp_nfree;	/* No of free blocks in the partition */
101 	uint32_t	udp_nblocks;	/* Total no of blks in the partition */
102 					/* From lvid */
103 	uint32_t	udp_last_alloc;	/* Last allocated space in bitmap */
104 
105 	int32_t		udp_cache_count;	/* Cache is used for metadata */
106 	daddr_t		udp_cache[CLSTR_SIZE];
107 };
108 
109 /*
110  * udp_flags
111  */
112 #define	UDP_BITMAPS	0x00
113 #define	UDP_SPACETBLS	0x01
114 
115 /*
116  * udp_access
117  */
118 #define	UDP_MT_RO	0x0001		/* ROM */
119 #define	UDP_MT_WO	0x0002		/* WORM */
120 #define	UDP_MT_RW	0x0003		/* RW */
121 #define	UDP_MT_OW	0x0004		/* OW */
122 
123 
124 
125 #define	MAX_SPM		4
126 
127 struct ud_map {
128 	uint32_t	udm_flags;	/* Flags */
129 	uint16_t	udm_vsn;	/* Volume Sequence Number */
130 	uint16_t	udm_pn;		/* Partition Number */
131 	uint32_t	udm_vat_icb;	/* VAT ICB location */
132 	uint32_t	udm_nent;	/* Number of vat entries */
133 	uint32_t	*udm_count;	/* Number of entrues in each table */
134 	struct buf	**udm_bp;	/* VAT translation tables */
135 	uint32_t	**udm_addr;
136 
137 
138 	int32_t		udm_plen;
139 	int32_t		udm_nspm;
140 	uint32_t	udm_spsz;
141 	uint32_t	udm_loc[MAX_SPM];
142 	struct buf	*udm_sbp[MAX_SPM];
143 	caddr_t		udm_spaddr[MAX_SPM];
144 };
145 
146 /*
147  * udm_flags
148  */
149 #define	UDM_MAP_NORM	0x00
150 #define	UDM_MAP_VPM	0x01
151 #define	UDM_MAP_SPM	0x02
152 
153 struct udf_vfs {
154 	struct vfs	*udf_vfs;	/* Back link */
155 	struct udf_vfs	*udf_next;	/* Chain of udf file-system's */
156 	struct udf_vfs	*udf_wnext;	/* work list link */
157 
158 	struct buf	*udf_vds;	/* most of the superblock */
159 	struct buf	*udf_iseq;	/* Integrity of the fs */
160 	struct vnode	*udf_root;	/* Root vnode */
161 	struct vnode	*udf_devvp;	/* Block device vnode */
162 
163 	char		*udf_fsmnt;	/* Path name of directory mouted on */
164 	uint32_t	udf_flags;	/* Flags */
165 	uint32_t	udf_mtype;	/* Media type */
166 
167 	int32_t		udf_rdclustsz;	/* read cluster size */
168 	int32_t		udf_wrclustsz;	/* write cluster size */
169 
170 	uint64_t	udf_maxfsize;	/* Max file size allowed in this fs */
171 	int32_t		udf_maxfbits;	/* No of bit's for max file size */
172 
173 	char		udf_volid[32];	/* volume identifier */
174 					/* from pvd */
175 	uint16_t	udf_tsno;	/* Taken from pvd and */
176 					/* used in making tags */
177 
178 	int32_t		udf_lbsize;	/* Block size */
179 					/* from lvd */
180 	int32_t		udf_lbmask;	/* udf_lbsize - 1 */
181 	int32_t		udf_l2b_shift;	/* lbsize to bytes */
182 	int32_t		udf_l2d_shift;	/* right shift's to */
183 					/* make lbsize to DEV_BSIZE */
184 
185 	int32_t		udf_npart;	/* No. of partition's in the volume */
186 					/* restricted to 1 till udf 1.50 */
187 	struct ud_part	*udf_parts;	/* pointer to array of partitions */
188 					/* from part desc's */
189 
190 	int32_t		udf_nmaps;
191 	struct ud_map	*udf_maps;
192 
193 	int32_t		udf_fragmented;	/* File System fragmented */
194 	int32_t		udf_mark_bad;	/* force fsck at next mount */
195 
196 	/*
197 	 * sum of udp_nfree and udp_nblocks
198 	 * from the array udf_parts[0] to udf_parts[udf_nparts - 1]
199 	 */
200 	uint32_t	udf_freeblks;	/* Total udf_lbsize Free Blocks */
201 	uint32_t	udf_totalblks;	/* Total number of Blocks */
202 				/* udf_parts[0].udp_nfree == udf_freespace */
203 				/* till udf 1.50 (DVD-R?) */
204 	uint64_t	udf_maxuniq;	/* Maximum unique ID on the fs */
205 	uint32_t	udf_nfiles;	/* No of files */
206 	uint32_t	udf_ndirs;	/* No of directories */
207 	uint32_t	udf_miread;	/* minimum read revision */
208 	uint32_t	udf_miwrite;	/* minimum write revision */
209 	uint32_t	udf_mawrite;	/* maximum read revision */
210 					/* from lvid */
211 
212 	time_t		udf_time;	/* Last time super block is written */
213 	uint32_t	udf_mod;	/* file system was modified */
214 	uint32_t	udf_clean;	/* state of the file system */
215 	kmutex_t	udf_lock;	/* protects contents */
216 
217 	kmutex_t	udf_rename_lck;	/* lock for udf_rename */
218 
219 	/*
220 	 * Have them cached here for fast access
221 	 */
222 	struct pri_vol_desc	*udf_pvd;
223 	struct log_vol_desc	*udf_lvd;
224 	struct log_vol_int_desc *udf_lvid;
225 
226 	uint32_t		udf_mvds_loc;
227 	uint32_t		udf_mvds_len;
228 
229 	uint32_t		udf_rvds_loc;
230 	uint32_t		udf_rvds_len;
231 
232 	uint32_t		udf_iseq_loc;
233 	uint32_t		udf_iseq_len;
234 
235 	uint16_t		udf_fsd_prn;
236 	uint32_t		udf_fsd_loc;
237 	uint32_t		udf_fsd_len;
238 
239 	uint16_t		udf_ricb_prn;
240 	uint32_t		udf_ricb_loc;
241 	uint32_t		udf_ricb_len;
242 	daddr_t			udf_root_blkno;
243 };
244 
245 
246 #ifndef	__lint
247 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs::udf_lock,
248 		udf_vfs::udf_fragmented))
249 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs::udf_lock,
250 		udf_vfs::udf_freeblks udf_vfs::udf_totalblks))
251 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs::udf_lock,
252 		udf_vfs::udf_maxuniq udf_vfs::udf_nfiles
253 		udf_vfs::udf_ndirs))
254 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs::udf_lock,
255 		udf_vfs::udf_time
256 		udf_vfs::udf_mod udf_vfs::udf_clean))
257 
258 _NOTE(READ_ONLY_DATA(udf_vfs::udf_nmaps udf_vfs::udf_maps))
259 
260 _NOTE(READ_ONLY_DATA(udf_vfs::udf_mtype
261 		udf_vfs::udf_rdclustsz
262 		udf_vfs::udf_wrclustsz
263 		udf_vfs::udf_maxfsize
264 		udf_vfs::udf_maxfbits
265 		udf_vfs::udf_lbsize
266 		udf_vfs::udf_l2b_shift
267 		udf_vfs::udf_lbmask
268 		udf_vfs::udf_l2d_shift))
269 
270 _NOTE(READ_ONLY_DATA(udf_vfs::udf_pvd
271 		udf_vfs::udf_lvd
272 		udf_vfs::udf_lvid))
273 
274 _NOTE(READ_ONLY_DATA(udf_vfs::udf_mvds_loc
275 		udf_vfs::udf_mvds_len
276 		udf_vfs::udf_iseq_loc
277 		udf_vfs::udf_iseq_len
278 		udf_vfs::udf_fsd_prn
279 		udf_vfs::udf_fsd_loc
280 		udf_vfs::udf_fsd_len
281 		udf_vfs::udf_ricb_prn
282 		udf_vfs::udf_ricb_loc
283 		udf_vfs::udf_ricb_len
284 		udf_vfs::udf_root_blkno))
285 
286 _NOTE(READ_ONLY_DATA(ud_part::udp_flags
287 		ud_part::udp_number
288 		ud_part::udp_seqno
289 		ud_part::udp_access
290 		ud_part::udp_start
291 		ud_part::udp_length
292 		ud_part::udp_unall_loc
293 		ud_part::udp_unall_len
294 		ud_part::udp_freed_loc
295 		ud_part::udp_freed_len
296 		ud_part::udp_nblocks))
297 
298 _NOTE(MUTEX_PROTECTS_DATA(udf_vfs::udf_lock,
299 		ud_part::udp_nfree
300 		ud_part::udp_last_alloc
301 		ud_part::udp_cache_count
302 		ud_part::udp_cache))
303 #endif
304 
305 /*
306  * udf_mtype
307  */
308 #define	UDF_MT_RO	UDP_MT_RO		/* ROM */
309 #define	UDF_MT_WO	UDP_MT_OW		/* WORM */
310 #define	UDF_MT_RW	UDP_MT_RW		/* RW */
311 #define	UDF_MT_OW	UDP_MT_OW		/* OW */
312 
313 /*
314  * udf_flags
315  */
316 #define	UDF_FL_RDONLY	0x0001		/* file system is read only */
317 #define	UDF_FL_RW	0x0002		/* file system is read write */
318 
319 /*
320  * udf_clean
321  */
322 #define	UDF_DIRTY	0x00
323 #define	UDF_CLEAN	0x01
324 
325 
326 #define	RD_CLUSTSZ(ip)		((ip)->i_udf->udf_rdclustsz)
327 #define	WR_CLUSTSZ(ip)		((ip)->i_udf->udf_wrclustsz)
328 
329 /*
330  * Size can be a 64-bit value and therefore we sign extend fs_bmask
331  * to a 64-bit value too so that the higher 32 bits are masked
332  * properly. Note that the type of fs_bmask has to be signed. Otherwise
333  * compiler will set the higher 32 bits as zero and we don't want
334  * this to happen.
335  */
336 
337 #ifdef	UNDEF
338 #define	blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
339 	(((size) + (fs)->udf_lbsize - 1) & (offset_t)(fs)->udf_lbmask)
340 #endif
341 
342 #define	blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
343 	(((size) + (fs)->udf_lbmask) & (offset_t)(~(fs)->udf_lbmask))
344 
345 #define	blksize(fs)	(fs->udf_lbsize)
346 
347 
348 /*
349  * Convert between inode pointers and vnode pointers
350  */
351 #define	VTOI(VP)	((struct ud_inode *)(VP)->v_data)
352 #define	ITOV(IP)	((IP)->i_vnode)
353 #define	i_vfs		i_vnode->v_vfsp
354 
355 struct icb_ext {
356 	uint16_t	ib_flags;
357 
358 	/* Direct Entry will go here */
359 	uint16_t	ib_prn;		/* partition reference number */
360 	uint32_t	ib_block;	/* block offset into partition */
361 	uint64_t	ib_offset;	/* offset into the file bytes */
362 	int32_t		ib_count;	/* No of bytes in current ext */
363 	uint32_t	ib_marker1;	/* 0xAAAAAAAA */
364 	uint32_t	ib_marker2;	/* 0xBBBBBBBB */
365 };
366 
367 
368 /* ib_flags */
369 #define	IB_UN_REC	0x1		/* The entry is not allocated */
370 #define	IB_UN_RE_AL	0x2		/* The entry is not recorded */
371 					/* and not unallocated */
372 #define	IB_CON		0x3		/* Continuation entry */
373 
374 #define	IB_MASK		0x3
375 
376 #define	IB_ALLOCATED(flags)	\
377 	(((flags) & IB_MASK) != IB_UN_RE_AL)
378 
379 #define	EXT_PER_MALLOC	8
380 
381 
382 struct ud_inode {
383 	struct ud_inode	*i_forw;
384 	struct ud_inode	*i_back;
385 	struct ud_inode	*i_freef;
386 	struct ud_inode	*i_freeb;
387 
388 	struct vnode	*i_vnode;	/* vnode associated with this inode */
389 	struct vnode	*i_devvp;	/* vnode for block I/O */
390 	struct udf_vfs	*i_udf;		/* incore fs associated with inode */
391 	krwlock_t	i_rwlock;	/* serializes write/setattr requests */
392 	krwlock_t	i_contents;	/* protects (most of) inode contents */
393 	dev_t		i_dev;		/* device where inode resides */
394 	u_offset_t	i_diroff;	/* last loc for fast name lookup */
395 
396 	daddr_t		i_icb_lbano;	/* Loc of file icb on disk */
397 	uint16_t	i_icb_prn;	/* partition reference number */
398 	kcondvar_t	i_wrcv;		/* sleep/wakeup for write throttle */
399 	uint32_t	i_flag;
400 	uint32_t	i_icb_block;
401 
402 	int16_t		i_astrat;	/* ICB strategy */
403 	int16_t		i_desc_type;	/* Allocation desc type */
404 	int32_t		i_ext_count;	/* Number of extents allocated */
405 	int32_t		i_ext_used;	/* Number of extents used */
406 	struct icb_ext	*i_ext;		/* array of extents */
407 
408 	kmutex_t	i_con_lock;
409 	struct icb_ext	*i_con;
410 	int32_t		i_con_count;
411 	int32_t		i_con_used;
412 	int32_t		i_con_read;
413 
414 	uint32_t	i_cur_max_ext;
415 	vtype_t		i_type;		/* File type */
416 	uint16_t	i_char;		/* File characteristics */
417 	uint16_t	i_perm;		/* File permissions */
418 
419 	uid_t		i_uid;		/* File owner's uid */
420 	gid_t		i_gid;		/* File owner's gid */
421 	uint32_t	i_nlink;	/* number of links to file */
422 	uint32_t	i_maxent;	/* Max entries that are recorded */
423 	u_offset_t	i_size;		/* File size in bytes */
424 	uint64_t	i_lbr;		/* Logical blocks recorded */
425 	uint64_t	i_uniqid;	/* from the file entry */
426 
427 	timespec32_t	i_atime;
428 	timespec32_t	i_mtime;
429 	timespec32_t	i_ctime;
430 
431 	size_t		i_delaylen;	/* delayed writes, units=bytes */
432 	offset_t	i_delayoff;	/* where we started delaying */
433 	offset_t	i_nextrio;	/* where to start the next clust */
434 	uint64_t	i_writes;	/* remaining bytes in write q */
435 	kmutex_t	i_tlock;	/* protects time fields, i_flag */
436 	major_t		i_major;
437 	minor_t		i_minor;
438 
439 	uint32_t	i_marker1;	/* 0xAAAAAAAA */
440 	uint32_t	i_seq;		/* sequence number attribute */
441 	offset_t	i_nextr;	/* next byte read offset (read-ahead) */
442 	long		i_mapcnt;	/* number of mappings of pages */
443 	int		*i_map;		/* block list for the file */
444 	dev_t		i_rdev;		/* INCORE rdev from */
445 	uint32_t	i_marker2;	/* 0xBBBBBBBB */
446 	uint32_t	i_data_off;	/* Data offset into embedded file */
447 	uint32_t	i_max_emb;
448 	uint32_t	i_marker3;
449 };
450 
451 
452 #ifndef	__lint
453 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_astrat))
454 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_desc_type))
455 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_ext_count))
456 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_ext_used))
457 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_ext))
458 
459 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_type))
460 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_char))
461 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_perm))
462 
463 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_uid))
464 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_gid))
465 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_nlink))
466 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_size))
467 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_lbr))
468 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_uniqid))
469 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_major))
470 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents, ud_inode::i_minor))
471 
472 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_atime))
473 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_mtime))
474 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_ctime))
475 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_delayoff))
476 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_delaylen))
477 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_nextrio))
478 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_writes))
479 _NOTE(MUTEX_PROTECTS_DATA(ud_inode::i_tlock, ud_inode::i_flag))
480 
481 _NOTE(RWLOCK_PROTECTS_DATA(ud_inode::i_contents,
482 		icb_ext::ib_flags icb_ext::ib_prn
483 		icb_ext::ib_block
484 		icb_ext::ib_count icb_ext::ib_offset))
485 #endif
486 
487 
488 /* i_flag */
489 #define	IUPD		0x0001		/* file has been modified */
490 #define	IACC		0x0002		/* inode access time to be updated */
491 #define	IMOD		0x0004		/* inode has been modified */
492 #define	ICHG		0x0008		/* inode has been changed */
493 #define	INOACC		0x0010		/* no access time update in getpage */
494 #define	IMODTIME	0x0020		/* mod time already set */
495 #define	IREF		0x0040		/* inode is being referenced */
496 #define	ISYNC		0x0080		/* do all allocation synchronously */
497 #define	IMODACC		0x0200		/* only access time changed; */
498 #define	IATTCHG		0x0400		/* only size/blocks have changed */
499 #define	IBDWRITE	0x0800		/* the inode has been scheduled for */
500 					/* write operation asynchrously */
501 
502 /*
503  * i_char
504  * Do not change used by MANDLOCK macro in vnode.h
505  */
506 #define	ISUID		VSUID		/* set user id on execution */
507 #define	ISGID		VSGID		/* set group id on execution */
508 #define	ISVTX		VSVTX		/* save swapped text even after use */
509 /*
510  * Setuid	--S---------
511  * Setgid	-G----------
512  * SaveTXT	T-----------
513  */
514 
515 /* i_perm */
516 #define	IEXEC		0x0400		/* read, write, execute permissions */
517 #define	IWRITE		0x0800
518 #define	IREAD		0x1000
519 #define	IATTR		0x2000
520 #define	IDELE		0x4000
521 
522 #define	UP_MASK		0x1CE7
523 #define	VA2UD_PERM(perm)	\
524 	(((perm) & 0x7) | (((perm) & 0x38) << 2) | (((perm) & 0x1C0) << 4))
525 #define	UD2VA_PERM(perm)	\
526 	(((perm) & 0x7) | (((perm) & 0xE0) >> 2) | (((perm) & 0x1C00) >> 4))
527 
528 /*
529  * Permissions
530  * Other	-----------DARWX
531  * Group	------DARWX-----
532  * Owner	-DARWX----------
533  */
534 #define	UD_DPERM2UPERM(dperm)	((((dperm) >> 4) & 0x1C0) |	\
535 					(((dperm) >> 2) & 0x38) |	\
536 					((dperm) & 0x7))
537 #define	UD_UPERM2DPERM(uperm)	((((uperm) & 0x1C0) << 4) |	\
538 					(((uperm) & 0x38) << 2) |	\
539 					((uperm) & 0x7))
540 
541 
542 /* specify how the inode info is written in ud_syncip() */
543 #define	I_SYNC	1	/* wait for the inode written to disk */
544 #define	I_DSYNC	2	/* wait for the inode written to disk */
545 			/* only if IATTCHG is set */
546 #define	I_ASYNC	0	/* don't wait for the inode written */
547 
548 
549 #define	UD_HASH_SZ	512
550 
551 #if ((UD_HASH_SZ & (UD_HASH_SZ - 1)) == 0)
552 #define	UD_INOHASH(dev, bno)	(hash2ints((int)dev, (int)bno) & UD_HASH_SZ - 1)
553 #else
554 #define	UD_INOHASH(dev, bno)	(hash2ints((int)dev, (int)bno) % UD_HASH_SZ)
555 #endif
556 
557 union ihead {
558 	union	ihead		*ih_head[2];
559 	struct	ud_inode	*ih_chain[2];
560 };
561 
562 
563 #define	IMARK(ip) ud_imark(ip)
564 #define	ITIMES_NOLOCK(ip) ud_itimes_nolock(ip)
565 
566 #define	ITIMES(ip) { \
567 	mutex_enter(&(ip)->i_tlock); \
568 	ITIMES_NOLOCK(ip); \
569 	mutex_exit(&(ip)->i_tlock); \
570 }
571 
572 #define	ESAME	(-1)		/* trying to rename linked files (special) */
573 
574 #define	UDF_HOLE	(daddr32_t)-1	/* value used when no block allocated */
575 
576 
577 extern int32_t ud_trace;
578 #define	ud_printf(xyz)	\
579 		if (ud_trace) {	\
580 			cmn_err(CE_NOTE, xyz);	\
581 		}
582 
583 #ifndef	__lint
584 _NOTE(SCHEME_PROTECTS_DATA("Unshared data",
585 		buf
586 		dirent64
587 		fid
588 		flock64
589 		statvfs64
590 		timespec32
591 		udf_fid
592 		uio
593 		vattr
594 		vfs
595 		vnode))
596 
597 _NOTE(SCHEME_PROTECTS_DATA("Unshared data",
598 		file_entry
599 		file_id
600 		icb_tag
601 		indirect_entry
602 		log_vol_int_desc
603 		long_ad
604 		lvid_iu
605 		regid
606 		short_ad
607 		tag
608 		tstamp))
609 
610 _NOTE(LOCK_ORDER(ud_inode::i_rwlock
611 		ud_inode::i_contents
612 		ud_inode::i_tlock))
613 #endif
614 
615 /*
616  * udf_vfsops.c
617  */
618 void		ud_update_superblock(struct vfs *);
619 
620 
621 /*
622  * udf_vnops.c
623  */
624 int32_t		ud_rdwri(enum uio_rw, int32_t, struct ud_inode *, caddr_t,
625 			int32_t, offset_t, enum uio_seg, int32_t *,
626 			struct cred *cr);
627 int32_t		ud_putapage(struct vnode *, page_t *, u_offset_t *,
628 			size_t *, int32_t, struct cred *);
629 
630 
631 /*
632  * udf_inode.c
633  */
634 int32_t	ud_iget(struct vfs *, uint16_t, uint32_t, struct ud_inode **,
635     struct buf *, struct cred *);
636 void	ud_iinactive(struct ud_inode *, struct cred *);
637 void	ud_iupdat(struct ud_inode *, int32_t);
638 int32_t	ud_itrunc(struct ud_inode *, u_offset_t, int32_t, struct cred *);
639 int32_t	ud_iaccess(struct ud_inode *, int32_t, struct cred *, int dolock);
640 int32_t	ud_iflush(struct vfs *);
641 void	ud_imark(struct ud_inode *);
642 void	ud_itimes_nolock(struct ud_inode *);
643 void	ud_delcache(struct ud_inode *);
644 void	ud_idrop(struct ud_inode *);
645 void	ud_init_inodes(void);
646 
647 
648 /*
649  * udf_alloc.c
650  */
651 int32_t		ud_alloc_space(struct vfs *, uint16_t, uint32_t,
652 			uint32_t, uint32_t *, uint32_t *, int32_t, int32_t);
653 void		ud_free_space(struct vfs *, uint16_t, uint32_t, uint32_t);
654 int32_t		ud_ialloc(struct ud_inode *, struct ud_inode **,
655 			struct vattr *, struct cred *);
656 void		ud_ifree(struct ud_inode *, vtype_t);
657 int32_t		ud_freesp(struct vnode *, struct flock64 *, int32_t,
658 			struct cred *);
659 int32_t		ud_alloc_from_cache(struct udf_vfs *, struct ud_part *,
660 			uint32_t *);
661 int32_t		ud_release_cache(struct udf_vfs *);
662 
663 
664 /*
665  * udf_subr.c
666  */
667 void		ud_vfs_add(struct udf_vfs *);
668 void		ud_vfs_remove(struct udf_vfs *);
669 daddr_t		ud_xlate_to_daddr(struct udf_vfs *, uint16_t,
670 			uint32_t, int32_t, uint32_t *);
671 int32_t		ud_ip_off2bno(struct ud_inode *, uint32_t, uint32_t *);
672 void		ud_dtime2utime(struct timespec32 *, struct tstamp const *);
673 void		ud_utime2dtime(struct timespec32 const *, struct tstamp *);
674 int32_t		ud_syncip(struct ud_inode *, int32_t, int32_t);
675 void		ud_update(int32_t);
676 int32_t		ud_fbwrite(struct fbuf *, struct ud_inode *);
677 void		ud_sbwrite(struct udf_vfs *);
678 int32_t		ud_sync_indir(struct ud_inode *);
679 void		ud_update_regid(struct regid *);
680 int32_t		ud_read_icb_till_off(struct ud_inode *, u_offset_t);
681 void		ud_make_tag(struct udf_vfs *, struct tag *,
682 			uint16_t, uint32_t, uint16_t);
683 int32_t		ud_make_dev_spec_ear(struct dev_spec_ear *, major_t, minor_t);
684 int32_t		ud_make_ftimes_ear(struct ftimes_ear *,
685 			int32_t, struct timespec32 *);
686 int32_t		ud_get_next_fid(struct ud_inode *, struct fbuf **, uint32_t,
687 			struct file_id **, uint8_t **, uint8_t *);
688 int32_t		ud_verify_tag_and_desc(struct tag *, uint16_t, uint32_t,
689 		int32_t, int32_t);
690 uint16_t	ud_crc(uint8_t *, int32_t);
691 int32_t		ud_compressunicode(int32_t, int32_t, uint16_t *, uint8_t *);
692 uint32_t	ud_check_te_unrec(struct udf_vfs *, caddr_t, uint32_t);
693 int32_t		ud_compress(int32_t, int32_t *, uint8_t *, uint8_t *);
694 int32_t		ud_uncompress(int32_t, int32_t *, uint8_t *, uint8_t *);
695 struct buf	*ud_bread(dev_t, daddr_t, long);
696 int		ud_sticky_remove_access(struct ud_inode *, struct ud_inode *,
697 			struct cred *);
698 
699 
700 /*
701  * udf_dir.c
702  */
703 int32_t		ud_dirlook(struct ud_inode *,
704 			char *, struct ud_inode **, struct cred *, int32_t);
705 int32_t		ud_direnter(struct ud_inode *, char *, enum de_op,
706 			struct ud_inode *, struct ud_inode *, struct vattr *,
707 			struct ud_inode **, struct cred *, caller_context_t *);
708 int32_t		ud_dirremove(struct ud_inode *,
709 			char *, struct ud_inode *, struct vnode *,
710 			enum dr_op, struct cred *, caller_context_t *);
711 
712 
713 /*
714  * udf_bmap.c
715  */
716 int32_t		ud_bmap_has_holes(struct ud_inode *);
717 int32_t		ud_bmap_write(struct ud_inode *, u_offset_t,
718 			int, int32_t, struct cred *);
719 int32_t		ud_bmap_read(struct ud_inode *, u_offset_t,
720 			daddr_t *, int32_t *);
721 void		ud_insert_new_ext(struct ud_inode *,
722 			int32_t, struct icb_ext *);
723 int32_t		ud_alloc_and_make_ext(struct ud_inode *, int32_t);
724 int32_t		ud_create_new_icb(struct ud_inode *);
725 void		ud_append_new_ext(struct ud_inode *, uint16_t,
726 			u_offset_t, uint32_t, uint16_t, uint32_t);
727 
728 
729 #ifdef	__cplusplus
730 }
731 #endif
732 
733 #endif	/* _SYS_FS_UDF_INODE_H */
734