fdesc_vfsops.c revision 1.1 1 /*
2 * Copyright (c) 1992 The Regents of the University of California
3 * Copyright (c) 1990, 1992 Jan-Simon Pendry
4 * All rights reserved.
5 *
6 * This code is derived from software donated to Berkeley by
7 * Jan-Simon Pendry.
8 *
9 * %sccs.redist.c%
10 *
11 * %W% (Berkeley) %G%
12 *
13 * $Id: fdesc_vfsops.c,v 1.1 1993/03/23 23:56:33 cgd Exp $
14 */
15
16 /*
17 * /dev/fd Filesystem
18 */
19
20 #include "param.h"
21 #include "systm.h"
22 #include "time.h"
23 #include "types.h"
24 #include "proc.h"
25 #include "resourcevar.h"
26 #include "filedesc.h"
27 #include "vnode.h"
28 #include "mount.h"
29 #include "namei.h"
30 #include "malloc.h"
31 #include "miscfs/fdesc/fdesc.h"
32
33 static u_short fdesc_mntid;
34
35 fdesc_init()
36 {
37 #ifdef FDESC_DIAGNOSTIC
38 printf("fdesc_init\n"); /* printed during system boot */
39 #endif
40 }
41
42 /*
43 * Mount the per-process file descriptors (/dev/fd)
44 */
45 fdesc_mount(mp, path, data, ndp, p)
46 struct mount *mp;
47 char *path;
48 caddr_t data;
49 struct nameidata *ndp;
50 struct proc *p;
51 {
52 int error = 0;
53 u_int size;
54 struct fdescmount *fmp;
55 struct vnode *rvp;
56
57 #ifdef FDESC_DIAGNOSTIC
58 printf("fdesc_mount(mp = %x)\n", mp);
59 #endif
60
61 /*
62 * Update is a no-op
63 */
64 if (mp->mnt_flag & MNT_UPDATE)
65 return (EOPNOTSUPP);
66
67 error = getnewvnode(VT_UFS, mp, &fdesc_vnodeops, &rvp); /* XXX */
68 if (error)
69 return (error);
70
71 fmp = (struct fdescmount *) malloc(sizeof(struct fdescmount),
72 M_UFSMNT, M_WAITOK); /* XXX */
73 rvp->v_type = VDIR;
74 rvp->v_flag |= VROOT;
75 /*VTOFDESC(rvp)->f_isroot = 1;*/
76 #ifdef FDESC_DIAGNOSTIC
77 printf("fdesc_mount: root vp = %x\n", rvp);
78 #endif
79 fmp->f_root = rvp;
80 mp->mnt_flag |= MNT_LOCAL;
81 mp->mnt_data = (qaddr_t) fmp;
82 getnewfsid(mp, MOUNT_FDESC);
83
84 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
85 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
86 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
87 bcopy("fdesc", mp->mnt_stat.f_mntfromname, sizeof("fdesc"));
88 #ifdef FDESC_DIAGNOSTIC
89 printf("fdesc_mount: at %s\n", mp->mnt_stat.f_mntonname);
90 #endif
91 return (0);
92 }
93
94 fdesc_start(mp, flags, p)
95 struct mount *mp;
96 int flags;
97 struct proc *p;
98 {
99 return (0);
100 }
101
102 fdesc_unmount(mp, mntflags, p)
103 struct mount *mp;
104 int mntflags;
105 struct proc *p;
106 {
107 int error;
108 int flags = 0;
109 extern int doforce;
110 struct vnode *rootvp = VFSTOFDESC(mp)->f_root;
111
112 #ifdef FDESC_DIAGNOSTIC
113 printf("fdesc_unmount(mp = %x)\n", mp);
114 #endif
115
116 if (mntflags & MNT_FORCE) {
117 /* fdesc can never be rootfs so don't check for it */
118 if (!doforce)
119 return (EINVAL);
120 flags |= FORCECLOSE;
121 }
122
123 /*
124 * Clear out buffer cache. I don't think we
125 * ever get anything cached at this level at the
126 * moment, but who knows...
127 */
128 #ifdef FDESC_DIAGNOSTIC
129 printf("fdesc_unmount: calling mntflushbuf\n");
130 #endif
131 mntflushbuf(mp, 0);
132 #ifdef FDESC_DIAGNOSTIC
133 printf("fdesc_unmount: calling mntinvalbuf\n");
134 #endif
135 if (mntinvalbuf(mp, 1))
136 return (EBUSY);
137 if (rootvp->v_usecount > 1)
138 return (EBUSY);
139 #ifdef FDESC_DIAGNOSTIC
140 printf("fdesc_unmount: calling vflush\n");
141 #endif
142 if (error = vflush(mp, rootvp, flags))
143 return (error);
144
145 #ifdef FDESC_DIAGNOSTIC
146 vprint("fdesc root", rootvp);
147 #endif
148 /*
149 * Release reference on underlying root vnode
150 */
151 vrele(rootvp);
152 /*
153 * And blow it away for future re-use
154 */
155 vgone(rootvp);
156 /*
157 * Finally, throw away the fdescmount structure
158 */
159 free(mp->mnt_data, M_UFSMNT); /* XXX */
160 mp->mnt_data = 0;
161 return 0;
162 }
163
164 fdesc_root(mp, vpp)
165 struct mount *mp;
166 struct vnode **vpp;
167 {
168 struct vnode *vp;
169 int error;
170
171 #ifdef FDESC_DIAGNOSTIC
172 printf("fdesc_root(mp = %x)\n", mp);
173 #endif
174
175 /*
176 * Return locked reference to root.
177 */
178 vp = VFSTOFDESC(mp)->f_root;
179 VREF(vp);
180 VOP_LOCK(vp);
181 *vpp = vp;
182 return (0);
183 }
184
185 fdesc_quotactl(mp, cmd, uid, arg, p)
186 struct mount *mp;
187 int cmd;
188 uid_t uid;
189 caddr_t arg;
190 struct proc *p;
191 {
192 return (EOPNOTSUPP);
193 }
194
195 fdesc_statfs(mp, sbp, p)
196 struct mount *mp;
197 struct statfs *sbp;
198 struct proc *p;
199 {
200 struct filedesc *fdp;
201 int lim;
202 int i;
203 int last;
204 int freefd;
205
206 #ifdef FDESC_DIAGNOSTIC
207 printf("fdesc_statfs(mp = %x)\n", mp);
208 #endif
209
210 /*
211 * Compute number of free file descriptors.
212 * [ Strange results will ensue if the open file
213 * limit is ever reduced below the current number
214 * of open files... ]
215 */
216 lim = p->p_rlimit[RLIMIT_OFILE].rlim_cur;
217 fdp = p->p_fd;
218 last = min(fdp->fd_nfiles, lim);
219 freefd = 0;
220 for (i = fdp->fd_freefile; i < last; i++)
221 if (fdp->fd_ofiles[i] == NULL)
222 freefd++;
223
224 /*
225 * Adjust for the fact that the fdesc array may not
226 * have been fully allocated yet.
227 */
228 if (fdp->fd_nfiles < lim)
229 freefd += (lim - fdp->fd_nfiles);
230
231 sbp->f_type = MOUNT_FDESC;
232 sbp->f_flags = 0;
233 sbp->f_fsize = DEV_BSIZE;
234 sbp->f_bsize = DEV_BSIZE;
235 sbp->f_blocks = 2; /* 1K to keep df happy */
236 sbp->f_bfree = 0;
237 sbp->f_bavail = 0;
238 sbp->f_files = lim + 1; /* Allow for "." */
239 sbp->f_ffree = freefd; /* See comments above */
240 if (sbp != &mp->mnt_stat) {
241 bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
242 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
243 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
244 }
245 return (0);
246 }
247
248 fdesc_sync(mp, waitfor)
249 struct mount *mp;
250 int waitfor;
251 {
252 return (0);
253 }
254
255 fdesc_fhtovp(mp, fhp, vpp)
256 struct mount *mp;
257 struct fid *fhp;
258 struct vnode **vpp;
259 {
260 return (EOPNOTSUPP);
261 }
262
263 fdesc_vptofh(vp, fhp)
264 struct vnode *vp;
265 struct fid *fhp;
266 {
267 return (EOPNOTSUPP);
268 }
269
270 struct vfsops fdesc_vfsops = {
271 fdesc_mount,
272 fdesc_start,
273 fdesc_unmount,
274 fdesc_root,
275 fdesc_quotactl,
276 fdesc_statfs,
277 fdesc_sync,
278 fdesc_fhtovp,
279 fdesc_vptofh,
280 fdesc_init,
281 };
282