1 /* $OpenBSD: udf_vnops.c,v 1.45 2012/06/20 17:30:22 matthew Exp $ */ 2 3 /* 4 * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.50 2005/01/28 14:42:16 phk Exp $ 29 */ 30 31 /* 32 * Ported to OpenBSD by Pedro Martelletto in February 2005. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/namei.h> 38 #include <sys/kernel.h> 39 #include <sys/malloc.h> 40 #include <sys/mutex.h> 41 #include <sys/stat.h> 42 #include <sys/buf.h> 43 #include <sys/pool.h> 44 #include <sys/lock.h> 45 #include <sys/mount.h> 46 #include <sys/vnode.h> 47 #include <sys/dirent.h> 48 #include <sys/queue.h> 49 #include <sys/unistd.h> 50 #include <sys/endian.h> 51 #include <sys/specdev.h> 52 53 #include <isofs/udf/ecma167-udf.h> 54 #include <isofs/udf/udf.h> 55 #include <isofs/udf/udf_extern.h> 56 57 int udf_bmap_internal(struct unode *, off_t, daddr64_t *, uint32_t *); 58 59 struct vops udf_vops = { 60 .vop_access = udf_access, 61 .vop_bmap = udf_bmap, 62 .vop_lookup = udf_lookup, 63 .vop_getattr = udf_getattr, 64 .vop_open = udf_open, 65 .vop_close = udf_close, 66 .vop_ioctl = udf_ioctl, 67 .vop_read = udf_read, 68 .vop_readdir = udf_readdir, 69 .vop_readlink = udf_readlink, 70 .vop_inactive = udf_inactive, 71 .vop_reclaim = udf_reclaim, 72 .vop_strategy = udf_strategy, 73 .vop_lock = udf_lock, 74 .vop_unlock = udf_unlock, 75 .vop_islocked = udf_islocked, 76 .vop_print = udf_print 77 }; 78 79 #define UDF_INVALID_BMAP -1 80 81 /* Look up a unode based on the ino_t passed in and return its vnode */ 82 int 83 udf_hashlookup(struct umount *ump, ino_t id, int flags, struct vnode **vpp) 84 { 85 struct unode *up; 86 struct udf_hash_lh *lh; 87 struct proc *p = curproc; 88 int error; 89 90 *vpp = NULL; 91 92 loop: 93 mtx_enter(&ump->um_hashmtx); 94 lh = &ump->um_hashtbl[id & ump->um_hashsz]; 95 if (lh == NULL) { 96 mtx_leave(&ump->um_hashmtx); 97 return (ENOENT); 98 } 99 100 LIST_FOREACH(up, lh, u_le) { 101 if (up->u_ino == id) { 102 mtx_leave(&ump->um_hashmtx); 103 error = vget(up->u_vnode, flags, p); 104 if (error == ENOENT) 105 goto loop; 106 if (error) 107 return (error); 108 *vpp = up->u_vnode; 109 return (0); 110 } 111 } 112 113 mtx_leave(&ump->um_hashmtx); 114 115 return (0); 116 } 117 118 int 119 udf_hashins(struct unode *up) 120 { 121 struct umount *ump; 122 struct udf_hash_lh *lh; 123 struct proc *p = curproc; 124 125 ump = up->u_ump; 126 127 vn_lock(up->u_vnode, LK_EXCLUSIVE | LK_RETRY, p); 128 mtx_enter(&ump->um_hashmtx); 129 lh = &ump->um_hashtbl[up->u_ino & ump->um_hashsz]; 130 if (lh == NULL) 131 panic("hash entry is NULL, up->u_ino = %d", up->u_ino); 132 LIST_INSERT_HEAD(lh, up, u_le); 133 mtx_leave(&ump->um_hashmtx); 134 135 return (0); 136 } 137 138 int 139 udf_hashrem(struct unode *up) 140 { 141 struct umount *ump; 142 struct udf_hash_lh *lh; 143 144 ump = up->u_ump; 145 146 mtx_enter(&ump->um_hashmtx); 147 lh = &ump->um_hashtbl[up->u_ino & ump->um_hashsz]; 148 if (lh == NULL) 149 panic("hash entry is NULL, up->u_ino = %d", up->u_ino); 150 LIST_REMOVE(up, u_le); 151 mtx_leave(&ump->um_hashmtx); 152 153 return (0); 154 } 155 156 int 157 udf_allocv(struct mount *mp, struct vnode **vpp, struct proc *p) 158 { 159 int error; 160 struct vnode *vp; 161 162 error = getnewvnode(VT_UDF, mp, &udf_vops, &vp); 163 if (error) { 164 printf("udf_allocv: failed to allocate new vnode\n"); 165 return (error); 166 } 167 168 *vpp = vp; 169 return (0); 170 } 171 172 /* Convert file entry permission (5 bits per owner/group/user) to a mode_t */ 173 static mode_t 174 udf_permtomode(struct unode *up) 175 { 176 uint32_t perm; 177 uint16_t flags; 178 mode_t mode; 179 180 perm = letoh32(up->u_fentry->perm); 181 flags = letoh16(up->u_fentry->icbtag.flags); 182 183 mode = perm & UDF_FENTRY_PERM_USER_MASK; 184 mode |= ((perm & UDF_FENTRY_PERM_GRP_MASK) >> 2); 185 mode |= ((perm & UDF_FENTRY_PERM_OWNER_MASK) >> 4); 186 mode |= ((flags & UDF_ICB_TAG_FLAGS_STICKY) << 4); 187 mode |= ((flags & UDF_ICB_TAG_FLAGS_SETGID) << 6); 188 mode |= ((flags & UDF_ICB_TAG_FLAGS_SETUID) << 8); 189 190 return (mode); 191 } 192 193 int 194 udf_access(void *v) 195 { 196 struct vop_access_args *ap = v; 197 struct vnode *vp; 198 struct unode *up; 199 mode_t a_mode, mode; 200 201 vp = ap->a_vp; 202 up = VTOU(vp); 203 a_mode = ap->a_mode; 204 205 if (a_mode & VWRITE) { 206 switch (vp->v_type) { 207 case VDIR: 208 case VLNK: 209 case VREG: 210 return (EROFS); 211 /* NOTREACHED */ 212 default: 213 break; 214 } 215 } 216 217 mode = udf_permtomode(up); 218 219 return (vaccess(vp->v_type, mode, up->u_fentry->uid, up->u_fentry->gid, 220 a_mode, ap->a_cred)); 221 } 222 223 static int mon_lens[2][12] = { 224 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 225 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 226 }; 227 228 static int 229 udf_isaleapyear(int year) 230 { 231 int i; 232 233 i = (year % 4) ? 0 : 1; 234 i &= (year % 100) ? 1 : 0; 235 i |= (year % 400) ? 0 : 1; 236 237 return (i); 238 } 239 240 /* 241 * This is just a rough hack. Daylight savings isn't calculated and tv_nsec 242 * is ignored. 243 * Timezone calculation compliments of Julian Elischer <julian@elischer.org>. 244 */ 245 static void 246 udf_timetotimespec(struct timestamp *time, struct timespec *t) 247 { 248 int i, lpyear, daysinyear, year; 249 union { 250 uint16_t u_tz_offset; 251 int16_t s_tz_offset; 252 } tz; 253 254 t->tv_nsec = 0; 255 256 /* DirectCD seems to like using bogus year values */ 257 year = letoh16(time->year); 258 if (year < 1970) { 259 t->tv_sec = 0; 260 return; 261 } 262 263 /* Calculate the time and day */ 264 t->tv_sec = time->second; 265 t->tv_sec += time->minute * 60; 266 t->tv_sec += time->hour * 3600; 267 t->tv_sec += time->day * 3600 * 24; 268 269 /* Calculate the month */ 270 lpyear = udf_isaleapyear(year); 271 for (i = 1; i < time->month; i++) 272 t->tv_sec += mon_lens[lpyear][i] * 3600 * 24; 273 274 /* Speed up the calculation */ 275 if (year > 1979) 276 t->tv_sec += 315532800; 277 if (year > 1989) 278 t->tv_sec += 315619200; 279 if (year > 1999) 280 t->tv_sec += 315532800; 281 for (i = 2000; i < year; i++) { 282 daysinyear = udf_isaleapyear(i) + 365 ; 283 t->tv_sec += daysinyear * 3600 * 24; 284 } 285 286 /* 287 * Calculate the time zone. The timezone is 12 bit signed 2's 288 * compliment, so we gotta do some extra magic to handle it right. 289 */ 290 tz.u_tz_offset = letoh16(time->type_tz); 291 tz.u_tz_offset &= 0x0fff; 292 if (tz.u_tz_offset & 0x0800) 293 tz.u_tz_offset |= 0xf000; /* extend the sign to 16 bits */ 294 if ((time->type_tz & 0x1000) && (tz.s_tz_offset != -2047)) 295 t->tv_sec -= tz.s_tz_offset * 60; 296 297 return; 298 } 299 300 int 301 udf_getattr(void *v) 302 { 303 struct vop_getattr_args *ap = v; 304 struct vnode *vp; 305 struct unode *up; 306 struct vattr *vap; 307 struct extfile_entry *xfentry; 308 struct file_entry *fentry; 309 struct timespec ts; 310 311 ts.tv_sec = 0; 312 313 vp = ap->a_vp; 314 vap = ap->a_vap; 315 up = VTOU(vp); 316 317 xfentry = up->u_fentry; 318 fentry = (struct file_entry *)up->u_fentry; 319 320 vap->va_fsid = up->u_dev; 321 vap->va_fileid = up->u_ino; 322 vap->va_mode = udf_permtomode(up); 323 vap->va_nlink = letoh16(fentry->link_cnt); 324 /* 325 * The spec says that -1 is valid for uid/gid and indicates an 326 * invalid uid/gid. How should this be represented? 327 */ 328 vap->va_uid = (letoh32(fentry->uid) == -1) ? 0 : letoh32(fentry->uid); 329 vap->va_gid = (letoh32(fentry->gid) == -1) ? 0 : letoh32(fentry->gid); 330 vap->va_rdev = 0; 331 if (vp->v_type & VDIR) { 332 vap->va_nlink++; /* Count a reference to ourselves */ 333 /* 334 * Directories that are recorded within their ICB will show 335 * as having 0 blocks recorded. Since tradition dictates 336 * that directories consume at least one logical block, 337 * make it appear so. 338 */ 339 vap->va_size = up->u_ump->um_bsize; 340 } else 341 vap->va_size = letoh64(fentry->inf_len); 342 if (udf_checktag(&xfentry->tag, TAGID_EXTFENTRY) == 0) { 343 udf_timetotimespec(&xfentry->atime, &vap->va_atime); 344 udf_timetotimespec(&xfentry->mtime, &vap->va_mtime); 345 if ((vp->v_type & VDIR) && xfentry->logblks_rec != 0) 346 vap->va_size = 347 letoh64(xfentry->logblks_rec) * up->u_ump->um_bsize; 348 } else { 349 udf_timetotimespec(&fentry->atime, &vap->va_atime); 350 udf_timetotimespec(&fentry->mtime, &vap->va_mtime); 351 if ((vp->v_type & VDIR) && fentry->logblks_rec != 0) 352 vap->va_size = 353 letoh64(fentry->logblks_rec) * up->u_ump->um_bsize; 354 } 355 vap->va_ctime = vap->va_mtime; /* Stored as an Extended Attribute */ 356 vap->va_flags = 0; 357 vap->va_gen = 1; 358 vap->va_blocksize = up->u_ump->um_bsize; 359 vap->va_bytes = letoh64(fentry->inf_len); 360 vap->va_type = vp->v_type; 361 vap->va_filerev = 0; 362 363 return (0); 364 } 365 366 int 367 udf_open(void *v) 368 { 369 return (0); /* Nothing to be done at this point */ 370 } 371 372 int 373 udf_close(void *v) 374 { 375 return (0); /* Nothing to be done at this point */ 376 } 377 378 /* 379 * File specific ioctls. 380 */ 381 int 382 udf_ioctl(void *v) 383 { 384 return (ENOTTY); 385 } 386 387 /* 388 * I'm not sure that this has much value in a read-only filesystem, but 389 * cd9660 has it too. 390 */ 391 #if 0 392 static int 393 udf_pathconf(struct vop_pathconf_args *a) 394 { 395 int error = 0; 396 397 switch (ap->a_name) { 398 case _PC_LINK_MAX: 399 *ap->a_retval = 65535; 400 break; 401 case _PC_NAME_MAX: 402 *ap->a_retval = NAME_MAX; 403 break; 404 case _PC_PATH_MAX: 405 *ap->a_retval = PATH_MAX; 406 break; 407 case _PC_NO_TRUNC: 408 *ap->a_retval = 1; 409 break; 410 default: 411 error = EINVAL; 412 break; 413 } 414 415 return (error); 416 } 417 #endif 418 419 int 420 udf_read(void *v) 421 { 422 struct vop_read_args *ap = v; 423 struct vnode *vp = ap->a_vp; 424 struct uio *uio = ap->a_uio; 425 struct unode *up = VTOU(vp); 426 struct buf *bp; 427 uint8_t *data; 428 off_t fsize, offset; 429 int error = 0; 430 int size; 431 432 if (uio->uio_offset < 0) 433 return (EINVAL); 434 435 fsize = letoh64(up->u_fentry->inf_len); 436 437 while (uio->uio_offset < fsize && uio->uio_resid > 0) { 438 offset = uio->uio_offset; 439 if (uio->uio_resid + offset <= fsize) 440 size = uio->uio_resid; 441 else 442 size = fsize - offset; 443 error = udf_readatoffset(up, &size, offset, &bp, &data); 444 if (error == 0) 445 error = uiomove(data, size, uio); 446 if (bp != NULL) { 447 brelse(bp); 448 bp = NULL; 449 } 450 if (error) 451 break; 452 }; 453 454 return (error); 455 } 456 457 /* 458 * Translate the name from a CS0 dstring to a 16-bit Unicode String. 459 * Hooks need to be placed in here to translate from Unicode to the encoding 460 * that the kernel/user expects. Return the length of the translated string. 461 */ 462 int 463 udf_transname(char *cs0string, char *destname, int len, struct umount *ump) 464 { 465 unicode_t *transname; 466 int i, unilen = 0, destlen; 467 468 if (len > MAXNAMLEN) { 469 #ifdef DIAGNOSTIC 470 printf("udf_transname(): name too long\n"); 471 #endif 472 return (0); 473 } 474 475 /* allocate a buffer big enough to hold an 8->16 bit expansion */ 476 transname = pool_get(&udf_trans_pool, PR_WAITOK); 477 478 if ((unilen = udf_rawnametounicode(len, cs0string, transname)) == -1) { 479 #ifdef DIAGNOSTIC 480 printf("udf_transname(): Unicode translation failed\n"); 481 #endif 482 pool_put(&udf_trans_pool, transname); 483 return (0); 484 } 485 486 /* Pack it back to 8-bit Unicode. */ 487 for (i = 0; i < unilen ; i++) 488 if (transname[i] & 0xff00) 489 destname[i] = '?'; /* Fudge the 16bit chars */ 490 else 491 destname[i] = transname[i] & 0xff; 492 493 pool_put(&udf_trans_pool, transname); 494 495 /* Don't forget to terminate the string. */ 496 destname[unilen] = 0; 497 destlen = unilen; 498 499 return (destlen); 500 } 501 502 /* 503 * Compare a CS0 dstring with a name passed in from the VFS layer. Return 504 * 0 on a successful match, nonzero otherwise. Unicode work may need to be 505 * done here also. 506 */ 507 static int 508 udf_cmpname(char *cs0string, char *cmpname, int cs0len, int cmplen, struct umount *ump) 509 { 510 char *transname; 511 int error = 0; 512 513 /* This is overkill, but not worth creating a new pool */ 514 transname = pool_get(&udf_trans_pool, PR_WAITOK); 515 516 cs0len = udf_transname(cs0string, transname, cs0len, ump); 517 518 /* Easy check. If they aren't the same length, they aren't equal */ 519 if ((cs0len == 0) || (cs0len != cmplen)) 520 error = -1; 521 else 522 error = bcmp(transname, cmpname, cmplen); 523 524 pool_put(&udf_trans_pool, transname); 525 526 return (error); 527 } 528 529 struct udf_uiodir { 530 struct dirent *dirent; 531 u_long *cookies; 532 int ncookies; 533 int acookies; 534 int eofflag; 535 }; 536 537 static int 538 udf_uiodir(struct udf_uiodir *uiodir, int de_size, struct uio *uio, long cookie) 539 { 540 if (uiodir->cookies != NULL) { 541 if (++uiodir->acookies > uiodir->ncookies) { 542 uiodir->eofflag = 0; 543 return (-1); 544 } 545 *uiodir->cookies++ = cookie; 546 } 547 548 if (uio->uio_resid < de_size) { 549 uiodir->eofflag = 0; 550 return (-1); 551 } 552 553 return (uiomove(uiodir->dirent, de_size, uio)); 554 } 555 556 static struct udf_dirstream * 557 udf_opendir(struct unode *up, int offset, int fsize, struct umount *ump) 558 { 559 struct udf_dirstream *ds; 560 561 ds = pool_get(&udf_ds_pool, PR_WAITOK | PR_ZERO); 562 563 ds->node = up; 564 ds->offset = offset; 565 ds->ump = ump; 566 ds->fsize = fsize; 567 568 return (ds); 569 } 570 571 static struct fileid_desc * 572 udf_getfid(struct udf_dirstream *ds) 573 { 574 struct fileid_desc *fid; 575 int error, frag_size = 0, total_fid_size; 576 577 /* End of directory? */ 578 if (ds->offset + ds->off >= ds->fsize) { 579 ds->error = 0; 580 return (NULL); 581 } 582 583 /* Grab the first extent of the directory */ 584 if (ds->off == 0) { 585 ds->size = 0; 586 error = udf_readatoffset(ds->node, &ds->size, ds->offset, 587 &ds->bp, &ds->data); 588 if (error) { 589 ds->error = error; 590 if (ds->bp != NULL) { 591 brelse(ds->bp); 592 ds->bp = NULL; 593 } 594 return (NULL); 595 } 596 } 597 598 /* 599 * Clean up from a previous fragmented FID. 600 * Is this the right place for this? 601 */ 602 if (ds->fid_fragment && ds->buf != NULL) { 603 ds->fid_fragment = 0; 604 free(ds->buf, M_UDFFID); 605 } 606 607 fid = (struct fileid_desc*)&ds->data[ds->off]; 608 609 /* 610 * Check to see if the fid is fragmented. The first test 611 * ensures that we don't wander off the end of the buffer 612 * looking for the l_iu and l_fi fields. 613 */ 614 if (ds->off + UDF_FID_SIZE > ds->size || 615 ds->off + letoh16(fid->l_iu) + fid->l_fi + UDF_FID_SIZE > ds->size){ 616 617 /* Copy what we have of the fid into a buffer */ 618 frag_size = ds->size - ds->off; 619 if (frag_size >= ds->ump->um_bsize) { 620 printf("udf: invalid FID fragment\n"); 621 ds->error = EINVAL; 622 return (NULL); 623 } 624 625 /* 626 * File ID descriptors can only be at most one 627 * logical sector in size. 628 */ 629 ds->buf = malloc(ds->ump->um_bsize, M_UDFFID, M_WAITOK|M_ZERO); 630 bcopy(fid, ds->buf, frag_size); 631 632 /* Reduce all of the casting magic */ 633 fid = (struct fileid_desc*)ds->buf; 634 635 if (ds->bp != NULL) { 636 brelse(ds->bp); 637 ds->bp = NULL; 638 } 639 640 /* Fetch the next allocation */ 641 ds->offset += ds->size; 642 ds->size = 0; 643 error = udf_readatoffset(ds->node, &ds->size, ds->offset, 644 &ds->bp, &ds->data); 645 if (error) { 646 ds->error = error; 647 if (ds->bp != NULL) { 648 brelse(ds->bp); 649 ds->bp = NULL; 650 } 651 return (NULL); 652 } 653 654 /* 655 * If the fragment was so small that we didn't get 656 * the l_iu and l_fi fields, copy those in. 657 */ 658 if (frag_size < UDF_FID_SIZE) 659 bcopy(ds->data, &ds->buf[frag_size], 660 UDF_FID_SIZE - frag_size); 661 662 /* 663 * Now that we have enough of the fid to work with, 664 * copy in the rest of the fid from the new 665 * allocation. 666 */ 667 total_fid_size = UDF_FID_SIZE + letoh16(fid->l_iu) + fid->l_fi; 668 if (total_fid_size > ds->ump->um_bsize) { 669 printf("udf: invalid FID\n"); 670 ds->error = EIO; 671 return (NULL); 672 } 673 bcopy(ds->data, &ds->buf[frag_size], 674 total_fid_size - frag_size); 675 676 ds->fid_fragment = 1; 677 } else { 678 total_fid_size = letoh16(fid->l_iu) + fid->l_fi + UDF_FID_SIZE; 679 } 680 681 /* 682 * Update the offset. Align on a 4 byte boundary because the 683 * UDF spec says so. 684 */ 685 ds->this_off = ds->off; 686 if (!ds->fid_fragment) { 687 ds->off += (total_fid_size + 3) & ~0x03; 688 } else { 689 ds->off = (total_fid_size - frag_size + 3) & ~0x03; 690 } 691 692 return (fid); 693 } 694 695 static void 696 udf_closedir(struct udf_dirstream *ds) 697 { 698 699 if (ds->bp != NULL) { 700 brelse(ds->bp); 701 ds->bp = NULL; 702 } 703 704 if (ds->fid_fragment && ds->buf != NULL) 705 free(ds->buf, M_UDFFID); 706 707 pool_put(&udf_ds_pool, ds); 708 } 709 710 int 711 udf_readdir(void *v) 712 { 713 struct vop_readdir_args *ap = v; 714 struct vnode *vp; 715 struct uio *uio; 716 struct dirent dir; 717 struct unode *up; 718 struct umount *ump; 719 struct fileid_desc *fid; 720 struct udf_uiodir uiodir; 721 struct udf_dirstream *ds; 722 u_long *cookies = NULL; 723 int ncookies; 724 int error = 0; 725 726 #define GENERIC_DIRSIZ(dp) \ 727 ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) 728 729 vp = ap->a_vp; 730 uio = ap->a_uio; 731 up = VTOU(vp); 732 ump = up->u_ump; 733 uiodir.eofflag = 1; 734 735 if (ap->a_ncookies != NULL) { 736 /* 737 * Guess how many entries are needed. If we run out, this 738 * function will be called again and thing will pick up were 739 * it left off. 740 */ 741 ncookies = uio->uio_resid / 8; 742 cookies = malloc(sizeof(u_long) * ncookies, M_TEMP, M_WAITOK); 743 uiodir.ncookies = ncookies; 744 uiodir.cookies = cookies; 745 uiodir.acookies = 0; 746 } else { 747 uiodir.cookies = NULL; 748 } 749 750 /* 751 * Iterate through the file id descriptors. Give the parent dir 752 * entry special attention. 753 */ 754 if (ISSET(up->u_ump->um_flags, UDF_MNT_USES_META)) { 755 up->u_ump->um_start += up->u_ump->um_meta_start; 756 up->u_ump->um_len = up->u_ump->um_meta_len; 757 } 758 ds = udf_opendir(up, uio->uio_offset, 759 letoh64(up->u_fentry->inf_len), up->u_ump); 760 761 while ((fid = udf_getfid(ds)) != NULL) { 762 763 /* Should we return an error on a bad fid? */ 764 if (udf_checktag(&fid->tag, TAGID_FID)) { 765 printf("Invalid FID tag (%d)\n", fid->tag.id); 766 error = EIO; 767 break; 768 } 769 770 /* Is this a deleted file? */ 771 if (fid->file_char & UDF_FILE_CHAR_DEL) 772 continue; 773 774 if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) { 775 /* Do up the '.' and '..' entries. Dummy values are 776 * used for the cookies since the offset here is 777 * usually zero, and NFS doesn't like that value 778 */ 779 dir.d_fileno = up->u_ino; 780 dir.d_type = DT_DIR; 781 dir.d_name[0] = '.'; 782 dir.d_name[1] = '\0'; 783 dir.d_namlen = 1; 784 dir.d_reclen = GENERIC_DIRSIZ(&dir); 785 uiodir.dirent = &dir; 786 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 1); 787 if (error) 788 break; 789 790 dir.d_fileno = udf_getid(&fid->icb); 791 dir.d_type = DT_DIR; 792 dir.d_name[0] = '.'; 793 dir.d_name[1] = '.'; 794 dir.d_name[2] = '\0'; 795 dir.d_namlen = 2; 796 dir.d_reclen = GENERIC_DIRSIZ(&dir); 797 uiodir.dirent = &dir; 798 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 2); 799 } else { 800 dir.d_namlen = udf_transname(&fid->data[fid->l_iu], 801 &dir.d_name[0], fid->l_fi, ump); 802 dir.d_fileno = udf_getid(&fid->icb); 803 dir.d_type = (fid->file_char & UDF_FILE_CHAR_DIR) ? 804 DT_DIR : DT_UNKNOWN; 805 dir.d_reclen = GENERIC_DIRSIZ(&dir); 806 uiodir.dirent = &dir; 807 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 808 ds->this_off); 809 } 810 if (error) { 811 printf("uiomove returned %d\n", error); 812 break; 813 } 814 815 } 816 817 #undef GENERIC_DIRSIZ 818 819 /* tell the calling layer whether we need to be called again */ 820 *ap->a_eofflag = uiodir.eofflag; 821 uio->uio_offset = ds->offset + ds->off; 822 823 if (!error) 824 error = ds->error; 825 826 udf_closedir(ds); 827 if (ISSET(up->u_ump->um_flags, UDF_MNT_USES_META)) { 828 up->u_ump->um_start = up->u_ump->um_realstart; 829 up->u_ump->um_len = up->u_ump->um_reallen; 830 } 831 832 if (ap->a_ncookies != NULL) { 833 if (error) 834 free(cookies, M_TEMP); 835 else { 836 *ap->a_ncookies = uiodir.acookies; 837 *ap->a_cookies = cookies; 838 } 839 } 840 841 return (error); 842 } 843 844 /* Are there any implementations out there that do soft-links? */ 845 int 846 udf_readlink(void *v) 847 { 848 return (EOPNOTSUPP); 849 } 850 851 int 852 udf_strategy(void *v) 853 { 854 struct vop_strategy_args *ap = v; 855 struct buf *bp; 856 struct vnode *vp; 857 struct unode *up; 858 int maxsize, s, error; 859 860 bp = ap->a_bp; 861 vp = bp->b_vp; 862 up = VTOU(vp); 863 864 /* cd9660 has this test reversed, but it seems more logical this way */ 865 if (bp->b_blkno != bp->b_lblkno) { 866 /* 867 * Files that are embedded in the fentry don't translate well 868 * to a block number. Reject. 869 */ 870 if (udf_bmap_internal(up, bp->b_lblkno * up->u_ump->um_bsize, 871 &bp->b_lblkno, &maxsize)) { 872 clrbuf(bp); 873 bp->b_blkno = -1; 874 } 875 } else { 876 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL); 877 if (error) { 878 bp->b_error = error; 879 bp->b_flags |= B_ERROR; 880 s = splbio(); 881 biodone(bp); 882 splx(s); 883 return (error); 884 } 885 886 if ((long)bp->b_blkno == -1) 887 clrbuf(bp); 888 } 889 890 if ((long)bp->b_blkno == -1) { 891 s = splbio(); 892 biodone(bp); 893 splx(s); 894 } else { 895 bp->b_dev = vp->v_rdev; 896 (up->u_devvp->v_op->vop_strategy)(ap); 897 } 898 899 return (0); 900 } 901 902 int 903 udf_lock(void *v) 904 { 905 struct vop_lock_args *ap = v; 906 907 struct vnode *vp = ap->a_vp; 908 909 return (lockmgr(&VTOU(vp)->u_lock, ap->a_flags, NULL)); 910 } 911 912 int 913 udf_unlock(void *v) 914 { 915 struct vop_unlock_args *ap = v; 916 917 struct vnode *vp = ap->a_vp; 918 919 return (lockmgr(&VTOU(vp)->u_lock, ap->a_flags | LK_RELEASE, NULL)); 920 } 921 922 int 923 udf_islocked(void *v) 924 { 925 struct vop_islocked_args *ap = v; 926 927 return (lockstatus(&VTOU(ap->a_vp)->u_lock)); 928 } 929 930 int 931 udf_print(void *v) 932 { 933 struct vop_print_args *ap = v; 934 struct vnode *vp = ap->a_vp; 935 struct unode *up = VTOU(vp); 936 937 /* 938 * Complete the information given by vprint(). 939 */ 940 printf("tag VT_UDF, hash id %u\n", up->u_ino); 941 #ifdef DIAGNOSTIC 942 lockmgr_printinfo(&up->u_lock); 943 printf("\n"); 944 #endif 945 return (0); 946 } 947 948 int 949 udf_bmap(void *v) 950 { 951 struct vop_bmap_args *ap = v; 952 struct unode *up; 953 uint32_t max_size; 954 daddr64_t lsector; 955 int error; 956 957 up = VTOU(ap->a_vp); 958 959 if (ap->a_vpp != NULL) 960 *ap->a_vpp = up->u_devvp; 961 if (ap->a_bnp == NULL) 962 return (0); 963 964 error = udf_bmap_internal(up, ap->a_bn * up->u_ump->um_bsize, 965 &lsector, &max_size); 966 if (error) 967 return (error); 968 969 /* Translate logical to physical sector number */ 970 *ap->a_bnp = lsector << (up->u_ump->um_bshift - DEV_BSHIFT); 971 972 /* Punt on read-ahead for now */ 973 if (ap->a_runp) 974 *ap->a_runp = 0; 975 976 return (0); 977 } 978 979 /* 980 * The all powerful VOP_LOOKUP(). 981 */ 982 int 983 udf_lookup(void *v) 984 { 985 struct vop_lookup_args *ap = v; 986 struct vnode *dvp; 987 struct vnode *tdp = NULL; 988 struct vnode **vpp = ap->a_vpp; 989 struct unode *up; 990 struct umount *ump; 991 struct fileid_desc *fid = NULL; 992 struct udf_dirstream *ds; 993 struct proc *p; 994 u_long nameiop; 995 u_long flags; 996 char *nameptr; 997 long namelen; 998 ino_t id = 0; 999 int offset, error = 0; 1000 int numdirpasses, fsize; 1001 1002 extern struct nchstats nchstats; 1003 1004 dvp = ap->a_dvp; 1005 up = VTOU(dvp); 1006 ump = up->u_ump; 1007 nameiop = ap->a_cnp->cn_nameiop; 1008 flags = ap->a_cnp->cn_flags; 1009 nameptr = ap->a_cnp->cn_nameptr; 1010 namelen = ap->a_cnp->cn_namelen; 1011 fsize = letoh64(up->u_fentry->inf_len); 1012 p = ap->a_cnp->cn_proc; 1013 *vpp = NULL; 1014 1015 /* 1016 * Make sure the process can scan the requested directory. 1017 */ 1018 error = VOP_ACCESS(dvp, VEXEC, ap->a_cnp->cn_cred, p); 1019 if (error) 1020 return (error); 1021 1022 /* 1023 * Check if the (directory, name) tuple has been already cached. 1024 */ 1025 error = cache_lookup(dvp, vpp, ap->a_cnp); 1026 if (error >= 0) 1027 return (error); 1028 else 1029 error = 0; 1030 1031 /* 1032 * If dvp is what's being looked up, then return it. 1033 */ 1034 if (ap->a_cnp->cn_namelen == 1 && ap->a_cnp->cn_nameptr[0] == '.') { 1035 vref(dvp); 1036 *vpp = dvp; 1037 return (0); 1038 } 1039 1040 /* 1041 * If this is a LOOKUP and we've already partially searched through 1042 * the directory, pick up where we left off and flag that the 1043 * directory may need to be searched twice. For a full description, 1044 * see /sys/isofs/cd9660/cd9660_lookup.c:cd9660_lookup() 1045 */ 1046 if (nameiop != LOOKUP || up->u_diroff == 0 || up->u_diroff > fsize) { 1047 offset = 0; 1048 numdirpasses = 1; 1049 } else { 1050 offset = up->u_diroff; 1051 numdirpasses = 2; 1052 nchstats.ncs_2passes++; 1053 } 1054 1055 if (ISSET(up->u_ump->um_flags, UDF_MNT_USES_META)) { 1056 up->u_ump->um_start += up->u_ump->um_meta_start; 1057 up->u_ump->um_len = up->u_ump->um_meta_len; 1058 } 1059 lookloop: 1060 ds = udf_opendir(up, offset, fsize, ump); 1061 1062 while ((fid = udf_getfid(ds)) != NULL) { 1063 /* Check for a valid FID tag. */ 1064 if (udf_checktag(&fid->tag, TAGID_FID)) { 1065 printf("udf_lookup: Invalid tag\n"); 1066 error = EIO; 1067 break; 1068 } 1069 1070 /* Is this a deleted file? */ 1071 if (fid->file_char & UDF_FILE_CHAR_DEL) 1072 continue; 1073 1074 if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) { 1075 if (flags & ISDOTDOT) { 1076 id = udf_getid(&fid->icb); 1077 break; 1078 } 1079 } else { 1080 if (!(udf_cmpname(&fid->data[fid->l_iu], 1081 nameptr, fid->l_fi, namelen, ump))) { 1082 id = udf_getid(&fid->icb); 1083 break; 1084 } 1085 } 1086 } 1087 1088 if (!error) 1089 error = ds->error; 1090 1091 if (error) { 1092 udf_closedir(ds); 1093 if (ISSET(up->u_ump->um_flags, UDF_MNT_USES_META)) { 1094 up->u_ump->um_start = up->u_ump->um_realstart; 1095 up->u_ump->um_len = up->u_ump->um_reallen; 1096 } 1097 return (error); 1098 } 1099 1100 /* Did we have a match? */ 1101 if (id) { 1102 error = udf_vget(ump->um_mountp, id, &tdp); 1103 if (!error) { 1104 /* 1105 * Remember where this entry was if it's the final 1106 * component. 1107 */ 1108 if ((flags & ISLASTCN) && nameiop == LOOKUP) 1109 up->u_diroff = ds->offset + ds->off; 1110 if (numdirpasses == 2) 1111 nchstats.ncs_pass2++; 1112 if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) { 1113 ap->a_cnp->cn_flags |= PDIRUNLOCK; 1114 VOP_UNLOCK(dvp, 0, p); 1115 } 1116 1117 *vpp = tdp; 1118 } 1119 } else { 1120 /* Name wasn't found on this pass. Do another pass? */ 1121 if (numdirpasses == 2) { 1122 numdirpasses--; 1123 offset = 0; 1124 udf_closedir(ds); 1125 goto lookloop; 1126 } 1127 1128 if ((flags & ISLASTCN) && 1129 (nameiop == CREATE || nameiop == RENAME)) { 1130 error = EROFS; 1131 } else { 1132 error = ENOENT; 1133 } 1134 } 1135 1136 /* 1137 * Cache the result of this lookup. 1138 */ 1139 if (flags & MAKEENTRY) 1140 cache_enter(dvp, *vpp, ap->a_cnp); 1141 1142 udf_closedir(ds); 1143 if (ISSET(up->u_ump->um_flags, UDF_MNT_USES_META)) { 1144 up->u_ump->um_start = up->u_ump->um_realstart; 1145 up->u_ump->um_len = up->u_ump->um_reallen; 1146 } 1147 1148 return (error); 1149 } 1150 1151 int 1152 udf_inactive(void *v) 1153 { 1154 struct vop_inactive_args *ap = v; 1155 struct vnode *vp = ap->a_vp; 1156 struct proc *p = ap->a_p; 1157 1158 /* 1159 * No need to sync anything, so just unlock the vnode and return. 1160 */ 1161 VOP_UNLOCK(vp, 0, p); 1162 1163 return (0); 1164 } 1165 1166 int 1167 udf_reclaim(void *v) 1168 { 1169 struct vop_reclaim_args *ap = v; 1170 struct vnode *vp; 1171 struct unode *up; 1172 1173 vp = ap->a_vp; 1174 up = VTOU(vp); 1175 1176 if (up != NULL) { 1177 udf_hashrem(up); 1178 if (up->u_devvp) { 1179 vrele(up->u_devvp); 1180 up->u_devvp = 0; 1181 } 1182 1183 if (up->u_fentry != NULL) 1184 free(up->u_fentry, M_UDFFENTRY); 1185 1186 pool_put(&unode_pool, up); 1187 vp->v_data = NULL; 1188 } 1189 1190 return (0); 1191 } 1192 1193 /* 1194 * Read the block and then set the data pointer to correspond with the 1195 * offset passed in. Only read in at most 'size' bytes, and then set 'size' 1196 * to the number of bytes pointed to. If 'size' is zero, try to read in a 1197 * whole extent. 1198 * 1199 * Note that *bp may be assigned error or not. 1200 * 1201 */ 1202 int 1203 udf_readatoffset(struct unode *up, int *size, off_t offset, 1204 struct buf **bp, uint8_t **data) 1205 { 1206 struct umount *ump; 1207 struct extfile_entry *xfentry = NULL; 1208 struct file_entry *fentry = NULL; 1209 struct buf *bp1; 1210 uint32_t max_size; 1211 daddr64_t sector; 1212 int error; 1213 1214 ump = up->u_ump; 1215 1216 *bp = NULL; 1217 error = udf_bmap_internal(up, offset, §or, &max_size); 1218 if (error == UDF_INVALID_BMAP) { 1219 /* 1220 * This error means that the file *data* is stored in the 1221 * allocation descriptor field of the file entry. 1222 */ 1223 if (udf_checktag(&up->u_fentry->tag, TAGID_EXTFENTRY) == 0) { 1224 xfentry = up->u_fentry; 1225 *data = &xfentry->data[letoh32(xfentry->l_ea)]; 1226 *size = letoh32(xfentry->l_ad); 1227 } else { 1228 fentry = (struct file_entry *)up->u_fentry; 1229 *data = &fentry->data[letoh32(fentry->l_ea)]; 1230 *size = letoh32(fentry->l_ad); 1231 } 1232 return (0); 1233 } else if (error != 0) { 1234 return (error); 1235 } 1236 1237 /* Adjust the size so that it is within range */ 1238 if (*size == 0 || *size > max_size) 1239 *size = max_size; 1240 *size = min(*size, MAXBSIZE); 1241 1242 if ((error = udf_readlblks(ump, sector, *size, bp))) { 1243 printf("warning: udf_readlblks returned error %d\n", error); 1244 /* note: *bp may be non-NULL */ 1245 return (error); 1246 } 1247 1248 bp1 = *bp; 1249 *data = (uint8_t *)&bp1->b_data[offset % ump->um_bsize]; 1250 return (0); 1251 } 1252 1253 /* 1254 * Translate a file offset into a logical block and then into a physical 1255 * block. 1256 */ 1257 int 1258 udf_bmap_internal(struct unode *up, off_t offset, daddr64_t *sector, 1259 uint32_t *max_size) 1260 { 1261 struct umount *ump; 1262 struct extfile_entry *xfentry; 1263 struct file_entry *fentry; 1264 void *icb; 1265 struct icb_tag *tag; 1266 uint32_t icblen = 0; 1267 daddr64_t lsector; 1268 int ad_offset, ad_num = 0; 1269 int i, p_offset, l_ea, l_ad; 1270 1271 ump = up->u_ump; 1272 xfentry = up->u_fentry; 1273 fentry = (struct file_entry *)up->u_fentry; 1274 tag = &fentry->icbtag; 1275 if (udf_checktag(&xfentry->tag, TAGID_EXTFENTRY) == 0) { 1276 l_ea = letoh32(xfentry->l_ea); 1277 l_ad = letoh32(xfentry->l_ad); 1278 } else { 1279 l_ea = letoh32(fentry->l_ea); 1280 l_ad = letoh32(fentry->l_ad); 1281 } 1282 1283 switch (letoh16(tag->strat_type)) { 1284 case 4: 1285 break; 1286 1287 case 4096: 1288 printf("Cannot deal with strategy4096 yet!\n"); 1289 return (ENODEV); 1290 1291 default: 1292 printf("Unknown strategy type %d\n", tag->strat_type); 1293 return (ENODEV); 1294 } 1295 1296 switch (letoh16(tag->flags) & 0x7) { 1297 case 0: 1298 /* 1299 * The allocation descriptor field is filled with short_ad's. 1300 * If the offset is beyond the current extent, look for the 1301 * next extent. 1302 */ 1303 do { 1304 offset -= icblen; 1305 ad_offset = sizeof(struct short_ad) * ad_num; 1306 if (ad_offset > l_ad) { 1307 printf("SFile offset out of bounds (%d > %d)\n", 1308 ad_offset, l_ad); 1309 return (EINVAL); 1310 } 1311 1312 if (udf_checktag(&up->u_fentry->tag, TAGID_EXTFENTRY) == 0) 1313 icb = GETICB(short_ad, xfentry, l_ea + ad_offset); 1314 else 1315 icb = GETICB(short_ad, fentry, l_ea + ad_offset); 1316 1317 icblen = GETICBLEN(short_ad, icb); 1318 ad_num++; 1319 } while(offset >= icblen); 1320 1321 lsector = (offset >> ump->um_bshift) + 1322 letoh32(((struct short_ad *)(icb))->lb_num); 1323 1324 *max_size = GETICBLEN(short_ad, icb); 1325 1326 break; 1327 case 1: 1328 /* 1329 * The allocation descriptor field is filled with long_ad's 1330 * If the offset is beyond the current extent, look for the 1331 * next extent. 1332 */ 1333 do { 1334 offset -= icblen; 1335 ad_offset = sizeof(struct long_ad) * ad_num; 1336 if (ad_offset > l_ad) { 1337 printf("LFile offset out of bounds (%d > %d)\n", 1338 ad_offset, l_ad); 1339 return (EINVAL); 1340 } 1341 if (udf_checktag(&up->u_fentry->tag, TAGID_EXTFENTRY) == 0) 1342 icb = GETICB(long_ad, xfentry, l_ea + ad_offset); 1343 else 1344 icb = GETICB(long_ad, fentry, l_ea + ad_offset); 1345 icblen = GETICBLEN(long_ad, icb); 1346 ad_num++; 1347 } while(offset >= icblen); 1348 1349 lsector = (offset >> ump->um_bshift) + 1350 letoh32(((struct long_ad *)(icb))->loc.lb_num); 1351 1352 *max_size = GETICBLEN(long_ad, icb); 1353 1354 break; 1355 case 3: 1356 /* 1357 * This type means that the file *data* is stored in the 1358 * allocation descriptor field of the file entry. 1359 */ 1360 *max_size = 0; 1361 *sector = up->u_ino + ump->um_start; 1362 1363 return (UDF_INVALID_BMAP); 1364 case 2: 1365 /* DirectCD does not use extended_ad's */ 1366 default: 1367 printf("Unsupported allocation descriptor %d\n", 1368 tag->flags & 0x7); 1369 return (ENODEV); 1370 } 1371 1372 *sector = lsector + ump->um_start; 1373 1374 /* 1375 * Check the sparing table. Each entry represents the beginning of 1376 * a packet. 1377 */ 1378 if (ump->um_stbl != NULL) { 1379 for (i = 0; i< ump->um_stbl_len; i++) { 1380 p_offset = 1381 lsector - letoh32(ump->um_stbl->entries[i].org); 1382 if ((p_offset < ump->um_psecs) && (p_offset >= 0)) { 1383 *sector = 1384 letoh32(ump->um_stbl->entries[i].map) + 1385 p_offset; 1386 break; 1387 } 1388 } 1389 } 1390 1391 return (0); 1392 } 1393