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