|
|
1.1.1.2 root 1: /* 1.1.1.3 ! root 2: * isofs_vnops.c,v 1.5 1993/07/19 13:40:10 cgd Exp 1.1.1.2 root 3: */ 1.1 root 4: #include "param.h" 5: #include "systm.h" 6: #include "namei.h" 7: #include "resourcevar.h" 8: #include "kernel.h" 9: #include "file.h" 10: #include "stat.h" 11: #include "buf.h" 12: #include "proc.h" 13: #include "conf.h" 14: #include "mount.h" 15: #include "vnode.h" 16: #include "specdev.h" 17: #include "fifo.h" 18: #include "malloc.h" 19: #include "dir.h" 20: 21: #include "iso.h" 22: #include "isofs_node.h" 1.1.1.3 ! root 23: #include "iso_rrip.h" 1.1 root 24: 25: /* 26: * Open called. 27: * 28: * Nothing to do. 29: */ 30: /* ARGSUSED */ 31: isofs_open(vp, mode, cred, p) 32: struct vnode *vp; 33: int mode; 34: struct ucred *cred; 35: struct proc *p; 36: { 37: return (0); 38: } 39: 40: /* 41: * Close called 42: * 43: * Update the times on the inode on writeable file systems. 44: */ 45: /* ARGSUSED */ 46: isofs_close(vp, fflag, cred, p) 47: struct vnode *vp; 48: int fflag; 49: struct ucred *cred; 50: struct proc *p; 51: { 52: return (0); 53: } 54: 55: /* 56: * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 57: * The mode is shifted to select the owner/group/other fields. The 58: * super user is granted all permissions. 59: */ 60: isofs_access(vp, mode, cred, p) 61: struct vnode *vp; 62: register int mode; 63: struct ucred *cred; 64: struct proc *p; 65: { 66: return (0); 67: } 68: 69: /* ARGSUSED */ 70: isofs_getattr(vp, vap, cred, p) 71: struct vnode *vp; 72: register struct vattr *vap; 73: struct ucred *cred; 74: struct proc *p; 75: { 76: register struct iso_node *ip = VTOI(vp); 77: int i; 78: 79: vap->va_fsid = ip->i_dev; 80: vap->va_fileid = ip->i_number; 81: if (vp->v_type == VDIR) 82: vap->va_nlink = 2; 83: else 84: vap->va_nlink = 1; 1.1.1.3 ! root 85: ! 86: vap->va_mode = ip->inode.iso_mode; ! 87: vap->va_uid = ip->inode.iso_uid; ! 88: vap->va_gid = ip->inode.iso_gid; ! 89: vap->va_atime= ip->inode.iso_atime; ! 90: vap->va_mtime= ip->inode.iso_mtime; ! 91: vap->va_ctime= ip->inode.iso_ctime; ! 92: 1.1 root 93: vap->va_rdev = 0; 94: vap->va_size = ip->i_size; 95: vap->va_size_rsv = 0; 96: vap->va_flags = 0; 97: vap->va_gen = 1; 98: vap->va_blocksize = ip->i_mnt->logical_block_size; 99: vap->va_bytes = ip->i_size; 100: vap->va_bytes_rsv = 0; 101: vap->va_type = vp->v_type; 102: return (0); 103: } 104: 105: /* 106: * Vnode op for reading. 107: */ 108: /* ARGSUSED */ 109: isofs_read(vp, uio, ioflag, cred) 110: struct vnode *vp; 111: register struct uio *uio; 112: int ioflag; 113: struct ucred *cred; 114: { 115: register struct iso_node *ip = VTOI(vp); 116: register struct iso_mnt *imp; 117: struct buf *bp; 118: daddr_t lbn, bn, rablock; 119: int size, diff, error = 0; 120: long n, on, type; 121: 122: #ifdef DIAGNOSTICx 123: if (uio->uio_rw != UIO_READ) 124: panic("isofs_read mode"); 125: type = ip->i_mode & IFMT; 126: if (type != IFDIR && type != IFREG && type != IFLNK) 127: panic("isofs_read type"); 128: #endif 129: if (uio->uio_resid == 0) 130: return (0); 131: if (uio->uio_offset < 0) 132: return (EINVAL); 133: ip->i_flag |= IACC; 134: imp = ip->i_mnt; 135: do { 136: lbn = iso_lblkno(imp, uio->uio_offset); 137: on = iso_blkoff(imp, uio->uio_offset); 138: n = MIN((unsigned)(imp->im_bsize - on), uio->uio_resid); 139: diff = ip->i_size - uio->uio_offset; 140: if (diff <= 0) 141: return (0); 142: if (diff < n) 143: n = diff; 144: size = iso_blksize(imp, ip, lbn); 145: rablock = lbn + 1; 146: if (vp->v_lastr + 1 == lbn && 147: iso_lblktosize(imp, rablock) < ip->i_size) 148: error = breada(ITOV(ip), lbn, size, rablock, 149: iso_blksize(imp, ip, rablock), NOCRED, &bp); 150: else 151: error = bread(ITOV(ip), lbn, size, NOCRED, &bp); 152: vp->v_lastr = lbn; 153: n = MIN(n, size - bp->b_resid); 154: if (error) { 155: brelse(bp); 156: return (error); 157: } 158: 159: error = uiomove(bp->b_un.b_addr + on, (int)n, uio); 160: if (n + on == imp->im_bsize || uio->uio_offset == ip->i_size) 161: bp->b_flags |= B_AGE; 162: brelse(bp); 163: } while (error == 0 && uio->uio_resid > 0 && n != 0); 164: return (error); 165: } 166: 167: /* ARGSUSED */ 168: isofs_ioctl(vp, com, data, fflag, cred, p) 169: struct vnode *vp; 170: int com; 171: caddr_t data; 172: int fflag; 173: struct ucred *cred; 174: struct proc *p; 175: { 176: return (ENOTTY); 177: } 178: 179: /* ARGSUSED */ 180: isofs_select(vp, which, fflags, cred, p) 181: struct vnode *vp; 182: int which, fflags; 183: struct ucred *cred; 184: struct proc *p; 185: { 186: 187: /* 188: * We should really check to see if I/O is possible. 189: */ 190: return (1); 191: } 192: 193: /* 194: * Mmap a file 195: * 196: * NB Currently unsupported. 197: */ 198: /* ARGSUSED */ 199: isofs_mmap(vp, fflags, cred, p) 200: struct vnode *vp; 201: int fflags; 202: struct ucred *cred; 203: struct proc *p; 204: { 205: 206: return (EINVAL); 207: } 208: 209: /* 210: * Seek on a file 211: * 212: * Nothing to do, so just return. 213: */ 214: /* ARGSUSED */ 215: isofs_seek(vp, oldoff, newoff, cred) 216: struct vnode *vp; 217: off_t oldoff, newoff; 218: struct ucred *cred; 219: { 220: 221: return (0); 222: } 223: 224: /* 225: * Vnode op for readdir 226: */ 227: isofs_readdir(vp, uio, cred, eofflagp) 228: struct vnode *vp; 229: register struct uio *uio; 230: struct ucred *cred; 231: int *eofflagp; 232: { 233: struct dirent dirent; 234: int iso_offset; 235: int entryoffsetinblock; 236: int error = 0; 237: int endsearch; 238: struct iso_directory_record *ep; 239: int reclen; 240: struct iso_mnt *imp; 241: struct iso_node *ip; 242: struct buf *bp = NULL; 243: int i; 244: int end_flag = 0; 1.1.1.3 ! root 245: ISO_RRIP_ANALYZE ana; 1.1 root 246: 247: ip = VTOI (vp); 248: imp = ip->i_mnt; 249: 250: iso_offset = uio->uio_offset; 251: 252: entryoffsetinblock = iso_blkoff(imp, iso_offset); 253: if (entryoffsetinblock != 0) { 254: if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp)) 255: return (error); 256: } 257: 258: endsearch = ip->i_size; 259: 260: while (iso_offset < endsearch && uio->uio_resid > 0) { 261: /* 262: * If offset is on a block boundary, 263: * read the next directory block. 264: * Release previous if it exists. 265: */ 266: 267: if (iso_blkoff(imp, iso_offset) == 0) { 268: if (bp != NULL) 269: brelse(bp); 270: if (error = iso_blkatoff(ip, iso_offset, 271: (char **)0, &bp)) 272: return (error); 273: entryoffsetinblock = 0; 274: } 275: /* 276: * Get pointer to next entry. 277: */ 278: 279: ep = (struct iso_directory_record *) 280: (bp->b_un.b_addr + entryoffsetinblock); 281: 282: reclen = isonum_711 (ep->length); 283: if (reclen == 0) { 284: /* skip to next block, if any */ 285: iso_offset = roundup (iso_offset, 286: imp->logical_block_size); 287: continue; 288: } 289: 290: if (reclen < sizeof (struct iso_directory_record)) 291: /* illegal entry, stop */ 292: break; 293: 1.1.1.2 root 294: /* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) 1.1 root 295: /* illegal directory, so stop looking */ 296: break; 297: 298: dirent.d_fileno = isonum_733 (ep->extent); 299: dirent.d_namlen = isonum_711 (ep->name_len); 300: 301: if (reclen < sizeof (struct iso_directory_record) 302: + dirent.d_namlen) 303: /* illegal entry, stop */ 304: break; 305: 1.1.1.3 ! root 306: /* ! 307: * ! 308: */ ! 309: switch (ep->name[0]) { 1.1 root 310: case 0: 311: dirent.d_name[0] = '.'; 1.1.1.3 ! root 312: dirent.d_namlen = 1; 1.1 root 313: break; 314: case 1: 315: dirent.d_name[0] = '.'; 316: dirent.d_name[1] = '.'; 317: dirent.d_namlen = 2; 1.1.1.3 ! root 318: break; ! 319: default: ! 320: switch ( imp->iso_ftype ) { ! 321: case ISO_FTYPE_RRIP: ! 322: isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen ); ! 323: break; ! 324: case ISO_FTYPE_9660: ! 325: isofntrans(ep->name, dirent.d_namlen, dirent.d_name, &dirent.d_namlen); ! 326: break; ! 327: default: ! 328: break; ! 329: } ! 330: break; 1.1 root 331: } 1.1.1.3 ! root 332: 1.1 root 333: dirent.d_name[dirent.d_namlen] = 0; 334: dirent.d_reclen = DIRSIZ (&dirent); 335: 336: if (uio->uio_resid < dirent.d_reclen) 337: break; 338: 339: if (error = uiomove (&dirent, dirent.d_reclen, uio)) 340: break; 341: 342: iso_offset += reclen; 343: entryoffsetinblock += reclen; 344: } 345: 346: if (bp) 347: brelse (bp); 348: 349: if (end_flag || (VTOI(vp)->i_size - iso_offset) <= 0) 350: *eofflagp = 1; 351: else 352: *eofflagp = 0; 353: 354: uio->uio_offset = iso_offset; 355: 356: return (error); 357: } 358: 359: /* 1.1.1.3 ! root 360: * Return target name of a symbolic link ! 361: */ ! 362: typedef struct iso_directory_record ISODIR; ! 363: typedef struct iso_node ISONODE; ! 364: typedef struct iso_mnt ISOMNT; ! 365: int isofs_readlink(vp, uio, cred) ! 366: struct vnode *vp; ! 367: struct uio *uio; ! 368: struct ucred *cred; ! 369: { ! 370: ISONODE *ip; ! 371: ISODIR *dirp; ! 372: ISOMNT *imp; ! 373: struct buf *bp; ! 374: int symlen; ! 375: int error; ! 376: char symname[NAME_MAX]; ! 377: ! 378: ip = VTOI( vp ); ! 379: imp = ip->i_mnt; ! 380: /* ! 381: * Get parents directory record block that this inode included. ! 382: */ ! 383: error = bread( imp->im_devvp, ! 384: (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 11 ) ) ! 385: * imp->im_bsize / DEV_BSIZE ), ! 386: imp->im_bsize, ! 387: NOCRED, ! 388: &bp ); ! 389: if ( error ) { ! 390: return( EINVAL ); ! 391: } ! 392: ! 393: /* ! 394: * Setup the directory pointer for this inode ! 395: */ ! 396: ! 397: dirp = (ISODIR *)(bp->b_un.b_addr + ( ip->iso_parent & 0x7ff ) ); ! 398: #ifdef DEBUG ! 399: printf("lbn=%d[base=%d,off=%d,bsize=%d,DEV_BSIZE=%d], dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n", ! 400: (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 12 ) ) * imp->im_bsize / DEV_BSIZE ), ! 401: ip->iso_parent_ext, ! 402: (ip->iso_parent >> 11 ), ! 403: imp->im_bsize, ! 404: DEV_BSIZE, ! 405: dirp, ! 406: bp->b_un.b_addr, ! 407: ip->iso_parent, ! 408: ip->iso_parent & 0x7ff ); ! 409: #endif ! 410: ! 411: /* ! 412: * Just make sure, we have a right one.... ! 413: * 1: Check not cross boundary on block ! 414: * 2: Check number of inode ! 415: */ ! 416: if ( (ip->iso_parent & 0x7ff) + isonum_711( dirp->length ) >= ! 417: imp->im_bsize ) { ! 418: brelse ( bp ); ! 419: return( EINVAL ); ! 420: } ! 421: if ( isonum_733(dirp->extent) != ip->i_number ) { ! 422: brelse ( bp ); ! 423: return( EINVAL ); ! 424: } ! 425: ! 426: /* ! 427: * Ok, we just gathering a Symbolick name in SL record. ! 428: */ ! 429: if ( isofs_rrip_getsymname( vp, dirp, symname, &symlen ) == 0 ) { ! 430: brelse ( bp ); ! 431: return( EINVAL ); ! 432: } ! 433: /* ! 434: * Don't forget before you leave from home ;-) ! 435: */ ! 436: brelse( bp ); ! 437: ! 438: /* ! 439: * return with the Symbolick name to caller's. ! 440: */ ! 441: return ( uiomove( symname, symlen, uio ) ); ! 442: } ! 443: ! 444: /* 1.1 root 445: * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually 446: * done. If a buffer has been saved in anticipation of a CREATE, delete it. 447: */ 448: /* ARGSUSED */ 449: isofs_abortop(ndp) 450: struct nameidata *ndp; 451: { 452: 453: if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF) 454: FREE(ndp->ni_pnbuf, M_NAMEI); 455: return (0); 456: } 457: 458: /* 459: * Lock an inode. 460: */ 461: isofs_lock(vp) 462: struct vnode *vp; 463: { 464: register struct iso_node *ip = VTOI(vp); 465: 466: ISO_ILOCK(ip); 467: return (0); 468: } 469: 470: /* 471: * Unlock an inode. 472: */ 473: isofs_unlock(vp) 474: struct vnode *vp; 475: { 476: register struct iso_node *ip = VTOI(vp); 477: 478: if (!(ip->i_flag & ILOCKED)) 479: panic("isofs_unlock NOT LOCKED"); 480: ISO_IUNLOCK(ip); 481: return (0); 482: } 483: 484: /* 485: * Check for a locked inode. 486: */ 487: isofs_islocked(vp) 488: struct vnode *vp; 489: { 490: 491: if (VTOI(vp)->i_flag & ILOCKED) 492: return (1); 493: return (0); 494: } 495: 496: /* 497: * Calculate the logical to physical mapping if not done already, 498: * then call the device strategy routine. 499: */ 500: 501: isofs_strategy(bp) 502: register struct buf *bp; 503: { 504: register struct iso_node *ip = VTOI(bp->b_vp); 505: struct vnode *vp; 506: int error; 507: 508: if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR) 509: panic("isofs_strategy: spec"); 510: if (bp->b_blkno == bp->b_lblkno) { 511: if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno)) 512: return (error); 513: if ((long)bp->b_blkno == -1) 514: clrbuf(bp); 515: } 516: if ((long)bp->b_blkno == -1) { 517: biodone(bp); 518: return (0); 519: } 520: vp = ip->i_devvp; 521: bp->b_dev = vp->v_rdev; 522: (*(vp->v_op->vop_strategy))(bp); 523: return (0); 524: } 525: 526: /* 527: * Print out the contents of an inode. 528: */ 529: isofs_print(vp) 530: struct vnode *vp; 531: { 1.1.1.3 ! root 532: printf ("tag VT_ISOFS, isofs vnode\n"); 1.1 root 533: } 534: 535: extern int enodev (); 536: 537: /* 538: * Global vfs data structures for isofs 539: */ 540: struct vnodeops isofs_vnodeops = { 541: isofs_lookup, /* lookup */ 542: (void *)enodev, /* create */ 543: (void *)enodev, /* mknod */ 544: isofs_open, /* open */ 545: isofs_close, /* close */ 546: isofs_access, /* access */ 547: isofs_getattr, /* getattr */ 548: (void *)enodev, /* setattr */ 549: isofs_read, /* read */ 550: (void *)enodev, /* write */ 551: isofs_ioctl, /* ioctl */ 552: isofs_select, /* select */ 553: isofs_mmap, /* mmap */ 554: (void *)nullop, /* fsync */ 555: isofs_seek, /* seek */ 556: (void *)enodev, /* remove */ 557: (void *)enodev, /* link */ 558: (void *)enodev, /* rename */ 559: (void *)enodev, /* mkdir */ 560: (void *)enodev, /* rmdir */ 561: (void *)enodev, /* symlink */ 562: isofs_readdir, /* readdir */ 1.1.1.3 ! root 563: isofs_readlink, /* readlink */ 1.1 root 564: isofs_abortop, /* abortop */ 565: isofs_inactive, /* inactive */ 566: isofs_reclaim, /* reclaim */ 567: isofs_lock, /* lock */ 568: isofs_unlock, /* unlock */ 569: (void *)enodev, /* bmap */ 570: isofs_strategy, /* strategy */ 571: isofs_print, /* print */ 572: isofs_islocked, /* islocked */ 573: (void *)enodev, /* advlock */ 574: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.