Annotation of researchv10no/sys/fs/ms.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     This file contains the routines which support mounted
        !             3:  *     streams (file system type 3).
        !             4:  */
        !             5: #include "sys/param.h"
        !             6: #include "sys/systm.h"
        !             7: #include "sys/inode.h"
        !             8: #include "sys/stream.h"
        !             9: #include "sys/user.h"
        !            10: #include "sys/file.h"
        !            11: #include "sys/stat.h"
        !            12: #include "sys/conf.h"
        !            13: 
        !            14: int msupdat(), msread(), mswrite(), msstat();
        !            15: int msmount(), msioctl();
        !            16: struct inode *msopen();
        !            17: struct fstypsw msfs =
        !            18: fsinit(nulldev, msupdat, msread, mswrite, nulldev, msstat,
        !            19:        nullnami, msmount, msioctl, msopen, nodev);
        !            20: 
        !            21: /*
        !            22:  *  The following definitions apply to all comments:
        !            23:  *     - `locked' means that an inode has had `plock' applied to it
        !            24:  *     - `reserved' means that the inode's i_count has been incremented to
        !            25:  *       ensure that the inode will be freed during an operation.
        !            26:  */
        !            27: 
        !            28: /*
        !            29:  *  To ensure consistency
        !            30:  */
        !            31: #define SETMOUNT(d,r) d->i_mroot = r
        !            32: #define CLRMOUNT(d) d->i_mroot = NULL
        !            33: 
        !            34: msmount(cip, dip, flag, mnt, fstyp)
        !            35: struct inode *cip, *dip;
        !            36: {
        !            37: 
        !            38:        if(accowner(dip) == 0)  /* only owner can mount */
        !            39:                return;         /* errno set by accowner */
        !            40: 
        !            41:        if (mnt) {
        !            42:                /*
        !            43:                 * from fmount(), `dip' is locked and reserved
        !            44:                 */
        !            45:                mson(cip, dip, flag, fstyp);
        !            46:                /*
        !            47:                 * iput occurs in fmount();
        !            48:                 */
        !            49:        } else {
        !            50:                /*
        !            51:                 * from fmount(), nothing locked or reserved
        !            52:                 */
        !            53:                msoff(dip, 0);
        !            54:        }
        !            55: }
        !            56: 
        !            57: /*
        !            58:  *  Create an in core root node, mount it, and attach a communications inode.
        !            59:  *  On entry, `dip' is locked and reserved.  On exit, `dip' is still locked
        !            60:  *  and reserved (i.e. shoud be iput).
        !            61:  */
        !            62: mson(cip, dip, flag, fstyp)
        !            63:        register struct inode *cip;     /* stream being mounted */
        !            64:        register struct inode *dip;     /* mount point */
        !            65: {
        !            66:        register struct inode *rip;     /* root inode for new fs */
        !            67: 
        !            68:        /* must be mounting a stream */
        !            69:        if(cip->i_sptr == NULL) {
        !            70:                u.u_error = ENXIO;
        !            71:                return;
        !            72:        }
        !            73: 
        !            74:        /* already mounted? */
        !            75:        if(dip->i_fstyp == fstyp) {
        !            76:                u.u_error = EBUSY;              /* in use */
        !            77:                return;
        !            78:        }
        !            79: 
        !            80:        /* create a new inode for the fs root */
        !            81:        rip = iuniq(fstyp);
        !            82:        if(rip == NULL)
        !            83:                return;         /* errno already set */
        !            84:        rip->i_un.i_cip = cip;
        !            85:        rip->i_mpoint = dip;
        !            86:        rip->i_mode &= IFMT;
        !            87:        rip->i_mode |= dip->i_mode & ~IFMT;
        !            88:        rip->i_flag |= IACC;    /* force update */
        !            89:        prele(rip);
        !            90:        cip->i_count++;
        !            91: 
        !            92:        /* mount the root */
        !            93:        SETMOUNT(dip,rip);
        !            94:        dip->i_count++;
        !            95: }
        !            96: 
        !            97: /*
        !            98:  *  Unmount the stream and close it if approriate.
        !            99:  *  On entry, `dip' is neither reserved or locked.
        !           100:  */
        !           101: msoff(dip, rlocked)
        !           102:        register struct inode *dip;     /* mount point */
        !           103: {
        !           104:        register struct inode *rip;     /* root inode */
        !           105:        register struct inode *cip;     /* mounted stream */
        !           106: 
        !           107:        /* if not mounted, we're done */
        !           108:        if (dip->i_mroot==NULL)
        !           109:                return;
        !           110: 
        !           111:        /* 
        !           112:         *  To avoid deadlock, always lock the resources in the same order.
        !           113:         *  Since the root may already be locked on the way in, it comes
        !           114:         *  first.
        !           115:         */
        !           116:        rip = dip->i_mroot;
        !           117:        if (!rlocked)
        !           118:                plock(rip);
        !           119:        plock(dip);
        !           120: 
        !           121:        /* make sure nothing changed while we were locking the inodes */
        !           122:        if (dip->i_mroot!=rip) {
        !           123:                prele(dip);
        !           124:                if (!rlocked)
        !           125:                        prele(rip);
        !           126:                return;
        !           127:        }
        !           128: 
        !           129:        /* disassociate the stream from the mount point */
        !           130:        cip = rip->i_un.i_cip;
        !           131:        rip->i_un.i_cip = NULL;
        !           132:        if(cip != NULL) {
        !           133:                if(cip->i_count==1)
        !           134:                        stclose(cip, 1);
        !           135:                iput(cip);
        !           136:        }
        !           137: 
        !           138:        /* unmount root from file system */
        !           139:        rip->i_mpoint = NULL;
        !           140:        CLRMOUNT(dip);
        !           141:        iput(dip);
        !           142:        iput(rip);
        !           143: }
        !           144: 
        !           145: /*
        !           146:  * If the node is still mounted and the stream has hung up,
        !           147:  * unmount it.  On entry, rip is locked.
        !           148:  * This is called by `update()'.
        !           149:  *
        !           150:  * This is called because IACC is set in rip in mson above.
        !           151:  * update routines are meant to clear IACC|IUPD|ICHG, but
        !           152:  * we don't, so the calls keep coming.
        !           153:  *
        !           154:  * stat and open should probably check the stream too.
        !           155:  */
        !           156: msupdat(rip, ta, tm, waitfor)
        !           157:        register struct inode *rip;
        !           158:        time_t *ta, *tm;
        !           159: {
        !           160:        register struct inode *cip;
        !           161:        register struct inode *dip;
        !           162: 
        !           163:        cip = rip->i_un.i_cip;
        !           164:        if (cip==NULL || cip->i_sptr==NULL || cip->i_sptr->flag&HUNGUP) {
        !           165:                dip = rip->i_mpoint;
        !           166:                if (dip != NULL) {
        !           167:                        if (!(rip->i_flag&ILOCK))
        !           168:                                panic("msupdate: inode not locked");
        !           169:                        msoff(dip, 1);
        !           170:                }
        !           171:        }
        !           172: }
        !           173: 
        !           174: /*
        !           175:  *  Pass read onto the stream's inode.
        !           176:  *  `rip' is locked during this operation.
        !           177:  */
        !           178: msread(rip)
        !           179:        struct inode *rip;
        !           180: {
        !           181:        register struct inode *cip;
        !           182: 
        !           183:        cip = rip->i_un.i_cip;
        !           184:        if (cip!=NULL)
        !           185:                readi(cip);
        !           186:        else
        !           187:                u.u_error = EPIPE;
        !           188: }
        !           189: 
        !           190: /*
        !           191:  *  Pass write onto the stream's inode.
        !           192:  *  `rip' is locked during this operation.
        !           193:  */
        !           194: mswrite(rip)
        !           195:        struct inode *rip;
        !           196: {
        !           197:        register struct inode *cip;
        !           198: 
        !           199:        cip = rip->i_un.i_cip;
        !           200:        if (cip!=NULL)
        !           201:                writei(cip);
        !           202:        else
        !           203:                u.u_error = EPIPE;
        !           204: }
        !           205: 
        !           206: /*
        !           207:  *  Pass ioctl onto the stream's inode.
        !           208:  *  `rip' is locked during this operation.
        !           209:  */
        !           210: msioctl(rip, cmd, cmarg, flag)
        !           211: register struct inode *rip;
        !           212: caddr_t cmarg;
        !           213: {
        !           214:        register struct inode *cip;
        !           215: 
        !           216:        cip = rip->i_un.i_cip;
        !           217:        if (cip!=NULL)
        !           218:                stioctl(cip, cmd, cmarg);
        !           219:        else
        !           220:                u.u_error = EPIPE;
        !           221: }
        !           222: 
        !           223: /*
        !           224:  * stat `mounted' inode
        !           225:  */
        !           226: msstat(rip, ub)
        !           227:        struct inode *rip;
        !           228:        struct stat *ub;
        !           229: {
        !           230:        struct stat ds;
        !           231: 
        !           232:        ds.st_dev = rip->i_dev;
        !           233:        ds.st_ino = rip->i_number;
        !           234:        ds.st_mode = rip->i_mode;
        !           235:        ds.st_nlink = 0;
        !           236:        ds.st_uid = rip->i_uid;
        !           237:        ds.st_gid = rip->i_gid;
        !           238:        ds.st_rdev = (dev_t)0;
        !           239:        ds.st_size = 0;
        !           240:        ds.st_atime = time;
        !           241:        ds.st_mtime = time;
        !           242:        ds.st_ctime = time;
        !           243:        if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
        !           244:                u.u_error = EFAULT;
        !           245: }
        !           246: 
        !           247: /*
        !           248:  *  Change an open of the root into a stopen of the communications inode.
        !           249:  */
        !           250: struct inode *
        !           251: msopen(rip, rw)
        !           252: register struct inode *rip;
        !           253: {
        !           254:        register struct inode *cip;
        !           255:        register struct inode *nip;
        !           256: 
        !           257:        /*
        !           258:         *  Locking the root also locks out cip changes.
        !           259:         */
        !           260:        plock(rip);
        !           261: 
        !           262:        /* return error if stream is dead */
        !           263:        cip = rip->i_un.i_cip;
        !           264:        if (cip==NULL||cip->i_sptr==NULL||cip->i_sptr->flag&HUNGUP) {
        !           265:                u.u_error = ENXIO;
        !           266:                iput(rip);
        !           267:                return(NULL);
        !           268:        }
        !           269: 
        !           270:        /*
        !           271:         *  Reopen stream, perhaps returning a fresh inode,
        !           272:         *  or NULL on error, which is what we should do too.
        !           273:         *  either this is a fresh reference to cip, or stopen will iput.
        !           274:         */
        !           275:        cip->i_count++;
        !           276:        nip = stopen((struct streamtab *)NULL, cip->i_un.i_rdev, rw, cip);
        !           277:        iput(rip);
        !           278:        return(nip);
        !           279: }

unix.superglobalmegacorp.com

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