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