Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
[linux-2.6-microblaze.git] / fs / ext4 / ext4.h
index 7ebaf66..90ff5ac 100644 (file)
@@ -1034,7 +1034,14 @@ struct ext4_inode_info {
         */
        struct rw_semaphore xattr_sem;
 
         */
        struct rw_semaphore xattr_sem;
 
-       struct list_head i_orphan;      /* unlinked but open inodes */
+       /*
+        * Inodes with EXT4_STATE_ORPHAN_FILE use i_orphan_idx. Otherwise
+        * i_orphan is used.
+        */
+       union {
+               struct list_head i_orphan;      /* unlinked but open inodes */
+               unsigned int i_orphan_idx;      /* Index in orphan file */
+       };
 
        /* Fast commit related info */
 
 
        /* Fast commit related info */
 
@@ -1419,7 +1426,8 @@ struct ext4_super_block {
        __u8    s_last_error_errcode;
        __le16  s_encoding;             /* Filename charset encoding */
        __le16  s_encoding_flags;       /* Filename charset encoding flags */
        __u8    s_last_error_errcode;
        __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_orphan_file_inum;     /* Inode for tracking orphan inodes */
+       __le32  s_reserved[94];         /* Padding to the end of the block */
        __le32  s_checksum;             /* crc32c(superblock) */
 };
 
        __le32  s_checksum;             /* crc32c(superblock) */
 };
 
