|
|
1.1 ! root 1: /* $Header: /y/coh.386/RCS/fs1.c,v 1.8 93/04/14 10:06:28 root Exp $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * Filesystem (mostly handling of in core inodes). ! 18: * ! 19: * $Log: fs1.c,v $ ! 20: * Revision 1.8 93/04/14 10:06:28 root ! 21: * r75 ! 22: * ! 23: * Revision 1.7 93/02/23 15:50:51 root ! 24: * after caddr_t change, before blclear ! 25: * ! 26: * Revision 1.4 92/07/16 16:33:32 hal ! 27: * Kernel #58 ! 28: * ! 29: * Revision 1.3 92/02/06 17:55:36 vlad ! 30: * Fix typo in ialloc panic. ! 31: * ! 32: * Revision 1.2 92/01/06 11:59:17 hal ! 33: * Compile with cc.mwc. ! 34: * ! 35: * Revision 1.1 88/03/24 16:13:47 src ! 36: * Initial revision ! 37: * ! 38: * 86/12/13 Allan Cornish /usr/src/sys/coh/fs1.c ! 39: * isync() no longer updates the disk image of a character device inode. ! 40: * ! 41: * 86/11/19 Allan Cornish /usr/src/sys/coh/fs1.c ! 42: * idirent() initializes the (new) (IO).io_flag field to 0. ! 43: */ ! 44: #include <sys/coherent.h> ! 45: #include <sys/buf.h> ! 46: #include <canon.h> ! 47: #include <dirent.h> ! 48: #include <errno.h> ! 49: #include <sys/filsys.h> ! 50: #include <sys/ino.h> ! 51: #include <sys/inode.h> ! 52: #include <sys/io.h> ! 53: #include <sys/mount.h>> ! 54: #include <sys/stat.h> ! 55: ! 56: /* ! 57: * Get character for `ftoi' depending on what space the characters are ! 58: * coming from. ! 59: */ ! 60: #define ftoic(p) (u.u_io.io_seg==IOSYS ? *p : getubd(p)) ! 61: ! 62: /* ! 63: * Map the given filename to an inode. If an error is encountered, ! 64: * `u.u_error' is set. `u.u_error' is always returned. As this routine ! 65: * needs to set several things, depending on the type of access, `t', ! 66: * there are places in the processes' user area reserved for this routine ! 67: * to set. These are defined in the user process structure. The seek ! 68: * position is always set to the position of the directory entry of the ! 69: * child if the child exists or the first free position if it doesn't. ! 70: * 'r' => Reference. A pointer to the child's inode is returned locked. ! 71: * 'c' => Create. If the child exists, a pointer to the inode is returned ! 72: * locked. Otherwise if the parent directory exists, a pointer to ! 73: * the parent directory is returned locked. Otherwise, an error. ! 74: * 'u' => Unlink. The parent directory is returned unlocked. The child's ! 75: * inode number is returned. The seek position is also set. ! 76: */ ! 77: ftoi(np, t) ! 78: char *np; ! 79: { ! 80: register INODE *cip; ! 81: register char *cp; ! 82: register int c; ! 83: register struct direct *dp; ! 84: register BUF *bp; ! 85: off_t cseek, fseek, s; ! 86: int fflag, mflag; ! 87: dev_t dev; ! 88: ino_t ino; ! 89: daddr_t b; ! 90: ! 91: u.u_cdirn = 0; ! 92: u.u_cdiri = NULL; ! 93: u.u_pdiri = NULL; ! 94: if ((c=ftoic(np++)) != '/') ! 95: cip = u.u_cdir; ! 96: else { ! 97: c = ftoic(np++); ! 98: cip = u.u_rdir; ! 99: } ! 100: while (c == '/') ! 101: c = ftoic(np++); ! 102: ilock(cip); ! 103: cip->i_refc++; ! 104: if (c == '\0') { ! 105: if (t == 'r') { ! 106: u.u_cdiri = cip; ! 107: return (u.u_error); ! 108: } ! 109: u.u_error = ENOENT; ! 110: idetach(cip); ! 111: return (u.u_error); ! 112: } ! 113: for (;;) { ! 114: cp = u.u_direct.d_name; ! 115: while (c!='/' && c!='\0') { ! 116: if (cp < &u.u_direct.d_name[DIRSIZ]) ! 117: *cp++ = c; ! 118: c = ftoic(np++); ! 119: } ! 120: while (c == '/') ! 121: c = ftoic(np++); ! 122: while (cp < &u.u_direct.d_name[DIRSIZ]) ! 123: *cp++ = '\0'; ! 124: if ((cip->i_mode&IFMT) != IFDIR) ! 125: u.u_error = ENOTDIR; ! 126: else ! 127: iaccess(cip, IPE); ! 128: if (u.u_error) { ! 129: idetach(cip); ! 130: return (u.u_error); ! 131: } ! 132: cp = u.u_direct.d_name; ! 133: if (cip->i_ino==ROOTIN && cip->i_dev!=rootdev) ! 134: if (*cp++=='.' && *cp++=='.' && *cp++=='\0') ! 135: cip = ftoim(cip); ! 136: b = 0; ! 137: fflag = 0; ! 138: mflag = 0; ! 139: cseek = 0; ! 140: s = cip->i_size; ! 141: while (s > 0) { ! 142: if ((bp=vread(cip, b++)) == NULL) { ! 143: idetach(cip); ! 144: return (u.u_error); ! 145: } ! 146: dp = bp->b_vaddr; ! 147: while (dp < bp->b_vaddr+BSIZE) { ! 148: if ((s-=sizeof(*dp)) < 0) ! 149: break; ! 150: if ((ino=dp->d_ino) == 0) { ! 151: if (fflag == 0) { ! 152: fflag++; ! 153: fseek = cseek; ! 154: } ! 155: } else { ! 156: if (direq(dp)) { ! 157: canino(ino); ! 158: mflag = 1; ! 159: s = 0; ! 160: break; ! 161: } ! 162: } ! 163: cseek += sizeof(*dp); ! 164: dp++; ! 165: } ! 166: brelease(bp); ! 167: } ! 168: dev = cip->i_dev; ! 169: if (fflag == 0) ! 170: fseek = cseek; ! 171: if (mflag == 0) { ! 172: if (c=='\0' && t=='c') { ! 173: u.u_pdiri = cip; ! 174: u.u_io.io_seek = fseek; ! 175: } else { ! 176: u.u_error = ENOENT; ! 177: idetach(cip); ! 178: } ! 179: return (u.u_error); ! 180: } ! 181: if (c == '\0') { ! 182: if (t == 'u') { ! 183: u.u_cdirn = ino; ! 184: u.u_pdiri = cip; ! 185: u.u_io.io_seek = cseek; ! 186: return (u.u_error); ! 187: } ! 188: idetach(cip); ! 189: u.u_cdiri = iattach(dev, ino); ! 190: return (u.u_error); ! 191: } ! 192: idetach(cip); ! 193: if ((cip=iattach(dev, ino)) == NULL) ! 194: return (u.u_error); ! 195: } ! 196: } ! 197: ! 198: /* ! 199: * Given an inode which is the root of a file system, return the inode ! 200: * on which the file system was mounted. ! 201: */ ! 202: INODE * ! 203: ftoim(ip) ! 204: register INODE *ip; ! 205: { ! 206: register MOUNT *mp; ! 207: ! 208: for (mp=mountp; mp!=NULL; mp=mp->m_next) { ! 209: if (mp->m_dev == ip->i_dev) { ! 210: idetach(ip); ! 211: ip = mp->m_ip; ! 212: ilock(ip); ! 213: ip->i_refc++; ! 214: break; ! 215: } ! 216: } ! 217: return (ip); ! 218: } ! 219: ! 220: /* ! 221: * Compare the string in `u.u_direct.d_name' with the name in the ! 222: * given directory pointer. ! 223: */ ! 224: direq(dp) ! 225: struct direct *dp; ! 226: { ! 227: register char *cp1, *cp2; ! 228: register unsigned n; ! 229: ! 230: if (dp->d_ino == 0) ! 231: return 0; ! 232: cp1 = dp->d_name; ! 233: cp2 = u.u_direct.d_name; ! 234: n = DIRSIZ; ! 235: do { ! 236: if (*cp1++ != *cp2++) ! 237: return 0; ! 238: } while (--n); ! 239: return 1; ! 240: } ! 241: ! 242: /* ! 243: * Make an inode of the given mode and device. The parent directory, ! 244: * name and such stuff is set by ftoi. ! 245: */ ! 246: INODE * ! 247: imake(mode, rdev) ! 248: unsigned mode; ! 249: dev_t rdev; ! 250: { ! 251: register INODE *ip; ! 252: ! 253: ip = NULL; ! 254: mode &= ~u.u_umask; ! 255: if ((mode&ISVTXT)!=0 && super()==0) ! 256: goto det; ! 257: if (iaccess(u.u_pdiri, IPW) == 0) ! 258: goto det; ! 259: if ((ip=ialloc(u.u_pdiri->i_dev, mode)) == NULL) ! 260: goto det; ! 261: ip->i_nlink = 1; ! 262: ip->i_a.i_rdev = rdev; ! 263: idirent(ip->i_ino); ! 264: iamc(ip); /* creat/mknod - atime/mtime/ctime */ ! 265: det: ! 266: idetach(u.u_pdiri); ! 267: return (ip); ! 268: } ! 269: ! 270: /* ! 271: * Write a directory entry out. Everything necessary has been conveniently ! 272: * set by `ftoi', except the new inode number of this directory entry. ! 273: */ ! 274: idirent(ino) ! 275: { ! 276: u.u_direct.d_ino = ino; ! 277: canino(u.u_direct.d_ino); ! 278: u.u_io.io_ioc = sizeof (struct direct); ! 279: u.u_io.io.vbase = &u.u_direct; ! 280: u.u_io.io_seg = IOSYS; ! 281: u.u_io.io_flag = 0; ! 282: iwrite(u.u_pdiri, &u.u_io); ! 283: } ! 284: ! 285: /* ! 286: * Return a pointer to a locked inode in core containing the given ! 287: * inode number and device. ! 288: */ ! 289: INODE * ! 290: iattach(dev, ino) ! 291: { ! 292: register INODE *ip; ! 293: register INODE *fip; ! 294: register unsigned lrt; ! 295: register MOUNT *mp; ! 296: ! 297: for (;;) { ! 298: fip = NULL; ! 299: for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) { ! 300: if (ip->i_ino==ino && ip->i_dev==dev) ! 301: break; ! 302: if (ip->i_refc == 0) { ! 303: if (fip==NULL || ip->i_lrt<lrt) { ! 304: fip = ip; ! 305: lrt = ip->i_lrt; ! 306: } ! 307: } ! 308: } ! 309: if (ip < inodep) { ! 310: if ((ip=fip) == NULL) { ! 311: devmsg(dev, "Inode table overflow"); ! 312: u.u_error = ENFILE; ! 313: return (NULL); ! 314: } ! 315: ilock(ip); ! 316: if (ip->i_refc != 0) { ! 317: iunlock(ip); ! 318: continue; ! 319: } ! 320: ip->i_dev = dev; ! 321: ip->i_ino = ino; ! 322: ip->i_refc = 1; ! 323: ip->i_lrt = timer.t_time; ! 324: if (icopydm(ip) == 0) { ! 325: ip->i_ino = 0; ! 326: ip->i_refc = 0; ! 327: iunlock(ip); ! 328: return (NULL); ! 329: } ! 330: return (ip); ! 331: } ! 332: if ((ip->i_flag&IFMNT) != 0) { ! 333: for (mp=mountp; mp!=NULL; mp=mp->m_next) { ! 334: if (mp->m_ip == ip) { ! 335: ino = ROOTIN; ! 336: dev = mp->m_dev; ! 337: break; ! 338: } ! 339: } ! 340: continue; ! 341: } ! 342: ilock(ip); ! 343: if (ip->i_ino!=ino || ip->i_dev!=dev) { ! 344: iunlock(ip); ! 345: continue; ! 346: } ! 347: if (ip->i_refc < 0) ! 348: panic("iattach(%x)", ip); ! 349: ip->i_refc++; ! 350: ip->i_lrt = timer.t_time; ! 351: return (ip); ! 352: } ! 353: } ! 354: ! 355: /* ! 356: * Given a locked inode, deaccess it. ! 357: */ ! 358: idetach(ip) ! 359: register INODE *ip; ! 360: { ! 361: #if 0 ! 362: if (ilocked(ip)==0 || ip->i_refc<=0) ! 363: panic("idetach(%p)", ip); ! 364: #else ! 365: if (ilocked(ip)==0) { ! 366: printf("bad unlocked inode, dev=%x, ino=%d, flags=%x\n", ! 367: ip->i_dev, ip->i_ino, ip->i_flag); ! 368: panic("idetach(%p)", ip); ! 369: } ! 370: if (ip->i_refc<=0) { ! 371: printf("negative refc, dev=%x, ino=%d, flags=%x, refc=%d\n", ! 372: ip->i_dev, ip->i_ino, ip->i_flag, ip->i_refc); ! 373: panic("idetach(%p)", ip); ! 374: } ! 375: #endif ! 376: if (--ip->i_refc == 0) { ! 377: #if 1 ! 378: if (ip->i_rl) ! 379: panic("idetach(%p) with locked records", ip); ! 380: #endif ! 381: if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) ! 382: || ip->i_nlink == 0) ! 383: icopymd(ip); ! 384: } ! 385: iunlock(ip); ! 386: } ! 387: ! 388: /* ! 389: * Given a inode which isn't locked, lock it and then deaccess. ! 390: */ ! 391: ldetach(ip) ! 392: register INODE *ip; ! 393: { ! 394: ilock(ip); ! 395: idetach(ip); ! 396: } ! 397: ! 398: /* ! 399: * A specialized routine for finding whether the given inode may be unlinked. ! 400: * Quite simple you say, but we already have an inode locked and could run ! 401: * into gating problems if we were to lock another. So we look through the ! 402: * cache to see if the inode is there. If it is, we can easily tell. If it ! 403: * isn't, `icopydm' is called with a static. This routine is only used by ! 404: * `uunlink'. ! 405: */ ! 406: iucheck(dev, ino) ! 407: register dev_t dev; ! 408: register ino_t ino; ! 409: { ! 410: register INODE *ip; ! 411: INODE inode; ! 412: ! 413: for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) { ! 414: if (ip->i_ino==ino && ip->i_dev==dev) ! 415: break; ! 416: } ! 417: if (ip < inodep) { ! 418: ip = &inode; ! 419: ip->i_dev = dev; ! 420: ip->i_ino = ino; ! 421: if (icopydm(ip) == 0) ! 422: return 0; ! 423: } ! 424: if ((ip->i_mode&IFMT) == IFDIR) { ! 425: if (super() == 0) ! 426: return 0; ! 427: } ! 428: return 1; ! 429: } ! 430: ! 431: /* ! 432: * Copy an inode from disk to memory performing canonization. ! 433: */ ! 434: icopydm(ip) ! 435: register INODE *ip; ! 436: { ! 437: register struct dinode *dip; ! 438: register BUF *bp; ! 439: register ino_t ino; ! 440: struct dinode dinode; ! 441: caddr_t v; ! 442: ! 443: ip->i_flag = 0; ! 444: ino = ip->i_ino; ! 445: ! 446: if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL) ! 447: return 0; ! 448: ! 449: dip = &dinode; ! 450: v = (char *)((struct dinode *)bp->b_vaddr + iblocko(ino)); ! 451: kkcopy( v, dip, sizeof(dinode)); ! 452: brelease(bp); ! 453: ip->i_mode = dip->di_mode; ! 454: canshort(ip->i_mode); ! 455: ip->i_nlink = dip->di_nlink; ! 456: canshort(ip->i_nlink); ! 457: ip->i_uid = dip->di_uid; ! 458: canshort(ip->i_uid); ! 459: ip->i_gid = dip->di_gid; ! 460: canshort(ip->i_gid); ! 461: ip->i_size = dip->di_size; ! 462: cansize(ip->i_size); ! 463: ! 464: switch (ip->i_mode&IFMT) { ! 465: case IFBLK: ! 466: case IFCHR: ! 467: ip->i_a.i_rdev = dip->di_a.di_rdev; ! 468: candev(ip->i_a.i_rdev); ! 469: break; ! 470: case IFREG: ! 471: case IFDIR: ! 472: l3tol(ip->i_a.i_addr, dip->di_a.di_addb, NADDR); ! 473: break; ! 474: case IFPIPE: ! 475: l3tol(ip->i_pipe, dip->di_addp, ND); ! 476: ip->i_pnc = dip->di_pnc; ! 477: canshort(ip->i_pnc); ! 478: ip->i_prx = dip->di_prx; ! 479: canshort(ip->i_prx); ! 480: ip->i_pwx = dip->di_pwx; ! 481: canshort(ip->i_pwx); ! 482: break; ! 483: default: ! 484: kclear(&ip->i_a, sizeof(ip->i_a)); ! 485: break; ! 486: } ! 487: ! 488: ip->i_atime = dip->di_atime; ! 489: cantime(ip->i_atime); ! 490: ip->i_mtime = dip->di_mtime; ! 491: cantime(ip->i_mtime); ! 492: ip->i_ctime = dip->di_ctime; ! 493: cantime(ip->i_ctime); ! 494: ip->i_rl = NULL; ! 495: return 1; ! 496: } ! 497: ! 498: /* ! 499: * Copy an inode from memory back on to disk performing canonization. ! 500: */ ! 501: icopymd(ip) ! 502: register INODE *ip; ! 503: { ! 504: register struct dinode *dip; ! 505: register BUF *bp; ! 506: register ino_t ino; ! 507: struct dinode dinode; ! 508: caddr_t v; ! 509: ! 510: if (getment(ip->i_dev, 0) == NULL) ! 511: return; ! 512: ! 513: ino = ip->i_ino; ! 514: if (ip->i_refc==0 && ip->i_nlink==0 && ino!=BADFIN && ino!=ROOTIN) { ! 515: iclear(ip); ! 516: ip->i_lrt = 0; ! 517: ip->i_mode = 0; ! 518: } ! 519: ! 520: dip = &dinode; ! 521: dip->di_mode = ip->i_mode; ! 522: canshort(dip->di_mode); ! 523: dip->di_nlink = ip->i_nlink; ! 524: canshort(dip->di_nlink); ! 525: dip->di_uid = ip->i_uid; ! 526: canshort(dip->di_uid); ! 527: dip->di_gid = ip->i_gid; ! 528: canshort(dip->di_gid); ! 529: dip->di_size = ip->i_size; ! 530: cansize(dip->di_size); ! 531: ! 532: switch (ip->i_mode&IFMT) { ! 533: case IFBLK: ! 534: case IFCHR: ! 535: dip->di_a.di_rdev = ip->i_a.i_rdev; ! 536: candev(dip->di_a.di_rdev); ! 537: break; ! 538: case IFREG: ! 539: case IFDIR: ! 540: ltol3(dip->di_addr, ip->i_a.i_addr, NADDR); ! 541: break; ! 542: case IFPIPE: ! 543: ltol3(dip->di_addp, ip->i_pipe, ND); ! 544: dip->di_pnc = ip->i_pnc; ! 545: canshort(dip->di_pnc); ! 546: dip->di_prx = ip->i_prx; ! 547: canshort(dip->di_prx); ! 548: dip->di_pwx = ip->i_pwx; ! 549: canshort(dip->di_pwx); ! 550: break; ! 551: default: ! 552: kclear(&dip->di_a, sizeof(dip->di_a)); ! 553: break; ! 554: } ! 555: ! 556: dip->di_atime = ip->i_atime; ! 557: cantime(dip->di_atime); ! 558: dip->di_mtime = ip->i_mtime; ! 559: cantime(dip->di_mtime); ! 560: dip->di_ctime = ip->i_ctime; ! 561: cantime(dip->di_ctime); ! 562: ! 563: if ((bp=bread(ip->i_dev, (daddr_t)iblockn(ino), 1)) == NULL) ! 564: return; ! 565: ! 566: v = (char *)((struct dinode *)bp->b_vaddr + iblocko(ino)); ! 567: kkcopy(dip, v, sizeof(dinode)); ! 568: bp->b_flag |= BFMOD; ! 569: brelease(bp); ! 570: ip->i_flag &= ~(IFACC|IFMOD|IFCRT); ! 571: if (ip->i_refc==0 && ip->i_nlink==0 && ino!=BADFIN && ino!=ROOTIN) ! 572: ifree(ip->i_dev, ino); ! 573: } ! 574: ! 575: /* ! 576: * Copy all relevant inodes out on device `dev'. ! 577: */ ! 578: isync(dev) ! 579: register dev_t dev; ! 580: { ! 581: register INODE *ip; ! 582: ! 583: for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) { ! 584: if (ip->i_refc == 0) ! 585: continue; ! 586: if (ip->i_dev != dev) ! 587: continue; ! 588: if ( (ip->i_mode & IFMT) == IFCHR ) ! 589: continue; ! 590: if ((ip->i_flag&(IFACC|IFMOD|IFCRT)) == 0) ! 591: continue; ! 592: icopymd(ip); ! 593: } ! 594: } ! 595: ! 596: /* ! 597: * Clear the given inode and all space associated with it. ! 598: */ ! 599: iclear(ip) ! 600: register INODE *ip; ! 601: { ! 602: register int n; ! 603: register daddr_t b; ! 604: ! 605: switch (ip->i_mode&IFMT) { ! 606: case IFPIPE: ! 607: ip->i_pnc = ip->i_prx = ip->i_pwx = 0; ! 608: n = ND; ! 609: while (n > 0) { ! 610: if ((b=ip->i_pipe[--n]) != 0) ! 611: bfree(ip->i_dev, b); ! 612: } ! 613: kclear(ip->i_pipe, sizeof(ip->i_pipe)); ! 614: break; ! 615: case IFDIR: ! 616: case IFREG: ! 617: n = NADDR; ! 618: while (n > ND) { ! 619: if ((b=ip->i_a.i_addr[--n]) != 0) ! 620: indfree(ip->i_dev, b, 1+n-ND); ! 621: } ! 622: while (n > 0) { ! 623: if ((b=ip->i_a.i_addr[--n]) != 0) ! 624: bfree(ip->i_dev, b); ! 625: } ! 626: kclear(ip->i_a.i_addr, sizeof(ip->i_a.i_addr)); ! 627: break; ! 628: default: ! 629: return; ! 630: } ! 631: ip->i_size = 0; ! 632: iamc(ip); /* creat/pipe - atime/mtime/ctime */ ! 633: } ! 634: ! 635: /* ! 636: * blclear(ip, lbn) -- Clear all blocks in inode ip beginning with ! 637: * logical blocks number lbn. Called from uchsize() in sys5.c ! 638: */ ! 639: blclear(ip, lbn) ! 640: register INODE *ip; ! 641: fsize_t lbn; ! 642: {} ! 643: ! 644: /* ! 645: * Copy the appropriate information from the inode to the stat buffer. ! 646: */ ! 647: istat(ip, sbp) ! 648: register INODE *ip; ! 649: register struct stat *sbp; ! 650: { ! 651: sbp->st_dev = ip->i_dev; ! 652: sbp->st_ino = ip->i_ino; ! 653: sbp->st_mode = ip->i_mode; ! 654: sbp->st_nlink = ip->i_nlink; ! 655: sbp->st_uid = ip->i_uid; ! 656: sbp->st_gid = ip->i_gid; ! 657: sbp->st_rdev = NODEV; ! 658: sbp->st_size = ip->i_size; ! 659: sbp->st_atime = ip->i_atime; ! 660: sbp->st_mtime = ip->i_mtime; ! 661: sbp->st_ctime = ip->i_ctime; ! 662: switch (ip->i_mode&IFMT) { ! 663: case IFBLK: ! 664: case IFCHR: ! 665: sbp->st_rdev = ip->i_a.i_rdev; ! 666: sbp->st_size = 0; ! 667: break; ! 668: case IFPIPE: ! 669: sbp->st_size = ip->i_pnc; ! 670: break; ! 671: } ! 672: } ! 673: ! 674: /* ! 675: * See if it is possible to access the given inode with the bits in ! 676: * the given mode. ! 677: * If the mode includes writing, and i_refc is > 1, then check for ! 678: * shared text problems. ! 679: */ ! 680: iaccess(ip, mode) ! 681: register INODE *ip; ! 682: register int mode; ! 683: { ! 684: if ((imode(ip, u.u_uid, u.u_gid)&mode) != mode) { ! 685: u.u_error = EACCES; ! 686: return 0; ! 687: } ! 688: if ((mode & IPW) && ip->i_refc > 1 && sbusy(ip)) { ! 689: u.u_error = ETXTBSY; ! 690: return 0; ! 691: } ! 692: return 1; ! 693: } ! 694: ! 695: /* ! 696: * Get the maximum allowable mode on a file. ! 697: */ ! 698: imode(ip, uid, gid) ! 699: register INODE *ip; ! 700: { ! 701: if (uid == 0) { ! 702: /* Superuser can read or write anything. */ ! 703: int ret = IPR | IPW; ! 704: /* ! 705: * If superuser, say the file is executable if any ! 706: * of the 'x' perm bits is set. ! 707: */ ! 708: if (ip->i_mode & 0111) ! 709: ret |= IPE; ! 710: return ret; ! 711: } ! 712: if (uid == ip->i_uid) ! 713: return ((ip->i_mode>>6) & 07); ! 714: if (gid == ip->i_gid) ! 715: return ((ip->i_mode>>3) & 07); ! 716: return (ip->i_mode & 07); ! 717: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.