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 45fcdbf..2866d24 100644 (file)
 #define ext_debug(ino, fmt, ...)       no_printk(fmt, ##__VA_ARGS__)
 #endif
 
+#define ASSERT(assert)                                         \
+do {                                                                   \
+       if (unlikely(!(assert))) {                                      \
+               printk(KERN_EMERG                                       \
+                      "Assertion failure in %s() at %s:%d: '%s'\n",    \
+                      __func__, __FILE__, __LINE__, #assert);          \
+               BUG();                                                  \
+       }                                                               \
+} while (0)
+
 /* data type for block offset of block group */
 typedef int ext4_grpblk_t;
 
@@ -1028,9 +1038,6 @@ struct ext4_inode_info {
                                         * protected by sbi->s_fc_lock.
                                         */
 
-       /* Fast commit subtid when this inode was committed */
-       unsigned int i_fc_committed_subtid;
-
        /* Start of lblk range that needs to be committed in this fast commit */
        ext4_lblk_t i_fc_lblk_start;
 
@@ -1234,13 +1241,13 @@ struct ext4_inode_info {
                                                      blocks */
 #define EXT4_MOUNT2_HURD_COMPAT                0x00000004 /* Support HURD-castrated
                                                      file systems */
-#define EXT4_MOUNT2_DAX_NEVER          0x00000008 /* Do not allow Direct Access */
-#define EXT4_MOUNT2_DAX_INODE          0x00000010 /* For printing options only */
-
 #define EXT4_MOUNT2_EXPLICIT_JOURNAL_CHECKSUM  0x00000008 /* User explicitly
                                                specified journal checksum */
 
 #define EXT4_MOUNT2_JOURNAL_FAST_COMMIT        0x00000010 /* Journal fast commit */
+#define EXT4_MOUNT2_DAX_NEVER          0x00000020 /* Do not allow Direct Access */
+#define EXT4_MOUNT2_DAX_INODE          0x00000040 /* For printing options only */
+
 
 #define clear_opt(sb, opt)             EXT4_SB(sb)->s_mount_opt &= \
                                                ~EXT4_MOUNT_##opt
@@ -1422,16 +1429,6 @@ struct ext4_super_block {
 
 #ifdef __KERNEL__
 
-/*
- * run-time mount flags
- */
-#define EXT4_MF_MNTDIR_SAMPLED         0x0001
-#define EXT4_MF_FS_ABORTED             0x0002  /* Fatal error detected */
-#define EXT4_MF_FC_INELIGIBLE          0x0004  /* Fast commit ineligible */
-#define EXT4_MF_FC_COMMITTING          0x0008  /* File system underoing a fast
-                                                * commit.
-                                                */
-
 #ifdef CONFIG_FS_ENCRYPTION
 #define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_policy.policy != NULL)
 #else
@@ -1466,7 +1463,7 @@ struct ext4_sb_info {
        struct buffer_head * __rcu *s_group_desc;
        unsigned int s_mount_opt;
        unsigned int s_mount_opt2;
-       unsigned int s_mount_flags;
+       unsigned long s_mount_flags;
        unsigned int s_def_mount_opt;
        ext4_fsblk_t s_sb_block;
        atomic64_t s_resv_clusters;
@@ -1632,6 +1629,27 @@ struct ext4_sb_info {
        errseq_t s_bdev_wb_err;
        spinlock_t s_bdev_wb_lock;
 
+       /* Information about errors that happened during this mount */
+       spinlock_t s_error_lock;
+       int s_add_error_count;
+       int s_first_error_code;
+       __u32 s_first_error_line;
+       __u32 s_first_error_ino;
+       __u64 s_first_error_block;
+       const char *s_first_error_func;
+       time64_t s_first_error_time;
+       int s_last_error_code;
+       __u32 s_last_error_line;
+       __u32 s_last_error_ino;
+       __u64 s_last_error_block;
+       const char *s_last_error_func;
+       time64_t s_last_error_time;
+       /*
+        * If we are in a context where we cannot update error information in
+        * the on-disk superblock, we queue this work to do it.
+        */
+       struct work_struct s_error_work;
+
        /* Ext4 fast commit stuff */
        atomic_t s_fc_subtid;
        atomic_t s_fc_ineligible_updates;
@@ -1694,6 +1712,34 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
        _v;                                                                \
 })
 
+/*
+ * run-time mount flags
+ */
+enum {
+       EXT4_MF_MNTDIR_SAMPLED,
+       EXT4_MF_FS_ABORTED,     /* Fatal error detected */
+       EXT4_MF_FC_INELIGIBLE,  /* Fast commit ineligible */
+       EXT4_MF_FC_COMMITTING   /* File system underoing a fast
+                                * commit.
+                                */
+};
+
+static inline void ext4_set_mount_flag(struct super_block *sb, int bit)
+{
+       set_bit(bit, &EXT4_SB(sb)->s_mount_flags);
+}
+
+static inline void ext4_clear_mount_flag(struct super_block *sb, int bit)
+{
+       clear_bit(bit, &EXT4_SB(sb)->s_mount_flags);
+}
+
+static inline int ext4_test_mount_flag(struct super_block *sb, int bit)
+{
+       return test_bit(bit, &EXT4_SB(sb)->s_mount_flags);
+}
+
+
 /*
  * Simulate_fail codes
  */
@@ -1843,7 +1889,6 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
 #define EXT4_GOOD_OLD_REV      0       /* The good old (original) format */
 #define EXT4_DYNAMIC_REV       1       /* V2 format w/ dynamic inode sizes */
 
-#define EXT4_CURRENT_REV       EXT4_GOOD_OLD_REV
 #define EXT4_MAX_SUPP_REV      EXT4_DYNAMIC_REV
 
 #define EXT4_GOOD_OLD_INODE_SIZE 128
@@ -1863,6 +1908,13 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
 #define EXT4_FEATURE_COMPAT_RESIZE_INODE       0x0010
 #define EXT4_FEATURE_COMPAT_DIR_INDEX          0x0020
 #define EXT4_FEATURE_COMPAT_SPARSE_SUPER2      0x0200
+/*
+ * The reason why "FAST_COMMIT" is a compat feature is that, FS becomes
+ * incompatible only if fast commit blocks are present in the FS. Since we
+ * clear the journal (and thus the fast commit blocks), we don't mark FS as
+ * incompatible. We also have a JBD2 incompat feature, which gets set when
+ * there are fast commit blocks present in the journal.
+ */
 #define EXT4_FEATURE_COMPAT_FAST_COMMIT                0x0400
 #define EXT4_FEATURE_COMPAT_STABLE_INODES      0x0800
 
@@ -2673,7 +2725,8 @@ void ext4_insert_dentry(struct inode *inode,
                        struct ext4_filename *fname);
 static inline void ext4_update_dx_flag(struct inode *inode)
 {
-       if (!ext4_has_feature_dir_index(inode->i_sb)) {
+       if (!ext4_has_feature_dir_index(inode->i_sb) &&
+           ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) {
                /* ext4_iget() should have caught this... */
                WARN_ON_ONCE(ext4_has_feature_metadata_csum(inode->i_sb));
                ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
@@ -2731,12 +2784,16 @@ extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
 int ext4_fc_info_show(struct seq_file *seq, void *v);
 void ext4_fc_init(struct super_block *sb, journal_t *journal);
 void ext4_fc_init_inode(struct inode *inode);
-void ext4_fc_track_range(struct inode *inode, ext4_lblk_t start,
+void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t start,
                         ext4_lblk_t end);
-void ext4_fc_track_unlink(struct inode *inode, struct dentry *dentry);
-void ext4_fc_track_link(struct inode *inode, struct dentry *dentry);
-void ext4_fc_track_create(struct inode *inode, struct dentry *dentry);
-void ext4_fc_track_inode(struct inode *inode);
+void __ext4_fc_track_unlink(handle_t *handle, struct inode *inode,
+       struct dentry *dentry);
+void __ext4_fc_track_link(handle_t *handle, struct inode *inode,
+       struct dentry *dentry);
+void ext4_fc_track_unlink(handle_t *handle, struct dentry *dentry);
+void ext4_fc_track_link(handle_t *handle, struct dentry *dentry);
+void ext4_fc_track_create(handle_t *handle, struct dentry *dentry);
+void ext4_fc_track_inode(handle_t *handle, struct inode *inode);
 void ext4_fc_mark_ineligible(struct super_block *sb, int reason);
 void ext4_fc_start_ineligible(struct super_block *sb, int reason);
 void ext4_fc_stop_ineligible(struct super_block *sb);
@@ -2925,9 +2982,9 @@ extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb,
                                             ext4_group_t block_group,
                                             unsigned int flags);
 
-extern __printf(6, 7)
-void __ext4_error(struct super_block *, const char *, unsigned int, int, __u64,
-                 const char *, ...);
+extern __printf(7, 8)
+void __ext4_error(struct super_block *, const char *, unsigned int, bool,
+                 int, __u64, const char *, ...);
 extern __printf(6, 7)
 void __ext4_error_inode(struct inode *, const char *, unsigned int,
                        ext4_fsblk_t, int, const char *, ...);
@@ -2936,9 +2993,6 @@ void __ext4_error_file(struct file *, const char *, unsigned int, ext4_fsblk_t,
                     const char *, ...);
 extern void __ext4_std_error(struct super_block *, const char *,
                             unsigned int, int);
-extern __printf(5, 6)
-void __ext4_abort(struct super_block *, const char *, unsigned int, int,
-                 const char *, ...);
 extern __printf(4, 5)
 void __ext4_warning(struct super_block *, const char *, unsigned int,
                    const char *, ...);
@@ -2968,6 +3022,9 @@ void __ext4_grp_locked_error(const char *, unsigned int,
 #define EXT4_ERROR_FILE(file, block, fmt, a...)                                \
        ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
 
+#define ext4_abort(sb, err, fmt, a...)                                 \
+       __ext4_error((sb), __func__, __LINE__, true, (err), 0, (fmt), ## a)
+
 #ifdef CONFIG_PRINTK
 
 #define ext4_error_inode(inode, func, line, block, fmt, ...)           \
@@ -2978,11 +3035,11 @@ void __ext4_grp_locked_error(const char *, unsigned int,
 #define ext4_error_file(file, func, line, block, fmt, ...)             \
        __ext4_error_file(file, func, line, block, fmt, ##__VA_ARGS__)
 #define ext4_error(sb, fmt, ...)                                       \
-       __ext4_error((sb), __func__, __LINE__, 0, 0, (fmt), ##__VA_ARGS__)
+       __ext4_error((sb), __func__, __LINE__, false, 0, 0, (fmt),      \
+               ##__VA_ARGS__)
 #define ext4_error_err(sb, err, fmt, ...)                              \
-       __ext4_error((sb), __func__, __LINE__, (err), 0, (fmt), ##__VA_ARGS__)
-#define ext4_abort(sb, err, fmt, ...)                                  \
-       __ext4_abort((sb), __func__, __LINE__, (err), (fmt), ##__VA_ARGS__)
+       __ext4_error((sb), __func__, __LINE__, false, (err), 0, (fmt),  \
+               ##__VA_ARGS__)
 #define ext4_warning(sb, fmt, ...)                                     \
        __ext4_warning(sb, __func__, __LINE__, fmt, ##__VA_ARGS__)
 #define ext4_warning_inode(inode, fmt, ...)                            \
@@ -3015,17 +3072,12 @@ do {                                                                    \
 #define ext4_error(sb, fmt, ...)                                       \
 do {                                                                   \
        no_printk(fmt, ##__VA_ARGS__);                                  \
-       __ext4_error(sb, "", 0, 0, 0, " ");                             \
+       __ext4_error(sb, "", 0, false, 0, 0, " ");                      \
 } while (0)
 #define ext4_error_err(sb, err, fmt, ...)                              \
 do {                                                                   \
        no_printk(fmt, ##__VA_ARGS__);                                  \
-       __ext4_error(sb, "", 0, err, 0, " ");                           \
-} while (0)
-#define ext4_abort(sb, err, fmt, ...)                                  \
-do {                                                                   \
-       no_printk(fmt, ##__VA_ARGS__);                                  \
-       __ext4_abort(sb, "", 0, err, " ");                              \
+       __ext4_error(sb, "", 0, false, err, 0, " ");                    \
 } while (0)
 #define ext4_warning(sb, fmt, ...)                                     \
 do {                                                                   \
@@ -3334,6 +3386,21 @@ static inline void ext4_unlock_group(struct super_block *sb,
        spin_unlock(ext4_group_lock_ptr(sb, group));
 }
 
+#ifdef CONFIG_QUOTA
+static inline bool ext4_quota_capable(struct super_block *sb)
+{
+       return (test_opt(sb, QUOTA) || ext4_has_feature_quota(sb));
+}
+
+static inline bool ext4_is_quota_journalled(struct super_block *sb)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       return (ext4_has_feature_quota(sb) ||
+               sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]);
+}
+#endif
+
 /*
  * Block validity checking
  */
@@ -3354,10 +3421,6 @@ 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;
@@ -3452,7 +3515,7 @@ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
 extern int ext4_ci_compare(const struct inode *parent,
                           const struct qstr *fname,
                           const struct qstr *entry, bool quick);
-extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
+extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
                         struct inode *inode);
 extern int __ext4_link(struct inode *dir, struct inode *inode,
                       struct dentry *dentry);
@@ -3586,7 +3649,6 @@ extern void ext4_io_submit(struct ext4_io_submit *io);
 extern int ext4_bio_write_page(struct ext4_io_submit *io,
                               struct page *page,
                               int len,
-                              struct writeback_control *wbc,
                               bool keep_towrite);
 extern struct ext4_io_end_vec *ext4_alloc_io_end_vec(ext4_io_end_t *io_end);
 extern struct ext4_io_end_vec *ext4_last_io_end_vec(ext4_io_end_t *io_end);