diff options
| author | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
|---|---|---|
| committer | Meizu OpenSource <patchwork@meizu.com> | 2016-08-15 10:19:42 +0800 |
| commit | d2e1446d81725c351dc73a03b397ce043fb18452 (patch) | |
| tree | 4dbc616b7f92aea39cd697a9084205ddb805e344 /fs/rawfs/rawfs.h | |
first commit
Diffstat (limited to 'fs/rawfs/rawfs.h')
| -rw-r--r-- | fs/rawfs/rawfs.h | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/fs/rawfs/rawfs.h b/fs/rawfs/rawfs.h new file mode 100644 index 000000000..3fea63249 --- /dev/null +++ b/fs/rawfs/rawfs.h @@ -0,0 +1,352 @@ +#ifndef __RAWFS_H__ +#define __RAWFS_H__ + +#include <asm/byteorder.h> +#include <linux/list.h> + +#if defined(CONFIG_MT_ENG_BUILD) /* log is only enabled in eng load */ +#define RAWFS_DBG pr_warn +#endif + +#define RAWFS_BLOCK_FILE +/* #define RAWFS_RAM_DISK */ + +#define RAWFS_VERSION 0x01 + +/* Debug Message Mask */ +enum rawfs_debug_level_enum { + RAWFS_DBG_SUPER = 0x0001, + RAWFS_DBG_DEVICE = 0x0002, + RAWFS_DBG_INODE = 0x0004, + RAWFS_DBG_FILE = 0x0008, + RAWFS_DBG_DIR = 0x0010, + RAWFS_DBG_DENTRY = 0x0020, + RAWFS_DBG_INIT = 0x0040, + RAWFS_DBG_GC = 0x0080, + RAWFS_DBG_MOUNT = 0x0100 +}; + +extern int rawfs_debug_msg_mask; + +#define RAWFS_DEBUG_MSG_DEFAULT (RAWFS_DBG_SUPER | RAWFS_DBG_DEVICE | \ + RAWFS_DBG_INODE | RAWFS_DBG_FILE | \ + RAWFS_DBG_DIR | RAWFS_DBG_DENTRY | \ + RAWFS_DBG_INIT | RAWFS_DBG_GC | RAWFS_DBG_MOUNT) + +#ifdef RAWFS_DBG +#define RAWFS_PRINT(category, str, ...) do { \ + if (category & rawfs_debug_msg_mask) { \ + RAWFS_DBG("rawfs: " str, ##__VA_ARGS__); \ + } } while (0) +#else +#define RAWFS_PRINT(...) +#endif + +#define RAWFS_MAX_FILENAME_LEN 60 + +#define RAWFS_MNT_RAM 0x01 +#define RAWFS_MNT_MTD 0x02 +#define RAWFS_MNT_CASE 0x10 + +#define RAWFS_MNT_BLOCKFILE 0x40 +#define RAWFS_MNT_FIRSTBOOT 0x80 + +/* RAW FS super block info */ +#define RAWFS_HASH_BITS 2 +#define RAWFS_HASH_SIZE (1UL << RAWFS_HASH_BITS) + +/* Interface to MTD block device */ +struct rawfs_dev { + int (*erase_block) (struct super_block *sb, int block_no); + int (*read_page_user) (struct super_block *sb, int block_no, int addr, + const struct iovec *iov, unsigned long nr_segs, int size); + int (*write_page) (struct super_block *sb, int block_no, + int page_no, void *buffer); + int (*read_page) (struct super_block *sb, int block_no, + int page_no, void *buffer); +}; + +/* RAW FS super block info */ +struct rawfs_sb_info { + /* File System Context */ + struct list_head fs_context; + struct super_block *super; + struct proc_dir_entry *s_proc; + /* Driver context */ + void *driver_context; + struct rawfs_dev dev; + /* Device Info */ + int total_blocks; + int pages_per_block; + int sectors_per_page; + int block_size; + int page_size; + int page_data_size; + /* Managment */ + int data_block; + int data_block_free_page_index; + int data_block_gcmarker_page_index; + int empty_block; + __u32 sequence_number; + __u32 erase_count_max; + int flags; + char *fake_block; + struct mutex rawfs_lock; + struct nls_table *local_nls; /* Codepage used on disk */ + /* File List */ + struct list_head folder_list; + struct list_head file_list; + struct mutex file_list_lock; + /* Inode Hash Table */ + spinlock_t inode_hash_lock; + struct hlist_head inode_hashtable[RAWFS_HASH_SIZE]; + /* Misc */ + unsigned int rsize; + unsigned int wsize; +}; + +#define RAWFS_NAND_BLOCKS(sb) ((sb)?2:0) /* We use only two block */ +#define RAWFS_NAND_PAGES(sb) (sb->pages_per_block) +#define RAWFS_NAND_PAGE_SIZE(sb) (sb->page_size) +#define RAWFS_NAND_BLOCK_SIZE(sb) (sb->block_size) +#define RAWFS_NAND_PAGE_SECTORS(sb) (sb->sectors_per_page) +#define RAWFS_NAND_PAGE_DATA_SIZE(sb) (sb->page_data_size) + +/* RAW FS inode info */ +struct rawfs_inode_info { + spinlock_t cache_lru_lock; + struct list_head cache_lru; + int nr_caches; + unsigned int cache_valid_id; + + /* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */ + loff_t mmu_private; /* physically allocated size */ + + int i_location_block; /* File Location: block */ + int i_location_page; /* File Location: starting page */ + int i_location_page_count; + int i_id; + int i_parent_folder_id; /* Parent folder ID */ + + char i_name[RAWFS_MAX_FILENAME_LEN+4]; + struct hlist_node i_rawfs_hash; /* hash by i_name */ + struct rw_semaphore truncate_lock; /* protect bmap against truncate */ + struct inode vfs_inode; +}; + +static inline struct rawfs_sb_info * +RAWFS_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + +static inline struct rawfs_inode_info * +RAWFS_I(struct inode *inode) +{ + return container_of(inode, struct rawfs_inode_info, vfs_inode); +} + +static inline struct mtd_info * +RAWFS_MTD(struct super_block *sb) +{ + return RAWFS_SB(sb)->driver_context; +} + +#define RAWFS_CACHE_VALID 0 + +#define RAWFS_ROOT_DIR_ID 1 + +/* RAWFS inode number */ +#define RAWFS_ROOT_INO 1 +#define RAWFS_BLOCK0_INO 2 +#define RAWFS_BLOCK1_INO 3 +#define RAWFS_MAX_RESERVED_INO 64 + +/* Page Signatures */ +#define RAWFS_NAND_BLOCK_SIG_HEAD 0x44484B42 /* BKHD */ +#define RAWFS_NAND_PAGE_SIG_HEAD 0x44484750 /* PGHD */ +#define RAWFS_NAND_PAGE_SIG_FOOT 0x54464750 /* PGFT */ +#define RAWFS_NAND_GC_MARKER_SIG_HEAD 0x44484347 /* GCHD */ +#define RAWFS_NAND_PAGE_SIG_EMPTY 0xFFFFFFFF + +enum rawfs_block_stat_enum { + RAWFS_BLOCK_STAT_INVALID_HEAD = 0, + RAWFS_BLOCK_STAT_EMPTY = 1, + RAWFS_BLOCK_STAT_INVALID_DATA = 2, + RAWFS_BLOCK_STAT_DATA = 3 +}; + +enum rawfs_page_stat_enum { + RAWFS_PAGE_STAT_EMPTY = 0, + RAWFS_PAGE_STAT_DELETED = 1, + RAWFS_PAGE_STAT_VALID = 2, + RAWFS_PAGE_STAT_BLOCK_HEAD = 3, + RAWFS_PAGE_STAT_GC_MARKER = 4, + RAWFS_PAGE_STAT_UNCORRECTABLE = 5, + RAWFS_PAGE_STAT_INVALID = 6 +}; + +struct rawfs_block_header { + __u32 i_signature_head; + __u32 i_rawfs_version; + __u32 i_sequence_number; + __u32 i_sequence_number_last; + __u32 i_erase_count; + __u32 i_crc; +} __packed; + +struct rawfs_gc_marker_page { + __u32 i_signature_head; + __u32 i_src_block_index; + __u32 i_src_block_sequence_number; + __u32 i_src_block_erase_count; + __u32 i_crc; +} __packed; + +struct rawfs_file_info { /* dentry */ + char i_name[RAWFS_MAX_FILENAME_LEN+4]; + int i_chunk_index; + int i_chunk_total; + struct timespec i_atime; + struct timespec i_mtime; + struct timespec i_ctime; + umode_t i_mode; + uid_t i_uid; + gid_t i_gid; + loff_t i_size; + int i_parent_folder_id; + int i_id; /* 0 for normal file */ +}; + +struct rawfs_file_list_entry { + struct list_head list; + struct rawfs_file_info file_info; + int i_location_block; /* File Location: block */ + int i_location_page; /* File Location: starting page */ + int i_location_page_count; +}; + +struct rawfs_page { + __u32 i_signature_head; + __u32 i_crc; + union { + struct rawfs_file_info i_file_info; + __u8 padding[488]; + } i_info; + __u8 i_data[1]; +} __packed; + + +/* Inode operations */ +int __init rawfs_init_inodecache(void); +void __exit rawfs_destroy_inodecache(void); +void rawfs_hash_init(struct super_block *sb); +struct inode *rawfs_alloc_inode(struct super_block *sb); +void rawfs_destroy_inode(struct inode *inode); +int rawfs_fill_inode(struct inode *inode, + struct rawfs_file_info *file_info, int block_no, int page_no, + umode_t mode, dev_t dev); +struct inode *rawfs_iget(struct super_block *sb, const char *name, + int folder); + +/* Mount-time analysis */ +int rawfs_block_level_analysis(struct super_block *sb); +int rawfs_page_level_analysis(struct super_block *sb); +int rawfs_file_level_analysis(struct super_block *sb); +int rawfs_page_get(struct super_block *sb, int block_no, int page_no, + struct rawfs_file_info *file_info, void *data); +int rawfs_block_is_valid(struct super_block *sb, int block_no, + struct rawfs_block_header *block_head_out, + struct rawfs_gc_marker_page *gc_page_out); + +/* Device Operation */ +int rawfs_dev_free_space(struct super_block *sb); +int rawfs_dev_garbage_collection(struct super_block *sb); +void rawfs_page_signature(struct super_block *sb, void *buf); + +int rawfs_dev_mtd_erase_block(struct super_block *sb, int block_no); +int rawfs_dev_mtd_read_page_user(struct super_block *sb, int block_no, + int block_offset, const struct iovec *iov, unsigned long nr_segs, int size); +int rawfs_dev_mtd_write_page(struct super_block *sb, + int block_no, int page_no, void *buffer); +int rawfs_dev_mtd_read_page(struct super_block *sb, + int block_no, int page_no, void *buffer); + +int rawfs_dev_ram_erase_block(struct super_block *sb, int block_no); +int rawfs_dev_ram_read_page_user(struct super_block *sb, int block_no, + int block_offset, const struct iovec *iov, unsigned long nr_segs, int size); +int rawfs_dev_ram_write_page(struct super_block *sb, + int block_no, int page_no, void *buffer); +int rawfs_dev_ram_read_page(struct super_block *sb, + int block_no, int page_no, void *buffer); + +/* File Operations */ +int rawfs_reg_file_delete(struct inode *dir, struct dentry *dentry); +int rawfs_reg_file_create(struct inode *dir, struct dentry *dentry, + umode_t mode, struct nameidata *nd); +int rawfs_reg_file_copy(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dest_dir, struct dentry *dest_dentry); +int rawfs_reserve_space(struct super_block *sb, int chunks); +ssize_t +rawfs_reg_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +ssize_t +rawfs_reg_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +ssize_t +rawfs_block_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +ssize_t rawfs_block_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +int rawfs_file_sync(struct file *file, loff_t start, loff_t end, + int datasync); +int rawfs_readdir(struct file *filp, void *dirent, filldir_t filldir); + +/* dentry operations */ +int rawfs_delete_dentry(const struct dentry *dentry); + +/* File info */ +void rawfs_fill_file_info(struct inode *inode, + struct rawfs_file_info *file_info); +void rawfs_fill_fileinfo_by_dentry(struct dentry *dentry, + struct rawfs_file_info *file_info); + +/* File and Folder lists */ +struct rawfs_file_list_entry *rawfs_file_list_get(struct super_block *sb, + const char *name, int folder_id); +struct rawfs_file_list_entry *rawfs_file_list_get_by_id( + struct super_block *sb, umode_t mode, int id); +void rawfs_file_list_init(struct super_block *sb); +int rawfs_file_list_add(struct super_block *sb, + struct rawfs_file_info *fi, int block_no, int page_no); +void rawfs_file_list_remove(struct super_block *sb, + struct rawfs_file_info *fi); +void rawfs_file_list_destroy(struct super_block *sb); +int rawfs_file_list_count(struct super_block *sb, + unsigned int *entry_count, unsigned int *used_blocks, + unsigned int *free_blocks); +__u32 rawfs_page_crc_data(struct super_block *sb, void *data_page); +__u32 rawfs_page_crc_gcmarker(struct super_block *sb, void *gcmarker_page); + +/* Address Space Operations: Block file & Normal file */ +int rawfs_readpage(struct file *filp, struct page *page); +int rawfs_write_begin(struct file *filp, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata); +int rawfs_write_end(struct file *filp, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *pg, void *fsdata); + +/* Case in-sensitive dentry operations */ +int rawfs_ci_hash(const struct dentry *dentry, const struct inode *inode, + struct qstr *q); +int rawfs_compare_dentry(const struct dentry *parent, + const struct inode *pinode, const struct dentry *dentry, + const struct inode *inode, unsigned int len, const char *str, + const struct qstr *name); +int rawfs_delete_dentry(const struct dentry *dentry); + +/* Utility */ +uint32_t rawfs_div(uint64_t n, uint32_t base); + +#endif |
