]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/btrfs/ctree.h
Btrfs: fix race between using extent maps and merging them
[linux.git] / fs / btrfs / ctree.h
index 0626e5562993494f79d5239837cf0246fa3274b9..36df977b64d91d1f3bbdd90edcb9da91751e87e4 100644 (file)
@@ -101,6 +101,14 @@ struct btrfs_ref;
 
 #define BTRFS_MAX_EXTENT_SIZE SZ_128M
 
+/*
+ * Deltas are an effective way to populate global statistics.  Give macro names
+ * to make it clear what we're doing.  An example is discard_extents in
+ * btrfs_free_space_ctl.
+ */
+#define BTRFS_STAT_NR_ENTRIES  2
+#define BTRFS_STAT_CURR                0
+#define BTRFS_STAT_PREV                1
 
 /*
  * Count how many BTRFS_MAX_EXTENT_SIZE cover the @size
@@ -448,7 +456,7 @@ struct btrfs_full_stripe_locks_tree {
  * afterwards represent monotonically decreasing discard filter sizes to
  * prioritize what should be discarded next.
  */
-#define BTRFS_NR_DISCARD_LISTS         2
+#define BTRFS_NR_DISCARD_LISTS         3
 #define BTRFS_DISCARD_INDEX_UNUSED     0
 #define BTRFS_DISCARD_INDEX_START      1
 
@@ -458,6 +466,16 @@ struct btrfs_discard_ctl {
        spinlock_t lock;
        struct btrfs_block_group *block_group;
        struct list_head discard_list[BTRFS_NR_DISCARD_LISTS];
+       u64 prev_discard;
+       atomic_t discardable_extents;
+       atomic64_t discardable_bytes;
+       u64 max_discard_size;
+       unsigned long delay;
+       u32 iops_limit;
+       u32 kbps_limit;
+       u64 discard_extent_bytes;
+       u64 discard_bitmap_bytes;
+       atomic64_t discard_bytes_saved;
 };
 
 /* delayed seq elem */
@@ -696,14 +714,12 @@ struct btrfs_fs_info {
        atomic_t nr_delayed_iputs;
        wait_queue_head_t delayed_iputs_wait;
 
-       /* this protects tree_mod_seq_list */
-       spinlock_t tree_mod_seq_lock;
        atomic64_t tree_mod_seq;
-       struct list_head tree_mod_seq_list;
 
-       /* this protects tree_mod_log */
+       /* this protects tree_mod_log and tree_mod_seq_list */
        rwlock_t tree_mod_log_lock;
        struct rb_root tree_mod_log;
+       struct list_head tree_mod_seq_list;
 
        atomic_t async_delalloc_pages;
 
@@ -930,6 +946,7 @@ struct btrfs_fs_info {
 
 #ifdef CONFIG_BTRFS_DEBUG
        struct kobject *debug_kobj;
+       struct kobject *discard_debug_kobj;
 #endif
 };
 
@@ -3138,17 +3155,21 @@ do {                                                            \
        rcu_read_unlock();                                      \
 } while (0)
 
-__cold
-static inline void assfail(const char *expr, const char *file, int line)
+#ifdef CONFIG_BTRFS_ASSERT
+__cold __noreturn
+static inline void assertfail(const char *expr, const char *file, int line)
 {
-       if (IS_ENABLED(CONFIG_BTRFS_ASSERT)) {
-               pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
-               BUG();
-       }
+       pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
+       BUG();
 }
 
-#define ASSERT(expr)   \
-       (likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
+#define ASSERT(expr)                                           \
+       (likely(expr) ? (void)0 : assertfail(#expr, __FILE__, __LINE__))
+
+#else
+static inline void assertfail(const char *expr, const char* file, int line) { }
+#define ASSERT(expr)   (void)(expr)
+#endif
 
 /*
  * Use that for functions that are conditionally exported for sanity tests but