Annotation of coherent/b/kernel/coh.386/fs1.c, revision 1.1

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

unix.superglobalmegacorp.com

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