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