os161-1.99
 All Data Structures
vnode.h
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_ */
 All Data Structures