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