|
|
1.1 ! root 1: /* ! 2: * This file contains the routines which support mounted ! 3: * streams (file system type 3). ! 4: */ ! 5: #include "../h/param.h" ! 6: #include "../h/systm.h" ! 7: #include "../h/dir.h" ! 8: #include "../h/inode.h" ! 9: #include "../h/stream.h" ! 10: #include "../h/user.h" ! 11: #include "../h/mount.h" ! 12: #include "../h/file.h" ! 13: #include "../h/stat.h" ! 14: #include "../h/conf.h" ! 15: ! 16: /* ! 17: * The following definitions apply to all comments: ! 18: * - `locked' means that an inode has had `plock' applied to it ! 19: * - `reserved' means that the inode's i_count has been incremented to ! 20: * ensure that the inode will be freed during an operation. ! 21: */ ! 22: ! 23: msmount(cip, dip, flag, mnt, fstyp) ! 24: struct inode *cip, *dip; ! 25: { ! 26: /* only writer can mount/unmount */ ! 27: if(access(dip, IWRITE)) ! 28: return; /* errno set by access */ ! 29: ! 30: if (mnt) { ! 31: /* ! 32: * from fmount(), `dip' is locked and reserved ! 33: */ ! 34: mson(cip, dip, flag, fstyp); ! 35: } else { ! 36: /* ! 37: * from fmount(), `dip' not yet locked or reserved ! 38: */ ! 39: dip->i_count++; /* reserve dip */ ! 40: msoff(dip); ! 41: iput(dip); /* let it disappear */ ! 42: } ! 43: } ! 44: ! 45: /* ! 46: * Unmount the stream currently mounted and mount a new one. ! 47: * `rip' is locked and reserved. ! 48: */ ! 49: msoffon(cip, rip, flag, fstyp) ! 50: register struct inode *cip; /* stream being mounted */ ! 51: register struct inode *rip; /* root inode for new fs */ ! 52: { ! 53: register struct inode *dip; /* mount point */ ! 54: ! 55: dip = rip->i_mpoint; ! 56: dip->i_count++; /* reserve dip */ ! 57: ! 58: prele(rip); ! 59: msoff(dip); ! 60: ! 61: plock(dip); ! 62: mson(cip, dip, flag, fstyp); ! 63: ! 64: iput(dip); /* let dip disappear */ ! 65: } ! 66: ! 67: /* ! 68: * Create an in core root node, mount it, and attach a communications inode. ! 69: * On entry, `dip' is locked and reserved. On exit, `dip' is still locked ! 70: * and reserved (i.e. shoud be iput). ! 71: */ ! 72: mson(cip, dip, flag, fstyp) ! 73: register struct inode *cip; /* stream being mounted */ ! 74: register struct inode *dip; /* mount point */ ! 75: { ! 76: register struct inode *rip; /* root inode for new fs */ ! 77: struct inode *ifake(); ! 78: ! 79: /* must be mounting a stream */ ! 80: if(cip->i_sptr == NULL) { ! 81: u.u_error = ENXIO; ! 82: return; ! 83: } ! 84: ! 85: /* already mounted? */ ! 86: if(dip->i_fstyp == fstyp) { ! 87: if (dip->i_un.i_cip==NULL || dip->i_un.i_cip->i_sptr->flag&HUNGUP) ! 88: u.u_error = EBUSY; /* in use */ ! 89: else ! 90: msoffon(cip, dip, flag, fstyp); /* old mount is stale */ ! 91: return; ! 92: } ! 93: ! 94: /* create a new inode for the fs root */ ! 95: rip = ifake(fstyp); ! 96: if(rip == NULL) ! 97: return; /* errno already set */ ! 98: ! 99: rip->i_un.i_cip = cip; ! 100: rip->i_mpoint = dip; ! 101: rip->i_mroot = NULL; ! 102: prele(rip); ! 103: cip->i_count++; ! 104: dip->i_mroot = rip; ! 105: dip->i_flag |= IMOUNT; ! 106: dip->i_count++; ! 107: } ! 108: ! 109: /* ! 110: * Unmount the stream and close it if approriate. ! 111: * On entry, `dip' is reserved. On exit, it is still reserved. ! 112: */ ! 113: msoff(dip) ! 114: register struct inode *dip; /* mount point */ ! 115: { ! 116: register struct inode *rip; /* root inode */ ! 117: register struct inode *cip; /* mounted stream */ ! 118: ! 119: /* lock the mount point */ ! 120: plock(dip); ! 121: ! 122: /* if not mounted, we're done */ ! 123: if (!(dip->i_flag&IMOUNT)) { ! 124: prele(dip); ! 125: return; ! 126: } ! 127: ! 128: /* lock the root */ ! 129: rip = dip->i_mroot; ! 130: plock(rip); ! 131: ! 132: /* disassociate the stream from the mount point */ ! 133: cip = rip->i_un.i_cip; ! 134: rip->i_un.i_cip = NULL; ! 135: if(cip != NULL) { ! 136: plock(cip); ! 137: if(cip->i_count==1) ! 138: stclose(cip, 1); ! 139: iput(cip); ! 140: } ! 141: ! 142: /* unmount root from file system */ ! 143: dip->i_flag &= ~IMOUNT; ! 144: dip->i_mroot = NULL; ! 145: rip->i_mpoint = NULL; ! 146: iput(dip); ! 147: iput(rip); ! 148: } ! 149: ! 150: /* ! 151: * get the inode ! 152: * it should always be the `root,' ! 153: * which is always in core, ! 154: * hence we should get here only when creating the inode. ! 155: */ ! 156: struct inode * ! 157: msget(fstyp, dev, ino, rip) ! 158: dev_t dev; ! 159: struct inode *rip; ! 160: { ! 161: rip->i_flag |= IACC; /* to force iupdat's */ ! 162: rip->i_mode = 0; /* mark as unopened */ ! 163: return rip; ! 164: } ! 165: ! 166: /* ! 167: * Pass read onto the stream's inode. ! 168: * `rip' is locked during this operation. ! 169: */ ! 170: msread(rip) ! 171: struct inode *rip; ! 172: { ! 173: register struct inode *cip; ! 174: ! 175: cip = rip->i_un.i_cip; ! 176: if (cip!=NULL) ! 177: readi(cip); ! 178: else ! 179: u.u_error = EPIPE; ! 180: } ! 181: ! 182: /* ! 183: * Pass write onto the stream's inode. ! 184: * `rip' is locked during this operation. ! 185: */ ! 186: mswrite(rip) ! 187: struct inode *rip; ! 188: { ! 189: register struct inode *cip; ! 190: ! 191: cip = rip->i_un.i_cip; ! 192: if (cip!=NULL) ! 193: writei(cip); ! 194: else ! 195: u.u_error = EPIPE; ! 196: } ! 197: ! 198: /* ! 199: * Pass ioctl onto the stream's inode. ! 200: * `rip' is locked during this operation. ! 201: */ ! 202: msioctl(rip, cmd, cmarg, flag) ! 203: register struct inode *rip; ! 204: caddr_t cmarg; ! 205: { ! 206: register struct inode *cip; ! 207: ! 208: cip = rip->i_un.i_cip; ! 209: if (cip!=NULL) ! 210: stioctl(cip, cmd, cmarg); ! 211: else ! 212: u.u_error = EPIPE; ! 213: } ! 214: ! 215: /* ! 216: * stat `mounted' inode ! 217: */ ! 218: msstat(rip, ub) ! 219: struct inode *rip; ! 220: struct stat *ub; ! 221: { ! 222: struct stat ds; ! 223: ! 224: ds.st_dev = rip->i_dev; ! 225: ds.st_ino = rip->i_number; ! 226: ds.st_mode = rip->i_mode; ! 227: ds.st_nlink = 0; ! 228: ds.st_uid = rip->i_uid; ! 229: ds.st_gid = rip->i_gid; ! 230: ds.st_rdev = (dev_t)0; ! 231: ds.st_size = 0; ! 232: ds.st_atime = time; ! 233: ds.st_mtime = time; ! 234: ds.st_ctime = time; ! 235: if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) ! 236: u.u_error = EFAULT; ! 237: } ! 238: ! 239: /* ! 240: * If the node is still mounted and the stream has hung up, ! 241: * unmount it. On entry, rip is locked. ! 242: * This is called by `update()'. ! 243: */ ! 244: msupdat(rip, ta, tm, waitfor) ! 245: register struct inode *rip; ! 246: time_t *ta, *tm; ! 247: { ! 248: register struct inode *cip; ! 249: register struct inode *dip; ! 250: ! 251: cip = rip->i_un.i_cip; ! 252: if (cip!=NULL && cip->i_sptr->flag&HUNGUP) { ! 253: dip = rip->i_mpoint; ! 254: dip->i_count++; /* reserve dip */ ! 255: prele(rip); ! 256: msoff(dip); ! 257: iput(dip); /* let dip disappear */ ! 258: } ! 259: } ! 260: ! 261: /* ! 262: * Change an open of the root into a stopen of the communications inode. ! 263: * As usual, be wary of i_count's. ! 264: */ ! 265: struct inode * ! 266: msopen(rip, rw) ! 267: register struct inode *rip; ! 268: { ! 269: register struct inode *cip; ! 270: register struct inode *dip; ! 271: dev_t dev; ! 272: ! 273: cip = rip->i_un.i_cip; ! 274: if (cip==NULL) { ! 275: u.u_error = ENXIO; ! 276: return NULL; ! 277: } ! 278: ! 279: /* dismount if the stream is closed */ ! 280: if (cip->i_sptr->flag&HUNGUP) { ! 281: dip = rip->i_mpoint; ! 282: dip->i_count++; /* reserve dip */ ! 283: prele(rip); ! 284: msoff(dip); ! 285: iput(dip); /* let dip disappear */ ! 286: u.u_error = ENXIO; ! 287: return NULL; ! 288: } ! 289: ! 290: /* replace rip by cip as inode being opened */ ! 291: cip->i_count++; /* corresponding iput done by stopen (yech!) */ ! 292: iput(rip); /* because of namei in open/creat */ ! 293: plock(cip); ! 294: ! 295: /* reopen the stream (must already be open) */ ! 296: if (cip->i_sptr==NULL) ! 297: panic("msopen"); ! 298: dev = (dev_t)cip->i_un.i_rdev; ! 299: return(stopen(0, dev, rw, cip)); ! 300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.