ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate
[cascardo/linux.git] / fs / ext4 / ext4.h
index ef267ad..3ab7cd8 100644 (file)
@@ -90,6 +90,11 @@ typedef __u32 ext4_lblk_t;
 /* data type for block group number */
 typedef unsigned int ext4_group_t;
 
+enum SHIFT_DIRECTION {
+       SHIFT_LEFT = 0,
+       SHIFT_RIGHT,
+};
+
 /*
  * Flags used in mballoc's allocation_context flags field.
  *
@@ -954,7 +959,7 @@ struct ext4_inode_info {
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
        /* Encryption params */
-       struct ext4_encryption_key i_encryption_key;
+       struct ext4_crypt_info *i_crypt_info;
 #endif
 };
 
@@ -1066,12 +1071,6 @@ extern void ext4_set_bits(void *bm, int cur, int len);
 /* Metadata checksum algorithm codes */
 #define EXT4_CRC32C_CHKSUM             1
 
-/* Encryption algorithms */
-#define EXT4_ENCRYPTION_MODE_INVALID           0
-#define EXT4_ENCRYPTION_MODE_AES_256_XTS       1
-#define EXT4_ENCRYPTION_MODE_AES_256_GCM       2
-#define EXT4_ENCRYPTION_MODE_AES_256_CBC       3
-
 /*
  * Structure of the super block
  */
@@ -1379,12 +1378,6 @@ struct ext4_sb_info {
        struct ratelimit_state s_err_ratelimit_state;
        struct ratelimit_state s_warning_ratelimit_state;
        struct ratelimit_state s_msg_ratelimit_state;
-
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
-       /* Encryption */
-       uint32_t s_file_encryption_mode;
-       uint32_t s_dir_encryption_mode;
-#endif
 };
 
 static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@ -1843,6 +1836,17 @@ struct dx_hash_info
  */
 #define HASH_NB_ALWAYS         1
 
+struct ext4_filename {
+       const struct qstr *usr_fname;
+       struct ext4_str disk_name;
+       struct dx_hash_info hinfo;
+#ifdef CONFIG_EXT4_FS_ENCRYPTION
+       struct ext4_str crypto_buf;
+#endif
+};
+
+#define fname_name(p) ((p)->disk_name.name)
+#define fname_len(p)  ((p)->disk_name.len)
 
 /*
  * Describe an inode's exact location on disk and in memory
@@ -2059,6 +2063,7 @@ int ext4_get_policy(struct inode *inode,
                    struct ext4_encryption_policy *policy);
 
 /* crypto.c */
+extern struct kmem_cache *ext4_crypt_info_cachep;
 bool ext4_valid_contents_enc_mode(uint32_t mode);
 uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
 extern struct workqueue_struct *ext4_read_workqueue;
@@ -2090,54 +2095,84 @@ static inline int ext4_sb_has_crypto(struct super_block *sb)
 /* crypto_fname.c */
 bool ext4_valid_filenames_enc_mode(uint32_t mode);
 u32 ext4_fname_crypto_round_up(u32 size, u32 blksize);
-int ext4_fname_crypto_alloc_buffer(struct ext4_fname_crypto_ctx *ctx,
+unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen);
+int ext4_fname_crypto_alloc_buffer(struct inode *inode,
                                   u32 ilen, struct ext4_str *crypto_str);
-int _ext4_fname_disk_to_usr(struct ext4_fname_crypto_ctx *ctx,
+int _ext4_fname_disk_to_usr(struct inode *inode,
+                           struct dx_hash_info *hinfo,
                            const struct ext4_str *iname,
                            struct ext4_str *oname);
-int ext4_fname_disk_to_usr(struct ext4_fname_crypto_ctx *ctx,
+int ext4_fname_disk_to_usr(struct inode *inode,
+                          struct dx_hash_info *hinfo,
                           const struct ext4_dir_entry_2 *de,
                           struct ext4_str *oname);
-int ext4_fname_usr_to_disk(struct ext4_fname_crypto_ctx *ctx,
+int ext4_fname_usr_to_disk(struct inode *inode,
                           const struct qstr *iname,
                           struct ext4_str *oname);
-int ext4_fname_usr_to_hash(struct ext4_fname_crypto_ctx *ctx,
-                          const struct qstr *iname,
-                          struct dx_hash_info *hinfo);
-int ext4_fname_disk_to_hash(struct ext4_fname_crypto_ctx *ctx,
-                           const struct ext4_dir_entry_2 *de,
-                           struct dx_hash_info *hinfo);
-int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
-                                     u32 namelen);
-
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
-void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx);
-struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
-                                                       u32 max_len);
 void ext4_fname_crypto_free_buffer(struct ext4_str *crypto_str);
+int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
+                             int lookup, struct ext4_filename *fname);
+void ext4_fname_free_filename(struct ext4_filename *fname);
 #else
 static inline
-void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx) { }
-static inline
-struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
-                                                       u32 max_len)
+int ext4_setup_fname_crypto(struct inode *inode)
 {
-       return NULL;
+       return 0;
 }
 static inline void ext4_fname_crypto_free_buffer(struct ext4_str *p) { }
