fscrypto/f2fs: allow fs-specific key prefix for fs encryption
[cascardo/linux.git] / fs / f2fs / f2fs.h
index 7a4558d..dbd277e 100644 (file)
        } while (0)
 #endif
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+enum {
+       FAULT_KMALLOC,
+       FAULT_PAGE_ALLOC,
+       FAULT_ALLOC_NID,
+       FAULT_ORPHAN,
+       FAULT_BLOCK,
+       FAULT_DIR_DEPTH,
+       FAULT_MAX,
+};
+
+extern u32 f2fs_fault_rate;
+extern atomic_t f2fs_ops;
+extern char *fault_name[FAULT_MAX];
+
+static inline bool time_to_inject(int type)
+{
+       atomic_inc(&f2fs_ops);
+       if (f2fs_fault_rate && (atomic_read(&f2fs_ops) >= f2fs_fault_rate)) {
+               atomic_set(&f2fs_ops, 0);
+               printk("%sF2FS-fs : inject %s in %pF\n",
+                               KERN_INFO,
+                               fault_name[type],
+                               __builtin_return_address(0));
+               return true;
+       }
+       return false;
+}
+#endif
+
 /*
  * For mount options
  */
@@ -56,6 +86,7 @@
 #define F2FS_MOUNT_EXTENT_CACHE                0x00002000
 #define F2FS_MOUNT_FORCE_FG_GC         0x00004000
 #define F2FS_MOUNT_DATA_FLUSH          0x00008000
+#define F2FS_MOUNT_FAULT_INJECTION     0x00010000
 
 #define clear_opt(sbi, option) (sbi->mount_opt.opt &= ~F2FS_MOUNT_##option)
 #define set_opt(sbi, option)   (sbi->mount_opt.opt |= F2FS_MOUNT_##option)
@@ -159,7 +190,6 @@ struct fsync_inode_entry {
        struct inode *inode;    /* vfs inode pointer */
        block_t blkaddr;        /* block address locating the last fsync */
        block_t last_dentry;    /* block address locating the last dentry */
-       block_t last_inode;     /* block address locating the last inode */
 };
 
 #define nats_in_cursum(jnl)            (le16_to_cpu(jnl->n_nats))
