FreeBSD/Linux Kernel Cross Reference
sys/sys/vnode.h
1 /* $NetBSD: vnode.h,v 1.121 2004/02/14 00:00:57 hannken Exp $ */
2
3 /*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)vnode.h 8.17 (Berkeley) 5/20/95
32 */
33
34 #ifndef _SYS_VNODE_H_
35 #define _SYS_VNODE_H_
36
37 #include <sys/event.h>
38 #include <sys/lock.h>
39 #include <sys/queue.h>
40
41 /* XXX: clean up includes later */
42 #include <uvm/uvm_param.h> /* XXX */
43 #include <uvm/uvm_pglist.h> /* XXX */
44 #include <uvm/uvm_object.h> /* XXX */
45 #include <uvm/uvm_extern.h> /* XXX */
46
47 struct namecache;
48
49 /*
50 * The vnode is the focus of all file activity in UNIX. There is a
51 * unique vnode allocated for each active file, each current directory,
52 * each mounted-on file, text file, and the root.
53 */
54
55 /*
56 * Vnode types. VNON means no type.
57 */
58 enum vtype { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO, VBAD };
59
60 /*
61 * Vnode tag types.
62 * These are for the benefit of external programs only (e.g., pstat)
63 * and should NEVER be inspected by the kernel.
64 */
65 enum vtagtype {
66 VT_NON, VT_UFS, VT_NFS, VT_MFS, VT_MSDOSFS, VT_LFS, VT_LOFS, VT_FDESC,
67 VT_PORTAL, VT_NULL, VT_UMAP, VT_KERNFS, VT_PROCFS, VT_AFS, VT_ISOFS,
68 VT_UNION, VT_ADOSFS, VT_EXT2FS, VT_CODA, VT_FILECORE, VT_NTFS, VT_VFS,
69 VT_OVERLAY, VT_SMBFS
70 };
71
72 LIST_HEAD(buflists, buf);
73
74 /*
75 * Reading or writing any of these items requires holding the appropriate lock.
76 * v_freelist is locked by the global vnode_free_list simple lock.
77 * v_mntvnodes is locked by the global mntvnodes simple lock.
78 * v_flag, v_usecount, v_holdcount and v_writecount are
79 * locked by the v_interlock simple lock
80 *
81 * Each underlying filesystem allocates its own private area and hangs
82 * it from v_data.
83 */
84 struct vnode {
85 struct uvm_object v_uobj; /* the VM object */
86 #define v_usecount v_uobj.uo_refs
87 #define v_interlock v_uobj.vmobjlock
88 voff_t v_size; /* size of file */
89 int v_flag; /* flags */
90 int v_numoutput; /* number of pending writes */
91 long v_writecount; /* reference count of writers */
92 long v_holdcnt; /* page & buffer references */
93 struct mount *v_mount; /* ptr to vfs we are in */
94 int (**v_op) __P((void *)); /* vnode operations vector */
95 TAILQ_ENTRY(vnode) v_freelist; /* vnode freelist */
96 LIST_ENTRY(vnode) v_mntvnodes; /* vnodes for mount point */
97 struct buflists v_cleanblkhd; /* clean blocklist head */
98 struct buflists v_dirtyblkhd; /* dirty blocklist head */
99 LIST_ENTRY(vnode) v_synclist; /* vnodes with dirty buffers */
100 LIST_HEAD(, namecache) v_dnclist; /* namecaches for children */
101 LIST_HEAD(, namecache) v_nclist; /* namecaches for our parent */
102 union {
103 struct mount *vu_mountedhere;/* ptr to mounted vfs (VDIR) */
104 struct socket *vu_socket; /* unix ipc (VSOCK) */
105 struct specinfo *vu_specinfo; /* device (VCHR, VBLK) */
106 struct fifoinfo *vu_fifoinfo; /* fifo (VFIFO) */
107 } v_un;
108 struct nqlease *v_lease; /* Soft reference to lease */
109 enum vtype v_type; /* vnode type */
110 enum vtagtype v_tag; /* type of underlying data */
111 struct lock v_lock; /* lock for this vnode */
112 struct lock *v_vnlock; /* pointer to lock */
113 void *v_data; /* private data for fs */
114 struct klist v_klist; /* knotes attached to vnode */
115 #ifdef VERIFIED_EXEC
116 char fp_status; /* fingerprint status
117 (see below) */
118 #endif
119 };
120 #define v_mountedhere v_un.vu_mountedhere
121 #define v_socket v_un.vu_socket
122 #define v_specinfo v_un.vu_specinfo
123 #define v_fifoinfo v_un.vu_fifoinfo
124 /*
125 * All vnode locking operations should use vp->v_vnlock. For leaf filesystems
126 * (such as ffs, lfs, msdosfs, etc), vp->v_vnlock = &vp->v_lock. For
127 * stacked filesystems, vp->v_vnlock may equal lowervp->v_vnlock.
128 *
129 * vp->v_vnlock may also be NULL, which indicates that a leaf node does not
130 * export a struct lock for vnode locking. Stacked filesystems (such as
131 * nullfs) must call the underlying fs for locking. See layerfs_ routines
132 * for examples.
133 *
134 * All filesystems must (pretend to) understand lockmanager flags.
135 */
136
137 /*
138 * Vnode flags.
139 */
140 #define VROOT 0x0001 /* root of its file system */
141 #define VTEXT 0x0002 /* vnode is a pure text prototype */
142 /* VSYSTEM only used to skip vflush()ing quota files */
143 #define VSYSTEM 0x0004 /* vnode being used by kernel */
144 /* VISTTY used when reading dead vnodes */
145 #define VISTTY 0x0008 /* vnode represents a tty */
146 #define VEXECMAP 0x0010 /* vnode has PROT_EXEC mappings */
147 #define VXLOCK 0x0100 /* vnode is locked to change underlying type */
148 #define VXWANT 0x0200 /* process is waiting for vnode */
149 #define VBWAIT 0x0400 /* waiting for output to complete */
150 #define VALIASED 0x0800 /* vnode has an alias */
151 #define VDIROP 0x1000 /* LFS: vnode is involved in a directory op */
152 #define VLAYER 0x2000 /* vnode is on a layer filesystem */
153 #define VONWORKLST 0x4000 /* On syncer work-list */
154 #define VDIRTY 0x8000 /* vnode possibly has dirty pages */
155
156 #define VSIZENOTSET ((voff_t)-1)
157
158 /*
159 * Use a global lock for all v_numoutput updates.
160 * Define a convenience macro to increment by one.
161 * Note: the only place where v_numoutput is decremented is in vwakeup().
162 */
163 extern struct simplelock global_v_numoutput_slock;
164 #define V_INCR_NUMOUTPUT(vp) do { \
165 simple_lock(&global_v_numoutput_slock); \
166 (vp)->v_numoutput++; \
167 simple_unlock(&global_v_numoutput_slock); \
168 } while (/*CONSTCOND*/ 0)
169
170 /*
171 * Valid states for the fingerprint flag - if signed exec is being used
172 */
173 #ifdef VERIFIED_EXEC
174 #define FINGERPRINT_INVALID 0 /* fingerprint has not been evaluated */
175 #define FINGERPRINT_VALID 1 /* fingerprint evaluated and matches list */
176 #define FINGERPRINT_INDIRECT 2 /* fingerprint eval'd/matched but only
177 indirect execs allowed */
178 #define FINGERPRINT_NOMATCH 3 /* fingerprint evaluated but does not match */
179 #define FINGERPRINT_NOENTRY 4 /* fingerprint evaluated but no list entry */
180 #define FINGERPRINT_NODEV 5 /* fingerprint evaluated but no dev list */
181 #endif
182
183 /*
184 * Vnode attributes. A field value of VNOVAL represents a field whose value
185 * is unavailable (getattr) or which is not to be changed (setattr).
186 */
187 struct vattr {
188 enum vtype va_type; /* vnode type (for create) */
189 mode_t va_mode; /* files access mode and type */
190 nlink_t va_nlink; /* number of references to file */
191 uid_t va_uid; /* owner user id */
192 gid_t va_gid; /* owner group id */
193 long va_fsid; /* file system id (dev for now) */
194 long va_fileid; /* file id */
195 u_quad_t va_size; /* file size in bytes */
196 long va_blocksize; /* blocksize preferred for i/o */
197 struct timespec va_atime; /* time of last access */
198 struct timespec va_mtime; /* time of last modification */
199 struct timespec va_ctime; /* time file changed */
200 struct timespec va_birthtime; /* time file created */
201 u_long va_gen; /* generation number of file */
202 u_long va_flags; /* flags defined for file */
203 dev_t va_rdev; /* device the special file represents */
204 u_quad_t va_bytes; /* bytes of disk space held by file */
205 u_quad_t va_filerev; /* file modification number */
206 u_int va_vaflags; /* operations flags, see below */
207 long va_spare; /* remain quad aligned */
208 };
209
210 /*
211 * Flags for va_vaflags.
212 */
213 #define VA_UTIMES_NULL 0x01 /* utimes argument was NULL */
214 #define VA_EXCLUSIVE 0x02 /* exclusive create request */
215
216 /*
217 * Flags for ioflag.
218 */
219 #define IO_UNIT 0x01 /* do I/O as atomic unit */
220 #define IO_APPEND 0x02 /* append write to end */
221 #define IO_SYNC (0x04|IO_DSYNC) /* sync I/O file integrity completion */
222 #define IO_NODELOCKED 0x08 /* underlying node already locked */
223 #define IO_NDELAY 0x10 /* FNDELAY flag set in file table */
224 #define IO_DSYNC 0x20 /* sync I/O data integrity completion */
225 #define IO_ALTSEMANTICS 0x40 /* use alternate i/o semantics */
226
227 /*
228 * Modes.
229 */
230 #define VREAD 00004 /* read, write, execute permissions */
231 #define VWRITE 00002
232 #define VEXEC 00001
233
234 /*
235 * Token indicating no attribute value yet assigned.
236 */
237 #define VNOVAL (-1)
238
239 #ifdef _KERNEL
240 /*
241 * Convert between vnode types and inode formats (since POSIX.1
242 * defines mode word of stat structure in terms of inode formats).
243 */
244 extern const enum vtype iftovt_tab[];
245 extern const int vttoif_tab[];
246 #define IFTOVT(mode) (iftovt_tab[((mode) & S_IFMT) >> 12])
247 #define VTTOIF(indx) (vttoif_tab[(int)(indx)])
248 #define MAKEIMODE(indx, mode) (int)(VTTOIF(indx) | (mode))
249
250 /*
251 * Flags to various vnode functions.
252 */
253 #define SKIPSYSTEM 0x0001 /* vflush: skip vnodes marked VSYSTEM */
254 #define FORCECLOSE 0x0002 /* vflush: force file closeure */
255 #define WRITECLOSE 0x0004 /* vflush: only close writable files */
256 #define DOCLOSE 0x0008 /* vclean: close active files */
257 #define V_SAVE 0x0001 /* vinvalbuf: sync file first */
258 /* vn_start_write: */
259 #define V_WAIT 0x0001 /* sleep for suspend */
260 #define V_NOWAIT 0x0002 /* don't sleep for suspend */
261 #define V_SLEEPONLY 0x0004 /* just return after sleep */
262 #define V_PCATCH 0x0008 /* sleep witch PCATCH set */
263 #define V_LOWER 0x0010 /* lower level operation */
264
265 /*
266 * Flags to various vnode operations.
267 */
268 #define REVOKEALL 0x0001 /* revoke: revoke all aliases */
269
270 #define FSYNC_WAIT 0x0001 /* fsync: wait for completion */
271 #define FSYNC_DATAONLY 0x0002 /* fsync: hint: sync file data only */
272 #define FSYNC_RECLAIM 0x0004 /* fsync: hint: vnode is being reclaimed */
273 #define FSYNC_LAZY 0x0008 /* fsync: lazy sync (trickle) */
274
275 #define UPDATE_WAIT 0x0001 /* update: wait for completion */
276 #define UPDATE_DIROP 0x0002 /* update: hint to fs to wait or not */
277
278 #define HOLDRELE(vp) holdrele(vp)
279 #define VHOLD(vp) vhold(vp)
280 #define VREF(vp) vref(vp)
281 TAILQ_HEAD(freelst, vnode);
282 extern struct freelst vnode_hold_list; /* free vnodes referencing buffers */
283 extern struct freelst vnode_free_list; /* vnode free list */
284 extern struct simplelock vnode_free_list_slock;
285
286 #ifdef DIAGNOSTIC
287 #define ilstatic
288 #else
289 #define ilstatic static
290 #endif
291
292 ilstatic void holdrelel(struct vnode *);
293 ilstatic void vholdl(struct vnode *);
294 ilstatic void vref(struct vnode *);
295
296 static __inline void holdrele(struct vnode *) __attribute__((__unused__));
297 static __inline void vhold(struct vnode *) __attribute__((__unused__));
298
299 #ifdef DIAGNOSTIC
300 #define VATTR_NULL(vap) vattr_null(vap)
301 #else
302 #define VATTR_NULL(vap) (*(vap) = va_null) /* initialize a vattr */
303
304 /*
305 * decrease buf or page ref
306 *
307 * called with v_interlock held
308 */
309 static __inline void
310 holdrelel(struct vnode *vp)
311 {
312
313 vp->v_holdcnt--;
314 if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) &&
315 vp->v_holdcnt == 0 && vp->v_usecount == 0) {
316 simple_lock(&vnode_free_list_slock);
317 TAILQ_REMOVE(&vnode_hold_list, vp, v_freelist);
318 TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
319 simple_unlock(&vnode_free_list_slock);
320 }
321 }
322
323 /*
324 * increase buf or page ref
325 *
326 * called with v_interlock held
327 */
328 static __inline void
329 vholdl(struct vnode *vp)
330 {
331
332 if ((vp->v_freelist.tqe_prev != (struct vnode **)0xdeadb) &&
333 vp->v_holdcnt == 0 && vp->v_usecount == 0) {
334 simple_lock(&vnode_free_list_slock);
335 TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
336 TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
337 simple_unlock(&vnode_free_list_slock);
338 }
339 vp->v_holdcnt++;
340 }
341
342 /*
343 * increase reference
344 */
345 static __inline void
346 vref(struct vnode *vp)
347 {
348
349 simple_lock(&vp->v_interlock);
350 vp->v_usecount++;
351 simple_unlock(&vp->v_interlock);
352 }
353 #endif /* DIAGNOSTIC */
354
355 /*
356 * decrease buf or page ref
357 */
358 static __inline void
359 holdrele(struct vnode *vp)
360 {
361
362 simple_lock(&vp->v_interlock);
363 holdrelel(vp);
364 simple_unlock(&vp->v_interlock);
365 }
366
367 /*
368 * increase buf or page ref
369 */
370 static __inline void
371 vhold(struct vnode *vp)
372 {
373
374 simple_lock(&vp->v_interlock);
375 vholdl(vp);
376 simple_unlock(&vp->v_interlock);
377 }
378
379 #define NULLVP ((struct vnode *)NULL)
380
381 #define VN_KNOTE(vp, b) KNOTE(&vp->v_klist, (b))
382
383 /*
384 * Global vnode data.
385 */
386 extern struct vnode *rootvnode; /* root (i.e. "/") vnode */
387 extern int desiredvnodes; /* number of vnodes desired */
388 extern long numvnodes; /* current number of vnodes */
389 extern time_t syncdelay; /* max time to delay syncing data */
390 extern time_t filedelay; /* time to delay syncing files */
391 extern time_t dirdelay; /* time to delay syncing directories */
392 extern time_t metadelay; /* time to delay syncing metadata */
393 extern struct vattr va_null; /* predefined null vattr structure */
394
395 /*
396 * Macro/function to check for client cache inconsistency w.r.t. leasing.
397 */
398 #define LEASE_READ 0x1 /* Check lease for readers */
399 #define LEASE_WRITE 0x2 /* Check lease for modifiers */
400
401 #endif /* _KERNEL */
402
403
404 /*
405 * Mods for exensibility.
406 */
407
408 /*
409 * Flags for vdesc_flags:
410 */
411 #define VDESC_MAX_VPS 8
412 /* Low order 16 flag bits are reserved for willrele flags for vp arguments. */
413 #define VDESC_VP0_WILLRELE 0x00000001
414 #define VDESC_VP1_WILLRELE 0x00000002
415 #define VDESC_VP2_WILLRELE 0x00000004
416 #define VDESC_VP3_WILLRELE 0x00000008
417 #define VDESC_VP0_WILLUNLOCK 0x00000100
418 #define VDESC_VP1_WILLUNLOCK 0x00000200
419 #define VDESC_VP2_WILLUNLOCK 0x00000400
420 #define VDESC_VP3_WILLUNLOCK 0x00000800
421 #define VDESC_VP0_WILLPUT 0x00000101
422 #define VDESC_VP1_WILLPUT 0x00000202
423 #define VDESC_VP2_WILLPUT 0x00000404
424 #define VDESC_VP3_WILLPUT 0x00000808
425 #define VDESC_NOMAP_VPP 0x00010000
426 #define VDESC_VPP_WILLRELE 0x00020000
427
428 /*
429 * VDESC_NO_OFFSET is used to identify the end of the offset list
430 * and in places where no such field exists.
431 */
432 #define VDESC_NO_OFFSET -1
433
434 /*
435 * This structure describes the vnode operation taking place.
436 */
437 struct vnodeop_desc {
438 int vdesc_offset; /* offset in vector--first for speed */
439 const char *vdesc_name; /* a readable name for debugging */
440 int vdesc_flags; /* VDESC_* flags */
441
442 /*
443 * These ops are used by bypass routines to map and locate arguments.
444 * Creds and procs are not needed in bypass routines, but sometimes
445 * they are useful to (for example) transport layers.
446 * Nameidata is useful because it has a cred in it.
447 */
448 const int *vdesc_vp_offsets; /* list ended by VDESC_NO_OFFSET */
449 int vdesc_vpp_offset; /* return vpp location */
450 int vdesc_cred_offset; /* cred location, if any */
451 int vdesc_proc_offset; /* proc location, if any */
452 int vdesc_componentname_offset; /* if any */
453 /*
454 * Finally, we've got a list of private data (about each operation)
455 * for each transport layer. (Support to manage this list is not
456 * yet part of BSD.)
457 */
458 caddr_t *vdesc_transports;
459 };
460
461 #ifdef _KERNEL
462 #include <sys/mallocvar.h>
463 MALLOC_DECLARE(M_CACHE);
464 MALLOC_DECLARE(M_VNODE);
465
466 /*
467 * A list of all the operation descs.
468 */
469 extern struct vnodeop_desc *vnodeop_descs[];
470
471 /*
472 * Interlock for scanning list of vnodes attached to a mountpoint
473 */
474 extern struct simplelock mntvnode_slock;
475
476 /*
477 * Union filesystem hook for vn_readdir().
478 */
479 extern int (*vn_union_readdir_hook) (struct vnode **, struct file *, struct proc *);
480
481 /*
482 * This macro is very helpful in defining those offsets in the vdesc struct.
483 *
484 * This is stolen from X11R4. I ingored all the fancy stuff for
485 * Crays, so if you decide to port this to such a serious machine,
486 * you might want to consult Intrisics.h's XtOffset{,Of,To}.
487 */
488 #define VOPARG_OFFSET(p_type,field) \
489 ((int) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
490 #define VOPARG_OFFSETOF(s_type,field) \
491 VOPARG_OFFSET(s_type*,field)
492 #define VOPARG_OFFSETTO(S_TYPE,S_OFFSET,STRUCT_P) \
493 ((S_TYPE)(((char*)(STRUCT_P))+(S_OFFSET)))
494
495
496 /*
497 * This structure is used to configure the new vnodeops vector.
498 */
499 struct vnodeopv_entry_desc {
500 const struct vnodeop_desc *opve_op; /* which operation this is */
501 int (*opve_impl)(void *); /* code implementing this operation */
502 };
503 struct vnodeopv_desc {
504 /* ptr to the ptr to the vector where op should go */
505 int (***opv_desc_vector_p)(void *);
506 const struct vnodeopv_entry_desc *opv_desc_ops; /* null terminated list */
507 };
508
509 /*
510 * A default routine which just returns an error.
511 */
512 int vn_default_error(void *);
513
514 /*
515 * A generic structure.
516 * This can be used by bypass routines to identify generic arguments.
517 */
518 struct vop_generic_args {
519 struct vnodeop_desc *a_desc;
520 /* other random data follows, presumably */
521 };
522
523 /*
524 * VOCALL calls an op given an ops vector. We break it out because BSD's
525 * vclean changes the ops vector and then wants to call ops with the old
526 * vector.
527 */
528 /*
529 * actually, vclean doesn't use it anymore, but nfs does,
530 * for device specials and fifos.
531 */
532 #define VOCALL(OPSV,OFF,AP) (( *((OPSV)[(OFF)])) (AP))
533
534 /*
535 * This call works for vnodes in the kernel.
536 */
537 #define VCALL(VP,OFF,AP) VOCALL((VP)->v_op,(OFF),(AP))
538 #define VDESC(OP) (& __CONCAT(OP,_desc))
539 #define VOFFSET(OP) (VDESC(OP)->vdesc_offset)
540
541 /*
542 * Functions to gate filesystem write operations. Declared static inline
543 * here because they usually go into time critical code paths.
544 */
545 #include <sys/mount.h>
546
547 /*
548 * Preparing to start a filesystem write operation. If the operation is
549 * permitted, then we bump the count of operations in progress and
550 * proceed. If a suspend request is in progress, we wait until the
551 * suspension is over, and then proceed.
552 * V_PCATCH adds PCATCH to the tsleep flags.
553 * V_WAIT waits until suspension is over. Otherwise returns EWOULDBLOCK.
554 * V_SLEEPONLY wait, but do not bump the operations count.
555 * V_LOWER this is a lower level operation. No further vnodes should be
556 * locked. Otherwise it is a upper level operation. No vnodes
557 * should be locked.
558 */
559 static inline int
560 vn_start_write(struct vnode *vp, struct mount **mpp, int flags)
561 {
562 struct mount *mp;
563 int error, mask, prio;
564
565 /*
566 * If a vnode is provided, get and return the mount point that
567 * to which it will write.
568 */
569 if (vp != NULL) {
570 *mpp = vp->v_mount;
571 }
572 if ((mp = *mpp) == NULL)
573 return (0);
574 /*
575 * Check on status of suspension.
576 */
577 prio = PUSER - 1;
578 if (flags & V_PCATCH)
579 prio |= PCATCH;
580
581 if ((flags & V_LOWER) == 0)
582 mask = IMNT_SUSPEND;
583 else
584 mask = IMNT_SUSPENDLOW;
585
586 while ((mp->mnt_iflag & mask) != 0) {
587 if ((flags & V_WAIT) == 0)
588 return (EWOULDBLOCK);
589 error = tsleep(&mp->mnt_flag, prio, "suspfs", 0);
590 if (error)
591 return (error);
592 }
593 if (flags & V_SLEEPONLY)
594 return (0);
595 if ((flags & V_LOWER) == 0)
596 mp->mnt_writeopcountupper++;
597 else
598 mp->mnt_writeopcountlower++;
599 return (0);
600 }
601
602 /*
603 * Filesystem write operation has completed. If we are suspending and this
604 * operation is the last one, notify the suspender that the suspension is
605 * now in effect.
606 */
607 static inline void
608 vn_finished_write(struct mount *mp, int flags)
609 {
610 if (mp == NULL)
611 return;
612 if ((flags & V_LOWER) == 0) {
613 mp->mnt_writeopcountupper--;
614 if (mp->mnt_writeopcountupper < 0)
615 printf("vn_finished_write: neg cnt upper=%d\n",
616 mp->mnt_writeopcountupper);
617 if ((mp->mnt_iflag & IMNT_SUSPEND) != 0 &&
618 mp->mnt_writeopcountupper <= 0)
619 wakeup(&mp->mnt_writeopcountupper);
620 } else {
621 mp->mnt_writeopcountlower--;
622 if (mp->mnt_writeopcountlower < 0)
623 printf("vn_finished_write: neg cnt lower=%d\n",
624 mp->mnt_writeopcountlower);
625 if ((mp->mnt_iflag & IMNT_SUSPENDLOW) != 0 &&
626 mp->mnt_writeopcountupper <= 0)
627 wakeup(&mp->mnt_writeopcountlower);
628 }
629 }
630
631 /*
632 * Finally, include the default set of vnode operations.
633 */
634 #include <sys/vnode_if.h>
635
636 /*
637 * Public vnode manipulation functions.
638 */
639 struct file;
640 struct filedesc;
641 struct nameidata;
642 struct proc;
643 struct stat;
644 struct ucred;
645 struct uio;
646 struct vattr;
647 struct vnode;
648
649 /* see vnode(9) */
650 int bdevvp(dev_t, struct vnode **);
651 int cdevvp(dev_t, struct vnode **);
652 struct vnode *
653 checkalias(struct vnode *, dev_t, struct mount *);
654 int getnewvnode(enum vtagtype, struct mount *, int (**)(void *),
655 struct vnode **);
656 void ungetnewvnode(struct vnode *);
657 int vaccess(enum vtype, mode_t, uid_t, gid_t, mode_t, struct ucred *);
658 void vattr_null(struct vattr *);
659 int vcount(struct vnode *);
660 void vdevgone(int, int, int, enum vtype);
661 int vfinddev(dev_t, enum vtype, struct vnode **);
662 int vflush(struct mount *, struct vnode *, int);
663 void vflushbuf(struct vnode *, int);
664 int vget(struct vnode *, int);
665 void vgone(struct vnode *);
666 void vgonel(struct vnode *, struct proc *);
667 int vinvalbuf(struct vnode *, int, struct ucred *,
668 struct proc *, int, int);
669 void vprint(char *, struct vnode *);
670 void vput(struct vnode *);
671 int vrecycle(struct vnode *, struct simplelock *, struct proc *);
672 void vrele(struct vnode *);
673 int vtruncbuf(struct vnode *, daddr_t, int, int);
674 void vwakeup(struct buf *);
675
676 /* see vnsubr(9) */
677 int vn_bwrite(void *);
678 int vn_close(struct vnode *, int, struct ucred *, struct proc *);
679 int vn_isunder(struct vnode *, struct vnode *, struct proc *);
680 int vn_lock(struct vnode *, int);
681 void vn_markexec(struct vnode *);
682 int vn_marktext(struct vnode *);
683 int vn_open(struct nameidata *, int, int);
684 int vn_rdwr(enum uio_rw, struct vnode *, caddr_t, int, off_t, enum uio_seg,
685 int, struct ucred *, size_t *, struct proc *);
686 int vn_readdir(struct file *, char *, int, u_int, int *, struct proc *,
687 off_t **, int *);
688 void vn_restorerecurse(struct vnode *, u_int);
689 u_int vn_setrecurse(struct vnode *);
690 int vn_stat(struct vnode *, struct stat *, struct proc *);
691 int vn_kqfilter(struct file *, struct knote *);
692 int vn_writechk(struct vnode *);
693 int vn_cow_establish(struct vnode *, void (*)(void *, struct buf *),
694 void *);
695 int vn_cow_disestablish(struct vnode *, void (*)(void *, struct buf *),
696 void *);
697
698 /* initialise global vnode management */
699 void vntblinit(void);
700
701 /* misc stuff */
702 void vn_syncer_add_to_worklist(struct vnode *vp, int delay);
703 void vn_syncer_remove_from_worklist(struct vnode *vp);
704 int speedup_syncer(void);
705
706 /* from vfs_syscalls.c - abused by compat code */
707 int getvnode(struct filedesc *fdp, int fd, struct file **fpp);
708
709 /* see vfssubr(9) */
710 void vfs_getnewfsid(struct mount *);
711 int vfs_drainvnodes(long target, struct proc *);
712 void vfs_write_resume(struct mount *);
713 int vfs_write_suspend(struct mount *, int, int);
714 #ifdef DDB
715 void vfs_vnode_print(struct vnode *, int, void (*)(const char *, ...));
716 void vfs_mount_print(struct mount *, int, void (*)(const char *, ...));
717 #endif /* DDB */
718 #endif /* _KERNEL */
719
720 #endif /* !_SYS_VNODE_H_ */
Cache object: eea9c98a4758e61c610709c467a26770
|