Annotation of researchv10no/sys/fs/ms.c, revision 1.1.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.