Annotation of coherent/b/STREAMS/coh.386/fs1.c, revision 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.