1 /*- 2 * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* udf_vnops.c */ 30 /* Take care of the vnode side of things */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/namei.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/stat.h> 38 #include <sys/bio.h> 39 #include <sys/conf.h> 40 #include <sys/buf.h> 41 #include <sys/iconv.h> 42 #include <sys/mount.h> 43 #include <sys/vnode.h> 44 #include <sys/dirent.h> 45 #include <sys/queue.h> 46 #include <sys/unistd.h> 47 #include <sys/endian.h> 48 49 #include <vm/uma.h> 50 51 #include <fs/udf/ecma167-udf.h> 52 #include <fs/udf/osta.h> 53 #include <fs/udf/udf.h> 54 #include <fs/udf/udf_mount.h> 55 56 extern struct iconv_functions *udf_iconv; 57 58 static vop_access_t udf_access; 59 static vop_getattr_t udf_getattr; 60 static vop_open_t udf_open; 61 static vop_ioctl_t udf_ioctl; 62 static vop_pathconf_t udf_pathconf; 63 static vop_read_t udf_read; 64 static vop_readdir_t udf_readdir; 65 static vop_readlink_t udf_readlink; 66 static vop_strategy_t udf_strategy; 67 static vop_bmap_t udf_bmap; 68 static vop_cachedlookup_t udf_lookup; 69 static vop_reclaim_t udf_reclaim; 70 static int udf_readatoffset(struct udf_node *node, int *size, off_t offset, 71 struct buf **bp, uint8_t **data); 72 static int udf_bmap_internal(struct udf_node *node, off_t offset, 73 daddr_t *sector, uint32_t *max_size); 74 75 static struct vop_vector udf_vnodeops = { 76 .vop_default = &default_vnodeops, 77 78 .vop_access = udf_access, 79 .vop_bmap = udf_bmap, 80 .vop_cachedlookup = udf_lookup, 81 .vop_getattr = udf_getattr, 82 .vop_ioctl = udf_ioctl, 83 .vop_lookup = vfs_cache_lookup, 84 .vop_open = udf_open, 85 .vop_pathconf = udf_pathconf, 86 .vop_read = udf_read, 87 .vop_readdir = udf_readdir, 88 .vop_readlink = udf_readlink, 89 .vop_reclaim = udf_reclaim, 90 .vop_strategy = udf_strategy, 91 }; 92 93 MALLOC_DEFINE(M_UDFFID, "udf_fid", "UDF FileId structure"); 94 MALLOC_DEFINE(M_UDFDS, "udf_ds", "UDF Dirstream structure"); 95 96 #define UDF_INVALID_BMAP -1 97 98 int 99 udf_allocv(struct mount *mp, struct vnode **vpp, struct thread *td) 100 { 101 int error; 102 struct vnode *vp; 103 104 error = getnewvnode("udf", mp, &udf_vnodeops, &vp); 105 if (error) { 106 printf("udf_allocv: failed to allocate new vnode\n"); 107 return (error); 108 } 109 110 *vpp = vp; 111 return (0); 112 } 113 114 /* Convert file entry permission (5 bits per owner/group/user) to a mode_t */ 115 static mode_t 116 udf_permtomode(struct udf_node *node) 117 { 118 uint32_t perm; 119 uint16_t flags; 120 mode_t mode; 121 122 perm = le32toh(node->fentry->perm); 123 flags = le16toh(node->fentry->icbtag.flags); 124 125 mode = perm & UDF_FENTRY_PERM_USER_MASK; 126 mode |= ((perm & UDF_FENTRY_PERM_GRP_MASK) >> 2); 127 mode |= ((perm & UDF_FENTRY_PERM_OWNER_MASK) >> 4); 128 mode |= ((flags & UDF_ICB_TAG_FLAGS_STICKY) << 4); 129 mode |= ((flags & UDF_ICB_TAG_FLAGS_SETGID) << 6); 130 mode |= ((flags & UDF_ICB_TAG_FLAGS_SETUID) << 8); 131 132 return (mode); 133 } 134 135 static int 136 udf_access(struct vop_access_args *a) 137 { 138 struct vnode *vp; 139 struct udf_node *node; 140 mode_t a_mode, mode; 141 142 vp = a->a_vp; 143 node = VTON(vp); 144 a_mode = a->a_mode; 145 146 if (a_mode & VWRITE) { 147 switch (vp->v_type) { 148 case VDIR: 149 case VLNK: 150 case VREG: 151 return (EROFS); 152 /* NOT REACHED */ 153 default: 154 break; 155 } 156 } 157 158 mode = udf_permtomode(node); 159 160 return (vaccess(vp->v_type, mode, node->fentry->uid, node->fentry->gid, 161 a_mode, a->a_cred, NULL)); 162 } 163 164 static int 165 udf_open(struct vop_open_args *ap) { 166 struct udf_node *np = VTON(ap->a_vp); 167 off_t fsize; 168 169 fsize = le64toh(np->fentry->inf_len); 170 vnode_create_vobject(ap->a_vp, fsize, ap->a_td); 171 return 0; 172 } 173 174 static int mon_lens[2][12] = { 175 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 176 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 177 }; 178 179 static int 180 udf_isaleapyear(int year) 181 { 182 int i; 183 184 i = (year % 4) ? 0 : 1; 185 i &= (year % 100) ? 1 : 0; 186 i |= (year % 400) ? 0 : 1; 187 188 return i; 189 } 190 191 /* 192 * XXX This is just a rough hack. Daylight savings isn't calculated and tv_nsec 193 * is ignored. 194 * Timezone calculation compliments of Julian Elischer <julian@elischer.org>. 195 */ 196 static void 197 udf_timetotimespec(struct timestamp *time, struct timespec *t) 198 { 199 int i, lpyear, daysinyear, year; 200 union { 201 uint16_t u_tz_offset; 202 int16_t s_tz_offset; 203 } tz; 204 205 t->tv_nsec = 0; 206 207 /* DirectCD seems to like using bogus year values */ 208 year = le16toh(time->year); 209 if (year < 1970) { 210 t->tv_sec = 0; 211 return; 212 } 213 214 /* Calculate the time and day */ 215 t->tv_sec = time->second; 216 t->tv_sec += time->minute * 60; 217 t->tv_sec += time->hour * 3600; 218 t->tv_sec += time->day * 3600 * 24; 219 220 /* Calculate the month */ 221 lpyear = udf_isaleapyear(year); 222 for (i = 1; i < time->month; i++) 223 t->tv_sec += mon_lens[lpyear][i] * 3600 * 24; 224 225 /* Speed up the calculation */ 226 if (year > 1979) 227 t->tv_sec += 315532800; 228 if (year > 1989) 229 t->tv_sec += 315619200; 230 if (year > 1999) 231 t->tv_sec += 315532800; 232 for (i = 2000; i < year; i++) { 233 daysinyear = udf_isaleapyear(i) + 365 ; 234 t->tv_sec += daysinyear * 3600 * 24; 235 } 236 237 /* 238 * Calculate the time zone. The timezone is 12 bit signed 2's 239 * complement, so we gotta do some extra magic to handle it right. 240 */ 241 tz.u_tz_offset = le16toh(time->type_tz); 242 tz.u_tz_offset &= 0x0fff; 243 if (tz.u_tz_offset & 0x0800) 244 tz.u_tz_offset |= 0xf000; /* extend the sign to 16 bits */ 245 if ((time->type_tz & 0x1000) && (tz.s_tz_offset != -2047)) 246 t->tv_sec -= tz.s_tz_offset * 60; 247 248 return; 249 } 250 251 static int 252 udf_getattr(struct vop_getattr_args *a) 253 { 254 struct vnode *vp; 255 struct udf_node *node; 256 struct vattr *vap; 257 struct file_entry *fentry; 258 struct timespec ts; 259 260 ts.tv_sec = 0; 261 262 vp = a->a_vp; 263 vap = a->a_vap; 264 node = VTON(vp); 265 fentry = node->fentry; 266 267 vap->va_fsid = dev2udev(node->udfmp->im_dev); 268 vap->va_fileid = node->hash_id; 269 vap->va_mode = udf_permtomode(node); 270 vap->va_nlink = le16toh(fentry->link_cnt); 271 /* 272 * XXX The spec says that -1 is valid for uid/gid and indicates an 273 * invalid uid/gid. How should this be represented? 274 */ 275 vap->va_uid = (le32toh(fentry->uid) == -1) ? 0 : le32toh(fentry->uid); 276 vap->va_gid = (le32toh(fentry->gid) == -1) ? 0 : le32toh(fentry->gid); 277 udf_timetotimespec(&fentry->atime, &vap->va_atime); 278 udf_timetotimespec(&fentry->mtime, &vap->va_mtime); 279 vap->va_ctime = vap->va_mtime; /* XXX Stored as an Extended Attribute */ 280 vap->va_rdev = 0; /* XXX */ 281 if (vp->v_type & VDIR) { 282 /* 283 * Directories that are recorded within their ICB will show 284 * as having 0 blocks recorded. Since tradition dictates 285 * that directories consume at least one logical block, 286 * make it appear so. 287 */ 288 if (fentry->logblks_rec != 0) { 289 vap->va_size = 290 le64toh(fentry->logblks_rec) * node->udfmp->bsize; 291 } else { 292 vap->va_size = node->udfmp->bsize; 293 } 294 } else { 295 vap->va_size = le64toh(fentry->inf_len); 296 } 297 vap->va_flags = 0; 298 vap->va_gen = 1; 299 vap->va_blocksize = node->udfmp->bsize; 300 vap->va_bytes = le64toh(fentry->inf_len); 301 vap->va_type = vp->v_type; 302 vap->va_filerev = 0; /* XXX */ 303 return (0); 304 } 305 306 /* 307 * File specific ioctls. 308 */ 309 static int 310 udf_ioctl(struct vop_ioctl_args *a) 311 { 312 printf("%s called\n", __func__); 313 return (ENOTTY); 314 } 315 316 /* 317 * I'm not sure that this has much value in a read-only filesystem, but 318 * cd9660 has it too. 319 */ 320 static int 321 udf_pathconf(struct vop_pathconf_args *a) 322 { 323 324 switch (a->a_name) { 325 case _PC_LINK_MAX: 326 *a->a_retval = 65535; 327 return (0); 328 case _PC_NAME_MAX: 329 *a->a_retval = NAME_MAX; 330 return (0); 331 case _PC_PATH_MAX: 332 *a->a_retval = PATH_MAX; 333 return (0); 334 case _PC_NO_TRUNC: 335 *a->a_retval = 1; 336 return (0); 337 default: 338 return (EINVAL); 339 } 340 } 341 342 #define lblkno(udfmp, loc) ((loc) >> (udfmp)->bshift) 343 #define blkoff(udfmp, loc) ((loc) & (udfmp)->bmask) 344 #define lblktosize(imp, blk) ((blk) << (udfmp)->bshift) 345 346 static int 347 udf_read(struct vop_read_args *ap) 348 { 349 struct vnode *vp = ap->a_vp; 350 struct uio *uio = ap->a_uio; 351 struct udf_node *node = VTON(vp); 352 struct udf_mnt *udfmp; 353 struct buf *bp; 354 daddr_t lbn, rablock; 355 off_t diff, fsize; 356 int error = 0; 357 long size, n, on; 358 359 if (uio->uio_resid == 0) 360 return (0); 361 if (uio->uio_offset < 0) 362 return (EINVAL); 363 fsize = le64toh(node->fentry->inf_len); 364 udfmp = node->udfmp; 365 do { 366 lbn = lblkno(udfmp, uio->uio_offset); 367 on = blkoff(udfmp, uio->uio_offset); 368 n = min((u_int)(udfmp->bsize - on), 369 uio->uio_resid); 370 diff = fsize - uio->uio_offset; 371 if (diff <= 0) 372 return (0); 373 if (diff < n) 374 n = diff; 375 size = udfmp->bsize; 376 rablock = lbn + 1; 377 if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) { 378 if (lblktosize(udfmp, rablock) < fsize) { 379 error = cluster_read(vp, fsize, lbn, size, NOCRED, 380 uio->uio_resid, (ap->a_ioflag >> 16), &bp); 381 } else { 382 error = bread(vp, lbn, size, NOCRED, &bp); 383 } 384 } else { 385 error = bread(vp, lbn, size, NOCRED, &bp); 386 } 387 n = min(n, size - bp->b_resid); 388 if (error) { 389 brelse(bp); 390 return (error); 391 } 392 393 error = uiomove(bp->b_data + on, (int)n, uio); 394 brelse(bp); 395 } while (error == 0 && uio->uio_resid > 0 && n != 0); 396 return (error); 397 } 398 399 /* 400 * Call the OSTA routines to translate the name from a CS0 dstring to a 401 * 16-bit Unicode String. Hooks need to be placed in here to translate from 402 * Unicode to the encoding that the kernel/user expects. Return the length 403 * of the translated string. 404 */ 405 static int 406 udf_transname(char *cs0string, char *destname, int len, struct udf_mnt *udfmp) 407 { 408 unicode_t *transname; 409 char *unibuf, *unip; 410 int i, destlen; 411 ssize_t unilen = 0; 412 size_t destleft = MAXNAMLEN; 413 414 /* Convert 16-bit Unicode to destname */ 415 if (udfmp->im_flags & UDFMNT_KICONV && udf_iconv) { 416 /* allocate a buffer big enough to hold an 8->16 bit expansion */ 417 unibuf = uma_zalloc(udf_zone_trans, M_WAITOK); 418 unip = unibuf; 419 if ((unilen = (ssize_t)udf_UncompressUnicodeByte(len, cs0string, unibuf)) == -1) { 420 printf("udf: Unicode translation failed\n"); 421 uma_zfree(udf_zone_trans, unibuf); 422 return 0; 423 } 424 425 while (unilen > 0 && destleft > 0) { 426 udf_iconv->conv(udfmp->im_d2l, (const char **)&unibuf, 427 (size_t *)&unilen, (char **)&destname, &destleft); 428 /* Unconverted character found */ 429 if (unilen > 0 && destleft > 0) { 430 *destname++ = '?'; 431 destleft--; 432 unibuf += 2; 433 unilen -= 2; 434 } 435 } 436 uma_zfree(udf_zone_trans, unip); 437 *destname = '\0'; 438 destlen = MAXNAMLEN - (int)destleft; 439 } else { 440 /* allocate a buffer big enough to hold an 8->16 bit expansion */ 441 transname = uma_zalloc(udf_zone_trans, M_WAITOK); 442 443 if ((unilen = (ssize_t)udf_UncompressUnicode(len, cs0string, transname)) == -1) { 444 printf("udf: Unicode translation failed\n"); 445 uma_zfree(udf_zone_trans, transname); 446 return 0; 447 } 448 449 for (i = 0; i < unilen ; i++) { 450 if (transname[i] & 0xff00) { 451 destname[i] = '.'; /* Fudge the 16bit chars */ 452 } else { 453 destname[i] = transname[i] & 0xff; 454 } 455 } 456 uma_zfree(udf_zone_trans, transname); 457 destname[unilen] = 0; 458 destlen = (int)unilen; 459 } 460 461 return (destlen); 462 } 463 464 /* 465 * Compare a CS0 dstring with a name passed in from the VFS layer. Return 466 * 0 on a successful match, nonzero otherwise. Unicode work may need to be done 467 * here also. 468 */ 469 static int 470 udf_cmpname(char *cs0string, char *cmpname, int cs0len, int cmplen, struct udf_mnt *udfmp) 471 { 472 char *transname; 473 int error = 0; 474 475 /* This is overkill, but not worth creating a new zone */ 476 transname = uma_zalloc(udf_zone_trans, M_WAITOK); 477 478 cs0len = udf_transname(cs0string, transname, cs0len, udfmp); 479 480 /* Easy check. If they aren't the same length, they aren't equal */ 481 if ((cs0len == 0) || (cs0len != cmplen)) 482 error = -1; 483 else 484 error = bcmp(transname, cmpname, cmplen); 485 486 uma_zfree(udf_zone_trans, transname); 487 return (error); 488 } 489 490 struct udf_uiodir { 491 struct dirent *dirent; 492 u_long *cookies; 493 int ncookies; 494 int acookies; 495 int eofflag; 496 }; 497 498 static int 499 udf_uiodir(struct udf_uiodir *uiodir, int de_size, struct uio *uio, long cookie) 500 { 501 if (uiodir->cookies != NULL) { 502 if (++uiodir->acookies > uiodir->ncookies) { 503 uiodir->eofflag = 0; 504 return (-1); 505 } 506 *uiodir->cookies++ = cookie; 507 } 508 509 if (uio->uio_resid < de_size) { 510 uiodir->eofflag = 0; 511 return (-1); 512 } 513 514 return (uiomove(uiodir->dirent, de_size, uio)); 515 } 516 517 static struct udf_dirstream * 518 udf_opendir(struct udf_node *node, int offset, int fsize, struct udf_mnt *udfmp) 519 { 520 struct udf_dirstream *ds; 521 522 ds = uma_zalloc(udf_zone_ds, M_WAITOK | M_ZERO); 523 524 ds->node = node; 525 ds->offset = offset; 526 ds->udfmp = udfmp; 527 ds->fsize = fsize; 528 529 return (ds); 530 } 531 532 static struct fileid_desc * 533 udf_getfid(struct udf_dirstream *ds) 534 { 535 struct fileid_desc *fid; 536 int error, frag_size = 0, total_fid_size; 537 538 /* End of directory? */ 539 if (ds->offset + ds->off >= ds->fsize) { 540 ds->error = 0; 541 return (NULL); 542 } 543 544 /* Grab the first extent of the directory */ 545 if (ds->off == 0) { 546 ds->size = 0; 547 error = udf_readatoffset(ds->node, &ds->size, ds->offset, 548 &ds->bp, &ds->data); 549 if (error) { 550 ds->error = error; 551 if (ds->bp != NULL) 552 brelse(ds->bp); 553 return (NULL); 554 } 555 } 556 557 /* 558 * Clean up from a previous fragmented FID. 559 * XXX Is this the right place for this? 560 */ 561 if (ds->fid_fragment && ds->buf != NULL) { 562 ds->fid_fragment = 0; 563 FREE(ds->buf, M_UDFFID); 564 } 565 566 fid = (struct fileid_desc*)&ds->data[ds->off]; 567 568 /* 569 * Check to see if the fid is fragmented. The first test 570 * ensures that we don't wander off the end of the buffer 571 * looking for the l_iu and l_fi fields. 572 */ 573 if (ds->off + UDF_FID_SIZE > ds->size || 574 ds->off + le16toh(fid->l_iu) + fid->l_fi + UDF_FID_SIZE > ds->size){ 575 576 /* Copy what we have of the fid into a buffer */ 577 frag_size = ds->size - ds->off; 578 if (frag_size >= ds->udfmp->bsize) { 579 printf("udf: invalid FID fragment\n"); 580 ds->error = EINVAL; 581 return (NULL); 582 } 583 584 /* 585 * File ID descriptors can only be at most one 586 * logical sector in size. 587 */ 588 MALLOC(ds->buf, uint8_t*, ds->udfmp->bsize, M_UDFFID, 589 M_WAITOK | M_ZERO); 590 bcopy(fid, ds->buf, frag_size); 591 592 /* Reduce all of the casting magic */ 593 fid = (struct fileid_desc*)ds->buf; 594 595 if (ds->bp != NULL) 596 brelse(ds->bp); 597 598 /* Fetch the next allocation */ 599 ds->offset += ds->size; 600 ds->size = 0; 601 error = udf_readatoffset(ds->node, &ds->size, ds->offset, 602 &ds->bp, &ds->data); 603 if (error) { 604 ds->error = error; 605 return (NULL); 606 } 607 608 /* 609 * If the fragment was so small that we didn't get 610 * the l_iu and l_fi fields, copy those in. 611 */ 612 if (frag_size < UDF_FID_SIZE) 613 bcopy(ds->data, &ds->buf[frag_size], 614 UDF_FID_SIZE - frag_size); 615 616 /* 617 * Now that we have enough of the fid to work with, 618 * copy in the rest of the fid from the new 619 * allocation. 620 */ 621 total_fid_size = UDF_FID_SIZE + le16toh(fid->l_iu) + fid->l_fi; 622 if (total_fid_size > ds->udfmp->bsize) { 623 printf("udf: invalid FID\n"); 624 ds->error = EIO; 625 return (NULL); 626 } 627 bcopy(ds->data, &ds->buf[frag_size], 628 total_fid_size - frag_size); 629 630 ds->fid_fragment = 1; 631 } else { 632 total_fid_size = le16toh(fid->l_iu) + fid->l_fi + UDF_FID_SIZE; 633 } 634 635 /* 636 * Update the offset. Align on a 4 byte boundary because the 637 * UDF spec says so. 638 */ 639 ds->this_off = ds->off; 640 if (!ds->fid_fragment) { 641 ds->off += (total_fid_size + 3) & ~0x03; 642 } else { 643 ds->off = (total_fid_size - frag_size + 3) & ~0x03; 644 } 645 646 return (fid); 647 } 648 649 static void 650 udf_closedir(struct udf_dirstream *ds) 651 { 652 653 if (ds->bp != NULL) 654 brelse(ds->bp); 655 656 if (ds->fid_fragment && ds->buf != NULL) 657 FREE(ds->buf, M_UDFFID); 658 659 uma_zfree(udf_zone_ds, ds); 660 } 661 662 static int 663 udf_readdir(struct vop_readdir_args *a) 664 { 665 struct vnode *vp; 666 struct uio *uio; 667 struct dirent dir; 668 struct udf_node *node; 669 struct udf_mnt *udfmp; 670 struct fileid_desc *fid; 671 struct udf_uiodir uiodir; 672 struct udf_dirstream *ds; 673 u_long *cookies = NULL; 674 int ncookies; 675 int error = 0; 676 677 vp = a->a_vp; 678 uio = a->a_uio; 679 node = VTON(vp); 680 udfmp = node->udfmp; 681 uiodir.eofflag = 1; 682 683 if (a->a_ncookies != NULL) { 684 /* 685 * Guess how many entries are needed. If we run out, this 686 * function will be called again and thing will pick up were 687 * it left off. 688 */ 689 ncookies = uio->uio_resid / 8; 690 MALLOC(cookies, u_long *, sizeof(u_long) * ncookies, 691 M_TEMP, M_WAITOK); 692 if (cookies == NULL) 693 return (ENOMEM); 694 uiodir.ncookies = ncookies; 695 uiodir.cookies = cookies; 696 uiodir.acookies = 0; 697 } else { 698 uiodir.cookies = NULL; 699 } 700 701 /* 702 * Iterate through the file id descriptors. Give the parent dir 703 * entry special attention. 704 */ 705 ds = udf_opendir(node, uio->uio_offset, le64toh(node->fentry->inf_len), 706 node->udfmp); 707 708 while ((fid = udf_getfid(ds)) != NULL) { 709 710 /* XXX Should we return an error on a bad fid? */ 711 if (udf_checktag(&fid->tag, TAGID_FID)) { 712 printf("Invalid FID tag\n"); 713 hexdump(fid, UDF_FID_SIZE, NULL, 0); 714 error = EIO; 715 break; 716 } 717 718 /* Is this a deleted file? */ 719 if (fid->file_char & UDF_FILE_CHAR_DEL) 720 continue; 721 722 if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) { 723 /* Do up the '.' and '..' entries. Dummy values are 724 * used for the cookies since the offset here is 725 * usually zero, and NFS doesn't like that value 726 */ 727 dir.d_fileno = node->hash_id; 728 dir.d_type = DT_DIR; 729 dir.d_name[0] = '.'; 730 dir.d_name[1] = '\0'; 731 dir.d_namlen = 1; 732 dir.d_reclen = GENERIC_DIRSIZ(&dir); 733 uiodir.dirent = &dir; 734 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 1); 735 if (error) 736 break; 737 738 dir.d_fileno = udf_getid(&fid->icb); 739 dir.d_type = DT_DIR; 740 dir.d_name[0] = '.'; 741 dir.d_name[1] = '.'; 742 dir.d_name[2] = '\0'; 743 dir.d_namlen = 2; 744 dir.d_reclen = GENERIC_DIRSIZ(&dir); 745 uiodir.dirent = &dir; 746 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 2); 747 } else { 748 dir.d_namlen = udf_transname(&fid->data[fid->l_iu], 749 &dir.d_name[0], fid->l_fi, udfmp); 750 dir.d_fileno = udf_getid(&fid->icb); 751 dir.d_type = (fid->file_char & UDF_FILE_CHAR_DIR) ? 752 DT_DIR : DT_UNKNOWN; 753 dir.d_reclen = GENERIC_DIRSIZ(&dir); 754 uiodir.dirent = &dir; 755 error = udf_uiodir(&uiodir, dir.d_reclen, uio, 756 ds->this_off); 757 } 758 if (error) { 759 printf("uiomove returned %d\n", error); 760 break; 761 } 762 763 } 764 765 /* tell the calling layer whether we need to be called again */ 766 *a->a_eofflag = uiodir.eofflag; 767 uio->uio_offset = ds->offset + ds->off; 768 769 if (!error) 770 error = ds->error; 771 772 udf_closedir(ds); 773 774 if (a->a_ncookies != NULL) { 775 if (error) 776 FREE(cookies, M_TEMP); 777 else { 778 *a->a_ncookies = uiodir.acookies; 779 *a->a_cookies = cookies; 780 } 781 } 782 783 return (error); 784 } 785 786 /* Are there any implementations out there that do soft-links? */ 787 static int 788 udf_readlink(struct vop_readlink_args *ap) 789 { 790 printf("%s called\n", __func__); 791 return (EOPNOTSUPP); 792 } 793 794 static int 795 udf_strategy(struct vop_strategy_args *a) 796 { 797 struct buf *bp; 798 struct vnode *vp; 799 struct udf_node *node; 800 int maxsize; 801 daddr_t sector; 802 struct bufobj *bo; 803 int multiplier; 804 805 bp = a->a_bp; 806 vp = a->a_vp; 807 node = VTON(vp); 808 809 if (bp->b_blkno == bp->b_lblkno) { 810 /* 811 * Files that are embedded in the fentry don't translate well 812 * to a block number. Reject. 813 */ 814 if (udf_bmap_internal(node, bp->b_lblkno * node->udfmp->bsize, 815 §or, &maxsize)) { 816 clrbuf(bp); 817 bp->b_blkno = -1; 818 } 819 820 /* bmap gives sector numbers, bio works with device blocks */ 821 multiplier = node->udfmp->bsize / DEV_BSIZE; 822 bp->b_blkno = sector * multiplier; 823 824 } 825 if ((long)bp->b_blkno == -1) { 826 bufdone(bp); 827 return (0); 828 } 829 bo = node->udfmp->im_bo; 830 bp->b_iooffset = dbtob(bp->b_blkno); 831 BO_STRATEGY(bo, bp); 832 return (0); 833 } 834 835 static int 836 udf_bmap(struct vop_bmap_args *a) 837 { 838 struct udf_node *node; 839 uint32_t max_size; 840 daddr_t lsector; 841 int error; 842 843 node = VTON(a->a_vp); 844 845 if (a->a_bop != NULL) 846 *a->a_bop = &node->udfmp->im_devvp->v_bufobj; 847 if (a->a_bnp == NULL) 848 return (0); 849 if (a->a_runb) 850 *a->a_runb = 0; 851 852 error = udf_bmap_internal(node, a->a_bn * node->udfmp->bsize, &lsector, 853 &max_size); 854 if (error) 855 return (error); 856 857 /* Translate logical to physical sector number */ 858 *a->a_bnp = lsector << (node->udfmp->bshift - DEV_BSHIFT); 859 860 /* Punt on read-ahead for now */ 861 if (a->a_runp) 862 *a->a_runp = 0; 863 864 return (0); 865 } 866 867 /* 868 * The all powerful VOP_LOOKUP(). 869 */ 870 static int 871 udf_lookup(struct vop_cachedlookup_args *a) 872 { 873 struct vnode *dvp; 874 struct vnode *tdp = NULL; 875 struct vnode **vpp = a->a_vpp; 876 struct udf_node *node; 877 struct udf_mnt *udfmp; 878 struct fileid_desc *fid = NULL; 879 struct udf_dirstream *ds; 880 struct thread *td; 881 u_long nameiop; 882 u_long flags; 883 char *nameptr; 884 long namelen; 885 ino_t id = 0; 886 int offset, error = 0; 887 int numdirpasses, fsize; 888 889 dvp = a->a_dvp; 890 node = VTON(dvp); 891 udfmp = node->udfmp; 892 nameiop = a->a_cnp->cn_nameiop; 893 flags = a->a_cnp->cn_flags; 894 nameptr = a->a_cnp->cn_nameptr; 895 namelen = a->a_cnp->cn_namelen; 896 fsize = le64toh(node->fentry->inf_len); 897 td = a->a_cnp->cn_thread; 898 899 /* 900 * If this is a LOOKUP and we've already partially searched through 901 * the directory, pick up where we left off and flag that the 902 * directory may need to be searched twice. For a full description, 903 * see /sys/isofs/cd9660/cd9660_lookup.c:cd9660_lookup() 904 */ 905 if (nameiop != LOOKUP || node->diroff == 0 || node->diroff > fsize) { 906 offset = 0; 907 numdirpasses = 1; 908 } else { 909 offset = node->diroff; 910 numdirpasses = 2; 911 nchstats.ncs_2passes++; 912 } 913 914 lookloop: 915 ds = udf_opendir(node, offset, fsize, udfmp); 916 917 while ((fid = udf_getfid(ds)) != NULL) { 918 919 /* XXX Should we return an error on a bad fid? */ 920 if (udf_checktag(&fid->tag, TAGID_FID)) { 921 printf("udf_lookup: Invalid tag\n"); 922 error = EIO; 923 break; 924 } 925 926 /* Is this a deleted file? */ 927 if (fid->file_char & UDF_FILE_CHAR_DEL) 928 continue; 929 930 if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) { 931 if (flags & ISDOTDOT) { 932 id = udf_getid(&fid->icb); 933 break; 934 } 935 } else { 936 if (!(udf_cmpname(&fid->data[fid->l_iu], 937 nameptr, fid->l_fi, namelen, udfmp))) { 938 id = udf_getid(&fid->icb); 939 break; 940 } 941 } 942 } 943 944 if (!error) 945 error = ds->error; 946 947 /* XXX Bail out here? */ 948 if (error) { 949 udf_closedir(ds); 950 return (error); 951 } 952 953 /* Did we have a match? */ 954 if (id) { 955 if (flags & ISDOTDOT) 956 VOP_UNLOCK(dvp, 0, a->a_cnp->cn_thread); 957 error = udf_vget(udfmp->im_mountp, id, LK_EXCLUSIVE, &tdp); 958 if (flags & ISDOTDOT) 959 vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY, a->a_cnp->cn_thread); 960 if (!error) { 961 /* 962 * Remember where this entry was if it's the final 963 * component. 964 */ 965 if ((flags & ISLASTCN) && nameiop == LOOKUP) 966 node->diroff = ds->offset + ds->off; 967 if (numdirpasses == 2) 968 nchstats.ncs_pass2++; 969 *vpp = tdp; 970 /* Put this entry in the cache */ 971 if (flags & MAKEENTRY) 972 cache_enter(dvp, *vpp, a->a_cnp); 973 } 974 } else { 975 /* Name wasn't found on this pass. Do another pass? */ 976 if (numdirpasses == 2) { 977 numdirpasses--; 978 offset = 0; 979 udf_closedir(ds); 980 goto lookloop; 981 } 982 983 /* Enter name into cache as non-existant */ 984 if (flags & MAKEENTRY) 985 cache_enter(dvp, *vpp, a->a_cnp); 986 987 if ((flags & ISLASTCN) && 988 (nameiop == CREATE || nameiop == RENAME)) { 989 error = EROFS; 990 } else { 991 error = ENOENT; 992 } 993 } 994 995 udf_closedir(ds); 996 return (error); 997 } 998 999 static int 1000 udf_reclaim(struct vop_reclaim_args *a) 1001 { 1002 struct vnode *vp; 1003 struct udf_node *unode; 1004 1005 vp = a->a_vp; 1006 unode = VTON(vp); 1007 1008 /* 1009 * Destroy the vm object and flush associated pages. 1010 */ 1011 vnode_destroy_vobject(vp); 1012 1013 if (unode != NULL) { 1014 vfs_hash_remove(vp); 1015 1016 if (unode->fentry != NULL) 1017 FREE(unode->fentry, M_UDFFENTRY); 1018 uma_zfree(udf_zone_node, unode); 1019 vp->v_data = NULL; 1020 } 1021 1022 return (0); 1023 } 1024 1025 /* 1026 * Read the block and then set the data pointer to correspond with the 1027 * offset passed in. Only read in at most 'size' bytes, and then set 'size' 1028 * to the number of bytes pointed to. If 'size' is zero, try to read in a 1029 * whole extent. 1030 * 1031 * Note that *bp may be assigned error or not. 1032 * 1033 */ 1034 static int 1035 udf_readatoffset(struct udf_node *node, int *size, off_t offset, 1036 struct buf **bp, uint8_t **data) 1037 { 1038 struct udf_mnt *udfmp; 1039 struct file_entry *fentry = NULL; 1040 struct buf *bp1; 1041 uint32_t max_size; 1042 daddr_t sector; 1043 int error; 1044 1045 udfmp = node->udfmp; 1046 1047 *bp = NULL; 1048 error = udf_bmap_internal(node, offset, §or, &max_size); 1049 if (error == UDF_INVALID_BMAP) { 1050 /* 1051 * This error means that the file *data* is stored in the 1052 * allocation descriptor field of the file entry. 1053 */ 1054 fentry = node->fentry; 1055 *data = &fentry->data[le32toh(fentry->l_ea)]; 1056 *size = le32toh(fentry->l_ad); 1057 return (0); 1058 } else if (error != 0) { 1059 return (error); 1060 } 1061 1062 /* Adjust the size so that it is within range */ 1063 if (*size == 0 || *size > max_size) 1064 *size = max_size; 1065 *size = min(*size, MAXBSIZE); 1066 1067 if ((error = udf_readlblks(udfmp, sector, *size, bp))) { 1068 printf("warning: udf_readlblks returned error %d\n", error); 1069 /* note: *bp may be non-NULL */ 1070 return (error); 1071 } 1072 1073 bp1 = *bp; 1074 *data = (uint8_t *)&bp1->b_data[offset % udfmp->bsize]; 1075 return (0); 1076 } 1077 1078 /* 1079 * Translate a file offset into a logical block and then into a physical 1080 * block. 1081 */ 1082 static int 1083 udf_bmap_internal(struct udf_node *node, off_t offset, daddr_t *sector, 1084 uint32_t *max_size) 1085 { 1086 struct udf_mnt *udfmp; 1087 struct file_entry *fentry; 1088 void *icb; 1089 struct icb_tag *tag; 1090 uint32_t icblen = 0; 1091 daddr_t lsector; 1092 int ad_offset, ad_num = 0; 1093 int i, p_offset; 1094 1095 udfmp = node->udfmp; 1096 fentry = node->fentry; 1097 tag = &fentry->icbtag; 1098 1099 switch (le16toh(tag->strat_type)) { 1100 case 4: 1101 break; 1102 1103 case 4096: 1104 printf("Cannot deal with strategy4096 yet!\n"); 1105 return (ENODEV); 1106 1107 default: 1108 printf("Unknown strategy type %d\n", tag->strat_type); 1109 return (ENODEV); 1110 } 1111 1112 switch (le16toh(tag->flags) & 0x7) { 1113 case 0: 1114 /* 1115 * The allocation descriptor field is filled with short_ad's. 1116 * If the offset is beyond the current extent, look for the 1117 * next extent. 1118 */ 1119 do { 1120 offset -= icblen; 1121 ad_offset = sizeof(struct short_ad) * ad_num; 1122 if (ad_offset > le32toh(fentry->l_ad)) { 1123 printf("File offset out of bounds\n"); 1124 return (EINVAL); 1125 } 1126 icb = GETICB(short_ad, fentry, 1127 le32toh(fentry->l_ea) + ad_offset); 1128 icblen = GETICBLEN(short_ad, icb); 1129 ad_num++; 1130 } while(offset >= icblen); 1131 1132 lsector = (offset >> udfmp->bshift) + 1133 le32toh(((struct short_ad *)(icb))->pos); 1134 1135 *max_size = GETICBLEN(short_ad, icb); 1136 1137 break; 1138 case 1: 1139 /* 1140 * The allocation descriptor field is filled with long_ad's 1141 * If the offset is beyond the current extent, look for the 1142 * next extent. 1143 */ 1144 do { 1145 offset -= icblen; 1146 ad_offset = sizeof(struct long_ad) * ad_num; 1147 if (ad_offset > le32toh(fentry->l_ad)) { 1148 printf("File offset out of bounds\n"); 1149 return (EINVAL); 1150 } 1151 icb = GETICB(long_ad, fentry, 1152 le32toh(fentry->l_ea) + ad_offset); 1153 icblen = GETICBLEN(long_ad, icb); 1154 ad_num++; 1155 } while(offset >= icblen); 1156 1157 lsector = (offset >> udfmp->bshift) + 1158 le32toh(((struct long_ad *)(icb))->loc.lb_num); 1159 1160 *max_size = GETICBLEN(long_ad, icb); 1161 1162 break; 1163 case 3: 1164 /* 1165 * This type means that the file *data* is stored in the 1166 * allocation descriptor field of the file entry. 1167 */ 1168 *max_size = 0; 1169 *sector = node->hash_id + udfmp->part_start; 1170 1171 return (UDF_INVALID_BMAP); 1172 case 2: 1173 /* DirectCD does not use extended_ad's */ 1174 default: 1175 printf("Unsupported allocation descriptor %d\n", 1176 tag->flags & 0x7); 1177 return (ENODEV); 1178 } 1179 1180 *sector = lsector + udfmp->part_start; 1181 1182 /* 1183 * Check the sparing table. Each entry represents the beginning of 1184 * a packet. 1185 */ 1186 if (udfmp->s_table != NULL) { 1187 for (i = 0; i< udfmp->s_table_entries; i++) { 1188 p_offset = 1189 lsector - le32toh(udfmp->s_table->entries[i].org); 1190 if ((p_offset < udfmp->p_sectors) && (p_offset >= 0)) { 1191 *sector = 1192 le32toh(udfmp->s_table->entries[i].map) + 1193 p_offset; 1194 break; 1195 } 1196 } 1197 } 1198 1199 return (0); 1200 } 1201