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