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