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