Annotation of 43BSDTahoe/new/enet/sys/sys_inode.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  *
        !             6:  *     @(#)sys_inode.c 6.13 (Berkeley) 8/4/85
        !             7:  */
        !             8: 
        !             9: #include "param.h"
        !            10: #include "systm.h"
        !            11: #include "dir.h"
        !            12: #include "user.h"
        !            13: #include "inode.h"
        !            14: #include "proc.h"
        !            15: #include "fs.h"
        !            16: #include "conf.h"
        !            17: #include "buf.h"
        !            18: #include "mount.h"
        !            19: #include "file.h"
        !            20: #include "uio.h"
        !            21: #include "ioctl.h"
        !            22: #include "tty.h"
        !            23: #include "cmap.h"
        !            24: #include "stat.h"
        !            25: #include "kernel.h"
        !            26: #include "quota.h"
        !            27: 
        !            28: int    ino_rw(), ino_ioctl(), ino_select(), ino_close();
        !            29: struct         fileops inodeops =
        !            30:        { ino_rw, ino_ioctl, ino_select, ino_close };
        !            31: 
        !            32: ino_rw(fp, rw, uio)
        !            33:        struct file *fp;
        !            34:        enum uio_rw rw;
        !            35:        struct uio *uio;
        !            36: {
        !            37:        register struct inode *ip = (struct inode *)fp->f_data;
        !            38:        int error;
        !            39: 
        !            40:        if ((ip->i_mode&IFMT) == IFREG) {
        !            41:                ILOCK(ip);
        !            42:                if (fp->f_flag&FAPPEND && rw == UIO_WRITE)
        !            43:                        uio->uio_offset = fp->f_offset = ip->i_size;
        !            44:                error = rwip(ip, uio, rw);
        !            45:                IUNLOCK(ip);
        !            46:        } else
        !            47:                error = rwip(ip, uio, rw);
        !            48:        return (error);
        !            49: }
        !            50: 
        !            51: rdwri(rw, ip, base, len, offset, segflg, aresid)
        !            52:        struct inode *ip;
        !            53:        caddr_t base;
        !            54:        int len, offset, segflg;
        !            55:        int *aresid;
        !            56:        enum uio_rw rw;
        !            57: {
        !            58:        struct uio auio;
        !            59:        struct iovec aiov;
        !            60:        int error;
        !            61: 
        !            62:        auio.uio_iov = &aiov;
        !            63:        auio.uio_iovcnt = 1;
        !            64:        aiov.iov_base = base;
        !            65:        aiov.iov_len = len;
        !            66:        auio.uio_resid = len;
        !            67:        auio.uio_offset = offset;
        !            68:        auio.uio_segflg = segflg;
        !            69:        error = rwip(ip, &auio, rw);
        !            70:        if (aresid)
        !            71:                *aresid = auio.uio_resid;
        !            72:        else
        !            73:                if (auio.uio_resid)
        !            74:                        error = EIO;
        !            75:        return (error);
        !            76: }
        !            77: 
        !            78: rwip(ip, uio, rw)
        !            79:        register struct inode *ip;
        !            80:        register struct uio *uio;
        !            81:        enum uio_rw rw;
        !            82: {
        !            83:        dev_t dev = (dev_t)ip->i_rdev;
        !            84:        struct buf *bp;
        !            85:        struct fs *fs;
        !            86:        daddr_t lbn, bn;
        !            87:        register int n, on, type;
        !            88:        int size;
        !            89:        long bsize;
        !            90:        extern int mem_no;
        !            91:        int error = 0;
        !            92: 
        !            93:        if (rw != UIO_READ && rw != UIO_WRITE)
        !            94:                panic("rwip");
        !            95:        if (rw == UIO_READ && uio->uio_resid == 0)
        !            96:                return (0);
        !            97:        if (uio->uio_offset < 0 &&
        !            98:            ((ip->i_mode&IFMT) != IFCHR || mem_no != major(dev)))
        !            99:                return (EINVAL);
        !           100:        if (rw == UIO_READ)
        !           101:                ip->i_flag |= IACC;
        !           102:        type = ip->i_mode&IFMT;
        !           103:        if (type == IFCHR) {
        !           104:                if (rw == UIO_READ)
        !           105:                        error = (*cdevsw[major(dev)].d_read)(dev, uio);
        !           106:                else {
        !           107:                        ip->i_flag |= IUPD|ICHG;
        !           108:                        error = (*cdevsw[major(dev)].d_write)(dev, uio);
        !           109:                }
        !           110:                return (error);
        !           111:        }
        !           112:        if (uio->uio_resid == 0)
        !           113:                return (0);
        !           114:        if (rw == UIO_WRITE && type == IFREG &&
        !           115:            uio->uio_offset + uio->uio_resid >
        !           116:              u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {
        !           117:                psignal(u.u_procp, SIGXFSZ);
        !           118:                return (EFBIG);
        !           119:        }
        !           120:        if (type != IFBLK) {
        !           121:                dev = ip->i_dev;
        !           122:                fs = ip->i_fs;
        !           123:                bsize = fs->fs_bsize;
        !           124:        } else
        !           125:                bsize = BLKDEV_IOSIZE;
        !           126:        do {
        !           127:                lbn = uio->uio_offset / bsize;
        !           128:                on = uio->uio_offset % bsize;
        !           129:                n = MIN((unsigned)(bsize - on), uio->uio_resid);
        !           130:                if (type != IFBLK) {
        !           131:                        if (rw == UIO_READ) {
        !           132:                                int diff = ip->i_size - uio->uio_offset;
        !           133:                                if (diff <= 0)
        !           134:                                        return (0);
        !           135:                                if (diff < n)
        !           136:                                        n = diff;
        !           137:                        }
        !           138:                        bn = fsbtodb(fs,
        !           139:                            bmap(ip, lbn, rw == UIO_WRITE ? B_WRITE: B_READ, (int)(on+n)));
        !           140:                        if (u.u_error || rw == UIO_WRITE && (long)bn<0)
        !           141:                                return (u.u_error);
        !           142:                        if (rw == UIO_WRITE && uio->uio_offset + n > ip->i_size &&
        !           143:                           (type == IFDIR || type == IFREG || type == IFLNK))
        !           144:                                ip->i_size = uio->uio_offset + n;
        !           145:                        size = blksize(fs, ip, lbn);
        !           146:                } else {
        !           147:                        bn = lbn * (BLKDEV_IOSIZE/DEV_BSIZE);
        !           148:                        rablock = bn + (BLKDEV_IOSIZE/DEV_BSIZE);
        !           149:                        rasize = size = bsize;
        !           150:                }
        !           151:                if (rw == UIO_READ) {
        !           152:                        if ((long)bn<0) {
        !           153:                                bp = geteblk(size);
        !           154:                                clrbuf(bp);
        !           155:                        } else if (ip->i_lastr + 1 == lbn)
        !           156:                                bp = breada(dev, bn, size, rablock, rasize);
        !           157:                        else
        !           158:                                bp = bread(dev, bn, size);
        !           159:                        ip->i_lastr = lbn;
        !           160:                } else {
        !           161:                        int i, count, s;
        !           162:                        extern struct cmap *mfind();
        !           163: 
        !           164:                        count = howmany(size, DEV_BSIZE);
        !           165:                        s = splimp();
        !           166:                        for (i = 0; i < count; i += CLBYTES / DEV_BSIZE)
        !           167:                                if (mfind(dev, bn + i))
        !           168:                                        munhash(dev, bn + i);
        !           169:                        splx(s);
        !           170:                        if (n == bsize) 
        !           171:                                bp = getblk(dev, bn, size);
        !           172:                        else
        !           173:                                bp = bread(dev, bn, size);
        !           174:                }
        !           175:                n = MIN(n, size - bp->b_resid);
        !           176:                if (bp->b_flags & B_ERROR) {
        !           177:                        error = EIO;
        !           178:                        brelse(bp);
        !           179:                        goto bad;
        !           180:                }
        !           181:                u.u_error =
        !           182:                    uiomove(bp->b_un.b_addr+on, n, rw, uio);
        !           183:                if (rw == UIO_READ) {
        !           184:                        if (n + on == bsize || uio->uio_offset == ip->i_size)
        !           185:                                bp->b_flags |= B_AGE;
        !           186:                        brelse(bp);
        !           187:                } else {
        !           188:                        if ((ip->i_mode&IFMT) == IFDIR)
        !           189:                                bwrite(bp);
        !           190:                        else if (n + on == bsize) {
        !           191:                                bp->b_flags |= B_AGE;
        !           192:                                bawrite(bp);
        !           193:                        } else
        !           194:                                bdwrite(bp);
        !           195:                        ip->i_flag |= IUPD|ICHG;
        !           196:                        if (u.u_ruid != 0)
        !           197:                                ip->i_mode &= ~(ISUID|ISGID);
        !           198:                }
        !           199:        } while (u.u_error == 0 && uio->uio_resid > 0 && n != 0);
        !           200:        if (error == 0)                         /* XXX */
        !           201:                error = u.u_error;              /* XXX */
        !           202: bad:
        !           203:        return (error);
        !           204: }
        !           205: 
        !           206: ino_ioctl(fp, com, data)
        !           207:        struct file *fp;
        !           208:        register int com;
        !           209:        caddr_t data;
        !           210: {
        !           211:        register struct inode *ip = ((struct inode *)fp->f_data);
        !           212:        register int fmt = ip->i_mode & IFMT;
        !           213:        dev_t dev;
        !           214: 
        !           215:        switch (fmt) {
        !           216: 
        !           217:        case IFREG:
        !           218:        case IFDIR:
        !           219:                if (com == FIONREAD) {
        !           220:                        *(off_t *)data = ip->i_size - fp->f_offset;
        !           221:                        return (0);
        !           222:                }
        !           223:                if (com == FIONBIO || com == FIOASYNC)  /* XXX */
        !           224:                        return (0);                     /* XXX */
        !           225:                /* fall into ... */
        !           226: 
        !           227:        default:
        !           228:                return (ENOTTY);
        !           229: 
        !           230:        case IFCHR:
        !           231:                dev = ip->i_rdev;
        !           232:                u.u_r.r_val1 = 0;
        !           233:                if (setjmp(&u.u_qsave)) {
        !           234:                        if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
        !           235:                                return(EINTR);
        !           236:                        u.u_eosys = RESTARTSYS;
        !           237:                        return (0);
        !           238:                }
        !           239:                return ((*cdevsw[major(dev)].d_ioctl)(dev, com, data,
        !           240:                    fp->f_flag));
        !           241:        }
        !           242: }
        !           243: 
        !           244: ino_select(fp, which)
        !           245:        struct file *fp;
        !           246:        int which;
        !           247: {
        !           248:        register struct inode *ip = (struct inode *)fp->f_data;
        !           249:        register dev_t dev;
        !           250: 
        !           251:        switch (ip->i_mode & IFMT) {
        !           252: 
        !           253:        default:
        !           254:                return (1);             /* XXX */
        !           255: 
        !           256:        case IFCHR:
        !           257:                dev = ip->i_rdev;
        !           258:                return (*cdevsw[major(dev)].d_select)(dev, which);
        !           259:        }
        !           260: }
        !           261: 
        !           262: #ifdef notdef
        !           263: ino_clone()
        !           264: {
        !           265: 
        !           266:        return (EOPNOTSUPP);
        !           267: }
        !           268: #endif
        !           269: 
        !           270: ino_stat(ip, sb)
        !           271:        register struct inode *ip;
        !           272:        register struct stat *sb;
        !           273: {
        !           274: 
        !           275:        ITIMES(ip, &time, &time);
        !           276:        /*
        !           277:         * Copy from inode table
        !           278:         */
        !           279:        sb->st_dev = ip->i_dev;
        !           280:        sb->st_ino = ip->i_number;
        !           281:        sb->st_mode = ip->i_mode;
        !           282:        sb->st_nlink = ip->i_nlink;
        !           283:        sb->st_uid = ip->i_uid;
        !           284:        sb->st_gid = ip->i_gid;
        !           285:        sb->st_rdev = (dev_t)ip->i_rdev;
        !           286:        sb->st_size = ip->i_size;
        !           287:        sb->st_atime = ip->i_atime;
        !           288:        sb->st_spare1 = 0;
        !           289:        sb->st_mtime = ip->i_mtime;
        !           290:        sb->st_spare2 = 0;
        !           291:        sb->st_ctime = ip->i_ctime;
        !           292:        sb->st_spare3 = 0;
        !           293:        /* this doesn't belong here */
        !           294:        if ((ip->i_mode&IFMT) == IFBLK)
        !           295:                sb->st_blksize = BLKDEV_IOSIZE;
        !           296:        else if ((ip->i_mode&IFMT) == IFCHR)
        !           297:                sb->st_blksize = MAXBSIZE;
        !           298:        else
        !           299:                sb->st_blksize = ip->i_fs->fs_bsize;
        !           300:        sb->st_blocks = ip->i_blocks;
        !           301:        sb->st_spare4[0] = sb->st_spare4[1] = 0;
        !           302:        return (0);
        !           303: }
        !           304: 
        !           305: ino_close(fp)
        !           306:        register struct file *fp;
        !           307: {
        !           308:        register struct inode *ip = (struct inode *)fp->f_data;
        !           309:        register struct mount *mp;
        !           310:        int flag, mode;
        !           311:        dev_t dev;
        !           312:        register int (*cfunc)();
        !           313: 
        !           314:        if (fp->f_flag & (FSHLOCK|FEXLOCK))
        !           315:                ino_unlock(fp, FSHLOCK|FEXLOCK);
        !           316:        flag = fp->f_flag;
        !           317:        dev = (dev_t)ip->i_rdev;
        !           318:        mode = ip->i_mode & IFMT;
        !           319:        ilock(ip);
        !           320:        iput(ip);
        !           321:        fp->f_data = (caddr_t) 0;               /* XXX */
        !           322:        switch (mode) {
        !           323: 
        !           324:        case IFCHR:
        !           325:                cfunc = cdevsw[major(dev)].d_close;
        !           326:                break;
        !           327: 
        !           328:        case IFBLK:
        !           329:                /*
        !           330:                 * We don't want to really close the device if it is mounted
        !           331:                 */
        !           332: /* MOUNT TABLE SHOULD HOLD INODE */
        !           333:                for (mp = mount; mp < &mount[NMOUNT]; mp++)
        !           334:                        if (mp->m_bufp != NULL && mp->m_dev == dev)
        !           335:                                return;
        !           336:                cfunc = bdevsw[major(dev)].d_close;
        !           337:                break;
        !           338: 
        !           339:        default:
        !           340:                return;
        !           341:        }
        !           342: 
        !           343:        /*
        !           344:         * Check that another inode for the same device isn't active.
        !           345:         * This is because the same device can be referenced by
        !           346:         * two different inodes.
        !           347:         */
        !           348:        for (fp = file; fp < fileNFILE; fp++) {
        !           349:                if (fp->f_type != DTYPE_INODE)          /* XXX */
        !           350:                        continue;
        !           351:                if (fp->f_count && (ip = (struct inode *)fp->f_data) &&
        !           352:                    ip->i_rdev == dev && (ip->i_mode&IFMT) == mode)
        !           353:                        return;
        !           354:        }
        !           355:        if (mode == IFBLK) {
        !           356:                /*
        !           357:                 * On last close of a block device (that isn't mounted)
        !           358:                 * we must invalidate any in core blocks, so that
        !           359:                 * we can, for instance, change floppy disks.
        !           360:                 */
        !           361:                bflush(dev);
        !           362:                binval(dev);
        !           363:        }
        !           364:        if (setjmp(&u.u_qsave)) {
        !           365:                /*
        !           366:                 * If device close routine is interrupted,
        !           367:                 * must return so closef can clean up.
        !           368:                 */
        !           369:                if (u.u_error == 0)
        !           370:                        u.u_error = EINTR;      /* ??? */
        !           371:                return;
        !           372:        }
        !           373:        (*cfunc)(dev, flag);
        !           374: }
        !           375: 
        !           376: /*
        !           377:  * Place an advisory lock on an inode.
        !           378:  */
        !           379: ino_lock(fp, cmd)
        !           380:        register struct file *fp;
        !           381:        int cmd;
        !           382: {
        !           383:        register int priority = PLOCK;
        !           384:        register struct inode *ip = (struct inode *)fp->f_data;
        !           385: 
        !           386:        if ((cmd & LOCK_EX) == 0)
        !           387:                priority += 4;
        !           388:        if (setjmp(&u.u_qsave)) {
        !           389:                if ((u.u_sigintr & sigmask(u.u_procp->p_cursig)) != 0)
        !           390:                        return(EINTR);
        !           391:                u.u_eosys = RESTARTSYS;
        !           392:                return (0);
        !           393:        }
        !           394:        /*
        !           395:         * If there's a exclusive lock currently applied
        !           396:         * to the file, then we've gotta wait for the
        !           397:         * lock with everyone else.
        !           398:         */
        !           399: again:
        !           400:        while (ip->i_flag & IEXLOCK) {
        !           401:                /*
        !           402:                 * If we're holding an exclusive
        !           403:                 * lock, then release it.
        !           404:                 */
        !           405:                if (fp->f_flag & FEXLOCK) {
        !           406:                        ino_unlock(fp, FEXLOCK);
        !           407:                        continue;
        !           408:                }
        !           409:                if (cmd & LOCK_NB)
        !           410:                        return (EWOULDBLOCK);
        !           411:                ip->i_flag |= ILWAIT;
        !           412:                sleep((caddr_t)&ip->i_exlockc, priority);
        !           413:        }
        !           414:        if ((cmd & LOCK_EX) && (ip->i_flag & ISHLOCK)) {
        !           415:                /*
        !           416:                 * Must wait for any shared locks to finish
        !           417:                 * before we try to apply a exclusive lock.
        !           418:                 *
        !           419:                 * If we're holding a shared
        !           420:                 * lock, then release it.
        !           421:                 */
        !           422:                if (fp->f_flag & FSHLOCK) {
        !           423:                        ino_unlock(fp, FSHLOCK);
        !           424:                        goto again;
        !           425:                }
        !           426:                if (cmd & LOCK_NB)
        !           427:                        return (EWOULDBLOCK);
        !           428:                ip->i_flag |= ILWAIT;
        !           429:                sleep((caddr_t)&ip->i_shlockc, PLOCK);
        !           430:                goto again;
        !           431:        }
        !           432:        if (fp->f_flag & FEXLOCK)
        !           433:                panic("ino_lock");
        !           434:        if (cmd & LOCK_EX) {
        !           435:                cmd &= ~LOCK_SH;
        !           436:                ip->i_exlockc++;
        !           437:                ip->i_flag |= IEXLOCK;
        !           438:                fp->f_flag |= FEXLOCK;
        !           439:        }
        !           440:        if ((cmd & LOCK_SH) && (fp->f_flag & FSHLOCK) == 0) {
        !           441:                ip->i_shlockc++;
        !           442:                ip->i_flag |= ISHLOCK;
        !           443:                fp->f_flag |= FSHLOCK;
        !           444:        }
        !           445:        return (0);
        !           446: }
        !           447: 
        !           448: /*
        !           449:  * Unlock a file.
        !           450:  */
        !           451: ino_unlock(fp, kind)
        !           452:        register struct file *fp;
        !           453:        int kind;
        !           454: {
        !           455:        register struct inode *ip = (struct inode *)fp->f_data;
        !           456:        int flags;
        !           457: 
        !           458:        kind &= fp->f_flag;
        !           459:        if (ip == NULL || kind == 0)
        !           460:                return;
        !           461:        flags = ip->i_flag;
        !           462:        if (kind & FSHLOCK) {
        !           463:                if ((flags & ISHLOCK) == 0)
        !           464:                        panic("ino_unlock: SHLOCK");
        !           465:                if (--ip->i_shlockc == 0) {
        !           466:                        ip->i_flag &= ~ISHLOCK;
        !           467:                        if (flags & ILWAIT)
        !           468:                                wakeup((caddr_t)&ip->i_shlockc);
        !           469:                }
        !           470:                fp->f_flag &= ~FSHLOCK;
        !           471:        }
        !           472:        if (kind & FEXLOCK) {
        !           473:                if ((flags & IEXLOCK) == 0)
        !           474:                        panic("ino_unlock: EXLOCK");
        !           475:                if (--ip->i_exlockc == 0) {
        !           476:                        ip->i_flag &= ~(IEXLOCK|ILWAIT);
        !           477:                        if (flags & ILWAIT)
        !           478:                                wakeup((caddr_t)&ip->i_exlockc);
        !           479:                }
        !           480:                fp->f_flag &= ~FEXLOCK;
        !           481:        }
        !           482: }
        !           483: 
        !           484: /*
        !           485:  * Openi called to allow handler
        !           486:  * of special files to initialize and
        !           487:  * validate before actual IO.
        !           488:  */
        !           489: openi(ip, mode)
        !           490:        register struct inode *ip;
        !           491: {
        !           492:        dev_t dev = (dev_t)ip->i_rdev;
        !           493:        register int maj = major(dev);
        !           494:        int minnum = minor(dev);
        !           495:        register int error;
        !           496: 
        !           497:        switch (ip->i_mode&IFMT) {
        !           498: 
        !           499:        case IFCHR:
        !           500:                if ((u_int)maj >= nchrdev)
        !           501:                        return (ENXIO);
        !           502:                error = (*cdevsw[maj].d_open)(dev, mode, &minnum);
        !           503: 
        !           504:                /*
        !           505:                 * Test for new minor device inode allocation
        !           506:                 */
        !           507:                if ((error == 0) && (minnum != minor(dev))) {
        !           508:                        register struct inode *nip;
        !           509: 
        !           510:                        /*
        !           511:                         * Allocate new inode with new minor device
        !           512:                         * Release old inode. Set vpp to point to new one.
        !           513:                         * This inode will go away when the last reference
        !           514:                         * to it goes away.
        !           515:                         * Warning: if you stat this, and try to match it
        !           516:                         * with a name in the filesystem you will fail,
        !           517:                         * unless you had previously put names in that match.
        !           518:                         */
        !           519:                        nip = ialloc(ip, dirpref(ip->i_fs), (int)ip->i_mode);
        !           520:                        if (nip == (struct inode *)0) {
        !           521:                                /*
        !           522:                                 * Give driver a chance to clean up;
        !           523:                                 * this is iffy since other instances
        !           524:                                 * of this device could be active.
        !           525:                                 */
        !           526:                                cdevsw[maj].d_close(makedev(maj, minnum),
        !           527:                                                                mode&FMASK);
        !           528:                                return (ENXIO);
        !           529:                        }
        !           530:                        nip->i_flag |= IACC|IUPD|ICHG;
        !           531:                        nip->i_mode = ip->i_mode;
        !           532:                        nip->i_nlink = 0;
        !           533:                        nip->i_uid = ip->i_uid;
        !           534:                        nip->i_gid = ip->i_gid;
        !           535:                        nip->i_rdev = makedev(maj, minnum);
        !           536: #ifdef QUOTA
        !           537:                        nip->i_dquot = inoquota(nip);
        !           538: #endif
        !           539:                        irele(ip);
        !           540:                        ip = nip;
        !           541:                        iunlock(ip);
        !           542:                        /*
        !           543:                         * This next line depends on the way copen()
        !           544:                         * works; it's a kludge.
        !           545:                         */
        !           546:                        u.u_ofile[u.u_r.r_val1]->f_data = (caddr_t)ip;
        !           547:                }
        !           548:                return(error);
        !           549: 
        !           550:        case IFBLK:
        !           551:                if ((u_int)maj >= nblkdev)
        !           552:                        return (ENXIO);
        !           553:                return ((*bdevsw[maj].d_open)(dev, mode));
        !           554:        }
        !           555:        return (0);
        !           556: }
        !           557: 
        !           558: /*
        !           559:  * Revoke access the current tty by all processes.
        !           560:  * Used only by the super-user in init
        !           561:  * to give ``clean'' terminals at login.
        !           562:  */
        !           563: vhangup()
        !           564: {
        !           565: 
        !           566:        if (!suser())
        !           567:                return;
        !           568:        if (u.u_ttyp == NULL)
        !           569:                return;
        !           570:        forceclose(u.u_ttyd);
        !           571:        if ((u.u_ttyp->t_state) & TS_ISOPEN)
        !           572:                gsignal(u.u_ttyp->t_pgrp, SIGHUP);
        !           573: }
        !           574: 
        !           575: forceclose(dev)
        !           576:        dev_t dev;
        !           577: {
        !           578:        register struct file *fp;
        !           579:        register struct inode *ip;
        !           580: 
        !           581:        for (fp = file; fp < fileNFILE; fp++) {
        !           582:                if (fp->f_count == 0)
        !           583:                        continue;
        !           584:                if (fp->f_type != DTYPE_INODE)
        !           585:                        continue;
        !           586:                ip = (struct inode *)fp->f_data;
        !           587:                if (ip == 0)
        !           588:                        continue;
        !           589:                if ((ip->i_mode & IFMT) != IFCHR)
        !           590:                        continue;
        !           591:                if (ip->i_rdev != dev)
        !           592:                        continue;
        !           593:                fp->f_flag &= ~(FREAD|FWRITE);
        !           594:        }
        !           595: }

unix.superglobalmegacorp.com

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