/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifndef _VNODE_H_
31 #define _VNODE_H_
32
33
34 struct uio;
35 struct stat;
36
37 /*
38 * A struct vnode is an abstract representation of a file.
39 *
40 * It is an interface in the Java sense that allows the kernel's
41 * filesystem-independent code to interact usefully with multiple sets
42 * of filesystem code.
43 */
44
45 /*
46 * Abstract low-level file.
47 *
48 * Note: vn_fs may be null if the vnode refers to a device.
49 *
50 * vn_opencount is managed using VOP_INCOPEN and VOP_DECOPEN by
51 * vfs_open() and vfs_close(). Code above the VFS layer should not
52 * need to worry about it.
53 */
54 struct vnode {
55 int vn_refcount; /* Reference count */
56 int vn_opencount;
57
58 struct fs *vn_fs; /* Filesystem vnode belongs to */
59
60 void *vn_data; /* Filesystem-specific data */
61
62 const struct vnode_ops *vn_ops; /* Functions on this vnode */
63 };
64
65 /*
66 * Abstract operations on a vnode.
67 *
68 * These are used in the form VOP_FOO(vnode, args), which are macros
69 * that expands to vnode->vn_ops->vop_foo(vnode, args). The operations
70 * "foo" are:
71 *
72 * vop_open - Called on *each* open() of a file. Can be used to
73 * reject illegal or undesired open modes. Note that
74 * various operations can be performed without the
75 * file actually being opened.
76 * The vnode need not look at O_CREAT, O_EXCL, or
77 * O_TRUNC, as these are handled in the VFS layer.
78 *
79 * VOP_OPEN should not be called directly from above
80 * the VFS layer - use vfs_open() to open vnodes.
81 * This maintains the open count so VOP_CLOSE can be
82 * called at the right time.
83 *
84 * vop_close - To be called on *last* close() of a file.
85 *
86 * VOP_CLOSE should not be called directly from above
87 * the VFS layer - use vfs_close() to close vnodes
88 * opened with vfs_open().
89 *
90 * vop_reclaim - Called when vnode is no longer in use. Note that
91 * this may be substantially after vop_close is
92 * called.
93 *
94 *****************************************
95 *
96 * vop_read - Read data from file to uio, at offset specified
97 * in the uio, updating uio_resid to reflect the
98 * amount read, and updating uio_offset to match.
99 * Not allowed on directories or symlinks.
100 *
101 * vop_readlink - Read the contents of a symlink into a uio.
102 * Not allowed on other types of object.
103 *
104 * vop_getdirentry - Read a single filename from a directory into a
105 * uio, choosing what name based on the offset
106 * field in the uio, and updating that field.
107 * Unlike with I/O on regular files, the value of
108 * the offset field is not interpreted outside
109 * the filesystem and thus need not be a byte
110 * count. However, the uio_resid field should be
111 * handled in the normal fashion.
112 * On non-directory objects, return ENOTDIR.
113 *
114 * vop_write - Write data from uio to file at offset specified
115 * in the uio, updating uio_resid to reflect the
116 * amount written, and updating uio_offset to match.
117 * Not allowed on directories or symlinks.
118 *
119 * vop_ioctl - Perform ioctl operation OP on file using data
120 * DATA. The interpretation of the data is specific
121 * to each ioctl.
122 *
123 * vop_stat - Return info about a file. The pointer is a
124 * pointer to struct stat; see kern/stat.h.
125 *
126 * vop_gettype - Return type of file. The values for file types
127 * are in kern/stattypes.h.
128 *
129 * vop_tryseek - Check if seeking to the specified position within
130 * the file is legal. (For instance, all seeks
131 * are illegal on serial port devices, and seeks
132 * past EOF on files whose sizes are fixed may be
133 * as well.)
134 *
135 * vop_fsync - Force any dirty buffers associated with this file
136 * to stable storage.
137 *
138 * vop_mmap - Map file into memory. If you implement this
139 * feature, you're responsible for choosing the
140 * arguments for this operation.
141 *
142 * vop_truncate - Forcibly set size of file to the length passed
143 * in, discarding any excess blocks.
144 *
145 * vop_namefile - Compute pathname relative to filesystem root
146 * of the file and copy to the specified
147 * uio. Need not work on objects that are not
148 * directories.
149 *
150 *****************************************
151 *
152 * vop_creat - Create a regular file named NAME in the passed
153 * directory DIR. If boolean EXCL is true, fail if
154 * the file already exists; otherwise, use the
155 * existing file if there is one. Hand back the
156 * vnode for the file as per vop_lookup.
157 *
158 * vop_symlink - Create symlink named NAME in the passed directory,
159 * with contents CONTENTS.
160 *
161 * vop_mkdir - Make directory NAME in the passed directory PARENTDIR.
162 *
163 * vop_link - Create hard link, with name NAME, to file FILE
164 * in the passed directory DIR.
165 *
166 * vop_remove - Delete non-directory object NAME from passed
167 * directory. If NAME refers to a directory,
168 * return EISDIR. If passed vnode is not a
169 * directory, return ENOTDIR.
170 *
171 * vop_rmdir - Delete directory object NAME from passed
172 * directory.
173 *
174 * vop_rename - Rename file NAME1 in directory VN1 to be
175 * file NAME2 in directory VN2.
176 *
177 *****************************************
178 *
179 * vop_lookup - Parse PATHNAME relative to the passed directory
180 * DIR, and hand back the vnode for the file it
181 * refers to. May destroy PATHNAME. Should increment
182 * refcount on vnode handed back.
183 *
184 * vop_lookparent - Parse PATHNAME relative to the passed directory
185 * DIR, and hand back (1) the vnode for the
186 * parent directory of the file it refers to, and
187 * (2) the last component of the filename, copied
188 * into kernel buffer BUF with max length LEN. May
189 * destroy PATHNAME. Should increment refcount on
190 * vnode handed back.
191 */
192
193 #define VOP_MAGIC 0xa2b3c4d5
194
195 struct vnode_ops {
196 unsigned long vop_magic; /* should always be VOP_MAGIC */
197
198 int (*vop_open)(struct vnode *object, int flags_from_open);
199 int (*vop_close)(struct vnode *object);
200 int (*vop_reclaim)(struct vnode *vnode);
201
202
203 int (*vop_read)(struct vnode *file, struct uio *uio);
204 int (*vop_readlink)(struct vnode *link, struct uio *uio);
205 int (*vop_getdirentry)(struct vnode *dir, struct uio *uio);
206 int (*vop_write)(struct vnode *file, struct uio *uio);
207 int (*vop_ioctl)(struct vnode *object, int op, userptr_t data);
208 int (*vop_stat)(struct vnode *object, struct stat *statbuf);
209 int (*vop_gettype)(struct vnode *object, mode_t *result);
210 int (*vop_tryseek)(struct vnode *object, off_t pos);
211 int (*vop_fsync)(struct vnode *object);
212 int (*vop_mmap)(struct vnode *file /* add stuff */);
213 int (*vop_truncate)(struct vnode *file, off_t len);
214 int (*vop_namefile)(struct vnode *file, struct uio *uio);
215
216
217 int (*vop_creat)(struct vnode *dir,
218 const char *name, bool excl, mode_t mode,
219 struct vnode **result);
220 int (*vop_symlink)(struct vnode *dir,
221 const char *contents, const char *name);
222 int (*vop_mkdir)(struct vnode *parentdir,
223 const char *name, mode_t mode);
224 int (*vop_link)(struct vnode *dir,
225 const char *name, struct vnode *file);
226 int (*vop_remove)(struct vnode *dir,
227 const char *name);
228 int (*vop_rmdir)(struct vnode *dir,
229 const char *name);
230
231 int (*vop_rename)(struct vnode *vn1, const char *name1,
232 struct vnode *vn2, const char *name2);
233
234
235 int (*vop_lookup)(struct vnode *dir,
236 char *pathname, struct vnode **result);
237 int (*vop_lookparent)(struct vnode *dir,
238 char *pathname, struct vnode **result,
239 char *buf, size_t len);
240 };
241
242 #define __VOP(vn, sym) (vnode_check(vn, #sym), (vn)->vn_ops->vop_##sym)
243
244 #define VOP_OPEN(vn, flags) (__VOP(vn, open)(vn, flags))
245 #define VOP_CLOSE(vn) (__VOP(vn, close)(vn))
246 #define VOP_RECLAIM(vn) (__VOP(vn, reclaim)(vn))
247
248 #define VOP_READ(vn, uio) (__VOP(vn, read)(vn, uio))
249 #define VOP_READLINK(vn, uio) (__VOP(vn, readlink)(vn, uio))
250 #define VOP_GETDIRENTRY(vn, uio) (__VOP(vn,getdirentry)(vn, uio))
251 #define VOP_WRITE(vn, uio) (__VOP(vn, write)(vn, uio))
252 #define VOP_IOCTL(vn, code, buf) (__VOP(vn, ioctl)(vn,code,buf))
253 #define VOP_STAT(vn, ptr) (__VOP(vn, stat)(vn, ptr))
254 #define VOP_GETTYPE(vn, result) (__VOP(vn, gettype)(vn, result))
255 #define VOP_TRYSEEK(vn, pos) (__VOP(vn, tryseek)(vn, pos))
256 #define VOP_FSYNC(vn) (__VOP(vn, fsync)(vn))
257 #define VOP_MMAP(vn /*add stuff */) (__VOP(vn, mmap)(vn /*add stuff */))
258 #define VOP_TRUNCATE(vn, pos) (__VOP(vn, truncate)(vn, pos))
259 #define VOP_NAMEFILE(vn, uio) (__VOP(vn, namefile)(vn, uio))
260
261 #define VOP_CREAT(vn,nm,excl,mode,res) (__VOP(vn, creat)(vn,nm,excl,mode,res))
262 #define VOP_SYMLINK(vn, name, content) (__VOP(vn, symlink)(vn, name, content))
263 #define VOP_MKDIR(vn, name, mode) (__VOP(vn, mkdir)(vn, name, mode))
264 #define VOP_LINK(vn, name, vn2) (__VOP(vn, link)(vn, name, vn2))
265 #define VOP_REMOVE(vn, name) (__VOP(vn, remove)(vn, name))
266 #define VOP_RMDIR(vn, name) (__VOP(vn, rmdir)(vn, name))
267 #define VOP_RENAME(vn1,name1,vn2,name2)(__VOP(vn1,rename)(vn1,name1,vn2,name2))
268
269 #define VOP_LOOKUP(vn, name, res) (__VOP(vn, lookup)(vn, name, res))
270 #define VOP_LOOKPARENT(vn,nm,res,bf,ln) (__VOP(vn,lookparent)(vn,nm,res,bf,ln))
271
272 /*
273 * Consistency check
274 */
275 void vnode_check(struct vnode *, const char *op);
276
277 /*
278 * Reference count manipulation (handled above filesystem level)
279 */
280 void vnode_incref(struct vnode *);
281 void vnode_decref(struct vnode *);
282
283 #define VOP_INCREF(vn) vnode_incref(vn)
284 #define VOP_DECREF(vn) vnode_decref(vn)
285
286 /*
287 * Open count manipulation (handled above filesystem level)
288 *
289 * VOP_INCOPEN is called by vfs_open. VOP_DECOPEN is called by vfs_close.
290 * Neither of these should need to be called from above the vfs layer.
291 */
292 void vnode_incopen(struct vnode *);
293 void vnode_decopen(struct vnode *);
294
295 #define VOP_INCOPEN(vn) vnode_incopen(vn)
296 #define VOP_DECOPEN(vn) vnode_decopen(vn)
297
298 /*
299 * Vnode initialization (intended for use by filesystem code)
300 * The reference count is initialized to 1.
301 */
302 int vnode_init(struct vnode *, const struct vnode_ops *ops,
303 struct fs *fs, void *fsdata);
304
305 #define VOP_INIT(vn, ops, fs, data) vnode_init(vn, ops, fs, data)
306
307 /*
308 * Vnode final cleanup (intended for use by filesystem code)
309 * The reference count is asserted to be 1.
310 */
311 void vnode_cleanup(struct vnode *);
312
313 #define VOP_CLEANUP(vn) vnode_cleanup(vn)
314
315
316 #endif /* _VNODE_H_ */