Home | History | Annotate | Download | only in udfs
      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 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 #include <sys/types.h>
     29 #include <sys/t_lock.h>
     30 #include <sys/param.h>
     31 #include <sys/time.h>
     32 #include <sys/systm.h>
     33 #include <sys/sysmacros.h>
     34 #include <sys/resource.h>
     35 #include <sys/signal.h>
     36 #include <sys/cred.h>
     37 #include <sys/user.h>
     38 #include <sys/buf.h>
     39 #include <sys/vfs.h>
     40 #include <sys/stat.h>
     41 #include <sys/vnode.h>
     42 #include <sys/mode.h>
     43 #include <sys/proc.h>
     44 #include <sys/disp.h>
     45 #include <sys/file.h>
     46 #include <sys/fcntl.h>
     47 #include <sys/flock.h>
     48 #include <sys/kmem.h>
     49 #include <sys/uio.h>
     50 #include <sys/dnlc.h>
     51 #include <sys/conf.h>
     52 #include <sys/errno.h>
     53 #include <sys/mman.h>
     54 #include <sys/fbuf.h>
     55 #include <sys/pathname.h>
     56 #include <sys/debug.h>
     57 #include <sys/vmsystm.h>
     58 #include <sys/cmn_err.h>
     59 #include <sys/dirent.h>
     60 #include <sys/errno.h>
     61 #include <sys/modctl.h>
     62 #include <sys/statvfs.h>
     63 #include <sys/mount.h>
     64 #include <sys/sunddi.h>
     65 #include <sys/bootconf.h>
     66 #include <sys/policy.h>
     67 
     68 #include <vm/hat.h>
     69 #include <vm/page.h>
     70 #include <vm/pvn.h>
     71 #include <vm/as.h>
     72 #include <vm/seg.h>
     73 #include <vm/seg_map.h>
     74 #include <vm/seg_kmem.h>
     75 #include <vm/seg_vn.h>
     76 #include <vm/rm.h>
     77 #include <vm/page.h>
     78 #include <sys/swap.h>
     79 
     80 
     81 #include <fs/fs_subr.h>
     82 
     83 
     84 #include <sys/fs/udf_volume.h>
     85 #include <sys/fs/udf_inode.h>
     86 
     87 int32_t ud_trace;
     88 
     89 /*
     90  * HASH chains and mutex
     91  */
     92 extern union ihead ud_ihead[UD_HASH_SZ];
     93 extern kmutex_t ud_icache_lock;
     94 
     95 
     96 extern kmutex_t ud_sync_busy;
     97 /*
     98  * udf_vfs list manipulation routines
     99  */
    100 extern kmutex_t udf_vfs_mutex;
    101 extern struct udf_vfs *udf_vfs_instances;
    102 
    103 /*
    104  * Used to verify that a given entry on the udf_instances list (see below)
    105  * still refers to a mounted file system.
    106  *
    107  * XXX: This is a crock that substitutes for proper locking to coordinate
    108  *      updates to and uses of the entries in udf_instances.
    109  */
    110 struct check_node {
    111 	struct vfs	*vfsp;
    112 	struct udf_vfs	*udf_vfs;
    113 	dev_t		vfs_dev;
    114 };
    115 
    116 vfs_t *ud_still_mounted(struct check_node *);
    117 void ud_checkclean(struct vfs *,
    118 		struct udf_vfs *, dev_t, time_t);
    119 int32_t ud_icheck(struct udf_vfs *);
    120 void ud_flushi(int32_t);
    121 
    122 /*
    123  * Link udf_vfsp in at the head of the list of udf_vfs_instances.
    124  */
    125 void
    126 ud_vfs_add(struct udf_vfs *udf_vfsp)
    127 {
    128 	mutex_enter(&udf_vfs_mutex);
    129 	udf_vfsp->udf_next = udf_vfs_instances;
    130 	udf_vfs_instances = udf_vfsp;
    131 	mutex_exit(&udf_vfs_mutex);
    132 }
    133 
    134 /*
    135  * Remove udf_vfsp from the list of udf_vfs_instances.
    136  *
    137  * Does no error checking; udf_vfsp is assumed to actually be on the list.
    138  */
    139 void
    140 ud_vfs_remove(struct udf_vfs *udf_vfsp)
    141 {
    142 	struct udf_vfs **delpt = &udf_vfs_instances;
    143 
    144 	mutex_enter(&udf_vfs_mutex);
    145 	for (; *delpt != NULL; delpt = &((*delpt)->udf_next)) {
    146 		if (*delpt == udf_vfsp) {
    147 			*delpt = udf_vfsp->udf_next;
    148 			udf_vfsp->udf_next = NULL;
    149 			break;
    150 		}
    151 	}
    152 	mutex_exit(&udf_vfs_mutex);
    153 }
    154 
    155 /*
    156  * Search for the prn in the array
    157  * of partitions and translate
    158  * to the disk block number
    159  */
    160 daddr_t
    161 ud_xlate_to_daddr(struct udf_vfs *udf_vfsp,
    162 	uint16_t prn, uint32_t blkno, int32_t nblks, uint32_t *count)
    163 {
    164 	int32_t i;
    165 	struct ud_map *map;
    166 	struct ud_part *ud_parts;
    167 	uint32_t lblkno, retblkno = 0, *addr;
    168 	uint32_t begin_req, end_req;
    169 	uint32_t begin_bad, end_bad;
    170 
    171 	ud_printf("ud_xlate_to_daddr\n");
    172 
    173 	/* Is prn valid */
    174 	if (prn < udf_vfsp->udf_nmaps) {
    175 		map = &(udf_vfsp->udf_maps[prn]);
    176 
    177 		if (map->udm_flags == UDM_MAP_VPM) {
    178 			/*
    179 			 * Map is Virtual Parition Map
    180 			 * first check for the appropriate
    181 			 * table and then return the converted
    182 			 * block number
    183 			 */
    184 			for (i = 0; i < map->udm_nent; i++) {
    185 				if (blkno < map->udm_count[i]) {
    186 					addr = map->udm_addr[i];
    187 					lblkno = SWAP_32(addr[blkno]);
    188 					*count = 1;
    189 					break;
    190 				} else {
    191 					blkno -= map->udm_count[i];
    192 				}
    193 			}
    194 		} else if (map->udm_flags == UDM_MAP_SPM) {
    195 			struct stbl *stbl;
    196 			struct stbl_entry *te;
    197 			int32_t entry_count;
    198 
    199 			/*
    200 			 * Map type is Sparable Parition Map
    201 			 * if the block is in the map
    202 			 * return the translated block
    203 			 * other wise use the regular
    204 			 * partition stuff
    205 			 */
    206 			begin_req = blkno;
    207 			end_req = begin_req + nblks;
    208 
    209 			stbl = (struct stbl *)map->udm_spaddr[0];
    210 			te = (struct stbl_entry *)&stbl->stbl_entry;
    211 			entry_count = SWAP_16(stbl->stbl_len);
    212 
    213 			for (i = 0; i < entry_count; i++, te++) {
    214 				begin_bad = SWAP_32(te->sent_ol);
    215 				end_bad = begin_bad + map->udm_plen;
    216 
    217 				/*
    218 				 * Either unmapped or reserved
    219 				 * or defective. need not consider
    220 				 */
    221 				if (begin_bad >= (uint32_t)0xFFFFFFF0) {
    222 					continue;
    223 				}
    224 				if ((end_req < begin_bad) ||
    225 				    (begin_req >= end_bad)) {
    226 					continue;
    227 				}
    228 
    229 				if (begin_req < begin_bad) {
    230 					ASSERT(end_req >= begin_bad);
    231 					end_req = begin_bad;
    232 				} else {
    233 					retblkno = SWAP_32(te->sent_ml) +
    234 					    begin_req - begin_bad;
    235 					if (end_req < end_bad) {
    236 						*count = end_req - begin_req;
    237 					} else {
    238 						*count = end_bad - begin_req;
    239 					}
    240 					goto end;
    241 				}
    242 			}
    243 
    244 			lblkno = blkno;
    245 			*count = end_req - begin_req;
    246 		} else {
    247 			/*
    248 			 * regular partition
    249 			 */
    250 			lblkno = blkno;
    251 			*count = nblks;
    252 		}
    253 		ud_parts = udf_vfsp->udf_parts;
    254 		for (i = 0; i < udf_vfsp->udf_npart; i++) {
    255 			if (map->udm_pn == ud_parts->udp_number) {
    256 				/*
    257 				 * Check if the block is inside
    258 				 * the partition or not
    259 				 */
    260 				if (lblkno >= ud_parts->udp_length) {
    261 					retblkno = 0;
    262 				} else {
    263 					retblkno = ud_parts->udp_start + lblkno;
    264 				}
    265 				goto end;
    266 			}
    267 			ud_parts ++;
    268 		}
    269 	}
    270 
    271 end:
    272 	return (retblkno);
    273 }
    274 
    275 #ifdef	UNDEF
    276 uint32_t
    277 ud_xlate_to_addr(struct udf_vfs *udf_vfsp,
    278 	uint16_t prn, daddr_t blkno, int32_t lad)
    279 {
    280 	int32_t i;
    281 	struct ud_part *ud_parts;
    282 
    283 	ud_printf("ud_xlate_to_addr\n");
    284 
    285 	if (lad == 0) {
    286 		return (blkno);
    287 	}
    288 	ud_parts = udf_vfsp->udf_parts;
    289 	for (i = 0; i < udf_vfsp->udf_npart; i++) {
    290 		if (prn == ud_parts->udp_number) {
    291 			return (blkno - ud_parts->udp_start);
    292 		}
    293 	}
    294 	return (0);
    295 }
    296 #endif
    297 
    298 /*
    299  * Directories do not have holes
    300  */
    301 int32_t
    302 ud_ip_off2bno(struct ud_inode *ip, uint32_t offset, uint32_t *bno)
    303 {
    304 	int32_t i, error;
    305 	struct icb_ext *iext;
    306 
    307 	ASSERT(ip->i_type == VDIR);
    308 
    309 	if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
    310 		*bno = ip->i_icb_block;
    311 		return (0);
    312 	}
    313 
    314 	if ((error = ud_read_icb_till_off(ip, (u_offset_t)offset)) != 0) {
    315 		return (error);
    316 	}
    317 
    318 	for (i = 0; i < ip->i_ext_used; i++) {
    319 		iext = &ip->i_ext[i];
    320 		if ((iext->ib_offset <= offset) &&
    321 		    (offset < (iext->ib_offset + iext->ib_count))) {
    322 			*bno = iext->ib_block +
    323 			    ((offset - iext->ib_offset) >>
    324 			    ip->i_udf->udf_l2b_shift);
    325 			break;
    326 		}
    327 	}
    328 	return (0);
    329 }
    330 
    331 static uint32_t cum_sec[] = {
    332 	0x0, 0x28de80, 0x4dc880, 0x76a700, 0x9e3400, 0xc71280,
    333 	0xee9f80, 0x1177e00, 0x1405c80, 0x167e980, 0x190c800, 0x1b85500
    334 };
    335 static uint32_t cum_sec_leap[] = {
    336 	0x0, 0x28de80, 0x4f1a00, 0x77f880, 0x9f8580, 0xc86400,
    337 	0xeff100, 0x118cf80, 0x141ae00, 0x1693b00, 0x1921980, 0x1b9a680
    338 };
    339 
    340 #define	DAYS_PER_YEAR	365
    341 
    342 #define	SEC_PER_DAY	0x15180
    343 #define	SEC_PER_YEAR	0x1e13380
    344 
    345 
    346 /* This holds good till yr 2100 */
    347 void
    348 ud_dtime2utime(struct timespec32 *utime,
    349 	struct tstamp const *dtime)
    350 {
    351 	int16_t year, tzone;
    352 	int32_t	sec;
    353 	uint32_t *cp;
    354 
    355 	ud_printf("ud_dtime2utime\n");
    356 
    357 	year = SWAP_16(dtime->ts_year);
    358 	cp = (year % 4) ? cum_sec : cum_sec_leap;
    359 
    360 	utime->tv_sec = cp[dtime->ts_month - 1];
    361 	utime->tv_sec += (dtime->ts_day - 1) * SEC_PER_DAY;
    362 	utime->tv_sec += ((dtime->ts_hour * 60) +
    363 	    dtime->ts_min) * 60 +
    364 	    dtime->ts_sec;
    365 
    366 	tzone = SWAP_16(dtime->ts_tzone);
    367 	if ((tzone & TMODE) == 0x1000) {
    368 		/* Local time */
    369 		if ((tzone & TINVALID) != TINVALID) {
    370 			if (tzone & TSIGN) {
    371 				/*
    372 				 * Sign extend the tzone
    373 				 */
    374 				sec = tzone | 0xFFFFF000;
    375 			} else {
    376 				sec = tzone & TOFFSET;
    377 			}
    378 			sec *= 60;
    379 			utime->tv_sec -= sec;
    380 		}
    381 	}
    382 
    383 	utime->tv_nsec = ((((dtime->ts_csec * 100) +
    384 	    dtime->ts_husec) * 100) +
    385 	    dtime->ts_usec) * 1000;
    386 	if (year >= 1970) {
    387 		utime->tv_sec += (year - 1970) * SEC_PER_YEAR;
    388 		utime->tv_sec += ((year - 1969) / 4) * SEC_PER_DAY;
    389 	} else {
    390 		utime->tv_sec = ((1970 - year) * SEC_PER_YEAR +
    391 		    ((1972 - year) / 4) * SEC_PER_DAY -
    392 		    utime->tv_sec) * -1;
    393 		if (utime->tv_nsec) {
    394 			utime->tv_sec++;
    395 			utime->tv_nsec = 1000 * 1000 * 1000 - utime->tv_nsec;
    396 		}
    397 	}
    398 }
    399 
    400 void
    401 ud_utime2dtime(struct timespec32 const *utime,
    402 	struct tstamp *dtime)
    403 {
    404 	time32_t sec = utime->tv_sec;
    405 	int32_t usec = utime->tv_nsec / 1000;
    406 	uint32_t lyrs, nyrs, dummy;
    407 	uint32_t *cp;
    408 	int32_t before = 0;
    409 
    410 	ud_printf("ud_utime2dtime\n");
    411 
    412 	if (sec < 0) {
    413 		before = 1;
    414 		sec = sec * -1;
    415 		if (usec) {
    416 			sec = sec + 1;
    417 			usec = 1000 * 1000 - usec;
    418 		}
    419 	}
    420 
    421 	dtime->ts_csec = usec / 10000;
    422 	usec %= 10000;
    423 	dtime->ts_husec = usec / 100;
    424 	dtime->ts_usec = usec % 100;
    425 
    426 	nyrs = sec / SEC_PER_YEAR;
    427 	if (before == 0) {
    428 		lyrs = (nyrs + 1) / 4;
    429 	} else {
    430 		lyrs = (nyrs + 2) / 4;
    431 	}
    432 	if (nyrs != ((sec - (lyrs * SEC_PER_DAY)) / SEC_PER_YEAR)) {
    433 		nyrs--;
    434 		if (before == 0) {
    435 			lyrs = (nyrs + 1) / 4;
    436 		} else {
    437 			lyrs = (nyrs + 2) / 4;
    438 		}
    439 	}
    440 	sec -= nyrs * SEC_PER_YEAR + lyrs * SEC_PER_DAY;
    441 
    442 	if (before == 1) {
    443 		nyrs = 1970 - nyrs;
    444 		if (sec != 0) {
    445 			nyrs --;
    446 			if ((nyrs % 4) == 0) {
    447 				sec = SEC_PER_YEAR + SEC_PER_DAY - sec;
    448 			} else {
    449 				sec = SEC_PER_YEAR - sec;
    450 			}
    451 		}
    452 	} else {
    453 		nyrs += 1970;
    454 	}
    455 	cp = (nyrs % 4) ? cum_sec : cum_sec_leap;
    456 	dummy = sec / (SEC_PER_DAY * 29);
    457 	if (dummy > 11) {
    458 		dummy = 11;
    459 	}
    460 	if (sec < cp[dummy]) {
    461 		dummy--;
    462 	}
    463 	dtime->ts_year = SWAP_16(nyrs);
    464 	dtime->ts_month = dummy;
    465 	sec -= cp[dtime->ts_month];
    466 	dtime->ts_month++;
    467 	dtime->ts_day = sec / SEC_PER_DAY;
    468 	sec -= dtime->ts_day * SEC_PER_DAY;
    469 	dtime->ts_day++;
    470 	dtime->ts_hour = sec / SECS_PER_HOUR;
    471 	sec -= dtime->ts_hour * SECS_PER_HOUR;
    472 	dtime->ts_min = sec / SECS_PER_MIN;
    473 	sec -= dtime->ts_min * SECS_PER_MIN;
    474 	dtime->ts_sec = (uint8_t)sec;
    475 
    476 	/* GMT offset is 0 */
    477 	dtime->ts_tzone = SWAP_16(0x1000);
    478 }
    479 
    480 
    481 int32_t
    482 ud_syncip(struct ud_inode *ip, int32_t flags, int32_t waitfor)
    483 {
    484 	int32_t error;
    485 	struct vnode *vp = ITOV(ip);
    486 
    487 	ud_printf("ud_syncip\n");
    488 
    489 	if (ip->i_udf == NULL) {
    490 		return (0);
    491 	}
    492 
    493 	if (!vn_has_cached_data(vp) || (vp->v_type == VCHR)) {
    494 		error = 0;
    495 	} else {
    496 		rw_exit(&ip->i_contents);
    497 		error = VOP_PUTPAGE(vp, (offset_t)0,
    498 		    (uint32_t)0, flags, CRED(), NULL);
    499 		rw_enter(&ip->i_contents, RW_WRITER);
    500 	}
    501 
    502 	if (ip->i_flag & (IUPD |IACC | ICHG | IMOD)) {
    503 		ud_iupdat(ip, waitfor);
    504 	}
    505 
    506 	return (error);
    507 }
    508 
    509 
    510 /* ARGSUSED */
    511 int32_t
    512 ud_fbwrite(struct fbuf *fbp, struct ud_inode *ip)
    513 {
    514 	ud_printf("ud_fbwrite\n");
    515 
    516 	ASSERT(fbp != NULL);
    517 
    518 	return (fbwrite(fbp));
    519 }
    520 
    521 
    522 void
    523 ud_sbwrite(struct udf_vfs *udf_vfsp)
    524 {
    525 	struct log_vol_int_desc *lvid;
    526 	struct ud_part *ud_part;
    527 	struct lvid_iu *iu;
    528 	uint32_t *temp;
    529 	int32_t i, c;
    530 
    531 	ud_printf("ud_sbwrite\n");
    532 	ASSERT(udf_vfsp);
    533 	ASSERT(MUTEX_HELD(&udf_vfsp->udf_lock));
    534 
    535 	/*
    536 	 * updatable information in the superblock
    537 	 * integrity type, udf_maxuniq, udf_nfiles, udf_ndirs
    538 	 * udp_nfree in lvid
    539 	 */
    540 	lvid = (struct log_vol_int_desc *)udf_vfsp->udf_lvid;
    541 	if (udf_vfsp->udf_clean == UDF_DIRTY) {
    542 		lvid->lvid_int_type = SWAP_32(LOG_VOL_OPEN_INT);
    543 	} else {
    544 		lvid->lvid_int_type = SWAP_32(LOG_VOL_CLOSE_INT);
    545 	}
    546 	lvid->lvid_uniqid = SWAP_64(udf_vfsp->udf_maxuniq);
    547 	temp = lvid->lvid_fst;
    548 	c = SWAP_32(lvid->lvid_npart);
    549 	ud_part = udf_vfsp->udf_parts;
    550 	for (i = 0; i < c; i++) {
    551 		temp[i] = SWAP_32(ud_part->udp_nfree);
    552 		ud_part++;
    553 	}
    554 	iu = (struct lvid_iu *)(temp + c * 2);
    555 	iu->lvidiu_nfiles = SWAP_32(udf_vfsp->udf_nfiles);
    556 	iu->lvidiu_ndirs = SWAP_32(udf_vfsp->udf_ndirs);
    557 
    558 	ud_update_regid(&iu->lvidiu_regid);
    559 
    560 	ud_make_tag(udf_vfsp, &lvid->lvid_tag,
    561 	    UD_LOG_VOL_INT, udf_vfsp->udf_iseq_loc,
    562 	    sizeof (struct log_vol_int_desc) - 8 +
    563 	    8 * udf_vfsp->udf_npart +
    564 	    SWAP_32(lvid->lvid_liu));
    565 
    566 	/*
    567 	 * Don't release the buffer after writing to the disk
    568 	 */
    569 	bwrite2(udf_vfsp->udf_iseq);
    570 }
    571 
    572 
    573 int32_t
    574 ud_sync_indir(struct ud_inode *ip)
    575 {
    576 	int32_t elen;
    577 
    578 	ud_printf("ud_sync_indir\n");
    579 
    580 	if (ip->i_desc_type == ICB_FLAG_ONE_AD) {
    581 		return (0);
    582 	} else if (ip->i_desc_type == ICB_FLAG_SHORT_AD) {
    583 		elen = sizeof (struct short_ad);
    584 	} else if (ip->i_desc_type == ICB_FLAG_LONG_AD) {
    585 		elen = sizeof (struct long_ad);
    586 	} else {
    587 		return (EINVAL);
    588 	}
    589 
    590 	if (ip->i_astrat == STRAT_TYPE4) {
    591 		int32_t ndentry;
    592 
    593 		ndentry = ip->i_max_emb / elen;
    594 		if (ip->i_ext_used < ndentry) {
    595 			return (0);
    596 		}
    597 		ASSERT(ip->i_con);
    598 	} else {
    599 		cmn_err(CE_WARN, "unsupported strategy type\n");
    600 		return (EINVAL);
    601 	}
    602 
    603 	return (0);
    604 }
    605 
    606 void
    607 ud_update(int32_t flag)
    608 {
    609 	struct vfs *vfsp;
    610 	struct udf_vfs *udfsp, *udfsnext, *update_list = NULL;
    611 	int32_t check_cnt = 0;
    612 	size_t check_size;
    613 	struct check_node *check_list, *ptr;
    614 	time_t start_time;
    615 
    616 	ud_printf("ud_update\n");
    617 
    618 	mutex_enter(&ud_sync_busy);
    619 	/*
    620 	 * Examine all udf_vfs structures and add those that we can lock to the
    621 	 * update list.  This is so that we don't hold the list lock for a
    622 	 * long time.  If vfs_lock fails for a file system instance, then skip
    623 	 * it because somebody is doing a unmount on it.
    624 	 */
    625 	mutex_enter(&udf_vfs_mutex);
    626 	for (udfsp = udf_vfs_instances;
    627 	    udfsp != NULL; udfsp = udfsp->udf_next) {
    628 		vfsp = udfsp->udf_vfs;
    629 		if (vfs_lock(vfsp) != 0) {
    630 			continue;
    631 		}
    632 		udfsp->udf_wnext = update_list;
    633 		update_list = udfsp;
    634 		check_cnt++;
    635 	}
    636 	mutex_exit(&udf_vfs_mutex);
    637 
    638 	if (update_list == NULL) {
    639 		mutex_exit(&ud_sync_busy);
    640 		return;
    641 	}
    642 
    643 	check_size = sizeof (struct check_node) * check_cnt;
    644 	check_list = ptr = kmem_alloc(check_size, KM_NOSLEEP);
    645 
    646 	/*
    647 	 * Write back modified superblocks.
    648 	 * Consistency check that the superblock of
    649 	 * each file system is still in the buffer cache.
    650 	 *
    651 	 * Note that the update_list traversal is done without the protection
    652 	 * of an overall list lock, so it's necessary to rely on the fact that
    653 	 * each entry of the list is vfs_locked when moving from one entry to
    654 	 * the next.  This works because a concurrent attempt to add an entry
    655 	 * to another thread's update_list won't find it, since it'll already
    656 	 * be locked.
    657 	 */
    658 	check_cnt = 0;
    659 	for (udfsp = update_list; udfsp != NULL; udfsp = udfsnext) {
    660 		/*
    661 		 * Need to grab the next ptr before we unlock this one so
    662 		 * another thread doesn't grab it and change it before we move
    663 		 * on to the next vfs.  (Once we unlock it, it's ok if another
    664 		 * thread finds it to add it to its own update_list; we don't
    665 		 * attempt to refer to it through our list any more.)
    666 		 */
    667 		udfsnext = udfsp->udf_wnext;
    668 		vfsp = udfsp->udf_vfs;
    669 
    670 		if (!vfsp->vfs_data) {
    671 			vfs_unlock(vfsp);
    672 			continue;
    673 		}
    674 		mutex_enter(&udfsp->udf_lock);
    675 
    676 		/*
    677 		 * Build up the STABLE check list, so we can unlock the vfs
    678 		 * until we do the actual checking.
    679 		 */
    680 		if (check_list != NULL) {
    681 			if ((udfsp->udf_flags & UDF_FL_RDONLY) == 0) {
    682 				ptr->vfsp = vfsp;
    683 				ptr->udf_vfs = udfsp;
    684 				ptr->vfs_dev = vfsp->vfs_dev;
    685 				ptr++;
    686 				check_cnt++;
    687 			}
    688 		}
    689 
    690 		/*
    691 		 * superblock is not modified
    692 		 */
    693 		if (udfsp->udf_mod == 0) {
    694 			mutex_exit(&udfsp->udf_lock);
    695 			vfs_unlock(vfsp);
    696 			continue;
    697 		}
    698 		if ((udfsp->udf_flags & UDF_FL_RDONLY) == 0) {
    699 			mutex_exit(&udfsp->udf_lock);
    700 			mutex_exit(&ud_sync_busy);
    701 			cmn_err(CE_WARN, "update ro udfs mod\n");
    702 			return;
    703 		}
    704 		udfsp->udf_mod = 0;
    705 		mutex_exit(&udfsp->udf_lock);
    706 
    707 		ud_update_superblock(vfsp);
    708 		vfs_unlock(vfsp);
    709 	}
    710 
    711 	ud_flushi(flag);
    712 	/*
    713 	 * Force stale buffer cache information to be flushed,
    714 	 * for all devices.  This should cause any remaining control
    715 	 * information (e.g., inode info) to be flushed back.
    716 	 */
    717 	bflush((dev_t)NODEV);
    718 
    719 	if (check_list == NULL) {
    720 		mutex_exit(&ud_sync_busy);
    721 		return;
    722 	}
    723 
    724 	/*
    725 	 * For each udf filesystem in the STABLE check_list, update
    726 	 * the clean flag if warranted.
    727 	 */
    728 	start_time = gethrestime_sec();
    729 	for (ptr = check_list; check_cnt > 0; check_cnt--, ptr++) {
    730 		/*
    731 		 * ud_still_mounted() returns with vfsp and the vfs_reflock
    732 		 * held if ptr refers to a vfs that is still mounted.
    733 		 */
    734 		if ((vfsp = ud_still_mounted(ptr)) == NULL) {
    735 			continue;
    736 		}
    737 		ud_checkclean(vfsp, ptr->udf_vfs, ptr->vfs_dev, start_time);
    738 		vfs_unlock(vfsp);
    739 	}
    740 	mutex_exit(&ud_sync_busy);
    741 	kmem_free(check_list, check_size);
    742 }
    743 
    744 
    745 /*
    746  * Returns vfsp and hold the lock if the vfs is still being mounted.
    747  * Otherwise, returns 0.
    748  *
    749  * For our purposes, "still mounted" means that the file system still appears
    750  * on the list of UFS file system instances.
    751  */
    752 vfs_t *
    753 ud_still_mounted(struct check_node *checkp)
    754 {
    755 	struct vfs *vfsp;
    756 	struct udf_vfs *udf_vfsp;
    757 
    758 	ud_printf("ud_still_mounted\n");
    759 
    760 	mutex_enter(&udf_vfs_mutex);
    761 	for (udf_vfsp = udf_vfs_instances;
    762 	    udf_vfsp != NULL; udf_vfsp = udf_vfsp->udf_next) {
    763 		if (udf_vfsp != checkp->udf_vfs) {
    764 			continue;
    765 		}
    766 		/*
    767 		 * Tentative match:  verify it and try to lock.  (It's not at
    768 		 * all clear how the verification could fail, given that we've
    769 		 * gotten this far.  We would have had to reallocate the
    770 		 * ufsvfs struct at hand for a new incarnation; is that really
    771 		 * possible in the interval from constructing the check_node
    772 		 * to here?)
    773 		 */
    774 		vfsp = udf_vfsp->udf_vfs;
    775 		if (vfsp != checkp->vfsp) {
    776 			continue;
    777 		}
    778 		if (vfsp->vfs_dev != checkp->vfs_dev) {
    779 			continue;
    780 		}
    781 		if (vfs_lock(vfsp) != 0) {
    782 			continue;
    783 		}
    784 		mutex_exit(&udf_vfs_mutex);
    785 		return (vfsp);
    786 	}
    787 	mutex_exit(&udf_vfs_mutex);
    788 	return (NULL);
    789 }
    790 
    791 /* ARGSUSED */
    792 void
    793 ud_checkclean(struct vfs *vfsp,
    794 	struct udf_vfs *udf_vfsp, dev_t dev, time_t timev)
    795 {
    796 	ud_printf("ud_checkclean\n");
    797 	udf_vfsp = (struct udf_vfs *)vfsp->vfs_data;
    798 	/*
    799 	 * ignore if buffers or inodes are busy
    800 	 */
    801 	if ((bcheck(dev, udf_vfsp->udf_iseq)) ||
    802 	    (ud_icheck(udf_vfsp))) {
    803 		return;
    804 	}
    805 	mutex_enter(&udf_vfsp->udf_lock);
    806 	ud_sbwrite(udf_vfsp);
    807 	mutex_exit(&udf_vfsp->udf_lock);
    808 }
    809 
    810 int32_t
    811 ud_icheck(struct udf_vfs *udf_vfsp)
    812 {
    813 	int32_t index, error = 0;
    814 	union ihead *ih;
    815 	struct ud_inode *ip;
    816 
    817 	mutex_enter(&ud_icache_lock);
    818 	for (index = 0; index < UD_HASH_SZ; index++) {
    819 		ih = &ud_ihead[index];
    820 		for (ip = ih->ih_chain[0];
    821 			ip != (struct ud_inode *)ih; ip = ip->i_forw) {
    822 			if ((ip->i_udf == udf_vfsp) &&
    823 				((ip->i_flag & (IMOD|IUPD|ICHG)) ||
    824 				(RW_ISWRITER(&ip->i_rwlock)) ||
    825 				((ip->i_nlink <= 0) && (ip->i_flag & IREF)))) {
    826 					error = 1;
    827 					goto end;
    828 			}
    829 		}
    830 	}
    831 end:
    832 	mutex_exit(&ud_icache_lock);
    833 	return (error);
    834 }
    835 
    836 void
    837 ud_flushi(int32_t flag)
    838 {
    839 	struct ud_inode *ip, *lip;
    840 	struct vnode *vp;
    841 	int cheap = flag & SYNC_ATTR;
    842 	int32_t index;
    843 	union  ihead *ih;
    844 
    845 	/*
    846 	 * Write back each (modified) inode,
    847 	 * but don't sync back pages if vnode is
    848 	 * part of the virtual swap device.
    849 	 */
    850 	mutex_enter(&ud_icache_lock);
    851 	for (index = 0; index < UD_HASH_SZ; index++) {
    852 		ih = &ud_ihead[index];
    853 		lip = NULL;
    854 
    855 		for (ip = ih->ih_chain[0], lip = NULL;
    856 		    ip && ip != (struct ud_inode *)ih;
    857 		    ip = ip->i_forw) {
    858 			int flag = ip->i_flag;
    859 
    860 			vp = ITOV(ip);
    861 			/*
    862 			 * Skip locked & inactive inodes.
    863 			 * Skip vnodes w/ no cached data and no inode changes.
    864 			 * Skip read-only vnodes
    865 			 */
    866 			if ((flag & IREF) == 0 ||
    867 			    (!vn_has_cached_data(vp) &&
    868 			    ((flag & (IMOD|IACC|IUPD|ICHG)) == 0)) ||
    869 			    (vp->v_vfsp == NULL) || vn_is_readonly(vp)) {
    870 				continue;
    871 			}
    872 
    873 			if (!rw_tryenter(&ip->i_contents, RW_WRITER)) {
    874 				continue;
    875 			}
    876 
    877 			VN_HOLD(vp);
    878 
    879 			if (lip != NULL) {
    880 				ITIMES(lip);
    881 				VN_RELE(ITOV(lip));
    882 			}
    883 			lip = ip;
    884 
    885 			/*
    886 			 * If this is an inode sync for file system hardening
    887 			 * or this is a full sync but file is a swap file,
    888 			 * don't sync pages but make sure the inode is up
    889 			 * to date.  In other cases, push everything out.
    890 			 */
    891 			if (cheap || IS_SWAPVP(vp)) {
    892 				ud_iupdat(ip, 0);
    893 			} else {
    894 				(void) ud_syncip(ip, B_ASYNC, I_SYNC);
    895 			}
    896 			rw_exit(&ip->i_contents);
    897 		}
    898 		if (lip != NULL) {
    899 			ITIMES(lip);
    900 			VN_RELE(ITOV(lip));
    901 		}
    902 	}
    903 	mutex_exit(&ud_icache_lock);
    904 }
    905 
    906 
    907 void
    908 ud_update_regid(struct regid *reg)
    909 {
    910 	ud_printf("ud_update_regid\n");
    911 
    912 	bzero(reg->reg_id, 23);
    913 	(void) strncpy(reg->reg_id, SUN_IMPL_ID, SUN_IMPL_ID_LEN);
    914 	reg->reg_ids[0] = SUN_OS_CLASS;
    915 	reg->reg_ids[1] = SUN_OS_ID;
    916 }
    917 
    918 /* ARGSUSED4 */
    919 void
    920 ud_make_tag(struct udf_vfs *udf_vfsp,
    921 	struct tag *tag, uint16_t tag_id, uint32_t blkno, uint16_t crc_len)
    922 {
    923 	int32_t i;
    924 	uint16_t crc;
    925 	uint8_t *addr, cksum = 0;
    926 
    927 	ud_printf("ud_make_tag\n");
    928 
    929 	ASSERT(crc_len > 0x10);
    930 	addr = (uint8_t *)tag;
    931 	crc_len -= sizeof (struct tag);
    932 	crc = ud_crc(addr + 0x10, crc_len);
    933 
    934 	tag->tag_id = SWAP_16(tag_id);
    935 	tag->tag_desc_ver = SWAP_16(2);
    936 	tag->tag_cksum = 0;
    937 	tag->tag_res = 0;
    938 	tag->tag_sno = SWAP_16(udf_vfsp->udf_tsno);
    939 	tag->tag_crc = SWAP_16(crc);
    940 
    941 	tag->tag_crc_len = SWAP_16(crc_len);
    942 	tag->tag_loc = SWAP_32(blkno);
    943 
    944 	addr = (uint8_t *)tag;
    945 	for (i = 0; i <= 15; i++) {
    946 		cksum += addr[i];
    947 	}
    948 	tag->tag_cksum = cksum;
    949 }
    950 
    951 int32_t
    952 ud_make_dev_spec_ear(struct dev_spec_ear *ds,
    953 	major_t major, minor_t minor)
    954 {
    955 	int32_t attr_len;
    956 
    957 	ud_printf("ud_make_dev_spec_ear\n");
    958 
    959 	bzero(ds, sizeof (struct dev_spec_ear));
    960 
    961 	attr_len = sizeof (struct dev_spec_ear);
    962 	ds->ds_atype = SWAP_32(12);
    963 	ds->ds_astype = 1;
    964 	ds->ds_attr_len = SWAP_32(attr_len);
    965 	ds->ds_iu_len = 0;
    966 	ds->ds_major_id = SWAP_32(major);
    967 	ds->ds_minor_id = SWAP_32(minor);
    968 
    969 	return (attr_len);
    970 }
    971 
    972 
    973 int32_t
    974 ud_get_next_fid(struct ud_inode *ip, struct fbuf **fbp, uint32_t offset,
    975 	struct file_id **fid, uint8_t **name, uint8_t *buf)
    976 {
    977 	struct vnode *vp = ITOV(ip);
    978 	caddr_t beg, end;
    979 	int32_t error, lbsize, lbmask, sz, iulen, idlen, copied = 0;
    980 	struct udf_vfs *udf_vfsp;
    981 	uint8_t *obuf;
    982 	int32_t count;
    983 	uint32_t tbno;
    984 	uint16_t crc_len;
    985 	uint32_t len;
    986 
    987 	ud_printf("ud_get_next_fid\n");
    988 
    989 	obuf = buf;
    990 	udf_vfsp = ip->i_udf;
    991 	lbsize = udf_vfsp->udf_lbsize;
    992 	lbmask = udf_vfsp->udf_lbmask;
    993 
    994 	if ((error = ud_ip_off2bno(ip, offset, &tbno)) != 0) {
    995 		return (error);
    996 	}
    997 	/* First time read */
    998 	if (*fbp == NULL) {
    999 		if ((error = fbread(vp, (offset_t)(offset & ~lbmask),
   1000 		    lbsize, S_READ, fbp)) != 0) {
   1001 			return (error);
   1002 		}
   1003 	}
   1004 
   1005 	end = (*fbp)->fb_addr + (*fbp)->fb_count;
   1006 	beg = (*fbp)->fb_addr + (offset & lbmask);
   1007 
   1008 
   1009 	if ((offset % lbsize) ||
   1010 	    (offset == 0)) {
   1011 		sz = end - beg;
   1012 	} else {
   1013 		sz = 0;
   1014 	}
   1015 
   1016 
   1017 	if (F_LEN <= sz) {
   1018 		*fid = (struct file_id *)beg;
   1019 		beg += F_LEN;
   1020 	} else {
   1021 		copied = 1;
   1022 		bcopy(beg, buf, sz);
   1023 		fbrelse(*fbp, S_OTHER);
   1024 		*fbp = NULL;
   1025 
   1026 		/* Skip to next block */
   1027 		if (offset & lbmask) {
   1028 			offset = (offset & ~lbmask) + lbsize;
   1029 		}
   1030 		if ((error = fbread(vp, (offset_t)offset,
   1031 		    lbsize, S_READ, fbp)) != 0) {
   1032 			return (error);
   1033 		}
   1034 		end = (*fbp)->fb_addr + (*fbp)->fb_count;
   1035 		beg = (*fbp)->fb_addr;
   1036 
   1037 		bcopy(beg, buf + sz, F_LEN - sz);
   1038 		beg = beg + F_LEN - sz;
   1039 		*fid = (struct file_id *)buf;
   1040 
   1041 		buf += F_LEN;
   1042 	}
   1043 
   1044 
   1045 	/*
   1046 	 * Check if this a valid file_identifier
   1047 	 */
   1048 	if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
   1049 	    tbno, 0, lbsize) != 0) {
   1050 		/*
   1051 		 * Either end of directory or corrupted
   1052 		 */
   1053 		return (EINVAL);
   1054 	}
   1055 
   1056 	crc_len = SWAP_16((*fid)->fid_tag.tag_crc_len);
   1057 	if (crc_len > udf_vfsp->udf_lbsize) {
   1058 		/*
   1059 		 * Entries cannot be larger than
   1060 		 * blocksize
   1061 		 */
   1062 		return (EINVAL);
   1063 	}
   1064 
   1065 	if (crc_len < (F_LEN - sizeof (struct tag))) {
   1066 		iulen = SWAP_16((*fid)->fid_iulen);
   1067 		idlen = FID_LEN(*fid) - F_LEN;
   1068 		goto use_id_iu_len;
   1069 	}
   1070 
   1071 	/*
   1072 	 * By now beg points to the start fo the file name
   1073 	 */
   1074 
   1075 	sz = end - beg;
   1076 	len = crc_len + sizeof (struct tag) - (F_LEN);
   1077 	if (len <= sz) {
   1078 		if (copied == 1) {
   1079 			bcopy(beg, buf, len);
   1080 			buf += len;
   1081 		}
   1082 		beg += len;
   1083 	} else {
   1084 		copied = 1;
   1085 		/*
   1086 		 * We are releasing the
   1087 		 * old buffer so copy fid to buf
   1088 		 */
   1089 		if (obuf == buf) {
   1090 			count = F_LEN + sz;
   1091 			bcopy(*fid, buf, count);
   1092 			*fid = (struct file_id *)buf;
   1093 			buf += count;
   1094 		} else {
   1095 			bcopy(beg, buf, sz);
   1096 			*fid = (struct file_id *)buf;
   1097 			buf += sz;
   1098 		}
   1099 		fbrelse(*fbp, S_OTHER);
   1100 		*fbp = NULL;
   1101 
   1102 		/* Skip to next block */
   1103 		if (offset & lbmask) {
   1104 			offset = (offset & ~lbmask) + lbsize;
   1105 		}
   1106 		if ((error = fbread(vp, (offset_t)offset,
   1107 		    lbsize, S_READ, fbp)) != 0) {
   1108 			return (error);
   1109 		}
   1110 		end = (*fbp)->fb_addr + (*fbp)->fb_count;
   1111 		beg = (*fbp)->fb_addr;
   1112 		count = len - sz;
   1113 		bcopy(beg, buf, count);
   1114 		beg += count;
   1115 	}
   1116 
   1117 	/*
   1118 	 * First we verify that the tag id and the FID_LEN are valid.
   1119 	 * Next we verify the crc of the descriptor.
   1120 	 */
   1121 	if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
   1122 	    tbno, 0, lbsize) != 0) {
   1123 		/* directory is corrupted */
   1124 		return (EINVAL);
   1125 	}
   1126 	if (ud_verify_tag_and_desc(&(*fid)->fid_tag, UD_FILE_ID_DESC,
   1127 	    tbno, 1, FID_LEN(*fid)) != 0) {
   1128 		/* directory is corrupted */
   1129 		return (EINVAL);
   1130 	}
   1131 
   1132 	idlen = FID_LEN(*fid);
   1133 
   1134 	idlen -= F_LEN;
   1135 	iulen = SWAP_16((*fid)->fid_iulen);
   1136 	if (crc_len < (F_LEN - sizeof (struct tag) + idlen)) {
   1137 use_id_iu_len:
   1138 		len = (F_LEN - sizeof (struct tag) + idlen) - crc_len;
   1139 		sz = end - beg;
   1140 		if (len <= sz) {
   1141 			if (copied == 1) {
   1142 				bcopy(beg, buf, len);
   1143 			}
   1144 		} else {
   1145 			if (obuf == buf) {
   1146 				count = crc_len + sizeof (struct tag);
   1147 				bcopy(*fid, buf, count);
   1148 				*fid = (struct file_id *)buf;
   1149 				buf += count;
   1150 			} else {
   1151 				bcopy(beg, buf, sz);
   1152 				*fid = (struct file_id *)buf;
   1153 				buf += sz;
   1154 			}
   1155 			fbrelse(*fbp, S_OTHER);
   1156 			*fbp = NULL;
   1157 
   1158 			/* Skip to next block */
   1159 			if (offset & lbmask) {
   1160 				offset = (offset & ~lbmask) + lbsize;
   1161 			}
   1162 			if ((error = fbread(vp, (offset_t)offset,
   1163 			    lbsize, S_READ, fbp)) != 0) {
   1164 				return (error);
   1165 			}
   1166 			end = (*fbp)->fb_addr + (*fbp)->fb_count;
   1167 			beg = (*fbp)->fb_addr;
   1168 			count = len - sz;
   1169 			bcopy(beg, buf, count);
   1170 			beg += count;
   1171 		}
   1172 	}
   1173 
   1174 	*name = ((uint8_t *)*fid) + F_LEN + iulen;
   1175 
   1176 	return (0);
   1177 }
   1178 
   1179 
   1180 int32_t
   1181 ud_verify_tag_and_desc(struct tag *tag, uint16_t id, uint32_t blockno,
   1182 			int32_t verify_desc, int32_t desc_len)
   1183 {
   1184 	int32_t i;
   1185 	uint8_t *addr, cksum = 0;
   1186 	uint16_t crc;
   1187 	file_entry_t	*fe;
   1188 	struct ext_attr_hdr *eah;
   1189 	struct file_id	*fid;
   1190 	int32_t fidlen, ea_off;
   1191 
   1192 	if (tag->tag_id != SWAP_16(id)) {
   1193 		return (1);
   1194 	}
   1195 	addr = (uint8_t *)tag;
   1196 	eah = (struct ext_attr_hdr *)tag;
   1197 	for (i = 0; i < 4; i++) {
   1198 		cksum += addr[i];
   1199 	}
   1200 	for (i = 5; i <= 15; i++) {
   1201 		cksum += addr[i];
   1202 	}
   1203 	if (cksum != tag->tag_cksum) {
   1204 		cmn_err(CE_NOTE,
   1205 		"Checksum Does not Verify TAG %x CALC %x blockno 0x%x\n",
   1206 		    tag->tag_cksum, cksum, blockno);
   1207 		return (1);
   1208 	}
   1209 	/*
   1210 	 * Validate the meta data for UD_FILE_ID_DESC.
   1211 	 * The FID_LEN should not exceed the desc_len.
   1212 	 * This validation is done before the entire descriptor is read.
   1213 	 * A call to this routine is made initially with verify_desc set as 0
   1214 	 * but a non zero value in desc_len.
   1215 	 */
   1216 	if (id == UD_FILE_ID_DESC) {
   1217 		fid = (struct file_id *)tag;
   1218 		fidlen = FID_LEN(fid);
   1219 		if (fidlen > desc_len) {
   1220 			cmn_err(CE_NOTE,
   1221 	"Invalid FID_LEN(0x%x). Greater than expected(0x%x) blockno 0x%x\n",
   1222 			    fidlen, desc_len, blockno);
   1223 				return (1);
   1224 		}
   1225 	}
   1226 	if (verify_desc == 0)
   1227 		return (0);
   1228 	/*
   1229 	 * We are done verifying the tag. We proceed with verifying the
   1230 	 * the descriptor. desc_len indicates the size of the structure
   1231 	 * pointed to by argument tag. It includes the size of struct tag.
   1232 	 * We first check the tag_crc_len since we use this to compute the
   1233 	 * crc of the descriptor.
   1234 	 * Verifying the crc is normally sufficient to ensure the integrity
   1235 	 * of the meta data in the descriptor. However given the paranoia
   1236 	 * about the panic caused by illegal meta data values we do an
   1237 	 * additional check of the meta data for decriptor UD_FILE_ENTRY.
   1238 	 * (The original panic was caused because this routine was not called
   1239 	 * to verify the integrity of the tag and descriptor.)
   1240 	 */
   1241 	if (SWAP_16(tag->tag_crc_len) > (desc_len - sizeof (struct tag))) {
   1242 		cmn_err(CE_NOTE,
   1243 	"tag_crc_len(0x%x) is greater than expected len(0x%x) blockno 0x%x\n",
   1244 		    SWAP_16(tag->tag_crc_len),
   1245 		    desc_len, blockno);
   1246 		return (1);
   1247 	}
   1248 	if (tag->tag_crc_len) {
   1249 		crc = ud_crc(addr + 0x10, SWAP_16(tag->tag_crc_len));
   1250 		if (crc != SWAP_16(tag->tag_crc)) {
   1251 			cmn_err(CE_NOTE, "CRC mismatch TAG_ID 0x%x TAG_CRC 0x%x"
   1252 			" Computed crc 0x%x tag_loc %x blockno 0x%x\n",
   1253 			    id, SWAP_16(tag->tag_crc), crc,
   1254 			    SWAP_32(tag->tag_loc), blockno);
   1255 			return (1);
   1256 		}
   1257 	}
   1258 	switch (id) {
   1259 		case UD_FILE_ENTRY:
   1260 			fe = (file_entry_t *)tag;
   1261 			if ((offsetof(struct file_entry, fe_spec) +
   1262 			    SWAP_32(fe->fe_len_ear) +
   1263 			    SWAP_32(fe->fe_len_adesc)) > desc_len) {
   1264 				cmn_err(CE_NOTE,
   1265 	"fe_len_ear(0x%x) fe_len_adesc(0x%x) fields are not OK. blockno 0x%x\n",
   1266 				    SWAP_32(fe->fe_len_ear),
   1267 				    SWAP_32(fe->fe_len_adesc),
   1268 				    blockno);
   1269 				return (1);
   1270 			}
   1271 			break;
   1272 		case UD_EXT_ATTR_HDR:
   1273 			eah = (struct ext_attr_hdr *)tag;
   1274 			if (SWAP_32(eah->eah_aal) > desc_len) {
   1275 				cmn_err(CE_NOTE,
   1276 		    "eah_all(0x%x) exceeds desc. len(0x%x) blockno 0x%x\n",
   1277 				    SWAP_32(eah->eah_aal), desc_len, blockno);
   1278 				return (1);
   1279 			}
   1280 			ea_off = GET_32(&eah->eah_ial);
   1281 			if (ea_off >= desc_len) {
   1282 				cmn_err(CE_NOTE,
   1283 		    "ea_off(0x%x) is not less than ea_len(0x%x) blockno 0x%x\n",
   1284 				    ea_off, desc_len, blockno);
   1285 				return (1);
   1286 			}
   1287 			break;
   1288 		default:
   1289 			break;
   1290 	}
   1291 	if (SWAP_32(blockno) != tag->tag_loc) {
   1292 		cmn_err(CE_NOTE,
   1293 		    "Tag Location mismatch blockno %x tag_blockno %x\n",
   1294 		    blockno, SWAP_32(tag->tag_loc));
   1295 		return (1);
   1296 	}
   1297 	return (0);
   1298 }
   1299 
   1300 /* **************** udf specific subroutines *********************** */
   1301 
   1302 uint16_t ud_crc_table[256] = {
   1303 	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
   1304 	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
   1305 	0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
   1306 	0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
   1307 	0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
   1308 	0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
   1309 	0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
   1310 	0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
   1311 	0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
   1312 	0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
   1313 	0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
   1314 	0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
   1315 	0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
   1316 	0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
   1317 	0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
   1318 	0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
   1319 	0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
   1320 	0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
   1321 	0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
   1322 	0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
   1323 	0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
   1324 	0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
   1325 	0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
   1326 	0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
   1327 	0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
   1328 	0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
   1329 	0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
   1330 	0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
   1331 	0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
   1332 	0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
   1333 	0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
   1334 	0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
   1335 };
   1336 
   1337 uint16_t
   1338 ud_crc(uint8_t *addr, int32_t len)
   1339 {
   1340 	uint16_t crc = 0;
   1341 
   1342 	while (len-- > 0) {
   1343 		crc = ud_crc_table[(crc >> 8 ^ *addr++) & 0xff] ^ (crc<<8);
   1344 	}
   1345 
   1346 	return (crc);
   1347 }
   1348 
   1349 typedef unsigned short unicode_t;
   1350 
   1351 #define	POUND		0x0023
   1352 #define	DOT		0x002E
   1353 #define	SLASH		0x002F
   1354 #define	UNDERBAR	0x005F
   1355 
   1356 
   1357 static uint16_t htoc[16] = {'0', '1', '2', '3',
   1358 	'4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
   1359 
   1360 
   1361 /*
   1362  * An unrecorded block will return all
   1363  * 0's on a WORM media. to simulate
   1364  * a unrecorded block on a rw media
   1365  * we fill it with all zero's
   1366  *	return 0 : If unrecorded
   1367  *	return 1 : If recorded.
   1368  */
   1369 uint32_t
   1370 ud_check_te_unrec(struct udf_vfs *udf_vfsp, caddr_t addr, uint32_t blkno)
   1371 {
   1372 	int32_t i, lbsize;
   1373 	struct term_entry *te;
   1374 
   1375 	ASSERT(udf_vfsp);
   1376 	ASSERT(addr);
   1377 
   1378 	te = (struct term_entry *)addr;
   1379 	if (ud_verify_tag_and_desc(&te->te_tag, UD_TERMINAL_ENT,
   1380 	    blkno, 1, udf_vfsp->udf_lbsize) != 0) {
   1381 		lbsize = udf_vfsp->udf_lbsize;
   1382 		for (i = 0; i < lbsize; i++) {
   1383 			if (addr[i] != 0) {
   1384 				return (1);
   1385 			}
   1386 		}
   1387 	}
   1388 	return (0);
   1389 }
   1390 
   1391 
   1392 /*
   1393  * The algorithms ud_utf82utf16 and ud_utf162utf8
   1394  * donot handle surrogates. This is unicode 1.1 as I
   1395  * understand. When writing udf2.0 this code has
   1396  * to be changed to process surrogates also
   1397  * (Dont ask me what is a surrogate character)
   1398  */
   1399 
   1400 /*
   1401  * This will take a utf8 string convert the first character
   1402  * to utf16 and return the number of bytes consumed in this
   1403  * process. A 0 will be returned if the character is invalid
   1404  */
   1405 uint8_t bytes_from_utf8[] = {
   1406 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1407 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1408 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1409 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1410 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1411 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1412 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1413 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1414 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1415 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1416 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1417 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
   1418 1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
   1419 1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
   1420 2, 2, 2, 2,  2, 2, 2, 2,  2, 2, 2, 2,  2, 2, 2, 2,
   1421 3, 3, 3, 3,  3, 3, 3, 3,  4, 4, 4, 4,  5, 5, 5, 5
   1422 };
   1423 int32_t
   1424 ud_utf82utf16(uint8_t *s_8, uint16_t *c_16, int32_t count)
   1425 {
   1426 	int32_t extra_bytes;
   1427 	uint32_t c_32;
   1428 	ASSERT(s_8);
   1429 	ASSERT(c_16);
   1430 
   1431 	/*
   1432 	 * First convert to a 32-bit
   1433 	 * character
   1434 	 */
   1435 	c_32 = 0;
   1436 	extra_bytes = bytes_from_utf8[*s_8];
   1437 	if (extra_bytes > count) {
   1438 		return (0);
   1439 	}
   1440 
   1441 	/*
   1442 	 * verify if the string is a valid
   1443 	 * utf8 string
   1444 	 */
   1445 	if (extra_bytes == 0) {
   1446 		/*
   1447 		 * Apply one byte rule
   1448 		 */
   1449 		if (*s_8 & 0x80) {
   1450 			return (0);
   1451 		}
   1452 		c_32 = *s_8 & 0x7F;
   1453 	} else if (extra_bytes == 1) {
   1454 		if (((*s_8 & 0xE0) != 0xC0) ||
   1455 		    ((*(s_8 + 1) & 0xC0) != 0x80)) {
   1456 			return (0);
   1457 		}
   1458 		c_32 = *s_8 & 0x1F;
   1459 	} else if (extra_bytes == 2) {
   1460 		if (((*s_8 & 0xF0) != 0xE0) ||
   1461 		    ((*(s_8 + 1) & 0xC0) != 0x80) ||
   1462 		    ((*(s_8 + 2) & 0xC0) != 0x80)) {
   1463 			return (0);
   1464 		}
   1465 		c_32 = *s_8 & 0x0F;
   1466 	} else if (extra_bytes == 3) {
   1467 		if (((*s_8 & 0xF8) != 0xF0) ||
   1468 		    ((*(s_8 + 1) & 0xC0) != 0x80) ||
   1469 		    ((*(s_8 + 2) & 0xC0) != 0x80) ||
   1470 		    ((*(s_8 + 3) & 0xC0) != 0x80)) {
   1471 			return (0);
   1472 		}
   1473 		c_32 = *s_8 & 0x07;
   1474 	} else if (extra_bytes == 4) {
   1475 		if (((*s_8 & 0xFC) != 0xF8) ||
   1476 		    ((*(s_8 + 1) & 0xC0) != 0x80) ||
   1477 		    ((*(s_8 + 2) & 0xC0) != 0x80) ||
   1478 		    ((*(s_8 + 3) & 0xC0) != 0x80) ||
   1479 		    ((*(s_8 + 4) & 0xC0) != 0x80)) {
   1480 			return (0);
   1481 		}
   1482 		c_32 = *s_8 & 0x03;
   1483 	} else if (extra_bytes == 5) {
   1484 		if (((*s_8 & 0xFE) != 0xFC) ||
   1485 		    ((*(s_8 + 1) & 0xC0) != 0x80) ||
   1486 		    ((*(s_8 + 2) & 0xC0) != 0x80) ||
   1487 		    ((*(s_8 + 3) & 0xC0) != 0x80) ||
   1488 		    ((*(s_8 + 4) & 0xC0) != 0x80) ||
   1489 		    ((*(s_8 + 5) & 0xC0) != 0x80)) {
   1490 			return (0);
   1491 		}
   1492 		c_32 = *s_8 & 0x01;
   1493 	} else {
   1494 		return (0);
   1495 	}
   1496 	s_8++;
   1497 
   1498 	/*
   1499 	 * Convert to 32-bit character
   1500 	 */
   1501 	switch (extra_bytes) {
   1502 		case 5 :
   1503 			c_32 <<= 6;
   1504 			c_32 += (*s_8++ & 0x3F);
   1505 			/* FALLTHROUGH */
   1506 		case 4 :
   1507 			c_32 <<= 6;
   1508 			c_32 += (*s_8++ & 0x3F);
   1509 			/* FALLTHROUGH */
   1510 		case 3 :
   1511 			c_32 <<= 6;
   1512 			c_32 += (*s_8++ & 0x3F);
   1513 			/* FALLTHROUGH */
   1514 		case 2 :
   1515 			c_32 <<= 6;
   1516 			c_32 += (*s_8++ & 0x3F);
   1517 			/* FALLTHROUGH */
   1518 		case 1 :
   1519 			c_32 <<= 6;
   1520 			c_32 += (*s_8++ & 0x3F);
   1521 			/* FALLTHROUGH */
   1522 		case 0 :
   1523 			break;
   1524 	}
   1525 
   1526 	/*
   1527 	 * now convert the 32-bit
   1528 	 * character into a 16-bit character
   1529 	 */
   1530 	*c_16 = c_32;
   1531 	return (extra_bytes + 1);
   1532 }
   1533 
   1534 /*
   1535  * Convert to a form that can be put on the media
   1536  * out_len has the size of out_str when we are called.
   1537  * This routine will set out_len to actual bytes written to out_str.
   1538  * We make sure that we will not attempt to write beyond the out_str_len.
   1539  */
   1540 int32_t
   1541 ud_compress(int32_t in_len, int32_t *out_len,
   1542 		uint8_t *in_str, uint8_t *out_str)
   1543 {
   1544 	int32_t error, in_index, out_index, index, c_tx_sz, out_str_len;
   1545 	uint16_t w2_char, *w2_str;
   1546 	uint8_t comp_id;
   1547 
   1548 	out_str_len = *out_len;
   1549 	if (in_len > (out_str_len - 2)) {
   1550 		return (ENAMETOOLONG);
   1551 	}
   1552 
   1553 	*out_len = 0;
   1554 	w2_str = (uint16_t *)kmem_zalloc(512, KM_SLEEP);
   1555 
   1556 	error = in_index = out_index = c_tx_sz = 0;
   1557 	comp_id = 8;
   1558 	for (in_index = 0; in_index < in_len; in_index += c_tx_sz) {
   1559 		if ((c_tx_sz = ud_utf82utf16(&in_str[in_index],
   1560 		    &w2_char, in_len - in_index)) == 0) {
   1561 			error = EINVAL;
   1562 			goto end;
   1563 		}
   1564 		/*
   1565 		 * utf-8 characters can be
   1566 		 * of 1 - 6 bytes in length
   1567 		 */
   1568 		ASSERT(c_tx_sz > 0);
   1569 		ASSERT(c_tx_sz < 7);
   1570 		if ((comp_id == 8) && (w2_char & 0xff00)) {
   1571 			comp_id = 0x10;
   1572 		}
   1573 		w2_str[out_index++] = w2_char;
   1574 	}
   1575 	if (((comp_id == 0x10) && (out_index > ((out_str_len - 2)/2))) ||
   1576 	    ((comp_id == 0x8) && (out_index > (out_str_len - 2)))) {
   1577 		error = ENAMETOOLONG;
   1578 		goto end;
   1579 	}
   1580 
   1581 	in_index = out_index;
   1582 	out_index = 0;
   1583 	out_str[out_index++] = comp_id;
   1584 	for (index = 0; index < in_index; index++) {
   1585 		if (comp_id == 0x10) {
   1586 			out_str[out_index++] = (w2_str[index] & 0xFF00) >> 8;
   1587 		}
   1588 		out_str[out_index++] = w2_str[index] & 0xFF;
   1589 	}
   1590 	ASSERT(out_index <= (out_str_len - 1));
   1591 	*out_len = out_index;
   1592 end:
   1593 	if (w2_str != NULL) {
   1594 		kmem_free((caddr_t)w2_str, 512);
   1595 	}
   1596 	return (error);
   1597 }
   1598 
   1599 /*
   1600  * Take a utf16 character and convert
   1601  * it into a utf8 character.
   1602  * A 0 will be returned if the conversion fails
   1603  */
   1604 uint8_t first_byte_mark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
   1605 int32_t
   1606 ud_utf162utf8(uint16_t c_16, uint8_t *s_8)
   1607 {
   1608 	int32_t nc;
   1609 	uint32_t c_32;
   1610 	uint32_t byte_mask = 0xBF;
   1611 	uint32_t byte_mark = 0x80;
   1612 
   1613 	ASSERT(s_8);
   1614 
   1615 	/*
   1616 	 * Convert the 16-bit character to
   1617 	 * a 32-bit character
   1618 	 */
   1619 	c_32 = c_16;
   1620 
   1621 	/*
   1622 	 * By here the 16-bit character is converted
   1623 	 * to a 32-bit wide character
   1624 	 */
   1625 	if (c_32 < 0x80) {
   1626 		nc = 1;
   1627 	} else if (c_32 < 0x800) {
   1628 		nc = 2;
   1629 	} else if (c_32 < 0x10000) {
   1630 		nc = 3;
   1631 	} else if (c_32 < 0x200000) {
   1632 		nc = 4;
   1633 	} else if (c_32 < 0x4000000) {
   1634 		nc = 5;
   1635 	} else if (c_32 < (uint32_t)0x80000000) {
   1636 		nc = 6;
   1637 	} else {
   1638 		nc = 0;
   1639 	}
   1640 	s_8 += nc;
   1641 	switch (nc) {
   1642 		case 6 :
   1643 			*(--s_8) = (c_32 | byte_mark)  & byte_mask;
   1644 			c_32 >>= 6;
   1645 			/* FALLTHROUGH */
   1646 		case 5 :
   1647 			*(--s_8) = (c_32 | byte_mark)  & byte_mask;
   1648 			c_32 >>= 6;
   1649 			/* FALLTHROUGH */
   1650 		case 4 :
   1651 			*(--s_8) = (c_32 | byte_mark)  & byte_mask;
   1652 			c_32 >>= 6;
   1653 			/* FALLTHROUGH */
   1654 		case 3 :
   1655 			*(--s_8) = (c_32 | byte_mark)  & byte_mask;
   1656 			c_32 >>= 6;
   1657 			/* FALLTHROUGH */
   1658 		case 2 :
   1659 			*(--s_8) = (c_32 | byte_mark)  & byte_mask;
   1660 			c_32 >>= 6;
   1661 			/* FALLTHROUGH */
   1662 		case 1 :
   1663 			*(--s_8) = c_32 | first_byte_mark[nc];
   1664 	}
   1665 	return (nc);
   1666 }
   1667 
   1668 /*
   1669  * Convert to a form that can be transferred to the user
   1670  * Assumption's
   1671  * in_length < 256, out_str is at least 255 bytes long
   1672  * The converted byte stream length is returned in out_len
   1673  */
   1674 #define	MAX_ALLOWABLE_STRING 250
   1675 
   1676 int32_t
   1677 ud_uncompress(int32_t in_len, int32_t *out_len,
   1678 		uint8_t *in_str, uint8_t *out_str)
   1679 {
   1680 	uint8_t comp_id, utf8[6];
   1681 	uint16_t w2_char, crc;
   1682 	int32_t error, index, c_tx_sz, len_till_now;
   1683 	int32_t make_crc, lic, dot_loc, crc_start_loc = 0, k = 0;
   1684 
   1685 	if (in_len == 0) {
   1686 		*out_len = 0;
   1687 		out_str[0] = '\0';
   1688 		return (0);
   1689 	}
   1690 
   1691 	error = len_till_now = make_crc = 0;
   1692 	dot_loc = lic = -2;
   1693 	*out_len = 0;
   1694 	crc = 0;
   1695 	comp_id = in_str[0];
   1696 
   1697 	/*
   1698 	 * File names "." and ".." are invalid under unix.
   1699 	 * Transform them into something
   1700 	 */
   1701 	if (comp_id == 8) {
   1702 		if ((in_str[1] == DOT) &&
   1703 		    ((in_len == 2) || ((in_len == 3) &&
   1704 		    (in_str[2] == DOT)))) {
   1705 			out_str[k++] = UNDERBAR;
   1706 			len_till_now = 1;
   1707 			goto make_append_crc;
   1708 		}
   1709 	} else if (comp_id == 0x10) {
   1710 		if (((in_str[1] << 8 | in_str[2]) == DOT) &&
   1711 		    ((in_len == 3) || ((in_len == 5) &&
   1712 		    ((in_str[3] << 8 | in_str[4]) == DOT)))) {
   1713 			out_str[k++] = UNDERBAR;
   1714 			len_till_now = 1;
   1715 			goto make_append_crc;
   1716 		}
   1717 	} else {
   1718 		*out_len = 0;
   1719 		return (EINVAL);
   1720 	}
   1721 
   1722 	for (index = 1; index < in_len; ) {
   1723 
   1724 		/*
   1725 		 * Uncompress each character
   1726 		 */
   1727 		if (comp_id == 0x10) {
   1728 			w2_char = in_str[index++] << 8;
   1729 			w2_char |= in_str[index++];
   1730 		} else {
   1731 			w2_char = in_str[index++];
   1732 		}
   1733 
   1734 		if (make_crc != 0) {
   1735 			crc += w2_char;
   1736 		}
   1737 
   1738 		if (w2_char == DOT) {
   1739 			dot_loc = len_till_now;
   1740 		}
   1741 
   1742 		/*
   1743 		 * Get rid of invalid characters
   1744 		 */
   1745 		if ((w2_char == SLASH) ||
   1746 		    (w2_char == NULL)) {
   1747 			make_crc = 1;
   1748 			if (((comp_id == 8) &&
   1749 			    (lic != (index - 1))) ||
   1750 			    (comp_id == 0x10) &&
   1751 			    (lic != (index - 2))) {
   1752 				w2_char = UNDERBAR;
   1753 				lic = index;
   1754 			} else {
   1755 				lic = index;
   1756 				continue;
   1757 			}
   1758 		}
   1759 
   1760 		/*
   1761 		 * Conver a 16bit character to a
   1762 		 * utf8 byte stream
   1763 		 */
   1764 		if ((c_tx_sz = ud_utf162utf8(w2_char, utf8)) == 0) {
   1765 			error = EINVAL;
   1766 			goto end;
   1767 		}
   1768 		ASSERT(c_tx_sz > 0);
   1769 		ASSERT(c_tx_sz < 7);
   1770 
   1771 		/*
   1772 		 * The output string is larger than
   1773 		 * the maximum allowed string length
   1774 		 */
   1775 		if ((crc_start_loc == 0) &&
   1776 		    ((len_till_now + c_tx_sz) > MAX_ALLOWABLE_STRING)) {
   1777 			crc_start_loc = len_till_now;
   1778 		}
   1779 
   1780 		if ((len_till_now + c_tx_sz) < MAXNAMELEN) {
   1781 			(void) strncpy((caddr_t)&out_str[len_till_now],
   1782 			    (caddr_t)utf8, c_tx_sz);
   1783 			len_till_now += c_tx_sz;
   1784 		} else {
   1785 			break;
   1786 		}
   1787 	}
   1788 
   1789 	/*
   1790 	 * If we need to append CRC do it now
   1791 	 */
   1792 
   1793 	if (make_crc) {
   1794 
   1795 		if (len_till_now > MAX_ALLOWABLE_STRING) {
   1796 			len_till_now = crc_start_loc;
   1797 		}
   1798 
   1799 		if (dot_loc > 0) {
   1800 			/*
   1801 			 * Make space for crc before the DOT
   1802 			 * move the rest of the file name to the end
   1803 			 */
   1804 			for (k = len_till_now - 1; k >= dot_loc; k--) {
   1805 				out_str[k + 5] = out_str[k];
   1806 			}
   1807 			k = dot_loc;
   1808 		} else {
   1809 			k = len_till_now;
   1810 		}
   1811 make_append_crc:
   1812 		crc = ud_crc(in_str, in_len);
   1813 		out_str[k++] = POUND;
   1814 		out_str[k++] = htoc[(uint16_t)(crc & 0xf000) >> 12];
   1815 		out_str[k++] = htoc[(uint16_t)(crc & 0xf00) >> 8];
   1816 		out_str[k++] = htoc[(uint16_t)(crc & 0xf0) >> 4];
   1817 		out_str[k++] = htoc[crc & 0xf];
   1818 		len_till_now += 5;
   1819 	}
   1820 	*out_len = len_till_now;
   1821 end:
   1822 	return (error);
   1823 }
   1824 
   1825 
   1826 struct buf *
   1827 ud_bread(dev_t dev, daddr_t blkno, long bsize)
   1828 {
   1829 	struct buf *bp;
   1830 
   1831 begin:
   1832 	bp = bread(dev, blkno, bsize);
   1833 
   1834 	if (((bp->b_flags & B_ERROR) == 0) &&
   1835 	    (bp->b_bcount != bsize)) {
   1836 		/*
   1837 		 * Buffer cache returned a
   1838 		 * wrong number of bytes
   1839 		 * flush the old buffer and
   1840 		 * reread it again
   1841 		 */
   1842 		if (bp->b_flags & B_DELWRI) {
   1843 			bwrite(bp);
   1844 		} else {
   1845 			bp->b_flags |= (B_AGE | B_STALE);
   1846 			brelse(bp);
   1847 		}
   1848 		goto begin;
   1849 	}
   1850 
   1851 	return (bp);
   1852 }
   1853 
   1854 /*
   1855  * Decide whether it is okay to remove within a sticky directory.
   1856  * Two conditions need to be met:  write access to the directory
   1857  * is needed.  In sticky directories, write access is not sufficient;
   1858  * you can remove entries from a directory only if you own the directory,
   1859  * if you are privileged, if you own the entry or if they entry is
   1860  * a plain file and you have write access to that file.
   1861  * Function returns 0 if remove access is granted.
   1862  */
   1863 int
   1864 ud_sticky_remove_access(struct ud_inode *dir, struct ud_inode *entry,
   1865 	struct cred *cr)
   1866 {
   1867 	uid_t uid;
   1868 
   1869 	if ((dir->i_char & ISVTX) &&
   1870 	    (uid = crgetuid(cr)) != dir->i_uid &&
   1871 	    uid != entry->i_uid &&
   1872 	    (entry->i_type != VREG ||
   1873 	    ud_iaccess(entry, IWRITE, cr) != 0))
   1874 		return (secpolicy_vnode_remove(cr));
   1875 
   1876 	return (0);
   1877 }
   1878