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