btrfs: Document consistency of transaction->io_bgs list
authorNikolay Borisov <nborisov@suse.com>
Thu, 8 Feb 2018 16:25:18 +0000 (18:25 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 26 Mar 2018 13:09:34 +0000 (15:09 +0200)
The reason why io_bgs can be modified without holding any lock is
non-obvious. Document it and reference that documentation from the
respective call sites.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/transaction.h

index dcfdb1f17f1b02b8d9566f045035e9a84daeb16d..08e33f316a86c5ab95b441da24eea9223c09a72b 100644 (file)
@@ -4346,6 +4346,10 @@ void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *cur_trans,
        }
        spin_unlock(&cur_trans->dirty_bgs_lock);
 
+       /*
+        * Refer to the definition of io_bgs member for details why it's safe
+        * to use it without any locking
+        */
        while (!list_empty(&cur_trans->io_bgs)) {
                cache = list_first_entry(&cur_trans->io_bgs,
                                         struct btrfs_block_group_cache,
index 7b4d6789cc66ec4a878cc90c53fe11cdc6045d2c..9a677860f64d2d623f22767361fe83d84f6924db 100644 (file)
@@ -3741,8 +3741,9 @@ again:
                                should_put = 0;
 
                                /*
-                                * the cache_write_mutex is protecting
-                                * the io_list
+                                * The cache_write_mutex is protecting the
+                                * io_list, also refer to the definition of
+                                * btrfs_transaction::io_bgs for more details
                                 */
                                list_add_tail(&cache->io_list, io);
                        } else {
@@ -3934,6 +3935,10 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
        }
        spin_unlock(&cur_trans->dirty_bgs_lock);
 
+       /*
+        * Refer to the definition of io_bgs member for details why it's safe
+        * to use it without any locking
+        */
        while (!list_empty(io)) {
                cache = list_first_entry(io, struct btrfs_block_group_cache,
                                         io_list);
index 817fd7c9836b18091160e412740ebd53b82f9ce6..2762c8d6191c55c45ea35271d616f1863f3d2e96 100644 (file)
@@ -69,6 +69,22 @@ struct btrfs_transaction {
        struct list_head pending_chunks;
        struct list_head switch_commits;
        struct list_head dirty_bgs;
+
+       /*
+        * There is no explicit lock which protects io_bgs, rather its
+        * consistency is implied by the fact that all the sites which modify
+        * it do so under some form of transaction critical section, namely:
+        *
+        * - btrfs_start_dirty_block_groups - This function can only ever be
+        *   run by one of the transaction committers. Refer to
+        *   BTRFS_TRANS_DIRTY_BG_RUN usage in btrfs_commit_transaction
+        *
+        * - btrfs_write_dirty_blockgroups - this is called by
+        *   commit_cowonly_roots from transaction critical section
+        *   (TRANS_STATE_COMMIT_DOING)
+        *
+        * - btrfs_cleanup_dirty_bgs - called on transaction abort
+        */
        struct list_head io_bgs;
        struct list_head dropped_roots;