@@ -1438,6 +1446,54 @@ struct ext4_super_block {
 
 #define EXT4_ENC_UTF8_12_1     1
 
 
 #define EXT4_ENC_UTF8_12_1     1
 
+/* Types of ext4 journal triggers */
+enum ext4_journal_trigger_type {
+       EXT4_JTR_ORPHAN_FILE,
+       EXT4_JTR_NONE   /* This must be the last entry for indexing to work! */
+};
+
+#define EXT4_JOURNAL_TRIGGER_COUNT EXT4_JTR_NONE
+
+struct ext4_journal_trigger {
+       struct jbd2_buffer_trigger_type tr_triggers;
+       struct super_block *sb;
+};
+
+static inline struct ext4_journal_trigger *EXT4_TRIGGER(
+                               struct jbd2_buffer_trigger_type *trigger)
+{
+       return container_of(trigger, struct ext4_journal_trigger, tr_triggers);
+}
+
+#define EXT4_ORPHAN_BLOCK_MAGIC 0x0b10ca04
+
+/* Structure at the tail of orphan block */
+struct ext4_orphan_block_tail {
+       __le32 ob_magic;
+       __le32 ob_checksum;
+};
+
+static inline int ext4_inodes_per_orphan_block(struct super_block *sb)
+{
+       return (sb->s_blocksize - sizeof(struct ext4_orphan_block_tail)) /
+                       sizeof(u32);
+}
+
+struct ext4_orphan_block {
+       atomic_t ob_free_entries;       /* Number of free orphan entries in block */
+       struct buffer_head *ob_bh;      /* Buffer for orphan block */
+};
+
+/*
+ * Info about orphan file.
+ */
+struct ext4_orphan_info {
+       int of_blocks;                  /* Number of orphan blocks in a file */
+       __u32 of_csum_seed;             /* Checksum seed for orphan file */
+       struct ext4_orphan_block *of_binfo;     /* Array with info about orphan
+                                                * file blocks */
+};
+
 /*
  * fourth extended-fs super-block data in memory
  */
 /*
  * fourth extended-fs super-block data in memory
  */
@@ -1492,9 +1548,11 @@ struct ext4_sb_info {
 
        /* Journaling */
        struct journal_s *s_journal;
 
        /* Journaling */
        struct journal_s *s_journal;
-       struct list_head s_orphan;
-       struct mutex s_orphan_lock;
        unsigned long s_ext4_flags;             /* Ext4 superblock flags */
        unsigned long s_ext4_flags;             /* Ext4 superblock flags */
+       struct mutex s_orphan_lock;     /* Protects on disk list changes */
+       struct list_head s_orphan;      /* List of orphaned inodes in on disk
+                                          list */
+       struct ext4_orphan_info s_orphan_info;
        unsigned long s_commit_interval;
        u32 s_max_batch_time;
        u32 s_min_batch_time;
        unsigned long s_commit_interval;
        u32 s_max_batch_time;
        u32 s_min_batch_time;
@@ -1527,6 +1585,9 @@ struct ext4_sb_info {
        unsigned int s_mb_free_pending;
        struct list_head s_freed_data_list;     /* List of blocks to be freed
                                                   after commit completed */
        unsigned int s_mb_free_pending;
        struct list_head s_freed_data_list;     /* List of blocks to be freed
                                                   after commit completed */
+       struct list_head s_discard_list;
+       struct work_struct s_discard_work;
+       atomic_t s_retry_alloc_pending;
        struct rb_root s_mb_avg_fragment_size_root;
        rwlock_t s_mb_rb_lock;
        struct list_head *s_mb_largest_free_orders;
        struct rb_root s_mb_avg_fragment_size_root;
        rwlock_t s_mb_rb_lock;
        struct list_head *s_mb_largest_free_orders;
@@ -1616,6 +1677,9 @@ struct ext4_sb_info {
        struct mb_cache *s_ea_inode_cache;
        spinlock_t s_es_lock ____cacheline_aligned_in_smp;
 
        struct mb_cache *s_ea_inode_cache;
        spinlock_t s_es_lock ____cacheline_aligned_in_smp;
 
+       /* Journal triggers for checksum computation */
+       struct ext4_journal_trigger s_journal_triggers[EXT4_JOURNAL_TRIGGER_COUNT];
+
        /* Ratelimit ext4 messages. */
        struct ratelimit_state s_err_ratelimit_state;
        struct ratelimit_state s_warning_ratelimit_state;
        /* Ratelimit ext4 messages. */
        struct ratelimit_state s_err_ratelimit_state;
        struct ratelimit_state s_warning_ratelimit_state;
@@ -1826,6 +1890,7 @@ enum {
        EXT4_STATE_LUSTRE_EA_INODE,     /* Lustre-style ea_inode */
        EXT4_STATE_VERITY_IN_PROGRESS,  /* building fs-verity Merkle tree */
        EXT4_STATE_FC_COMMITTING,       /* Fast commit ongoing */
        EXT4_STATE_LUSTRE_EA_INODE,     /* Lustre-style ea_inode */
        EXT4_STATE_VERITY_IN_PROGRESS,  /* building fs-verity Merkle tree */
        EXT4_STATE_FC_COMMITTING,       /* Fast commit ongoing */
+       EXT4_STATE_ORPHAN_FILE,         /* Inode orphaned in orphan file */
 };
 
 #define EXT4_INODE_BIT_FNS(name, field, offset)                                \
 };
 
 #define EXT4_INODE_BIT_FNS(name, field, offset)                                \
@@ -1927,6 +1992,7 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
  */
 #define EXT4_FEATURE_COMPAT_FAST_COMMIT                0x0400
 #define EXT4_FEATURE_COMPAT_STABLE_INODES      0x0800
  */
 #define EXT4_FEATURE_COMPAT_FAST_COMMIT                0x0400
 #define EXT4_FEATURE_COMPAT_STABLE_INODES      0x0800
+#define EXT4_FEATURE_COMPAT_ORPHAN_FILE                0x1000  /* Orphan file exists */
 
 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
 
 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
@@ -1947,6 +2013,8 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
 #define EXT4_FEATURE_RO_COMPAT_READONLY                0x1000
 #define EXT4_FEATURE_RO_COMPAT_PROJECT         0x2000
 #define EXT4_FEATURE_RO_COMPAT_VERITY          0x8000
 #define EXT4_FEATURE_RO_COMPAT_READONLY                0x1000
 #define EXT4_FEATURE_RO_COMPAT_PROJECT         0x2000
 #define EXT4_FEATURE_RO_COMPAT_VERITY          0x8000
+#define EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT  0x10000 /* Orphan file may be
+                                                          non-empty */
 
 #define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
 #define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
 
 #define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
 #define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
@@ -2030,6 +2098,7 @@ EXT4_FEATURE_COMPAT_FUNCS(dir_index,              DIR_INDEX)
 EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,       SPARSE_SUPER2)
 EXT4_FEATURE_COMPAT_FUNCS(fast_commit,         FAST_COMMIT)
 EXT4_FEATURE_COMPAT_FUNCS(stable_inodes,       STABLE_INODES)
 EXT4_FEATURE_COMPAT_FUNCS(sparse_super2,       SPARSE_SUPER2)
 EXT4_FEATURE_COMPAT_FUNCS(fast_commit,         FAST_COMMIT)
 EXT4_FEATURE_COMPAT_FUNCS(stable_inodes,       STABLE_INODES)
+EXT4_FEATURE_COMPAT_FUNCS(orphan_file,         ORPHAN_FILE)
 
 EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,     SPARSE_SUPER)
 EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,       LARGE_FILE)
 
 EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super,     SPARSE_SUPER)
 EXT4_FEATURE_RO_COMPAT_FUNCS(large_file,       LARGE_FILE)
