]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/btrfs/ctree.h
Btrfs: fix delalloc accounting leak caused by u32 overflow
[mirror_ubuntu-bionic-kernel.git] / fs / btrfs / ctree.h
index 7343bf7f2b358153e332ef0d1767cbeb9f0b8612..43a8c42cdf072b21da896f8ddfcddd95b9d06ae7 100644 (file)
@@ -539,6 +539,14 @@ struct btrfs_io_ctl {
        unsigned check_crcs:1;
 };
 
+/*
+ * Tree to record all locked full stripes of a RAID5/6 block group
+ */
+struct btrfs_full_stripe_locks_tree {
+       struct rb_root root;
+       struct mutex lock;
+};
+
 struct btrfs_block_group_cache {
        struct btrfs_key key;
        struct btrfs_block_group_item item;
@@ -649,6 +657,9 @@ struct btrfs_block_group_cache {
         * Protected by free_space_lock.
         */
        int needs_free_space;
+
+       /* Record locked full stripes for RAID5/6 block group */
+       struct btrfs_full_stripe_locks_tree full_stripe_locks_root;
 };
 
 /* delayed seq elem */
@@ -659,6 +670,8 @@ struct seq_list {
 
 #define SEQ_LIST_INIT(name)    { .list = LIST_HEAD_INIT((name).list), .seq = 0 }
 
+#define SEQ_LAST       ((u64)-1)
+
 enum btrfs_orphan_cleanup_state {
        ORPHAN_CLEANUP_STARTED  = 1,
        ORPHAN_CLEANUP_DONE     = 2,
@@ -703,6 +716,11 @@ struct btrfs_delayed_root;
 #define BTRFS_FS_BTREE_ERR                     11
 #define BTRFS_FS_LOG1_ERR                      12
 #define BTRFS_FS_LOG2_ERR                      13
+/*
+ * Indicate that a whole-filesystem exclusive operation is running
+ * (device replace, resize, device add/delete, balance)
+ */
+#define BTRFS_FS_EXCL_OP                       14
 
 struct btrfs_fs_info {
        u8 fsid[BTRFS_FSID_SIZE];
@@ -1068,8 +1086,6 @@ struct btrfs_fs_info {
        /* device replace state */
        struct btrfs_dev_replace dev_replace;
 
-       atomic_t mutually_exclusive_operation_running;
-
        struct percpu_counter bio_counter;
        wait_queue_head_t replace_wait;
 
@@ -2548,7 +2564,7 @@ u64 btrfs_csum_bytes_to_leaves(struct btrfs_fs_info *fs_info, u64 csum_bytes);
 static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_fs_info *fs_info,
                                                 unsigned num_items)
 {
-       return fs_info->nodesize * BTRFS_MAX_LEVEL * 2 * num_items;
+       return (u64)fs_info->nodesize * BTRFS_MAX_LEVEL * 2 * num_items;
 }
 
 /*
@@ -2558,7 +2574,7 @@ static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_fs_info *fs_info,
 static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_fs_info *fs_info,
                                                 unsigned num_items)
 {
-       return fs_info->nodesize * BTRFS_MAX_LEVEL * num_items;
+       return (u64)fs_info->nodesize * BTRFS_MAX_LEVEL * num_items;
 }
 
 int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans,
@@ -3648,6 +3664,12 @@ int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info,
                           struct btrfs_device *dev);
 int btrfs_scrub_progress(struct btrfs_fs_info *fs_info, u64 devid,
                         struct btrfs_scrub_progress *progress);
+static inline void btrfs_init_full_stripe_locks_tree(
+                       struct btrfs_full_stripe_locks_tree *locks_root)
+{
+       locks_root->root = RB_ROOT;
+       mutex_init(&locks_root->lock);
+}
 
 /* dev-replace.c */
 void btrfs_bio_counter_inc_blocked(struct btrfs_fs_info *fs_info);