You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
6.9 KiB
190 lines
6.9 KiB
2 years ago
|
#ifndef _VFS_H_
|
||
|
#define _VFS_H_
|
||
|
|
||
|
#include "util/types.h"
|
||
|
|
||
|
#define MAX_VFS_DEV 10 // the maximum number of vfs_dev_list
|
||
|
#define MAX_DENTRY_NAME_LEN 30 // the maximum length of dentry name
|
||
|
#define MAX_DEVICE_NAME_LEN 30 // the maximum length of device name
|
||
|
#define MAX_MOUNTS 10 // the maximum number of mounts
|
||
|
#define MAX_DENTRY_HASH_SIZE 100 // the maximum size of dentry hash table
|
||
|
#define MAX_PATH_LEN 30 // the maximum length of path
|
||
|
#define MAX_SUPPORTED_FS 10 // the maximum number of supported file systems
|
||
|
|
||
|
#define DIRECT_BLKNUM 10 // the number of direct blocks
|
||
|
|
||
|
/**** vfs initialization function ****/
|
||
|
int vfs_init();
|
||
|
|
||
|
/**** vfs interfaces ****/
|
||
|
|
||
|
// device interfaces
|
||
|
struct super_block *vfs_mount(const char *dev_name, int mnt_type);
|
||
|
|
||
|
// file interfaces
|
||
|
struct file *vfs_open(const char *path, int flags);
|
||
|
ssize_t vfs_read(struct file *file, char *buf, size_t count);
|
||
|
ssize_t vfs_write(struct file *file, const char *buf, size_t count);
|
||
|
ssize_t vfs_lseek(struct file *file, ssize_t offset, int whence);
|
||
|
int vfs_stat(struct file *file, struct istat *istat);
|
||
|
int vfs_disk_stat(struct file *file, struct istat *istat);
|
||
|
int vfs_close(struct file *file);
|
||
|
|
||
|
/**** vfs abstract object types ****/
|
||
|
// system root direntry
|
||
|
extern struct dentry *vfs_root_dentry;
|
||
|
|
||
|
// vfs abstract dentry
|
||
|
struct dentry {
|
||
|
char name[MAX_DENTRY_NAME_LEN];
|
||
|
int d_ref;
|
||
|
struct vinode *dentry_inode;
|
||
|
struct dentry *parent;
|
||
|
struct super_block *sb;
|
||
|
};
|
||
|
|
||
|
|
||
|
// dentry constructor and destructor
|
||
|
struct dentry *alloc_vfs_dentry(const char *name, struct vinode *inode,
|
||
|
struct dentry *parent);
|
||
|
int free_vfs_dentry(struct dentry *dentry);
|
||
|
|
||
|
// ** dentry hash table **
|
||
|
extern struct hash_table dentry_hash_table;
|
||
|
|
||
|
// dentry hash table key type
|
||
|
struct dentry_key {
|
||
|
struct dentry *parent;
|
||
|
char *name;
|
||
|
};
|
||
|
|
||
|
// generic hash table method implementation
|
||
|
int dentry_hash_equal(void *key1, void *key2);
|
||
|
size_t dentry_hash_func(void *key);
|
||
|
|
||
|
// dentry hash table interface
|
||
|
struct dentry *hash_get_dentry(struct dentry *parent, char *name);
|
||
|
int hash_put_dentry(struct dentry *dentry);
|
||
|
int hash_erase_dentry(struct dentry *dentry);
|
||
|
|
||
|
// data structure of an openned file
|
||
|
struct file {
|
||
|
int status;
|
||
|
int readable;
|
||
|
int writable;
|
||
|
int offset;
|
||
|
struct dentry *f_dentry;
|
||
|
};
|
||
|
|
||
|
// file constructor and destructor(use free_page to destruct)
|
||
|
struct file *alloc_vfs_file(struct dentry *dentry, int readable, int writable,
|
||
|
int offset);
|
||
|
|
||
|
// abstract device entry in vfs_dev_list
|
||
|
struct device {
|
||
|
char dev_name[MAX_DEVICE_NAME_LEN]; // the name of the device
|
||
|
int dev_id; // the id of the device (the meaning of an id is interpreted by
|
||
|
// the specific file system, all we need to know is that it is
|
||
|
// a unique identifier)
|
||
|
struct file_system_type *fs_type; // the file system type in the device
|
||
|
};
|
||
|
|
||
|
// device list in vfs layer
|
||
|
extern struct device *vfs_dev_list[MAX_VFS_DEV];
|
||
|
|
||
|
// supported file system types
|
||
|
struct file_system_type {
|
||
|
int type_num; // the number of the file system type
|
||
|
struct super_block *(*get_superblock)(struct device *dev);
|
||
|
};
|
||
|
|
||
|
extern struct file_system_type *fs_list[MAX_SUPPORTED_FS];
|
||
|
|
||
|
// general-purpose super_block structure
|
||
|
struct super_block {
|
||
|
int magic; // magic number of the file system
|
||
|
int size; // size of file system image (blocks)
|
||
|
int nblocks; // number of data blocks
|
||
|
int ninodes; // number of inodes.
|
||
|
struct dentry *s_root; // root dentry of inode
|
||
|
struct device *s_dev; // device of the superblock
|
||
|
void *s_fs_info; // filesystem-specific info. for rfs, it points bitmap
|
||
|
};
|
||
|
|
||
|
// abstract vfs inode
|
||
|
struct vinode {
|
||
|
int inum; // inode number of the disk inode
|
||
|
int ref; // reference count
|
||
|
int size; // size of the file (in bytes)
|
||
|
int type; // one of FILE_I, DIR_I
|
||
|
int nlinks; // number of hard links to this file
|
||
|
int blocks; // number of blocks
|
||
|
int addrs[DIRECT_BLKNUM]; // direct blocks
|
||
|
void *i_fs_info; // filesystem-specific info (see s_fs_info)
|
||
|
struct super_block *sb; // super block of the vfs inode
|
||
|
const struct vinode_ops *i_ops; // vfs inode operations
|
||
|
};
|
||
|
|
||
|
struct vinode_ops {
|
||
|
// file operations
|
||
|
ssize_t (*viop_read)(struct vinode *node, char *buf, ssize_t len,
|
||
|
int *offset);
|
||
|
ssize_t (*viop_write)(struct vinode *node, const char *buf, ssize_t len,
|
||
|
int *offset);
|
||
|
struct vinode *(*viop_create)(struct vinode *parent, struct dentry *sub_dentry);
|
||
|
int (*viop_lseek)(struct vinode *node, ssize_t new_off, int whence, int *off);
|
||
|
int (*viop_disk_stat)(struct vinode *node, struct istat *istat);
|
||
|
struct vinode *(*viop_lookup)(struct vinode *parent,
|
||
|
struct dentry *sub_dentry);
|
||
|
|
||
|
// write back inode to disk
|
||
|
int (*viop_write_back_vinode)(struct vinode *node);
|
||
|
|
||
|
// hook functions
|
||
|
// In the vfs layer, we do not assume that hook functions will do anything,
|
||
|
// but simply call them (when they are defined) at the appropriate time.
|
||
|
// Hook functions exist because the fs layer may need to do some additional
|
||
|
// operations (such as allocating additional data structures) at some critical
|
||
|
// times.
|
||
|
int (*viop_hook_open)(struct vinode *node, struct dentry *dentry);
|
||
|
int (*viop_hook_close)(struct vinode *node, struct dentry *dentry);
|
||
|
};
|
||
|
|
||
|
// vinode operation interface
|
||
|
// the implementation depends on the vinode type and the specific file system
|
||
|
|
||
|
// virtual file system inode interfaces
|
||
|
#define viop_read(node, buf, len, offset) (node->i_ops->viop_read(node, buf, len, offset))
|
||
|
#define viop_write(node, buf, len, offset) (node->i_ops->viop_write(node, buf, len, offset))
|
||
|
#define viop_create(node, name) (node->i_ops->viop_create(node, name))
|
||
|
#define viop_lseek(node, new_off, whence, off) (node->i_ops->viop_lseek(node, new_off, whence, off))
|
||
|
#define viop_disk_stat(node, istat) (node->i_ops->viop_disk_stat(node, istat))
|
||
|
#define viop_lookup(parent, sub_dentry) (parent->i_ops->viop_lookup(parent, sub_dentry))
|
||
|
#define viop_write_back_vinode(node) (node->i_ops->viop_write_back_vinode(node))
|
||
|
|
||
|
// vinode hash table
|
||
|
extern struct hash_table vinode_hash_table;
|
||
|
|
||
|
// vinode hash table key type
|
||
|
struct vinode_key {
|
||
|
int inum;
|
||
|
struct super_block *sb;
|
||
|
};
|
||
|
|
||
|
// generic hash table method implementation
|
||
|
int vinode_hash_equal(void *key1, void *key2);
|
||
|
size_t vinode_hash_func(void *key);
|
||
|
|
||
|
// vinode hash table interface
|
||
|
struct vinode *hash_get_vinode(struct super_block *sb, int inum);
|
||
|
int hash_put_vinode(struct vinode *vinode);
|
||
|
int hash_erase_vinode(struct vinode *vinode);
|
||
|
|
||
|
// other utility functions
|
||
|
struct vinode *default_alloc_vinode(struct super_block *sb);
|
||
|
struct dentry *lookup_final_dentry(const char *path, struct dentry **parent,
|
||
|
char *miss_name);
|
||
|
void get_base_name(const char *path, char *base_name);
|
||
|
|
||
|
#endif
|