|
|
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.