date and time created 92/07/13 15:47:59 by pendry
[unix-history] / usr / src / sys / miscfs / fdesc / fdesc_vnops.c
CommitLineData
e2e9adba
JSP
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.include.redist.c%
10 *
4a8e84ef 11 * @(#)fdesc_vnops.c 7.1 (Berkeley) %G%
e2e9adba
JSP
12 *
13 * $Id: fdesc_vnops.c,v 1.7 1992/05/30 10:05:34 jsp Exp jsp $
14 */
15
16/*
17 * /dev/fd Filesystem
18 */
19
20#include <sys/param.h>
21#include <sys/systm.h>
22#include <sys/types.h>
23#include <sys/time.h>
24#include <sys/proc.h>
25#include <sys/resourcevar.h>
26#include <sys/filedesc.h>
27#include <sys/vnode.h>
28#include <sys/malloc.h>
29#include <sys/file.h>
30#include <sys/stat.h>
31#include <sys/mount.h>
32#include <sys/namei.h>
33#include <sys/buf.h>
13ef814e 34#include <sys/dirent.h>
5e3f92c4 35#include <miscfs/fdesc/fdesc.h>
e2e9adba
JSP
36
37/*
38 * vp is the current namei directory
39 * ndp is the name to locate in that directory...
40 */
5e3f92c4
KM
41fdesc_lookup(ap)
42 struct vop_lookup_args /* {
43 struct vnode * a_dvp;
44 struct vnode ** a_vpp;
45 struct componentname * a_cnp;
46 } */ *ap;
e2e9adba 47{
a02db9dd
JSP
48 struct vnode **vpp = ap->a_vpp;
49 struct vnode *dvp = ap->a_dvp;
e2e9adba
JSP
50 char *pname;
51 struct proc *p;
52 int nfiles;
53 unsigned fd;
54 int error;
55 struct vnode *fvp;
56
57#ifdef FDESC_DIAGNOSTIC
58 printf("fdesc_lookup(%x)\n", ap);
a02db9dd 59 printf("fdesc_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp);
e2e9adba
JSP
60#endif
61 pname = ap->a_cnp->cn_nameptr;
62#ifdef FDESC_DIAGNOSTIC
63 printf("fdesc_lookup(%s)\n", pname);
64#endif
65 if (ap->a_cnp->cn_namelen == 1 && *pname == '.') {
a02db9dd
JSP
66 *vpp = dvp;
67 VREF(dvp);
68 /*VOP_LOCK(dvp);*/
e2e9adba
JSP
69 return (0);
70 }
71
72 p = ap->a_cnp->cn_proc;
73 nfiles = p->p_fd->fd_nfiles;
74
75 fd = 0;
76 while (*pname >= '0' && *pname <= '9') {
77 fd = 10 * fd + *pname++ - '0';
78 if (fd >= nfiles)
79 break;
80 }
81
82#ifdef FDESC_DIAGNOSTIC
83 printf("fdesc_lookup: fd = %d, *pname = %x\n", fd, *pname);
84#endif
e2e9adba
JSP
85 if (*pname != '\0') {
86 error = ENOENT;
87 goto bad;
88 }
89
90 if (fd >= nfiles || p->p_fd->fd_ofiles[fd] == NULL) {
91 error = EBADF;
92 goto bad;
93 }
94
95#ifdef FDESC_DIAGNOSTIC
96 printf("fdesc_lookup: allocate new vnode\n");
97#endif
a02db9dd 98 error = getnewvnode(VT_UFS, dvp->v_mount, fdesc_vnodeop_p, &fvp);
e2e9adba
JSP
99 if (error)
100 goto bad;
101 MALLOC(fvp->v_data, void *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
102 VTOFDESC(fvp)->f_fd = fd;
103 /*VTOFDESC(fvp)->f_isroot = 0;*/
a02db9dd 104 *vpp = fvp;
e2e9adba
JSP
105#ifdef FDESC_DIAGNOSTIC
106 printf("fdesc_lookup: newvp = %x\n", fvp);
107#endif
108 return (0);
109
110bad:;
a02db9dd 111 *vpp = NULL;
e2e9adba
JSP
112#ifdef FDESC_DIAGNOSTIC
113 printf("fdesc_lookup: error = %d\n", error);
114#endif
115 return (error);
116}
117
5e3f92c4
KM
118fdesc_open(ap)
119 struct vop_open_args /* {
120 struct vnode *a_vp;
121 int a_mode;
122 struct ucred *a_cred;
123 struct proc *a_p;
124 } */ *ap;
e2e9adba 125{
a02db9dd
JSP
126 struct vnode *vp = ap->a_vp;
127
e2e9adba
JSP
128 /*
129 * Can always open the root (modulo perms)
130 */
a02db9dd 131 if (vp->v_flag & VROOT)
e2e9adba
JSP
132 return (0);
133
134 /*
135 * XXX Kludge: set ap->a_p->p_dupfd to contain the value of the
136 * the file descriptor being sought for duplication. The error
137 * return ensures that the vnode for this device will be released
138 * by vn_open. Open will detect this special error and take the
139 * actions in dupfdopen. Other callers of vn_open or VOP_OPEN
140 * will simply report the error.
141 */
a02db9dd 142 ap->a_p->p_dupfd = VTOFDESC(vp)->f_fd; /* XXX */
e2e9adba
JSP
143 return (ENODEV);
144}
145
146static int
147fdesc_attr(fd, vap, cred, p)
148 int fd;
149 struct vattr *vap;
150 struct ucred *cred;
151 struct proc *p;
152{
e2e9adba
JSP
153 struct filedesc *fdp = p->p_fd;
154 struct file *fp;
155 int error;
156
157#ifdef FDESC_DIAGNOSTIC
158 printf("fdesc_attr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
159#endif
160 if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
161#ifdef FDESC_DIAGNOSTIC
162 printf("fdesc_attr: fp = %x (EBADF)\n", fp);
163#endif
164 return (EBADF);
165 }
166
167 /*
168 * Can stat the underlying vnode, but not sockets because
169 * they don't use struct vattrs. Well, we could convert from
170 * a struct stat back to a struct vattr, later...
171 */
172 switch (fp->f_type) {
173 case DTYPE_VNODE:
174 error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
175 break;
176
177 case DTYPE_SOCKET:
178 error = EOPNOTSUPP;
179 break;
180
181 default:
182 panic("fdesc attr");
183 break;
184 }
185
186#ifdef FDESC_DIAGNOSTIC
187 printf("fdesc_attr: returns error %d\n", error);
188#endif
189 return (error);
190}
191
5e3f92c4
KM
192fdesc_getattr(ap)
193 struct vop_getattr_args /* {
194 struct vnode *a_vp;
195 struct vattr *a_vap;
196 struct ucred *a_cred;
197 struct proc *a_p;
198 } */ *ap;
e2e9adba 199{
a02db9dd
JSP
200 struct vnode *vp = ap->a_vp;
201 struct vattr *vap = ap->a_vap;
e2e9adba
JSP
202 unsigned fd;
203 int error;
204
a02db9dd 205 if (vp->v_flag & VROOT) {
e2e9adba
JSP
206#ifdef FDESC_DIAGNOSTIC
207 printf("fdesc_getattr: stat rootdir\n");
208#endif
a02db9dd
JSP
209 bzero((caddr_t) vap, sizeof(*vap));
210 vattr_null(vap);
211 vap->va_type = VDIR;
212 vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
213 vap->va_nlink = 2;
214 vap->va_uid = 0;
215 vap->va_gid = 0;
216 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
217 vap->va_fileid = 2;
218 /* vap->va_qsize = 0; */
219 vap->va_size = DEV_BSIZE;
220 vap->va_blocksize = DEV_BSIZE;
221 microtime(&vap->va_atime);
222 vap->va_mtime = vap->va_atime;
223 vap->va_ctime = vap->va_ctime;
224 vap->va_gen = 0;
225 vap->va_flags = 0;
226 vap->va_rdev = 0;
227 /* vap->va_qbytes = 0; */
228 vap->va_bytes = 0;
e2e9adba
JSP
229 return (0);
230 }
231
a02db9dd
JSP
232 fd = VTOFDESC(vp)->f_fd;
233 error = fdesc_attr(fd, vap, ap->a_cred, ap->a_p);
e2e9adba 234 if (error == 0)
a02db9dd 235 vp->v_type = vap->va_type;
e2e9adba
JSP
236 return (error);
237}
238
5e3f92c4
KM
239fdesc_setattr(ap)
240 struct vop_setattr_args /* {
241 struct vnode *a_vp;
242 struct vattr *a_vap;
243 struct ucred *a_cred;
244 struct proc *a_p;
245 } */ *ap;
e2e9adba 246{
e2e9adba
JSP
247 struct filedesc *fdp = ap->a_p->p_fd;
248 struct file *fp;
249 unsigned fd;
250 int error;
251
252 /*
253 * Can't mess with the root vnode
254 */
255 if (ap->a_vp->v_flag & VROOT)
256 return (EACCES);
257
258 fd = VTOFDESC(ap->a_vp)->f_fd;
259#ifdef FDESC_DIAGNOSTIC
260 printf("fdesc_setattr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
261#endif
262 if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
263#ifdef FDESC_DIAGNOSTIC
264 printf("fdesc_setattr: fp = %x (EBADF)\n", fp);
265#endif
266 return (EBADF);
267 }
268
269 /*
270 * Can setattr the underlying vnode, but not sockets!
271 */
272 switch (fp->f_type) {
273 case DTYPE_VNODE:
274 error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->a_cred, ap->a_p);
275 break;
276
277 case DTYPE_SOCKET:
278 error = EOPNOTSUPP;
279 break;
280
281 default:
282 panic("fdesc setattr");
283 break;
284 }
285
286#ifdef FDESC_DIAGNOSTIC
287 printf("fdesc_setattr: returns error %d\n", error);
288#endif
289 return (error);
290}
291
5e3f92c4
KM
292fdesc_readdir(ap)
293 struct vop_readdir_args /* {
294 struct vnode *a_vp;
295 struct uio *a_uio;
296 struct ucred *a_cred;
297 } */ *ap;
e2e9adba 298{
a02db9dd 299 struct uio *uio = ap->a_uio;
e2e9adba
JSP
300 struct filedesc *fdp;
301 int i;
302 int error;
303
304#define UIO_MX 16
305
a02db9dd
JSP
306 fdp = uio->uio_procp->p_fd;
307 i = uio->uio_offset / UIO_MX;
e2e9adba 308 error = 0;
a02db9dd 309 while (uio->uio_resid > 0) {
e2e9adba 310 if (i >= fdp->fd_nfiles) {
159e7bde 311 /* *ap->a_eofflagp = 1; */
e2e9adba
JSP
312 break;
313 }
314 if (fdp->fd_ofiles[i] != NULL) {
13ef814e
JSP
315 struct dirent d;
316 struct dirent *dp = &d;
e2e9adba
JSP
317 char *cp = dp->d_name;
318#ifdef FDESC_FILEID
319 struct vattr va;
320#endif
321 bzero((caddr_t) dp, UIO_MX);
322
323 dp->d_namlen = sprintf(dp->d_name, "%d", i);
324 /*
325 * Fill in the remaining fields
326 */
327 dp->d_reclen = UIO_MX;
13ef814e
JSP
328 dp->d_type = DT_UNKNOWN;
329 dp->d_fileno = i + 3;
e2e9adba
JSP
330#ifdef FDESC_FILEID
331 /*
332 * If we want the file ids to match the
333 * we must call getattr on the underlying file.
334 * fdesc_attr may return an error, in which case
335 * we ignore the returned file id.
336 */
337 error = fdesc_attr(i, &va, ap->a_cred, p);
338 if (error == 0)
339 dp->d_ino = va.va_fileid;
340#endif
341 /*
342 * And ship to userland
343 */
a02db9dd 344 error = uiomove((caddr_t) dp, UIO_MX, uio);
e2e9adba
JSP
345 if (error)
346 break;
347 }
348 i++;
349 }
350
a02db9dd 351 uio->uio_offset = i * UIO_MX;
e2e9adba
JSP
352 return (error);
353}
354
5e3f92c4
KM
355fdesc_inactive(ap)
356 struct vop_inactive_args /* {
357 struct vnode *a_vp;
358 } */ *ap;
e2e9adba 359{
a02db9dd
JSP
360 struct vnode *vp = ap->a_vp;
361
e2e9adba
JSP
362 /*
363 * Clear out the v_type field to avoid
364 * nasty things happening in vgone().
365 */
a02db9dd 366 vp->v_type = VNON;
e2e9adba 367#ifdef FDESC_DIAGNOSTIC
a02db9dd 368 printf("fdesc_inactive(%x)\n", vp);
e2e9adba
JSP
369#endif
370 return (0);
371}
372
5e3f92c4
KM
373fdesc_reclaim(ap)
374 struct vop_reclaim_args /* {
375 struct vnode *a_vp;
376 } */ *ap;
e2e9adba
JSP
377{
378 struct vnode *vp = ap->a_vp;
379 printf("fdesc_reclaim(%x)\n", vp);
380 if (vp->v_data) {
381 FREE(vp->v_data, M_TEMP);
382 vp->v_data = 0;
383 }
384 return (0);
385}
386
387/*
388 * Print out the contents of a /dev/fd vnode.
389 */
390/* ARGSUSED */
5e3f92c4
KM
391fdesc_print(ap)
392 struct vop_print_args /* {
393 struct vnode *a_vp;
394 } */ *ap;
e2e9adba 395{
5e3f92c4 396
e2e9adba 397 printf("tag VT_NON, fdesc vnode\n");
5e3f92c4 398 return (0);
e2e9adba
JSP
399}
400
401/*void*/
5e3f92c4
KM
402fdesc_vfree(ap)
403 struct vop_vfree_args /* {
404 struct vnode *a_pvp;
405 ino_t a_ino;
406 int a_mode;
407 } */ *ap;
e2e9adba
JSP
408{
409
5e3f92c4 410 return (0);
e2e9adba
JSP
411}
412
413/*
414 * /dev/fd vnode unsupported operation
415 */
416fdesc_enotsupp()
417{
5e3f92c4 418
e2e9adba
JSP
419 return (EOPNOTSUPP);
420}
421
422/*
423 * /dev/fd "should never get here" operation
424 */
425fdesc_badop()
426{
5e3f92c4 427
e2e9adba
JSP
428 panic("fdesc: bad op");
429 /* NOTREACHED */
430}
431
432/*
433 * /dev/fd vnode null operation
434 */
435fdesc_nullop()
436{
5e3f92c4 437
e2e9adba
JSP
438 return (0);
439}
440
441#define fdesc_create ((int (*) __P((struct vop_create_args *)))fdesc_enotsupp)
442#define fdesc_mknod ((int (*) __P((struct vop_mknod_args *)))fdesc_enotsupp)
443#define fdesc_close ((int (*) __P((struct vop_close_args *)))nullop)
444#define fdesc_access ((int (*) __P((struct vop_access_args *)))nullop)
445#define fdesc_read ((int (*) __P((struct vop_read_args *)))fdesc_enotsupp)
446#define fdesc_write ((int (*) __P((struct vop_write_args *)))fdesc_enotsupp)
447#define fdesc_ioctl ((int (*) __P((struct vop_ioctl_args *)))fdesc_enotsupp)
448#define fdesc_select ((int (*) __P((struct vop_select_args *)))fdesc_enotsupp)
449#define fdesc_mmap ((int (*) __P((struct vop_mmap_args *)))fdesc_enotsupp)
450#define fdesc_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
451#define fdesc_seek ((int (*) __P((struct vop_seek_args *)))nullop)
452#define fdesc_remove ((int (*) __P((struct vop_remove_args *)))fdesc_enotsupp)
453#define fdesc_link ((int (*) __P((struct vop_link_args *)))fdesc_enotsupp)
454#define fdesc_rename ((int (*) __P((struct vop_rename_args *)))fdesc_enotsupp)
455#define fdesc_mkdir ((int (*) __P((struct vop_mkdir_args *)))fdesc_enotsupp)
456#define fdesc_rmdir ((int (*) __P((struct vop_rmdir_args *)))fdesc_enotsupp)
5e3f92c4
KM
457#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))fdesc_enotsupp)
458#define fdesc_readlink
459 ((int (*) __P((struct vop_readlink_args *)))fdesc_enotsupp)
e2e9adba
JSP
460#define fdesc_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
461#define fdesc_lock ((int (*) __P((struct vop_lock_args *)))nullop)
462#define fdesc_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
463#define fdesc_bmap ((int (*) __P((struct vop_bmap_args *)))fdesc_badop)
464#define fdesc_strategy ((int (*) __P((struct vop_strategy_args *)))fdesc_badop)
465#define fdesc_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
5e3f92c4
KM
466#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))fdesc_enotsupp)
467#define fdesc_blkatoff
468 ((int (*) __P((struct vop_blkatoff_args *)))fdesc_enotsupp)
e2e9adba
JSP
469#define fdesc_vget ((int (*) __P((struct vop_vget_args *)))fdesc_enotsupp)
470#define fdesc_valloc ((int(*) __P(( \
471 struct vnode *pvp, \
472 int mode, \
473 struct ucred *cred, \
474 struct vnode **vpp))) fdesc_enotsupp)
5e3f92c4
KM
475#define fdesc_truncate
476 ((int (*) __P((struct vop_truncate_args *)))fdesc_enotsupp)
e2e9adba
JSP
477#define fdesc_update ((int (*) __P((struct vop_update_args *)))fdesc_enotsupp)
478#define fdesc_bwrite ((int (*) __P((struct vop_bwrite_args *)))fdesc_enotsupp)
479
480int (**fdesc_vnodeop_p)();
481struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
482 { &vop_default_desc, vn_default_error },
483 { &vop_lookup_desc, fdesc_lookup }, /* lookup */
484 { &vop_create_desc, fdesc_create }, /* create */
485 { &vop_mknod_desc, fdesc_mknod }, /* mknod */
5e3f92c4 486 { &vop_open_desc, fdesc_open }, /* open */
e2e9adba
JSP
487 { &vop_close_desc, fdesc_close }, /* close */
488 { &vop_access_desc, fdesc_access }, /* access */
489 { &vop_getattr_desc, fdesc_getattr }, /* getattr */
490 { &vop_setattr_desc, fdesc_setattr }, /* setattr */
5e3f92c4 491 { &vop_read_desc, fdesc_read }, /* read */
e2e9adba
JSP
492 { &vop_write_desc, fdesc_write }, /* write */
493 { &vop_ioctl_desc, fdesc_ioctl }, /* ioctl */
494 { &vop_select_desc, fdesc_select }, /* select */
5e3f92c4 495 { &vop_mmap_desc, fdesc_mmap }, /* mmap */
e2e9adba 496 { &vop_fsync_desc, fdesc_fsync }, /* fsync */
5e3f92c4 497 { &vop_seek_desc, fdesc_seek }, /* seek */
e2e9adba 498 { &vop_remove_desc, fdesc_remove }, /* remove */
5e3f92c4 499 { &vop_link_desc, fdesc_link }, /* link */
e2e9adba
JSP
500 { &vop_rename_desc, fdesc_rename }, /* rename */
501 { &vop_mkdir_desc, fdesc_mkdir }, /* mkdir */
502 { &vop_rmdir_desc, fdesc_rmdir }, /* rmdir */
503 { &vop_symlink_desc, fdesc_symlink }, /* symlink */
504 { &vop_readdir_desc, fdesc_readdir }, /* readdir */
505 { &vop_readlink_desc, fdesc_readlink }, /* readlink */
506 { &vop_abortop_desc, fdesc_abortop }, /* abortop */
507 { &vop_inactive_desc, fdesc_inactive }, /* inactive */
508 { &vop_reclaim_desc, fdesc_reclaim }, /* reclaim */
5e3f92c4 509 { &vop_lock_desc, fdesc_lock }, /* lock */
e2e9adba 510 { &vop_unlock_desc, fdesc_unlock }, /* unlock */
5e3f92c4 511 { &vop_bmap_desc, fdesc_bmap }, /* bmap */
e2e9adba
JSP
512 { &vop_strategy_desc, fdesc_strategy }, /* strategy */
513 { &vop_print_desc, fdesc_print }, /* print */
514 { &vop_islocked_desc, fdesc_islocked }, /* islocked */
515 { &vop_advlock_desc, fdesc_advlock }, /* advlock */
516 { &vop_blkatoff_desc, fdesc_blkatoff }, /* blkatoff */
e2e9adba
JSP
517 { &vop_valloc_desc, fdesc_valloc }, /* valloc */
518 { &vop_vfree_desc, fdesc_vfree }, /* vfree */
519 { &vop_truncate_desc, fdesc_truncate }, /* truncate */
520 { &vop_update_desc, fdesc_update }, /* update */
521 { &vop_bwrite_desc, fdesc_bwrite }, /* bwrite */
522 { (struct vnodeop_desc*)NULL, (int(*)())NULL }
523};
524struct vnodeopv_desc fdesc_vnodeop_opv_desc =
525 { &fdesc_vnodeop_p, fdesc_vnodeop_entries };