Merge tag 'media/v5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[sfrench/cifs-2.6.git] / fs / ext4 / ext4.h
index 82ffdacdc7fac30b63da30a39bac9349a1244717..1cb67859e0518b590af7e44299125bddfccb0c27 100644 (file)
@@ -399,10 +399,11 @@ struct flex_groups {
 #define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
 #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
 #define EXT4_PROJINHERIT_FL            0x20000000 /* Create with parents projid */
+#define EXT4_CASEFOLD_FL               0x40000000 /* Casefolded file */
 #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
 
-#define EXT4_FL_USER_VISIBLE           0x304BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE                0x204BC0FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE           0x704BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE                0x604BC0FF /* User modifiable flags */
 
 /* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */
 #define EXT4_FL_XFLAG_VISIBLE          (EXT4_SYNC_FL | \
@@ -417,10 +418,10 @@ struct flex_groups {
                           EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
                           EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
                           EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
-                          EXT4_PROJINHERIT_FL)
+                          EXT4_PROJINHERIT_FL | EXT4_CASEFOLD_FL)
 
 /* Flags that are appropriate for regular files (all but dir-specific ones). */
-#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))
+#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL | EXT4_CASEFOLD_FL))
 
 /* Flags that are appropriate for non-directories/regular files. */
 #define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)
@@ -1313,7 +1314,9 @@ struct ext4_super_block {
        __u8    s_first_error_time_hi;
        __u8    s_last_error_time_hi;
        __u8    s_pad[2];
-       __le32  s_reserved[96];         /* Padding to the end of the block */
+       __le16  s_encoding;             /* Filename charset encoding */
+       __le16  s_encoding_flags;       /* Filename charset encoding flags */
+       __le32  s_reserved[95];         /* Padding to the end of the block */
        __le32  s_checksum;             /* crc32c(superblock) */
 };
 
@@ -1338,6 +1341,16 @@ struct ext4_super_block {
 /* Number of quota types we support */
 #define EXT4_MAXQUOTAS 3
 
+#define EXT4_ENC_UTF8_12_1     1
+
+/*
+ * Flags for ext4_sb_info.s_encoding_flags.
+ */
+#define EXT4_ENC_STRICT_MODE_FL        (1 << 0)
+
+#define ext4_has_strict_mode(sbi) \
+       (sbi->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL)
+
 /*
  * fourth extended-fs super-block data in memory
  */
@@ -1387,6 +1400,10 @@ struct ext4_sb_info {
        struct kobject s_kobj;
        struct completion s_kobj_unregister;
        struct super_block *s_sb;
+#ifdef CONFIG_UNICODE
+       struct unicode_map *s_encoding;
+       __u16 s_encoding_flags;
+#endif
 
        /* Journaling */
        struct journal_s *s_journal;
@@ -1592,9 +1609,6 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 #define EXT4_SB(sb)    (sb)
 #endif
 
-/*
- * Returns true if the inode is inode is encrypted
- */
 #define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
 
 /*
@@ -1663,6 +1677,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR         0x4000 /* >2GB or 3-lvl htree */
 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA      0x8000 /* data in inode */
 #define EXT4_FEATURE_INCOMPAT_ENCRYPT          0x10000
+#define EXT4_FEATURE_INCOMPAT_CASEFOLD         0x20000
 
 extern void ext4_update_dynamic_rev(struct super_block *sb);
 
@@ -1756,6 +1771,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed,            CSUM_SEED)
 EXT4_FEATURE_INCOMPAT_FUNCS(largedir,          LARGEDIR)
 EXT4_FEATURE_INCOMPAT_FUNCS(inline_data,       INLINE_DATA)
 EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,           ENCRYPT)
+EXT4_FEATURE_INCOMPAT_FUNCS(casefold,          CASEFOLD)
 
 #define EXT2_FEATURE_COMPAT_SUPP       EXT4_FEATURE_COMPAT_EXT_ATTR
 #define EXT2_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1783,6 +1799,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,              ENCRYPT)
                                         EXT4_FEATURE_INCOMPAT_MMP | \
                                         EXT4_FEATURE_INCOMPAT_INLINE_DATA | \
                                         EXT4_FEATURE_INCOMPAT_ENCRYPT | \
+                                        EXT4_FEATURE_INCOMPAT_CASEFOLD | \
                                         EXT4_FEATURE_INCOMPAT_CSUM_SEED | \
                                         EXT4_FEATURE_INCOMPAT_LARGEDIR)
 #define EXT4_FEATURE_RO_COMPAT_SUPP    (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
