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