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