@@ -2024,7 +2041,6 @@ static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc,
        BUG_ON(crypto_shash_descsize(sbi->s_chksum_driver)!=sizeof(desc.ctx));
 
        desc.shash.tfm = sbi->s_chksum_driver;
-       desc.shash.flags = 0;
        *(u32 *)desc.ctx = crc;
 
        BUG_ON(crypto_shash_update(&desc.shash, address, length));
@@ -2287,23 +2303,47 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
 ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
 
 #ifdef CONFIG_FS_ENCRYPTION
+static inline void ext4_fname_from_fscrypt_name(struct ext4_filename *dst,
+                                               const struct fscrypt_name *src)
+{
+       memset(dst, 0, sizeof(*dst));
+
+       dst->usr_fname = src->usr_fname;
+       dst->disk_name = src->disk_name;
+       dst->hinfo.hash = src->hash;
+       dst->hinfo.minor_hash = src->minor_hash;
+       dst->crypto_buf = src->crypto_buf;
+}
+
 static inline int ext4_fname_setup_filename(struct inode *dir,
-                       const struct qstr *iname,
-                       int lookup, struct ext4_filename *fname)
+                                           const struct qstr *iname,
+                                           int lookup,
+                                           struct ext4_filename *fname)
 {
        struct fscrypt_name name;
        int err;
 
-       memset(fname, 0, sizeof(struct ext4_filename));
-
        err = fscrypt_setup_filename(dir, iname, lookup, &name);
+       if (err)
+               return err;
+
+       ext4_fname_from_fscrypt_name(fname, &name);
+       return 0;
+}
 
-       fname->usr_fname = name.usr_fname;
-       fname->disk_name = name.disk_name;
-       fname->hinfo.hash = name.hash;
-       fname->hinfo.minor_hash = name.minor_hash;
-       fname->crypto_buf = name.crypto_buf;
-       return err;
+static inline int ext4_fname_prepare_lookup(struct inode *dir,
+                                           struct dentry *dentry,
+                                           struct ext4_filename *fname)
+{
+       struct fscrypt_name name;
+       int err;
+
+       err = fscrypt_prepare_lookup(dir, dentry, &name);
+       if (err)
+               return err;
+
+       ext4_fname_from_fscrypt_name(fname, &name);
+       return 0;
 }
 
 static inline void ext4_fname_free_filename(struct ext4_filename *fname)
@@ -2317,19 +2357,27 @@ static inline void ext4_fname_free_filename(struct ext4_filename *fname)
        fname->usr_fname = NULL;
        fname->disk_name.name = NULL;
 }
-#else
+#else /* !CONFIG_FS_ENCRYPTION */
 static inline int ext4_fname_setup_filename(struct inode *dir,
-               const struct qstr *iname,
-               int lookup, struct ext4_filename *fname)
+                                           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
+static inline int ext4_fname_prepare_lookup(struct inode *dir,
+                                           struct dentry *dentry,
+                                           struct ext4_filename *fname)
+{
+       return ext4_fname_setup_filename(dir, &dentry->d_name, 1, fname);
+}
+
+static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
+#endif /* !CONFIG_FS_ENCRYPTION */
 
 /* dir.c */
 extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *,
@@ -2377,8 +2425,8 @@ extern int ext4_check_all_de(struct inode *dir, struct buffer_head *bh,
 extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
 
 /* hash.c */
-extern int ext4fs_dirhash(const char *name, int len, struct
-                         dx_hash_info *hinfo);
+extern int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
+                         struct dx_hash_info *hinfo);
 
 /* ialloc.c */
 extern struct inode *__ext4_new_inode(handle_t *, struct inode *, umode_t,
@@ -2974,6 +3022,10 @@ static inline void ext4_unlock_group(struct super_block *sb,
 /* dir.c */
 extern const struct file_operations ext4_dir_operations;
 
+#ifdef CONFIG_UNICODE
+extern const struct dentry_operations ext4_dentry_ops;
+#endif
+
 /* file.c */
 extern const struct inode_operations ext4_file_inode_operations;
 extern const struct file_operations ext4_file_operations;
@@ -3066,6 +3118,10 @@ extern void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
 extern int ext4_handle_dirty_dirent_node(handle_t *handle,
                                         struct inode *inode,
                                         struct buffer_head *bh);
+extern int ext4_ci_compare(const struct inode *parent,
+                          const struct qstr *name,
+                          const struct qstr *entry);
+
 #define S_SHIFT 12
 static const unsigned char ext4_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = {
        [S_IFREG >> S_SHIFT]    = EXT4_FT_REG_FILE,