@@ -2044,6 +2113,7 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum,       METADATA_CSUM)
 EXT4_FEATURE_RO_COMPAT_FUNCS(readonly,         READONLY)
 EXT4_FEATURE_RO_COMPAT_FUNCS(project,          PROJECT)
 EXT4_FEATURE_RO_COMPAT_FUNCS(verity,           VERITY)
 EXT4_FEATURE_RO_COMPAT_FUNCS(readonly,         READONLY)
 EXT4_FEATURE_RO_COMPAT_FUNCS(project,          PROJECT)
 EXT4_FEATURE_RO_COMPAT_FUNCS(verity,           VERITY)
+EXT4_FEATURE_RO_COMPAT_FUNCS(orphan_present,   ORPHAN_PRESENT)
 
 EXT4_FEATURE_INCOMPAT_FUNCS(compression,       COMPRESSION)
 EXT4_FEATURE_INCOMPAT_FUNCS(filetype,          FILETYPE)
 
 EXT4_FEATURE_INCOMPAT_FUNCS(compression,       COMPRESSION)
 EXT4_FEATURE_INCOMPAT_FUNCS(filetype,          FILETYPE)
@@ -2077,7 +2147,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(casefold,             CASEFOLD)
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
 
                                         EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
 
-#define EXT4_FEATURE_COMPAT_SUPP       EXT4_FEATURE_COMPAT_EXT_ATTR
+#define EXT4_FEATURE_COMPAT_SUPP       (EXT4_FEATURE_COMPAT_EXT_ATTR| \
+                                        EXT4_FEATURE_COMPAT_ORPHAN_FILE)
 #define EXT4_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT4_FEATURE_INCOMPAT_RECOVER| \
                                         EXT4_FEATURE_INCOMPAT_META_BG| \
 #define EXT4_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
                                         EXT4_FEATURE_INCOMPAT_RECOVER| \
                                         EXT4_FEATURE_INCOMPAT_META_BG| \
@@ -2102,7 +2173,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(casefold,             CASEFOLD)
                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
                                         EXT4_FEATURE_RO_COMPAT_QUOTA |\
                                         EXT4_FEATURE_RO_COMPAT_PROJECT |\
                                         EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
                                         EXT4_FEATURE_RO_COMPAT_QUOTA |\
                                         EXT4_FEATURE_RO_COMPAT_PROJECT |\
-                                        EXT4_FEATURE_RO_COMPAT_VERITY)
+                                        EXT4_FEATURE_RO_COMPAT_VERITY |\
+                                        EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT)
 
 #define EXTN_FEATURE_FUNCS(ver) \
 static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
 
 #define EXTN_FEATURE_FUNCS(ver) \
 static inline bool ext4_has_unknown_ext##ver##_compat_features(struct super_block *sb) \
