00001 /* 00002 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 00003 * The President and Fellows of Harvard College. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the University nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 */ 00029 00030 #ifndef _VNODE_H_ 00031 #define _VNODE_H_ 00032 00033 00034 struct uio; 00035 struct stat; 00036 00037 /* 00038 * A struct vnode is an abstract representation of a file. 00039 * 00040 * It is an interface in the Java sense that allows the kernel's 00041 * filesystem-independent code to interact usefully with multiple sets 00042 * of filesystem code. 00043 */ 00044 00045 /* 00046 * Abstract low-level file. 00047 * 00048 * Note: vn_fs may be null if the vnode refers to a device. 00049 * 00050 * vn_opencount is managed using VOP_INCOPEN and VOP_DECOPEN by 00051 * vfs_open() and vfs_close(). Code above the VFS layer should not 00052 * need to worry about it. 00053 */ 00054 struct vnode { 00055 int vn_refcount; /* Reference count */ 00056 int vn_opencount; 00057 00058 struct fs *vn_fs; /* Filesystem vnode belongs to */ 00059 00060 void *vn_data; /* Filesystem-specific data */ 00061 00062 const struct vnode_ops *vn_ops; /* Functions on this vnode */ 00063 }; 00064 00065 /* 00066 * Abstract operations on a vnode. 00067 * 00068 * These are used in the form VOP_FOO(vnode, args), which are macros 00069 * that expands to vnode->vn_ops->vop_foo(vnode, args). The operations 00070 * "foo" are: 00071 * 00072 * vop_open - Called on *each* open() of a file. Can be used to 00073 * reject illegal or undesired open modes. Note that 00074 * various operations can be performed without the 00075 * file actually being opened. 00076 * The vnode need not look at O_CREAT, O_EXCL, or 00077 * O_TRUNC, as these are handled in the VFS layer. 00078 * 00079 * VOP_OPEN should not be called directly from above 00080 * the VFS layer - use vfs_open() to open vnodes. 00081 * This maintains the open count so VOP_CLOSE can be 00082 * called at the right time. 00083 * 00084 * vop_close - To be called on *last* close() of a file. 00085 * 00086 * VOP_CLOSE should not be called directly from above 00087 * the VFS layer - use vfs_close() to close vnodes 00088 * opened with vfs_open(). 00089 * 00090 * vop_reclaim - Called when vnode is no longer in use. Note that 00091 * this may be substantially after vop_close is 00092 * called. 00093 * 00094 ***************************************** 00095 * 00096 * vop_read - Read data from file to uio, at offset specified 00097 * in the uio, updating uio_resid to reflect the 00098 * amount read, and updating uio_offset to match. 00099 * Not allowed on directories or symlinks. 00100 * 00101 * vop_readlink - Read the contents of a symlink into a uio. 00102 * Not allowed on other types of object. 00103 * 00104 * vop_getdirentry - Read a single filename from a directory into a 00105 * uio, choosing what name based on the offset 00106 * field in the uio, and updating that field. 00107 * Unlike with I/O on regular files, the value of 00108 * the offset field is not interpreted outside 00109 * the filesystem and thus need not be a byte 00110 * count. However, the uio_resid field should be 00111 * handled in the normal fashion. 00112 * On non-directory objects, return ENOTDIR. 00113 * 00114 * vop_write - Write data from uio to file at offset specified 00115 * in the uio, updating uio_resid to reflect the 00116 * amount written, and updating uio_offset to match. 00117 * Not allowed on directories or symlinks. 00118 * 00119 * vop_ioctl - Perform ioctl operation OP on file using data 00120 * DATA. The interpretation of the data is specific 00121 * to each ioctl. 00122 * 00123 * vop_stat - Return info about a file. The pointer is a 00124 * pointer to struct stat; see kern/stat.h. 00125 * 00126 * vop_gettype - Return type of file. The values for file types 00127 * are in kern/stattypes.h. 00128 * 00129 * vop_tryseek - Check if seeking to the specified position within 00130 * the file is legal. (For instance, all seeks 00131 * are illegal on serial port devices, and seeks 00132 * past EOF on files whose sizes are fixed may be 00133 * as well.) 00134 * 00135 * vop_fsync - Force any dirty buffers associated with this file 00136 * to stable storage. 00137 * 00138 * vop_mmap - Map file into memory. If you implement this 00139 * feature, you're responsible for choosing the 00140 * arguments for this operation. 00141 * 00142 * vop_truncate - Forcibly set size of file to the length passed 00143 * in, discarding any excess blocks. 00144 * 00145 * vop_namefile - Compute pathname relative to filesystem root 00146 * of the file and copy to the specified 00147 * uio. Need not work on objects that are not 00148 * directories. 00149 * 00150 ***************************************** 00151 * 00152 * vop_creat - Create a regular file named NAME in the passed 00153 * directory DIR. If boolean EXCL is true, fail if 00154 * the file already exists; otherwise, use the 00155 * existing file if there is one. Hand back the 00156 * vnode for the file as per vop_lookup. 00157 * 00158 * vop_symlink - Create symlink named NAME in the passed directory, 00159 * with contents CONTENTS. 00160 * 00161 * vop_mkdir - Make directory NAME in the passed directory PARENTDIR. 00162 * 00163 * vop_link - Create hard link, with name NAME, to file FILE 00164 * in the passed directory DIR. 00165 * 00166 * vop_remove - Delete non-directory object NAME from passed 00167 * directory. If NAME refers to a directory, 00168 * return EISDIR. If passed vnode is not a 00169 * directory, return ENOTDIR. 00170 * 00171 * vop_rmdir - Delete directory object NAME from passed 00172 * directory. 00173 * 00174 * vop_rename - Rename file NAME1 in directory VN1 to be 00175 * file NAME2 in directory VN2. 00176 * 00177 ***************************************** 00178 * 00179 * vop_lookup - Parse PATHNAME relative to the passed directory 00180 * DIR, and hand back the vnode for the file it 00181 * refers to. May destroy PATHNAME. Should increment 00182 * refcount on vnode handed back. 00183 * 00184 * vop_lookparent - Parse PATHNAME relative to the passed directory 00185 * DIR, and hand back (1) the vnode for the 00186 * parent directory of the file it refers to, and 00187 * (2) the last component of the filename, copied 00188 * into kernel buffer BUF with max length LEN. May 00189 * destroy PATHNAME. Should increment refcount on 00190 * vnode handed back. 00191 */ 00192 00193 #define VOP_MAGIC 0xa2b3c4d5 00194 00195 struct vnode_ops { 00196 unsigned long vop_magic; /* should always be VOP_MAGIC */ 00197 00198 int (*vop_open)(struct vnode *object, int flags_from_open); 00199 int (*vop_close)(struct vnode *object); 00200 int (*vop_reclaim)(struct vnode *vnode); 00201 00202 00203 int (*vop_read)(struct vnode *file, struct uio *uio); 00204 int (*vop_readlink)(struct vnode *link, struct uio *uio); 00205 int (*vop_getdirentry)(struct vnode *dir, struct uio *uio); 00206 int (*vop_write)(struct vnode *file, struct uio *uio); 00207 int (*vop_ioctl)(struct vnode *object, int op, userptr_t data); 00208 int (*vop_stat)(struct vnode *object, struct stat *statbuf); 00209 int (*vop_gettype)(struct vnode *object, mode_t *result); 00210 int (*vop_tryseek)(struct vnode *object, off_t pos); 00211 int (*vop_fsync)(struct vnode *object); 00212 int (*vop_mmap)(struct vnode *file /* add stuff */); 00213 int (*vop_truncate)(struct vnode *file, off_t len); 00214 int (*vop_namefile)(struct vnode *file, struct uio *uio); 00215 00216 00217 int (*vop_creat)(struct vnode *dir, 00218 const char *name, bool excl, mode_t mode, 00219 struct vnode **result); 00220 int (*vop_symlink)(struct vnode *dir, 00221 const char *contents, const char *name); 00222 int (*vop_mkdir)(struct vnode *parentdir, 00223 const char *name, mode_t mode); 00224 int (*vop_link)(struct vnode *dir, 00225 const char *name, struct vnode *file); 00226 int (*vop_remove)(struct vnode *dir, 00227 const char *name); 00228 int (*vop_rmdir)(struct vnode *dir, 00229 const char *name); 00230 00231 int (*vop_rename)(struct vnode *vn1, const char *name1, 00232 struct vnode *vn2, const char *name2); 00233 00234 00235 int (*vop_lookup)(struct vnode *dir, 00236 char *pathname, struct vnode **result); 00237 int (*vop_lookparent)(struct vnode *dir, 00238 char *pathname, struct vnode **result, 00239 char *buf, size_t len); 00240 }; 00241 00242 #define __VOP(vn, sym) (vnode_check(vn, #sym), (vn)->vn_ops->vop_##sym) 00243 00244 #define VOP_OPEN(vn, flags) (__VOP(vn, open)(vn, flags)) 00245 #define VOP_CLOSE(vn) (__VOP(vn, close)(vn)) 00246 #define VOP_RECLAIM(vn) (__VOP(vn, reclaim)(vn)) 00247 00248 #define VOP_READ(vn, uio) (__VOP(vn, read)(vn, uio)) 00249 #define VOP_READLINK(vn, uio) (__VOP(vn, readlink)(vn, uio)) 00250 #define VOP_GETDIRENTRY(vn, uio) (__VOP(vn,getdirentry)(vn, uio)) 00251 #define VOP_WRITE(vn, uio) (__VOP(vn, write)(vn, uio)) 00252 #define VOP_IOCTL(vn, code, buf) (__VOP(vn, ioctl)(vn,code,buf)) 00253 #define VOP_STAT(vn, ptr) (__VOP(vn, stat)(vn, ptr)) 00254 #define VOP_GETTYPE(vn, result) (__VOP(vn, gettype)(vn, result)) 00255 #define VOP_TRYSEEK(vn, pos) (__VOP(vn, tryseek)(vn, pos)) 00256 #define VOP_FSYNC(vn) (__VOP(vn, fsync)(vn)) 00257 #define VOP_MMAP(vn /*add stuff */) (__VOP(vn, mmap)(vn /*add stuff */)) 00258 #define VOP_TRUNCATE(vn, pos) (__VOP(vn, truncate)(vn, pos)) 00259 #define VOP_NAMEFILE(vn, uio) (__VOP(vn, namefile)(vn, uio)) 00260 00261 #define VOP_CREAT(vn,nm,excl,mode,res) (__VOP(vn, creat)(vn,nm,excl,mode,res)) 00262 #define VOP_SYMLINK(vn, name, content) (__VOP(vn, symlink)(vn, name, content)) 00263 #define VOP_MKDIR(vn, name, mode) (__VOP(vn, mkdir)(vn, name, mode)) 00264 #define VOP_LINK(vn, name, vn2) (__VOP(vn, link)(vn, name, vn2)) 00265 #define VOP_REMOVE(vn, name) (__VOP(vn, remove)(vn, name)) 00266 #define VOP_RMDIR(vn, name) (__VOP(vn, rmdir)(vn, name)) 00267 #define VOP_RENAME(vn1,name1,vn2,name2)(__VOP(vn1,rename)(vn1,name1,vn2,name2)) 00268 00269 #define VOP_LOOKUP(vn, name, res) (__VOP(vn, lookup)(vn, name, res)) 00270 #define VOP_LOOKPARENT(vn,nm,res,bf,ln) (__VOP(vn,lookparent)(vn,nm,res,bf,ln)) 00271 00272 /* 00273 * Consistency check 00274 */ 00275 void vnode_check(struct vnode *, const char *op); 00276 00277 /* 00278 * Reference count manipulation (handled above filesystem level) 00279 */ 00280 void vnode_incref(struct vnode *); 00281 void vnode_decref(struct vnode *); 00282 00283 #define VOP_INCREF(vn) vnode_incref(vn) 00284 #define VOP_DECREF(vn) vnode_decref(vn) 00285 00286 /* 00287 * Open count manipulation (handled above filesystem level) 00288 * 00289 * VOP_INCOPEN is called by vfs_open. VOP_DECOPEN is called by vfs_close. 00290 * Neither of these should need to be called from above the vfs layer. 00291 */ 00292 void vnode_incopen(struct vnode *); 00293 void vnode_decopen(struct vnode *); 00294 00295 #define VOP_INCOPEN(vn) vnode_incopen(vn) 00296 #define VOP_DECOPEN(vn) vnode_decopen(vn) 00297 00298 /* 00299 * Vnode initialization (intended for use by filesystem code) 00300 * The reference count is initialized to 1. 00301 */ 00302 int vnode_init(struct vnode *, const struct vnode_ops *ops, 00303 struct fs *fs, void *fsdata); 00304 00305 #define VOP_INIT(vn, ops, fs, data) vnode_init(vn, ops, fs, data) 00306 00307 /* 00308 * Vnode final cleanup (intended for use by filesystem code) 00309 * The reference count is asserted to be 1. 00310 */ 00311 void vnode_cleanup(struct vnode *); 00312 00313 #define VOP_CLEANUP(vn) vnode_cleanup(vn) 00314 00315 00316 #endif /* _VNODE_H_ */