fdesc_vnops.c revision 1.1 1 1.1 cgd /*
2 1.1 cgd * Copyright (c) 1992 The Regents of the University of California
3 1.1 cgd * Copyright (c) 1990, 1992 Jan-Simon Pendry
4 1.1 cgd * All rights reserved.
5 1.1 cgd *
6 1.1 cgd * This code is derived from software donated to Berkeley by
7 1.1 cgd * Jan-Simon Pendry.
8 1.1 cgd *
9 1.1 cgd * %sccs.redist.c%
10 1.1 cgd *
11 1.1 cgd * %W% (Berkeley) %G%
12 1.1 cgd *
13 1.1 cgd * $Id: fdesc_vnops.c,v 1.1 1993/03/23 23:56:34 cgd Exp $
14 1.1 cgd */
15 1.1 cgd
16 1.1 cgd /*
17 1.1 cgd * /dev/fd Filesystem
18 1.1 cgd */
19 1.1 cgd
20 1.1 cgd #include "param.h"
21 1.1 cgd #include "systm.h"
22 1.1 cgd #include "types.h"
23 1.1 cgd #include "time.h"
24 1.1 cgd #include "proc.h"
25 1.1 cgd #include "resourcevar.h"
26 1.1 cgd #include "filedesc.h"
27 1.1 cgd #include "vnode.h"
28 1.1 cgd #include "file.h"
29 1.1 cgd #include "stat.h"
30 1.1 cgd #include "mount.h"
31 1.1 cgd #include "namei.h"
32 1.1 cgd #include "buf.h"
33 1.1 cgd #include "miscfs/fdesc/fdesc.h"
34 1.1 cgd
35 1.1 cgd #include "../ufs/dir.h" /* For readdir() XXX */
36 1.1 cgd
37 1.1 cgd /*
38 1.1 cgd * vp is the current namei directory
39 1.1 cgd * ndp is the name to locate in that directory...
40 1.1 cgd */
41 1.1 cgd fdesc_lookup(dvp, ndp, p)
42 1.1 cgd struct vnode *dvp;
43 1.1 cgd struct nameidata *ndp;
44 1.1 cgd struct proc *p;
45 1.1 cgd {
46 1.1 cgd char *pname = ndp->ni_ptr;
47 1.1 cgd int nfiles = p->p_fd->fd_nfiles;
48 1.1 cgd unsigned fd;
49 1.1 cgd int error;
50 1.1 cgd struct vnode *fvp;
51 1.1 cgd
52 1.1 cgd #ifdef FDESC_DIAGNOSTIC
53 1.1 cgd printf("fdesc_lookup(%s)\n", pname);
54 1.1 cgd #endif
55 1.1 cgd if (ndp->ni_namelen == 1 && *pname == '.') {
56 1.1 cgd ndp->ni_dvp = dvp;
57 1.1 cgd ndp->ni_vp = dvp;
58 1.1 cgd VREF(dvp);
59 1.1 cgd /*VOP_LOCK(dvp);*/
60 1.1 cgd return (0);
61 1.1 cgd }
62 1.1 cgd
63 1.1 cgd fd = 0;
64 1.1 cgd while (*pname >= '0' && *pname <= '9') {
65 1.1 cgd fd = 10 * fd + *pname++ - '0';
66 1.1 cgd if (fd >= nfiles)
67 1.1 cgd break;
68 1.1 cgd }
69 1.1 cgd
70 1.1 cgd #ifdef FDESC_DIAGNOSTIC
71 1.1 cgd printf("fdesc_lookup: fd = %d, *pname = %x\n", fd, *pname);
72 1.1 cgd #endif
73 1.1 cgd if (*pname == '/') {
74 1.1 cgd error = ENOTDIR;
75 1.1 cgd goto bad;
76 1.1 cgd }
77 1.1 cgd
78 1.1 cgd if (*pname != '\0') {
79 1.1 cgd error = ENOENT;
80 1.1 cgd goto bad;
81 1.1 cgd }
82 1.1 cgd
83 1.1 cgd if (fd >= nfiles || p->p_fd->fd_ofiles[fd] == NULL) {
84 1.1 cgd error = EBADF;
85 1.1 cgd goto bad;
86 1.1 cgd }
87 1.1 cgd
88 1.1 cgd #ifdef FDESC_DIAGNOSTIC
89 1.1 cgd printf("fdesc_lookup: allocate new vnode\n");
90 1.1 cgd #endif
91 1.1 cgd error = getnewvnode(VT_UFS, dvp->v_mount, &fdesc_vnodeops, &fvp);
92 1.1 cgd if (error)
93 1.1 cgd goto bad;
94 1.1 cgd VTOFDESC(fvp)->f_fd = fd;
95 1.1 cgd /*VTOFDESC(fvp)->f_isroot = 0;*/
96 1.1 cgd ndp->ni_dvp = dvp;
97 1.1 cgd ndp->ni_vp = fvp;
98 1.1 cgd #ifdef FDESC_DIAGNOSTIC
99 1.1 cgd printf("fdesc_lookup: newvp = %x\n", fvp);
100 1.1 cgd #endif
101 1.1 cgd return (0);
102 1.1 cgd
103 1.1 cgd bad:;
104 1.1 cgd ndp->ni_dvp = dvp;
105 1.1 cgd ndp->ni_vp = NULL;
106 1.1 cgd #ifdef FDESC_DIAGNOSTIC
107 1.1 cgd printf("fdesc_lookup: error = %d\n", error);
108 1.1 cgd #endif
109 1.1 cgd return (error);
110 1.1 cgd }
111 1.1 cgd
112 1.1 cgd fdesc_open(vp, mode, cred, p)
113 1.1 cgd struct vnode *vp;
114 1.1 cgd int mode;
115 1.1 cgd struct ucred *cred;
116 1.1 cgd struct proc *p;
117 1.1 cgd {
118 1.1 cgd int error;
119 1.1 cgd struct filedesc *fdp;
120 1.1 cgd struct file *fp;
121 1.1 cgd int dfd;
122 1.1 cgd int fd;
123 1.1 cgd
124 1.1 cgd /*
125 1.1 cgd * Can always open the root (modulo perms)
126 1.1 cgd */
127 1.1 cgd if (vp->v_flag & VROOT)
128 1.1 cgd return (0);
129 1.1 cgd
130 1.1 cgd /*
131 1.1 cgd * XXX Kludge: set p->p_dupfd to contain the value of the
132 1.1 cgd * the file descriptor being sought for duplication. The error
133 1.1 cgd * return ensures that the vnode for this device will be released
134 1.1 cgd * by vn_open. Open will detect this special error and take the
135 1.1 cgd * actions in dupfdopen. Other callers of vn_open or VOP_OPEN
136 1.1 cgd * will simply report the error.
137 1.1 cgd */
138 1.1 cgd p->p_dupfd = VTOFDESC(vp)->f_fd; /* XXX */
139 1.1 cgd return (ENODEV);
140 1.1 cgd }
141 1.1 cgd
142 1.1 cgd static int
143 1.1 cgd fdesc_attr(fd, vap, cred, p)
144 1.1 cgd int fd;
145 1.1 cgd struct vattr *vap;
146 1.1 cgd struct ucred *cred;
147 1.1 cgd struct proc *p;
148 1.1 cgd {
149 1.1 cgd struct filedesc *fdp = p->p_fd;
150 1.1 cgd struct file *fp;
151 1.1 cgd int error;
152 1.1 cgd
153 1.1 cgd #ifdef FDESC_DIAGNOSTIC
154 1.1 cgd printf("fdesc_attr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
155 1.1 cgd #endif
156 1.1 cgd if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
157 1.1 cgd #ifdef FDESC_DIAGNOSTIC
158 1.1 cgd printf("fdesc_attr: fp = %x (EBADF)\n", fp);
159 1.1 cgd #endif
160 1.1 cgd return (EBADF);
161 1.1 cgd }
162 1.1 cgd
163 1.1 cgd /*
164 1.1 cgd * Can stat the underlying vnode, but not sockets because
165 1.1 cgd * they don't use struct vattrs. Well, we could convert from
166 1.1 cgd * a struct stat back to a struct vattr, later...
167 1.1 cgd */
168 1.1 cgd switch (fp->f_type) {
169 1.1 cgd case DTYPE_VNODE:
170 1.1 cgd error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
171 1.1 cgd break;
172 1.1 cgd
173 1.1 cgd case DTYPE_SOCKET:
174 1.1 cgd error = EOPNOTSUPP;
175 1.1 cgd break;
176 1.1 cgd
177 1.1 cgd default:
178 1.1 cgd panic("fdesc attr");
179 1.1 cgd break;
180 1.1 cgd }
181 1.1 cgd
182 1.1 cgd #ifdef FDESC_DIAGNOSTIC
183 1.1 cgd printf("fdesc_attr: returns error %d\n", error);
184 1.1 cgd #endif
185 1.1 cgd return (error);
186 1.1 cgd }
187 1.1 cgd
188 1.1 cgd fdesc_getattr(vp, vap, cred, p)
189 1.1 cgd struct vnode *vp;
190 1.1 cgd struct vattr *vap;
191 1.1 cgd struct ucred *cred;
192 1.1 cgd struct proc *p;
193 1.1 cgd {
194 1.1 cgd unsigned fd;
195 1.1 cgd int error;
196 1.1 cgd
197 1.1 cgd if (vp->v_flag & VROOT) {
198 1.1 cgd #ifdef FDESC_DIAGNOSTIC
199 1.1 cgd printf("fdesc_getattr: stat rootdir\n");
200 1.1 cgd #endif
201 1.1 cgd bzero((caddr_t) vap, sizeof(*vap));
202 1.1 cgd vattr_null(vap);
203 1.1 cgd vap->va_type = VDIR;
204 1.1 cgd vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
205 1.1 cgd vap->va_nlink = 2;
206 1.1 cgd vap->va_uid = 0;
207 1.1 cgd vap->va_gid = 0;
208 1.1 cgd vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
209 1.1 cgd vap->va_fileid = 2;
210 1.1 cgd /* vap->va_qsize = 0; */
211 1.1 cgd vap->va_size = DEV_BSIZE;
212 1.1 cgd vap->va_blocksize = DEV_BSIZE;
213 1.1 cgd microtime(&vap->va_atime);
214 1.1 cgd vap->va_mtime = vap->va_atime;
215 1.1 cgd vap->va_ctime = vap->va_ctime;
216 1.1 cgd vap->va_gen = 0;
217 1.1 cgd vap->va_flags = 0;
218 1.1 cgd vap->va_rdev = 0;
219 1.1 cgd /* vap->va_qbytes = 0; */
220 1.1 cgd vap->va_bytes = 0;
221 1.1 cgd return (0);
222 1.1 cgd }
223 1.1 cgd
224 1.1 cgd fd = VTOFDESC(vp)->f_fd;
225 1.1 cgd error = fdesc_attr(fd, vap, cred, p);
226 1.1 cgd if (error == 0)
227 1.1 cgd vp->v_type = vap->va_type;
228 1.1 cgd return (error);
229 1.1 cgd }
230 1.1 cgd
231 1.1 cgd fdesc_setattr(vp, vap, cred, p)
232 1.1 cgd struct vnode *vp;
233 1.1 cgd struct vattr *vap;
234 1.1 cgd struct ucred *cred;
235 1.1 cgd struct proc *p;
236 1.1 cgd {
237 1.1 cgd struct filedesc *fdp = p->p_fd;
238 1.1 cgd struct file *fp;
239 1.1 cgd unsigned fd;
240 1.1 cgd int error;
241 1.1 cgd
242 1.1 cgd /*
243 1.1 cgd * Can't mess with the root vnode
244 1.1 cgd */
245 1.1 cgd if (vp->v_flag & VROOT)
246 1.1 cgd return (EACCES);
247 1.1 cgd
248 1.1 cgd fd = VTOFDESC(vp)->f_fd;
249 1.1 cgd #ifdef FDESC_DIAGNOSTIC
250 1.1 cgd printf("fdesc_setattr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
251 1.1 cgd #endif
252 1.1 cgd if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
253 1.1 cgd #ifdef FDESC_DIAGNOSTIC
254 1.1 cgd printf("fdesc_setattr: fp = %x (EBADF)\n", fp);
255 1.1 cgd #endif
256 1.1 cgd return (EBADF);
257 1.1 cgd }
258 1.1 cgd
259 1.1 cgd /*
260 1.1 cgd * Can setattr the underlying vnode, but not sockets!
261 1.1 cgd */
262 1.1 cgd switch (fp->f_type) {
263 1.1 cgd case DTYPE_VNODE:
264 1.1 cgd error = VOP_SETATTR((struct vnode *) fp->f_data, vap, cred, p);
265 1.1 cgd break;
266 1.1 cgd
267 1.1 cgd case DTYPE_SOCKET:
268 1.1 cgd error = EOPNOTSUPP;
269 1.1 cgd break;
270 1.1 cgd
271 1.1 cgd default:
272 1.1 cgd panic("fdesc setattr");
273 1.1 cgd break;
274 1.1 cgd }
275 1.1 cgd
276 1.1 cgd #ifdef FDESC_DIAGNOSTIC
277 1.1 cgd printf("fdesc_setattr: returns error %d\n", error);
278 1.1 cgd #endif
279 1.1 cgd return (error);
280 1.1 cgd }
281 1.1 cgd
282 1.1 cgd fdesc_readdir(vp, uio, cred, eofflagp)
283 1.1 cgd struct vnode *vp;
284 1.1 cgd struct uio *uio;
285 1.1 cgd struct ucred *cred;
286 1.1 cgd int *eofflagp;
287 1.1 cgd {
288 1.1 cgd struct filedesc *fdp;
289 1.1 cgd int i;
290 1.1 cgd int error;
291 1.1 cgd
292 1.1 cgd #define UIO_MX 16
293 1.1 cgd
294 1.1 cgd fdp = uio->uio_procp->p_fd;
295 1.1 cgd i = uio->uio_offset / UIO_MX;
296 1.1 cgd error = 0;
297 1.1 cgd while (uio->uio_resid > 0) {
298 1.1 cgd if (i >= fdp->fd_nfiles) {
299 1.1 cgd *eofflagp = 1;
300 1.1 cgd break;
301 1.1 cgd }
302 1.1 cgd if (fdp->fd_ofiles[i] != NULL) {
303 1.1 cgd struct direct d;
304 1.1 cgd struct direct *dp = &d;
305 1.1 cgd char *cp = dp->d_name;
306 1.1 cgd #ifdef FDESC_FILEID
307 1.1 cgd struct vattr va;
308 1.1 cgd #endif
309 1.1 cgd int j;
310 1.1 cgd
311 1.1 cgd bzero((caddr_t) dp, UIO_MX);
312 1.1 cgd
313 1.1 cgd /*
314 1.1 cgd * Generate an ASCII representation of the name.
315 1.1 cgd * This can cope with fds in the range 0..99999
316 1.1 cgd */
317 1.1 cgd cp++;
318 1.1 cgd if (i > 10) cp++;
319 1.1 cgd if (i > 100) cp++;
320 1.1 cgd if (i > 1000) cp++;
321 1.1 cgd if (i > 10000) cp++;
322 1.1 cgd if (i > 100000) panic("fdesc_readdir");
323 1.1 cgd dp->d_namlen = cp - dp->d_name;
324 1.1 cgd *cp = '\0';
325 1.1 cgd j = i;
326 1.1 cgd do {
327 1.1 cgd *--cp = j % 10 + '0';
328 1.1 cgd j /= 10;
329 1.1 cgd } while (j > 0);
330 1.1 cgd /*
331 1.1 cgd * Fill in the remaining fields
332 1.1 cgd */
333 1.1 cgd dp->d_reclen = UIO_MX;
334 1.1 cgd dp->d_ino = i + 3;
335 1.1 cgd #ifdef FDESC_FILEID
336 1.1 cgd /*
337 1.1 cgd * If we want the file ids to match the
338 1.1 cgd * we must call getattr on the underlying file.
339 1.1 cgd * fdesc_attr may return an error, in which case
340 1.1 cgd * we ignore the returned file id.
341 1.1 cgd */
342 1.1 cgd error = fdesc_attr(i, &va, cred, p);
343 1.1 cgd if (error == 0)
344 1.1 cgd dp->d_ino = va.va_fileid;
345 1.1 cgd #endif
346 1.1 cgd /*
347 1.1 cgd * And ship to userland
348 1.1 cgd */
349 1.1 cgd error = uiomove((caddr_t) dp, UIO_MX, uio);
350 1.1 cgd if (error)
351 1.1 cgd break;
352 1.1 cgd }
353 1.1 cgd i++;
354 1.1 cgd }
355 1.1 cgd
356 1.1 cgd uio->uio_offset = i * UIO_MX;
357 1.1 cgd return (error);
358 1.1 cgd }
359 1.1 cgd
360 1.1 cgd fdesc_inactive(vp, p)
361 1.1 cgd struct vnode *vp;
362 1.1 cgd struct proc *p;
363 1.1 cgd {
364 1.1 cgd /*
365 1.1 cgd * Clear out the v_type field to avoid
366 1.1 cgd * nasty things happening in vgone().
367 1.1 cgd */
368 1.1 cgd vp->v_type = VNON;
369 1.1 cgd #ifdef FDESC_DIAGNOSTIC
370 1.1 cgd printf("fdesc_inactive(%x)\n", vp);
371 1.1 cgd #endif
372 1.1 cgd return (0);
373 1.1 cgd }
374 1.1 cgd
375 1.1 cgd /*
376 1.1 cgd * Print out the contents of a /dev/fd vnode.
377 1.1 cgd */
378 1.1 cgd /* ARGSUSED */
379 1.1 cgd fdesc_print(vp)
380 1.1 cgd struct vnode *vp;
381 1.1 cgd {
382 1.1 cgd printf("tag VT_NON, fdesc vnode\n");
383 1.1 cgd }
384 1.1 cgd
385 1.1 cgd /*
386 1.1 cgd * /dev/fd vnode unsupported operation
387 1.1 cgd */
388 1.1 cgd fdesc_enotsupp()
389 1.1 cgd {
390 1.1 cgd return (EOPNOTSUPP);
391 1.1 cgd }
392 1.1 cgd
393 1.1 cgd /*
394 1.1 cgd * /dev/fd "should never get here" operation
395 1.1 cgd */
396 1.1 cgd fdesc_badop()
397 1.1 cgd {
398 1.1 cgd panic("fdesc: bad op");
399 1.1 cgd /* NOTREACHED */
400 1.1 cgd }
401 1.1 cgd
402 1.1 cgd /*
403 1.1 cgd * /dev/fd vnode null operation
404 1.1 cgd */
405 1.1 cgd fdesc_nullop()
406 1.1 cgd {
407 1.1 cgd return (0);
408 1.1 cgd }
409 1.1 cgd
410 1.1 cgd #define fdesc_create ((int (*) __P(( \
411 1.1 cgd struct nameidata *ndp, \
412 1.1 cgd struct vattr *vap, \
413 1.1 cgd struct proc *p))) fdesc_enotsupp)
414 1.1 cgd #define fdesc_mknod ((int (*) __P(( \
415 1.1 cgd struct nameidata *ndp, \
416 1.1 cgd struct vattr *vap, \
417 1.1 cgd struct ucred *cred, \
418 1.1 cgd struct proc *p))) fdesc_enotsupp)
419 1.1 cgd #define fdesc_close ((int (*) __P(( \
420 1.1 cgd struct vnode *vp, \
421 1.1 cgd int fflag, \
422 1.1 cgd struct ucred *cred, \
423 1.1 cgd struct proc *p))) nullop)
424 1.1 cgd #define fdesc_access ((int (*) __P(( \
425 1.1 cgd struct vnode *vp, \
426 1.1 cgd int mode, \
427 1.1 cgd struct ucred *cred, \
428 1.1 cgd struct proc *p))) nullop)
429 1.1 cgd #define fdesc_read ((int (*) __P(( \
430 1.1 cgd struct vnode *vp, \
431 1.1 cgd struct uio *uio, \
432 1.1 cgd int ioflag, \
433 1.1 cgd struct ucred *cred))) fdesc_enotsupp)
434 1.1 cgd #define fdesc_write ((int (*) __P(( \
435 1.1 cgd struct vnode *vp, \
436 1.1 cgd struct uio *uio, \
437 1.1 cgd int ioflag, \
438 1.1 cgd struct ucred *cred))) fdesc_enotsupp)
439 1.1 cgd #define fdesc_ioctl ((int (*) __P(( \
440 1.1 cgd struct vnode *vp, \
441 1.1 cgd int command, \
442 1.1 cgd caddr_t data, \
443 1.1 cgd int fflag, \
444 1.1 cgd struct ucred *cred, \
445 1.1 cgd struct proc *p))) fdesc_enotsupp)
446 1.1 cgd #define fdesc_select ((int (*) __P(( \
447 1.1 cgd struct vnode *vp, \
448 1.1 cgd int which, \
449 1.1 cgd int fflags, \
450 1.1 cgd struct ucred *cred, \
451 1.1 cgd struct proc *p))) fdesc_enotsupp)
452 1.1 cgd #define fdesc_mmap ((int (*) __P(( \
453 1.1 cgd struct vnode *vp, \
454 1.1 cgd int fflags, \
455 1.1 cgd struct ucred *cred, \
456 1.1 cgd struct proc *p))) fdesc_enotsupp)
457 1.1 cgd #define fdesc_fsync ((int (*) __P(( \
458 1.1 cgd struct vnode *vp, \
459 1.1 cgd int fflags, \
460 1.1 cgd struct ucred *cred, \
461 1.1 cgd int waitfor, \
462 1.1 cgd struct proc *p))) nullop)
463 1.1 cgd #define fdesc_seek ((int (*) __P(( \
464 1.1 cgd struct vnode *vp, \
465 1.1 cgd off_t oldoff, \
466 1.1 cgd off_t newoff, \
467 1.1 cgd struct ucred *cred))) nullop)
468 1.1 cgd #define fdesc_remove ((int (*) __P(( \
469 1.1 cgd struct nameidata *ndp, \
470 1.1 cgd struct proc *p))) fdesc_enotsupp)
471 1.1 cgd #define fdesc_link ((int (*) __P(( \
472 1.1 cgd struct vnode *vp, \
473 1.1 cgd struct nameidata *ndp, \
474 1.1 cgd struct proc *p))) fdesc_enotsupp)
475 1.1 cgd #define fdesc_rename ((int (*) __P(( \
476 1.1 cgd struct nameidata *fndp, \
477 1.1 cgd struct nameidata *tdnp, \
478 1.1 cgd struct proc *p))) fdesc_enotsupp)
479 1.1 cgd #define fdesc_mkdir ((int (*) __P(( \
480 1.1 cgd struct nameidata *ndp, \
481 1.1 cgd struct vattr *vap, \
482 1.1 cgd struct proc *p))) fdesc_enotsupp)
483 1.1 cgd #define fdesc_rmdir ((int (*) __P(( \
484 1.1 cgd struct nameidata *ndp, \
485 1.1 cgd struct proc *p))) fdesc_enotsupp)
486 1.1 cgd #define fdesc_symlink ((int (*) __P(( \
487 1.1 cgd struct nameidata *ndp, \
488 1.1 cgd struct vattr *vap, \
489 1.1 cgd char *target, \
490 1.1 cgd struct proc *p))) fdesc_enotsupp)
491 1.1 cgd #define fdesc_readlink ((int (*) __P(( \
492 1.1 cgd struct vnode *vp, \
493 1.1 cgd struct uio *uio, \
494 1.1 cgd struct ucred *cred))) fdesc_enotsupp)
495 1.1 cgd #define fdesc_abortop ((int (*) __P(( \
496 1.1 cgd struct nameidata *ndp))) nullop)
497 1.1 cgd #ifdef FDESC_DIAGNOSTIC
498 1.1 cgd int fdesc_reclaim(vp)
499 1.1 cgd struct vnode *vp;
500 1.1 cgd {
501 1.1 cgd printf("fdesc_reclaim(%x)\n", vp);
502 1.1 cgd return (0);
503 1.1 cgd }
504 1.1 cgd #else
505 1.1 cgd #define fdesc_reclaim ((int (*) __P(( \
506 1.1 cgd struct vnode *vp))) nullop)
507 1.1 cgd #endif
508 1.1 cgd #define fdesc_lock ((int (*) __P(( \
509 1.1 cgd struct vnode *vp))) nullop)
510 1.1 cgd #define fdesc_unlock ((int (*) __P(( \
511 1.1 cgd struct vnode *vp))) nullop)
512 1.1 cgd #define fdesc_bmap ((int (*) __P(( \
513 1.1 cgd struct vnode *vp, \
514 1.1 cgd daddr_t bn, \
515 1.1 cgd struct vnode **vpp, \
516 1.1 cgd daddr_t *bnp))) fdesc_badop)
517 1.1 cgd #define fdesc_strategy ((int (*) __P(( \
518 1.1 cgd struct buf *bp))) fdesc_badop)
519 1.1 cgd #define fdesc_islocked ((int (*) __P(( \
520 1.1 cgd struct vnode *vp))) nullop)
521 1.1 cgd #define fdesc_advlock ((int (*) __P(( \
522 1.1 cgd struct vnode *vp, \
523 1.1 cgd caddr_t id, \
524 1.1 cgd int op, \
525 1.1 cgd struct flock *fl, \
526 1.1 cgd int flags))) fdesc_enotsupp)
527 1.1 cgd
528 1.1 cgd struct vnodeops fdesc_vnodeops = {
529 1.1 cgd fdesc_lookup, /* lookup */
530 1.1 cgd fdesc_create, /* create */
531 1.1 cgd fdesc_mknod, /* mknod */
532 1.1 cgd fdesc_open, /* open */
533 1.1 cgd fdesc_close, /* close */
534 1.1 cgd fdesc_access, /* access */
535 1.1 cgd fdesc_getattr, /* getattr */
536 1.1 cgd fdesc_setattr, /* setattr */
537 1.1 cgd fdesc_read, /* read */
538 1.1 cgd fdesc_write, /* write */
539 1.1 cgd fdesc_ioctl, /* ioctl */
540 1.1 cgd fdesc_select, /* select */
541 1.1 cgd fdesc_mmap, /* mmap */
542 1.1 cgd fdesc_fsync, /* fsync */
543 1.1 cgd fdesc_seek, /* seek */
544 1.1 cgd fdesc_remove, /* remove */
545 1.1 cgd fdesc_link, /* link */
546 1.1 cgd fdesc_rename, /* rename */
547 1.1 cgd fdesc_mkdir, /* mkdir */
548 1.1 cgd fdesc_rmdir, /* rmdir */
549 1.1 cgd fdesc_symlink, /* symlink */
550 1.1 cgd fdesc_readdir, /* readdir */
551 1.1 cgd fdesc_readlink, /* readlink */
552 1.1 cgd fdesc_abortop, /* abortop */
553 1.1 cgd fdesc_inactive, /* inactive */
554 1.1 cgd fdesc_reclaim, /* reclaim */
555 1.1 cgd fdesc_lock, /* lock */
556 1.1 cgd fdesc_unlock, /* unlock */
557 1.1 cgd fdesc_bmap, /* bmap */
558 1.1 cgd fdesc_strategy, /* strategy */
559 1.1 cgd fdesc_print, /* print */
560 1.1 cgd fdesc_islocked, /* islocked */
561 1.1 cgd fdesc_advlock, /* advlock */
562 1.1 cgd };
563