@@ -2138,6 +2210,8 @@ static inline bool ext4_has_incompat_features(struct super_block *sb)
        return (EXT4_SB(sb)->s_es->s_feature_incompat != 0);
 }
 
        return (EXT4_SB(sb)->s_es->s_feature_incompat != 0);
 }
 
+extern int ext4_feature_set_ok(struct super_block *sb, int readonly);
+
 /*
  * Superblock flags
  */
 /*
  * Superblock flags
  */
@@ -2150,7 +2224,6 @@ static inline int ext4_forced_shutdown(struct ext4_sb_info *sbi)
        return test_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
 }
 
        return test_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
 }
 
-
 /*
  * Default values for user and/or group using reserved blocks
  */
 /*
  * Default values for user and/or group using reserved blocks
  */
@@ -2911,13 +2984,14 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
 int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
                           struct buffer_head *bh, int create);
 int ext4_walk_page_buffers(handle_t *handle,
 int ext4_da_get_block_prep(struct inode *inode, sector_t iblock,
                           struct buffer_head *bh, int create);
 int ext4_walk_page_buffers(handle_t *handle,
+                          struct inode *inode,
                           struct buffer_head *head,
                           unsigned from,
                           unsigned to,
                           int *partial,
                           struct buffer_head *head,
                           unsigned from,
                           unsigned to,
                           int *partial,
-                          int (*fn)(handle_t *handle,
+                          int (*fn)(handle_t *handle, struct inode *inode,
                                     struct buffer_head *bh));
                                     struct buffer_head *bh));
-int do_journal_get_write_access(handle_t *handle,
+int do_journal_get_write_access(handle_t *handle, struct inode *inode,
                                struct buffer_head *bh);
 #define FALL_BACK_TO_NONDELALLOC 1
 #define CONVERT_INLINE_DATA     2
                                struct buffer_head *bh);
 #define FALL_BACK_TO_NONDELALLOC 1
 #define CONVERT_INLINE_DATA     2
@@ -2996,8 +3070,6 @@ extern int ext4_init_new_dir(handle_t *handle, struct inode *dir,
                             struct inode *inode);
 extern int ext4_dirblock_csum_verify(struct inode *inode,
                                     struct buffer_head *bh);
                             struct inode *inode);
 extern int ext4_dirblock_csum_verify(struct inode *inode,
                                     struct buffer_head *bh);
-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 ext4_search_dir(struct buffer_head *bh,
 extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
                                __u32 start_minor_hash, __u32 *next_hash);
 extern int ext4_search_dir(struct buffer_head *bh,
@@ -3466,6 +3538,7 @@ static inline bool ext4_is_quota_journalled(struct super_block *sb)
        return (ext4_has_feature_quota(sb) ||
                sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]);
 }
        return (ext4_has_feature_quota(sb) ||
                sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]);
 }
+int ext4_enable_quotas(struct super_block *sb);
 #endif
 
 /*
 #endif
 
 /*
@@ -3727,6 +3800,19 @@ extern void ext4_stop_mmpd(struct ext4_sb_info *sbi);
 /* verity.c */
 extern const struct fsverity_operations ext4_verityops;
 
 /* verity.c */
 extern const struct fsverity_operations ext4_verityops;
 
+/* orphan.c */
+extern int ext4_orphan_add(handle_t *, struct inode *);
+extern int ext4_orphan_del(handle_t *, struct inode *);
+extern void ext4_orphan_cleanup(struct super_block *sb,
+                               struct ext4_super_block *es);
+extern void ext4_release_orphan_info(struct super_block *sb);
+extern int ext4_init_orphan_info(struct super_block *sb);
+extern int ext4_orphan_file_empty(struct super_block *sb);
+extern void ext4_orphan_file_block_trigger(
+                               struct jbd2_buffer_trigger_type *triggers,
+                               struct buffer_head *bh,
+                               void *data, size_t size);
+
 /*
  * Add new method to test whether block and inode bitmaps are properly
  * initialized. With uninit_bg reading the block from disk is not enough
 /*
  * Add new method to test whether block and inode bitmaps are properly
  * initialized. With uninit_bg reading the block from disk is not enough