aboutsummaryrefslogtreecommitdiff
path: root/fs/rawfs/rawfs.h
diff options
context:
space:
mode:
authorMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
committerMeizu OpenSource <patchwork@meizu.com>2016-08-15 10:19:42 +0800
commitd2e1446d81725c351dc73a03b397ce043fb18452 (patch)
tree4dbc616b7f92aea39cd697a9084205ddb805e344 /fs/rawfs/rawfs.h
first commit
Diffstat (limited to 'fs/rawfs/rawfs.h')
-rw-r--r--fs/rawfs/rawfs.h352
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