/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#ifndef _VNODE_H_30#define _VNODE_H_313233struct uio;34struct stat;3536/*37* A struct vnode is an abstract representation of a file.38*39* It is an interface in the Java sense that allows the kernel's40* filesystem-independent code to interact usefully with multiple sets41* of filesystem code.42*/4344/*45* Abstract low-level file.46*47* Note: vn_fs may be null if the vnode refers to a device.48*49* vn_opencount is managed using VOP_INCOPEN and VOP_DECOPEN by50* vfs_open() and vfs_close(). Code above the VFS layer should not51* need to worry about it.52*/53struct vnode {54int vn_refcount; /* Reference count */55int vn_opencount;5657struct fs *vn_fs; /* Filesystem vnode belongs to */5859void *vn_data; /* Filesystem-specific data */6061const struct vnode_ops *vn_ops; /* Functions on this vnode */62};6364/*65* Abstract operations on a vnode.66*67* These are used in the form VOP_FOO(vnode, args), which are macros68* that expands to vnode->vn_ops->vop_foo(vnode, args). The operations69* "foo" are:70*71* vop_open - Called on *each* open() of a file. Can be used to72* reject illegal or undesired open modes. Note that73* various operations can be performed without the74* file actually being opened.75* The vnode need not look at O_CREAT, O_EXCL, or76* O_TRUNC, as these are handled in the VFS layer.77*78* VOP_OPEN should not be called directly from above79* the VFS layer - use vfs_open() to open vnodes.80* This maintains the open count so VOP_CLOSE can be81* called at the right time.82*83* vop_close - To be called on *last* close() of a file.84*85* VOP_CLOSE should not be called directly from above86* the VFS layer - use vfs_close() to close vnodes87* opened with vfs_open().88*89* vop_reclaim - Called when vnode is no longer in use. Note that90* this may be substantially after vop_close is91* called.92*93*****************************************94*95* vop_read - Read data from file to uio, at offset specified96* in the uio, updating uio_resid to reflect the97* amount read, and updating uio_offset to match.98* Not allowed on directories or symlinks.99*100* vop_readlink - Read the contents of a symlink into a uio.101* Not allowed on other types of object.102*103* vop_getdirentry - Read a single filename from a directory into a104* uio, choosing what name based on the offset105* field in the uio, and updating that field.106* Unlike with I/O on regular files, the value of107* the offset field is not interpreted outside108* the filesystem and thus need not be a byte109* count. However, the uio_resid field should be110* handled in the normal fashion.111* On non-directory objects, return ENOTDIR.112*113* vop_write - Write data from uio to file at offset specified114* in the uio, updating uio_resid to reflect the115* amount written, and updating uio_offset to match.116* Not allowed on directories or symlinks.117*118* vop_ioctl - Perform ioctl operation OP on file using data119* DATA. The interpretation of the data is specific120* to each ioctl.121*122* vop_stat - Return info about a file. The pointer is a123* pointer to struct stat; see kern/stat.h.124*125* vop_gettype - Return type of file. The values for file types126* are in kern/stattypes.h.127*128* vop_tryseek - Check if seeking to the specified position within129* the file is legal. (For instance, all seeks130* are illegal on serial port devices, and seeks131* past EOF on files whose sizes are fixed may be132* as well.)133*134* vop_fsync - Force any dirty buffers associated with this file135* to stable storage.136*137* vop_mmap - Map file into memory. If you implement this138* feature, you're responsible for choosing the139* arguments for this operation.140*141* vop_truncate - Forcibly set size of file to the length passed142* in, discarding any excess blocks.143*144* vop_namefile - Compute pathname relative to filesystem root145* of the file and copy to the specified146* uio. Need not work on objects that are not147* directories.148*149*****************************************150*151* vop_creat - Create a regular file named NAME in the passed152* directory DIR. If boolean EXCL is true, fail if153* the file already exists; otherwise, use the154* existing file if there is one. Hand back the155* vnode for the file as per vop_lookup.156*157* vop_symlink - Create symlink named NAME in the passed directory,158* with contents CONTENTS.159*160* vop_mkdir - Make directory NAME in the passed directory PARENTDIR.161*162* vop_link - Create hard link, with name NAME, to file FILE163* in the passed directory DIR.164*165* vop_remove - Delete non-directory object NAME from passed166* directory. If NAME refers to a directory,167* return EISDIR. If passed vnode is not a168* directory, return ENOTDIR.169*170* vop_rmdir - Delete directory object NAME from passed171* directory.172*173* vop_rename - Rename file NAME1 in directory VN1 to be174* file NAME2 in directory VN2.175*176*****************************************177*178* vop_lookup - Parse PATHNAME relative to the passed directory179* DIR, and hand back the vnode for the file it180* refers to. May destroy PATHNAME. Should increment181* refcount on vnode handed back.182*183* vop_lookparent - Parse PATHNAME relative to the passed directory184* DIR, and hand back (1) the vnode for the185* parent directory of the file it refers to, and186* (2) the last component of the filename, copied187* into kernel buffer BUF with max length LEN. May188* destroy PATHNAME. Should increment refcount on189* vnode handed back.190*/191192#define VOP_MAGIC 0xa2b3c4d5193194struct vnode_ops {195unsigned long vop_magic; /* should always be VOP_MAGIC */196197int (*vop_open)(struct vnode *object, int flags_from_open);198int (*vop_close)(struct vnode *object);199int (*vop_reclaim)(struct vnode *vnode);200201202int (*vop_read)(struct vnode *file, struct uio *uio);203int (*vop_readlink)(struct vnode *link, struct uio *uio);204int (*vop_getdirentry)(struct vnode *dir, struct uio *uio);205int (*vop_write)(struct vnode *file, struct uio *uio);206int (*vop_ioctl)(struct vnode *object, int op, userptr_t data);207int (*vop_stat)(struct vnode *object, struct stat *statbuf);208int (*vop_gettype)(struct vnode *object, mode_t *result);209int (*vop_tryseek)(struct vnode *object, off_t pos);210int (*vop_fsync)(struct vnode *object);211int (*vop_mmap)(struct vnode *file /* add stuff */);212int (*vop_truncate)(struct vnode *file, off_t len);213int (*vop_namefile)(struct vnode *file, struct uio *uio);214215216int (*vop_creat)(struct vnode *dir,217const char *name, bool excl, mode_t mode,218struct vnode **result);219int (*vop_symlink)(struct vnode *dir,220const char *contents, const char *name);221int (*vop_mkdir)(struct vnode *parentdir,222const char *name, mode_t mode);223int (*vop_link)(struct vnode *dir,224const char *name, struct vnode *file);225int (*vop_remove)(struct vnode *dir,226const char *name);227int (*vop_rmdir)(struct vnode *dir,228const char *name);229230int (*vop_rename)(struct vnode *vn1, const char *name1,231struct vnode *vn2, const char *name2);232233234int (*vop_lookup)(struct vnode *dir,235char *pathname, struct vnode **result);236int (*vop_lookparent)(struct vnode *dir,237char *pathname, struct vnode **result,238char *buf, size_t len);239};240241#define __VOP(vn, sym) (vnode_check(vn, #sym), (vn)->vn_ops->vop_##sym)242243#define VOP_OPEN(vn, flags) (__VOP(vn, open)(vn, flags))244#define VOP_CLOSE(vn) (__VOP(vn, close)(vn))245#define VOP_RECLAIM(vn) (__VOP(vn, reclaim)(vn))246247#define VOP_READ(vn, uio) (__VOP(vn, read)(vn, uio))248#define VOP_READLINK(vn, uio) (__VOP(vn, readlink)(vn, uio))249#define VOP_GETDIRENTRY(vn, uio) (__VOP(vn,getdirentry)(vn, uio))250#define VOP_WRITE(vn, uio) (__VOP(vn, write)(vn, uio))251#define VOP_IOCTL(vn, code, buf) (__VOP(vn, ioctl)(vn,code,buf))252#define VOP_STAT(vn, ptr) (__VOP(vn, stat)(vn, ptr))253#define VOP_GETTYPE(vn, result) (__VOP(vn, gettype)(vn, result))254#define VOP_TRYSEEK(vn, pos) (__VOP(vn, tryseek)(vn, pos))255#define VOP_FSYNC(vn) (__VOP(vn, fsync)(vn))256#define VOP_MMAP(vn /*add stuff */) (__VOP(vn, mmap)(vn /*add stuff */))257#define VOP_TRUNCATE(vn, pos) (__VOP(vn, truncate)(vn, pos))258#define VOP_NAMEFILE(vn, uio) (__VOP(vn, namefile)(vn, uio))259260#define VOP_CREAT(vn,nm,excl,mode,res) (__VOP(vn, creat)(vn,nm,excl,mode,res))261#define VOP_SYMLINK(vn, name, content) (__VOP(vn, symlink)(vn, name, content))262#define VOP_MKDIR(vn, name, mode) (__VOP(vn, mkdir)(vn, name, mode))263#define VOP_LINK(vn, name, vn2) (__VOP(vn, link)(vn, name, vn2))264#define VOP_REMOVE(vn, name) (__VOP(vn, remove)(vn, name))265#define VOP_RMDIR(vn, name) (__VOP(vn, rmdir)(vn, name))266#define VOP_RENAME(vn1,name1,vn2,name2)(__VOP(vn1,rename)(vn1,name1,vn2,name2))267268#define VOP_LOOKUP(vn, name, res) (__VOP(vn, lookup)(vn, name, res))269#define VOP_LOOKPARENT(vn,nm,res,bf,ln) (__VOP(vn,lookparent)(vn,nm,res,bf,ln))270271/*272* Consistency check273*/274void vnode_check(struct vnode *, const char *op);275276/*277* Reference count manipulation (handled above filesystem level)278*/279void vnode_incref(struct vnode *);280void vnode_decref(struct vnode *);281282#define VOP_INCREF(vn) vnode_incref(vn)283#define VOP_DECREF(vn) vnode_decref(vn)284285/*286* Open count manipulation (handled above filesystem level)287*288* VOP_INCOPEN is called by vfs_open. VOP_DECOPEN is called by vfs_close.289* Neither of these should need to be called from above the vfs layer.290*/291void vnode_incopen(struct vnode *);292void vnode_decopen(struct vnode *);293294#define VOP_INCOPEN(vn) vnode_incopen(vn)295#define VOP_DECOPEN(vn) vnode_decopen(vn)296297/*298* Vnode initialization (intended for use by filesystem code)299* The reference count is initialized to 1.300*/301int vnode_init(struct vnode *, const struct vnode_ops *ops,302struct fs *fs, void *fsdata);303304#define VOP_INIT(vn, ops, fs, data) vnode_init(vn, ops, fs, data)305306/*307* Vnode final cleanup (intended for use by filesystem code)308* The reference count is asserted to be 1.309*/310void vnode_cleanup(struct vnode *);311312#define VOP_CLEANUP(vn) vnode_cleanup(vn)313314315#endif /* _VNODE_H_ */316317318