@@ -398,11 +428,11 @@ struct f2fs_inode_info {
 };
 
 static inline void get_extent_info(struct extent_info *ext,
-                                       struct f2fs_extent i_ext)
+                                       struct f2fs_extent *i_ext)
 {
-       ext->fofs = le32_to_cpu(i_ext.fofs);
-       ext->blk = le32_to_cpu(i_ext.blk);
-       ext->len = le32_to_cpu(i_ext.len);
+       ext->fofs = le32_to_cpu(i_ext->fofs);
+       ext->blk = le32_to_cpu(i_ext->blk);
+       ext->len = le32_to_cpu(i_ext->len);
 }
 
 static inline void set_raw_extent(struct extent_info *ext,
@@ -672,6 +702,7 @@ enum {
        SBI_IS_CLOSE,                           /* specify unmounting */
        SBI_NEED_FSCK,                          /* need fsck.f2fs to fix */
        SBI_POR_DOING,                          /* recovery is doing or not */
+       SBI_NEED_SB_WRITE,                      /* need to recover superblock */
 };
 
 enum {
@@ -680,6 +711,10 @@ enum {
        MAX_TIME,
 };
 
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#define F2FS_KEY_DESC_PREFIX "f2fs:"
+#define F2FS_KEY_DESC_PREFIX_SIZE 5
+#endif
 struct f2fs_sb_info {
        struct super_block *sb;                 /* pointer to VFS super block */
        struct proc_dir_entry *s_proc;          /* proc entry */
@@ -687,6 +722,10 @@ struct f2fs_sb_info {
        int valid_super_block;                  /* valid super block no */
        int s_flag;                             /* flags for sbi */
 
+#ifdef CONFIG_F2FS_FS_ENCRYPTION
+       u8 key_prefix[F2FS_KEY_DESC_PREFIX_SIZE];
+       u8 key_prefix_size;
+#endif
        /* for node-related operations */
        struct f2fs_nm_info *nm_info;           /* node manager */
        struct inode *node_inode;               /* cache node blocks */
@@ -1060,6 +1099,12 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi,
        block_t valid_block_count;
 
        spin_lock(&sbi->stat_lock);
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(FAULT_BLOCK)) {
+               spin_unlock(&sbi->stat_lock);
+               return false;
+       }
+#endif
        valid_block_count =
                sbi->total_valid_block_count + (block_t)count;
        if (unlikely(valid_block_count > sbi->user_block_count)) {
@@ -1270,6 +1315,14 @@ static inline unsigned int valid_inode_count(struct f2fs_sb_info *sbi)
 static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
                                                pgoff_t index, bool for_write)
 {
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       struct page *page = find_lock_page(mapping, index);
+       if (page)
+               return page;
+
+       if (time_to_inject(FAULT_PAGE_ALLOC))
+               return NULL;
+#endif
        if (!for_write)
                return grab_cache_page(mapping, index);
        return grab_cache_page_write_begin(mapping, index, AOP_FLAG_NOFS);
@@ -1644,6 +1697,15 @@ static inline bool f2fs_may_extent_tree(struct inode *inode)
        return S_ISREG(inode->i_mode);
 }
 
+static inline void *f2fs_kmalloc(size_t size, gfp_t flags)
+{
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(FAULT_KMALLOC))
+               return NULL;
+#endif
+       return kmalloc(size, flags);
+}
+
 static inline void *f2fs_kvmalloc(size_t size, gfp_t flags)
 {
        void *ret;
@@ -1710,7 +1772,7 @@ struct dentry *f2fs_get_parent(struct dentry *child);
  */
 extern unsigned char f2fs_filetype_table[F2FS_FT_MAX];
 void set_de_type(struct f2fs_dir_entry *, umode_t);
-
+unsigned char get_de_type(struct f2fs_dir_entry *);
 struct f2fs_dir_entry *find_target_dentry(struct fscrypt_name *,
                        f2fs_hash_t, int *, struct f2fs_dentry_ptr *);
 bool f2fs_fill_dentries(struct dir_context *, struct f2fs_dentry_ptr *,
@@ -1731,6 +1793,8 @@ void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
 int update_dent_inode(struct inode *, struct inode *, const struct qstr *);
 void f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *,
                        const struct qstr *, f2fs_hash_t , unsigned int);
+int f2fs_add_regular_entry(struct inode *, const struct qstr *,
+                                               struct inode *, nid_t, umode_t);
 int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *, nid_t,
                        umode_t);
 void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *,
@@ -1781,7 +1845,10 @@ void ra_node_page(struct f2fs_sb_info *, nid_t);
 struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_node_page_ra(struct page *, int);
 void sync_inode_page(struct dnode_of_data *);
-int sync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *);
+void move_node_page(struct page *, int);
+int fsync_node_pages(struct f2fs_sb_info *, nid_t, struct writeback_control *,
+                                                               bool);
+int sync_node_pages(struct f2fs_sb_info *, struct writeback_control *);
 bool alloc_nid(struct f2fs_sb_info *, nid_t *);
 void alloc_nid_done(struct f2fs_sb_info *, nid_t);
 void alloc_nid_failed(struct f2fs_sb_info *, nid_t);
@@ -1852,7 +1919,7 @@ void ra_meta_pages_cond(struct f2fs_sb_info *, pgoff_t);
 long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
 void add_ino_entry(struct f2fs_sb_info *, nid_t, int type);
 void remove_ino_entry(struct f2fs_sb_info *, nid_t, int type);
-void release_ino_entry(struct f2fs_sb_info *);
+void release_ino_entry(struct f2fs_sb_info *, bool);
 bool exist_written_data(struct f2fs_sb_info *, nid_t, int);
 int acquire_orphan_inode(struct f2fs_sb_info *);
 void release_orphan_inode(struct f2fs_sb_info *);
@@ -1906,7 +1973,7 @@ void build_gc_manager(struct f2fs_sb_info *);
 /*
  * recovery.c
  */
-int recover_fsync_data(struct f2fs_sb_info *);
+int recover_fsync_data(struct f2fs_sb_info *, bool);
 bool space_for_roll_forward(struct f2fs_sb_info *);
 
 /*