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