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