+static inline int ext4_fname_setup_filename(struct inode *dir,
+                                    const struct qstr *iname,
+                                    int lookup, struct ext4_filename *fname)
+{
+       fname->usr_fname = iname;
+       fname->disk_name.name = (unsigned char *) iname->name;
+       fname->disk_name.len = iname->len;
+       return 0;
+}
+static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
 #endif
 
 
 /* crypto_key.c */
-int ext4_generate_encryption_key(struct inode *inode);
+void ext4_free_crypt_info(struct ext4_crypt_info *ci);
+void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci);
+int _ext4_get_encryption_info(struct inode *inode);
 
 #ifdef CONFIG_EXT4_FS_ENCRYPTION
 int ext4_has_encryption_key(struct inode *inode);
+
+static inline int ext4_get_encryption_info(struct inode *inode)
+{
+       struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
+
+       if (!ci ||
+           (ci->ci_keyring_key &&
+            (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
+                                          (1 << KEY_FLAG_REVOKED) |
+                                          (1 << KEY_FLAG_DEAD)))))
+               return _ext4_get_encryption_info(inode);
+       return 0;
+}
+
+static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
+{
+       return EXT4_I(inode)->i_crypt_info;
+}
+
 #else
 static inline int ext4_has_encryption_key(struct inode *inode)
 {
        return 0;
 }
+static inline int ext4_get_encryption_info(struct inode *inode)
+{
+       return 0;
+}
+static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
+{
+       return NULL;
+}
 #endif
 
 
@@ -2158,14 +2193,13 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
 extern int ext4_find_dest_de(struct inode *dir, struct inode *inode,
                             struct buffer_head *bh,
                             void *buf, int buf_size,
-                            const char *name, int namelen,
+                            struct ext4_filename *fname,
                             struct ext4_dir_entry_2 **dest_de);
 int ext4_insert_dentry(struct inode *dir,
-                       struct inode *inode,
-                       struct ext4_dir_entry_2 *de,
-                       int buf_size,
-                      const struct qstr *iname,
-                       const char *name, int namelen);
+                      struct inode *inode,
+                      struct ext4_dir_entry_2 *de,
+                      int buf_size,
+                      struct ext4_filename *fname);
 static inline void ext4_update_dx_flag(struct inode *inode)
 {
        if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
@@ -2319,13 +2353,14 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
 extern int ext4_orphan_del(handle_t *, struct inode *);
 extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
                                __u32 start_minor_hash, __u32 *next_hash);
-extern int search_dir(struct buffer_head *bh,
-                     char *search_buf,
-                     int buf_size,
-                     struct inode *dir,
-                     const struct qstr *d_name,
-                     unsigned int offset,
-                     struct ext4_dir_entry_2 **res_dir);
+extern int ext4_search_dir(struct buffer_head *bh,
+                          char *search_buf,
+                          int buf_size,
+                          struct inode *dir,
+                          struct ext4_filename *fname,
+                          const struct qstr *d_name,
+                          unsigned int offset,
+                          struct ext4_dir_entry_2 **res_dir);
 extern int ext4_generic_delete_entry(handle_t *handle,
                                     struct inode *dir,
                                     struct ext4_dir_entry_2 *de_del,
@@ -2770,7 +2805,9 @@ extern int ext4_da_write_inline_data_begin(struct address_space *mapping,
 extern int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
                                         unsigned len, unsigned copied,
                                         struct page *page);
-extern int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
+extern int ext4_try_add_inline_entry(handle_t *handle,
+                                    struct ext4_filename *fname,
+                                    struct dentry *dentry,
                                     struct inode *inode);
 extern int ext4_try_create_inline_dir(handle_t *handle,
                                      struct inode *parent,
@@ -2784,6 +2821,7 @@ extern int htree_inlinedir_to_tree(struct file *dir_file,
                                   __u32 start_hash, __u32 start_minor_hash,
                                   int *has_inline_data);
 extern struct buffer_head *ext4_find_inline_entry(struct inode *dir,
+                                       struct ext4_filename *fname,
                                        const struct qstr *d_name,
                                        struct ext4_dir_entry_2 **res_dir,
                                        int *has_inline_data);
@@ -2891,7 +2929,6 @@ extern int ext4_map_blocks(handle_t *handle, struct inode *inode,
                           struct ext4_map_blocks *map, int flags);
 extern int ext4_ext_calc_metadata_amount(struct inode *inode,
                                         ext4_lblk_t lblocks);
-extern int ext4_extent_tree_init(handle_t *, struct inode *);
 extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode,
                                                   int num,
                                                   struct ext4_ext_path *path);
@@ -2915,6 +2952,7 @@ extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                        __u64 start, __u64 len);
 extern int ext4_ext_precache(struct inode *inode);
 extern int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len);
+extern int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len);
 extern int ext4_swap_extents(handle_t *handle, struct inode *inode1,
                                struct inode *inode2, ext4_lblk_t lblk1,
                             ext4_lblk_t lblk2,  ext4_lblk_t count,