|
|
- #ifndef __KERN_FS_VFS_INODE_H__
- #define __KERN_FS_VFS_INODE_H__
-
- #include <defs.h>
- #include <dev.h>
- #include <sfs.h>
- #include <atomic.h>
- #include <assert.h>
-
- struct stat;
- struct iobuf;
-
- /*
- * A struct inode is an abstract representation of a file.
- *
- * It is an interface that allows the kernel's filesystem-independent
- * code to interact usefully with multiple sets of filesystem code.
- */
-
- /*
- * Abstract low-level file.
- *
- * Note: in_info is Filesystem-specific data, in_type is the inode type
- *
- * open_count is managed using VOP_INCOPEN and VOP_DECOPEN by
- * vfs_open() and vfs_close(). Code above the VFS layer should not
- * need to worry about it.
- */
- struct inode {
- union {
- struct device __device_info;
- struct sfs_inode __sfs_inode_info;
- } in_info;
- enum {
- inode_type_device_info = 0x1234,
- inode_type_sfs_inode_info,
- } in_type;
- int ref_count;
- int open_count;
- struct fs *in_fs;
- const struct inode_ops *in_ops;
- };
-
- #define __in_type(type) inode_type_##type##_info
-
- #define check_inode_type(node, type) ((node)->in_type == __in_type(type))
-
- #define __vop_info(node, type) \
- ({ \
- struct inode *__node = (node); \
- assert(__node != NULL && check_inode_type(__node, type)); \
- &(__node->in_info.__##type##_info); \
- })
-
- #define vop_info(node, type) __vop_info(node, type)
-
- #define info2node(info, type) \
- to_struct((info), struct inode, in_info.__##type##_info)
-
- struct inode *__alloc_inode(int type);
-
- #define alloc_inode(type) __alloc_inode(__in_type(type))
-
- #define MAX_INODE_COUNT 0x10000
-
- int inode_ref_inc(struct inode *node);
- int inode_ref_dec(struct inode *node);
- int inode_open_inc(struct inode *node);
- int inode_open_dec(struct inode *node);
-
- void inode_init(struct inode *node, const struct inode_ops *ops, struct fs *fs);
- void inode_kill(struct inode *node);
-
- #define VOP_MAGIC 0x8c4ba476
-
- /*
- * Abstract operations on a inode.
- *
- * These are used in the form VOP_FOO(inode, args), which are macros
- * that expands to inode->inode_ops->vop_foo(inode, args). The operations
- * "foo" are:
- *
- * vop_open - Called on open() of a file. Can be used to
- * reject illegal or undesired open modes. Note that
- * various operations can be performed without the
- * file actually being opened.
- * The inode need not look at O_CREAT, O_EXCL, or
- * O_TRUNC, as these are handled in the VFS layer.
- *
- * VOP_EACHOPEN should not be called directly from
- * above the VFS layer - use vfs_open() to open inodes.
- * This maintains the open count so VOP_LASTCLOSE can
- * be called at the right time.
- *
- * vop_close - To be called on *last* close() of a file.
- *
- * VOP_LASTCLOSE should not be called directly from
- * above the VFS layer - use vfs_close() to close
- * inodes opened with vfs_open().
- *
- * vop_reclaim - Called when inode is no longer in use. Note that
- * this may be substantially after vop_lastclose is
- * called.
- *
- *****************************************
- *
- * vop_read - Read data from file to uio, at offset specified
- * in the uio, updating uio_resid to reflect the
- * amount read, and updating uio_offset to match.
- * Not allowed on directories or symlinks.
- *
- * vop_getdirentry - Read a single filename from a directory into a
- * uio, choosing what name based on the offset
- * field in the uio, and updating that field.
- * Unlike with I/O on regular files, the value of
- * the offset field is not interpreted outside
- * the filesystem and thus need not be a byte
- * count. However, the uio_resid field should be
- * handled in the normal fashion.
- * On non-directory objects, return ENOTDIR.
- *
- * vop_write - Write data from uio to file at offset specified
- * in the uio, updating uio_resid to reflect the
- * amount written, and updating uio_offset to match.
- * Not allowed on directories or symlinks.
- *
- * vop_ioctl - Perform ioctl operation OP on file using data
- * DATA. The interpretation of the data is specific
- * to each ioctl.
- *
- * vop_fstat -Return info about a file. The pointer is a
- * pointer to struct stat; see stat.h.
- *
- * vop_gettype - Return type of file. The values for file types
- * are in sfs.h.
- *
- * vop_tryseek - Check if seeking to the specified position within
- * the file is legal. (For instance, all seeks
- * are illegal on serial port devices, and seeks
- * past EOF on files whose sizes are fixed may be
- * as well.)
- *
- * vop_fsync - Force any dirty buffers associated with this file
- * to stable storage.
- *
- * vop_truncate - Forcibly set size of file to the length passed
- * in, discarding any excess blocks.
- *
- * vop_namefile - Compute pathname relative to filesystem root
- * of the file and copy to the specified io buffer.
- * Need not work on objects that are not
- * directories.
- *
- *****************************************
- *
- * vop_creat - Create a regular file named NAME in the passed
- * directory DIR. If boolean EXCL is true, fail if
- * the file already exists; otherwise, use the
- * existing file if there is one. Hand back the
- * inode for the file as per vop_lookup.
- *
- *****************************************
- *
- * vop_lookup - Parse PATHNAME relative to the passed directory
- * DIR, and hand back the inode for the file it
- * refers to. May destroy PATHNAME. Should increment
- * refcount on inode handed back.
- */
- struct inode_ops {
- unsigned long vop_magic;
- int (*vop_open)(struct inode *node, uint32_t open_flags);
- int (*vop_close)(struct inode *node);
- int (*vop_read)(struct inode *node, struct iobuf *iob);
- int (*vop_write)(struct inode *node, struct iobuf *iob);
- int (*vop_fstat)(struct inode *node, struct stat *stat);
- int (*vop_fsync)(struct inode *node);
- int (*vop_namefile)(struct inode *node, struct iobuf *iob);
- int (*vop_getdirentry)(struct inode *node, struct iobuf *iob);
- int (*vop_reclaim)(struct inode *node);
- int (*vop_gettype)(struct inode *node, uint32_t *type_store);
- int (*vop_tryseek)(struct inode *node, off_t pos);
- int (*vop_truncate)(struct inode *node, off_t len);
- int (*vop_create)(struct inode *node, const char *name, bool excl, struct inode **node_store);
- int (*vop_lookup)(struct inode *node, char *path, struct inode **node_store);
- int (*vop_ioctl)(struct inode *node, int op, void *data);
- };
-
- /*
- * Consistency check
- */
- void inode_check(struct inode *node, const char *opstr);
-
- #define __vop_op(node, sym) \
- ({ \
- struct inode *__node = (node); \
- assert(__node != NULL && __node->in_ops != NULL && __node->in_ops->vop_##sym != NULL); \
- inode_check(__node, #sym); \
- __node->in_ops->vop_##sym; \
- })
-
- #define vop_open(node, open_flags) (__vop_op(node, open)(node, open_flags))
- #define vop_close(node) (__vop_op(node, close)(node))
- #define vop_read(node, iob) (__vop_op(node, read)(node, iob))
- #define vop_write(node, iob) (__vop_op(node, write)(node, iob))
- #define vop_fstat(node, stat) (__vop_op(node, fstat)(node, stat))
- #define vop_fsync(node) (__vop_op(node, fsync)(node))
- #define vop_namefile(node, iob) (__vop_op(node, namefile)(node, iob))
- #define vop_getdirentry(node, iob) (__vop_op(node, getdirentry)(node, iob))
- #define vop_reclaim(node) (__vop_op(node, reclaim)(node))
- #define vop_ioctl(node, op, data) (__vop_op(node, ioctl)(node, op, data))
- #define vop_gettype(node, type_store) (__vop_op(node, gettype)(node, type_store))
- #define vop_tryseek(node, pos) (__vop_op(node, tryseek)(node, pos))
- #define vop_truncate(node, len) (__vop_op(node, truncate)(node, len))
- #define vop_create(node, name, excl, node_store) (__vop_op(node, create)(node, name, excl, node_store))
- #define vop_lookup(node, path, node_store) (__vop_op(node, lookup)(node, path, node_store))
-
-
- #define vop_fs(node) ((node)->in_fs)
- #define vop_init(node, ops, fs) inode_init(node, ops, fs)
- #define vop_kill(node) inode_kill(node)
-
- /*
- * Reference count manipulation (handled above filesystem level)
- */
- #define vop_ref_inc(node) inode_ref_inc(node)
- #define vop_ref_dec(node) inode_ref_dec(node)
- /*
- * Open count manipulation (handled above filesystem level)
- *
- * VOP_INCOPEN is called by vfs_open. VOP_DECOPEN is called by vfs_close.
- * Neither of these should need to be called from above the vfs layer.
- */
- #define vop_open_inc(node) inode_open_inc(node)
- #define vop_open_dec(node) inode_open_dec(node)
-
-
- static inline int
- inode_ref_count(struct inode *node) {
- return node->ref_count;
- }
-
- static inline int
- inode_open_count(struct inode *node) {
- return node->open_count;
- }
-
- #endif /* !__KERN_FS_VFS_INODE_H__ */
-
|