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