os_kernel_lab/code/lab8/kern/fs/vfs/vfs.h
2012-08-22 12:32:13 +08:00

192 lines
7.7 KiB
C

#ifndef __KERN_FS_VFS_VFS_H__
#define __KERN_FS_VFS_VFS_H__
#include <defs.h>
#include <fs.h>
#include <sfs.h>
struct inode; // abstract structure for an on-disk file (inode.h)
struct device; // abstract structure for a device (dev.h)
struct iobuf; // kernel or userspace I/O buffer (iobuf.h)
/*
* Abstract filesystem. (Or device accessible as a file.)
*
* Information:
* fs_info : filesystem-specific data (sfs_fs)
* fs_type : filesystem type
* Operations:
*
* fs_sync - Flush all dirty buffers to disk.
* fs_get_root - Return root inode of filesystem.
* fs_unmount - Attempt unmount of filesystem.
* fs_cleanup - Cleanup of filesystem.???
*
*
* fs_get_root should increment the refcount of the inode returned.
* It should not ever return NULL.
*
* If fs_unmount returns an error, the filesystem stays mounted, and
* consequently the struct fs instance should remain valid. On success,
* however, the filesystem object and all storage associated with the
* filesystem should have been discarded/released.
*
*/
struct fs {
union {
struct sfs_fs __sfs_info;
} fs_info; // filesystem-specific data
enum {
fs_type_sfs_info,
} fs_type; // filesystem type
int (*fs_sync)(struct fs *fs); // Flush all dirty buffers to disk
struct inode *(*fs_get_root)(struct fs *fs); // Return root inode of filesystem.
int (*fs_unmount)(struct fs *fs); // Attempt unmount of filesystem.
void (*fs_cleanup)(struct fs *fs); // Cleanup of filesystem.???
};
#define __fs_type(type) fs_type_##type##_info
#define check_fs_type(fs, type) ((fs)->fs_type == __fs_type(type))
#define __fsop_info(_fs, type) ({ \
struct fs *__fs = (_fs); \
assert(__fs != NULL && check_fs_type(__fs, type)); \
&(__fs->fs_info.__##type##_info); \
})
#define fsop_info(fs, type) __fsop_info(fs, type)
#define info2fs(info, type) \
to_struct((info), struct fs, fs_info.__##type##_info)
struct fs *__alloc_fs(int type);
#define alloc_fs(type) __alloc_fs(__fs_type(type))
// Macros to shorten the calling sequences.
#define fsop_sync(fs) ((fs)->fs_sync(fs))
#define fsop_get_root(fs) ((fs)->fs_get_root(fs))
#define fsop_unmount(fs) ((fs)->fs_unmount(fs))
#define fsop_cleanup(fs) ((fs)->fs_cleanup(fs))
/*
* Virtual File System layer functions.
*
* The VFS layer translates operations on abstract on-disk files or
* pathnames to operations on specific files on specific filesystems.
*/
void vfs_init(void);
void vfs_cleanup(void);
void vfs_devlist_init(void);
/*
* VFS layer low-level operations.
* See inode.h for direct operations on inodes.
* See fs.h for direct operations on filesystems/devices.
*
* vfs_set_curdir - change current directory of current thread by inode
* vfs_get_curdir - retrieve inode of current directory of current thread
* vfs_get_root - get root inode for the filesystem named DEVNAME
* vfs_get_devname - get mounted device name for the filesystem passed in
*/
int vfs_set_curdir(struct inode *dir);
int vfs_get_curdir(struct inode **dir_store);
int vfs_get_root(const char *devname, struct inode **root_store);
const char *vfs_get_devname(struct fs *fs);
/*
* VFS layer high-level operations on pathnames
* Because namei may destroy pathnames, these all may too.
*
* vfs_open - Open or create a file. FLAGS/MODE per the syscall.
* vfs_close - Close a inode opened with vfs_open. Does not fail.
* (See vfspath.c for a discussion of why.)
* vfs_link - Create a hard link to a file.
* vfs_symlink - Create a symlink PATH containing contents CONTENTS.
* vfs_readlink - Read contents of a symlink into a uio.
* vfs_mkdir - Create a directory. MODE per the syscall.
* vfs_unlink - Delete a file/directory.
* vfs_rename - rename a file.
* vfs_chdir - Change current directory of current thread by name.
* vfs_getcwd - Retrieve name of current directory of current thread.
*
*/
int vfs_open(char *path, uint32_t open_flags, struct inode **inode_store);
int vfs_close(struct inode *node);
int vfs_link(char *old_path, char *new_path);
int vfs_symlink(char *old_path, char *new_path);
int vfs_readlink(char *path, struct iobuf *iob);
int vfs_mkdir(char *path);
int vfs_unlink(char *path);
int vfs_rename(char *old_path, char *new_path);
int vfs_chdir(char *path);
int vfs_getcwd(struct iobuf *iob);
/*
* VFS layer mid-level operations.
*
* vfs_lookup - Like VOP_LOOKUP, but takes a full device:path name,
* or a name relative to the current directory, and
* goes to the correct filesystem.
* vfs_lookparent - Likewise, for VOP_LOOKPARENT.
*
* Both of these may destroy the path passed in.
*/
int vfs_lookup(char *path, struct inode **node_store);
int vfs_lookup_parent(char *path, struct inode **node_store, char **endp);
/*
* Misc
*
* vfs_set_bootfs - Set the filesystem that paths beginning with a
* slash are sent to. If not set, these paths fail
* with ENOENT. The argument should be the device
* name or volume name for the filesystem (such as
* "lhd0:") but need not have the trailing colon.
*
* vfs_get_bootfs - return the inode of the bootfs filesystem.
*
* vfs_add_fs - Add a hardwired filesystem to the VFS named device
* list. It will be accessible as "devname:". This is
* intended for filesystem-devices like emufs, and
* gizmos like Linux procfs or BSD kernfs, not for
* mounting filesystems on disk devices.
*
* vfs_add_dev - Add a device to the VFS named device list. If
* MOUNTABLE is zero, the device will be accessible
* as "DEVNAME:". If the mountable flag is set, the
* device will be accessible as "DEVNAMEraw:" and
* mountable under the name "DEVNAME". Thus, the
* console, added with MOUNTABLE not set, would be
* accessed by pathname as "con:", and lhd0, added
* with mountable set, would be accessed by
* pathname as "lhd0raw:" and mounted by passing
* "lhd0" to vfs_mount.
*
* vfs_mount - Attempt to mount a filesystem on a device. The
* device named by DEVNAME will be looked up and
* passed, along with DATA, to the supplied function
* MOUNTFUNC, which should create a struct fs and
* return it in RESULT.
*
* vfs_unmount - Unmount the filesystem presently mounted on the
* specified device.
*
* vfs_unmountall - Unmount all mounted filesystems.
*/
int vfs_set_bootfs(char *fsname);
int vfs_get_bootfs(struct inode **node_store);
int vfs_add_fs(const char *devname, struct fs *fs);
int vfs_add_dev(const char *devname, struct inode *devnode, bool mountable);
int vfs_mount(const char *devname, int (*mountfunc)(struct device *dev, struct fs **fs_store));
int vfs_unmount(const char *devname);
int vfs_unmount_all(void);
#endif /* !__KERN_FS_VFS_VFS_H__ */