Annotation of coherent/b/STREAMS/coh.386/fs1.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.