btrfs: reduce type width of btrfs_io_contexts
authorQu Wenruo <wqu@suse.com>
Tue, 7 Feb 2023 04:26:13 +0000 (12:26 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 17 Apr 2023 16:01:14 +0000 (18:01 +0200)
That structure is our ultimate object for all __btrfs_map_block()
related functions.  We have some hard to understand members, like
tgtdev_map, but without any comments.

This patch will improve the situation:

- Add extra comments for num_stripes, mirror_num, num_tgtdevs and
  tgtdev_map[]
  Especially for the last two members, add a dedicated (thus very long)
  comments for them, with example to explain it.

- Shrink those int members to u16.
  In fact our on-disk format is only using u16 for num_stripes, thus
  no need to use int at all.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index a29c9d5503914d4155c51b6babb4e03443ed54f8..2417f4fb87244db0e322a2df17c1a50e6b61b381 100644 (file)
@@ -5914,16 +5914,18 @@ static void sort_parity_stripes(struct btrfs_io_context *bioc, int num_stripes)
 }
 
 static struct btrfs_io_context *alloc_btrfs_io_context(struct btrfs_fs_info *fs_info,
-                                                      int total_stripes,
-                                                      int real_stripes)
+                                                      u16 total_stripes,
+                                                      u16 real_stripes)
 {
-       struct btrfs_io_context *bioc = kzalloc(
+       struct btrfs_io_context *bioc;
+
+       bioc = kzalloc(
                 /* The size of btrfs_io_context */
                sizeof(struct btrfs_io_context) +
                /* Plus the variable array for the stripes */
                sizeof(struct btrfs_io_stripe) * (total_stripes) +
                /* Plus the variable array for the tgt dev */
-               sizeof(int) * (real_stripes) +
+               sizeof(u16) * (real_stripes) +
                /*
                 * Plus the raid_map, which includes both the tgt dev
                 * and the stripes.
@@ -5937,7 +5939,7 @@ static struct btrfs_io_context *alloc_btrfs_io_context(struct btrfs_fs_info *fs_
        refcount_set(&bioc->refs, 1);
 
        bioc->fs_info = fs_info;
-       bioc->tgtdev_map = (int *)(bioc->stripes + total_stripes);
+       bioc->tgtdev_map = (u16 *)(bioc->stripes + total_stripes);
        bioc->raid_map = (u64 *)(bioc->tgtdev_map + real_stripes);
 
        return bioc;
@@ -6370,12 +6372,12 @@ int __btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
        int mirror_num = (mirror_num_ret ? *mirror_num_ret : 0);
        int num_stripes;
        int max_errors = 0;
-       int tgtdev_indexes = 0;
        struct btrfs_io_context *bioc = NULL;
        struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
        int dev_replace_is_ongoing = 0;
-       int num_alloc_stripes;
        int patch_the_first_stripe_for_dev_replace = 0;
+       u16 num_alloc_stripes;
+       u16 tgtdev_indexes = 0;
        u64 physical_to_patch_in_first_stripe = 0;
        u64 raid56_full_stripe_start = (u64)-1;
        u64 max_len;
index 9f397b4c1b4fa647f27b750316c61fc154ff6d95..da0f9a9eaf946d7e1dbd16309fe13b64ce9ad3af 100644 (file)
@@ -408,11 +408,55 @@ struct btrfs_io_context {
        u64 map_type; /* get from map_lookup->type */
        struct bio *orig_bio;
        atomic_t error;
-       int max_errors;
-       int num_stripes;
-       int mirror_num;
-       int num_tgtdevs;
-       int *tgtdev_map;
+       u16 max_errors;
+
+       /*
+        * The total number of stripes, including the extra duplicated
+        * stripe for replace.
+        */
+       u16 num_stripes;
+
+       /*
+        * The mirror_num of this bioc.
+        *
+        * This is for reads which use 0 as mirror_num, thus we should return a
+        * valid mirror_num (>0) for the reader.
+        */
+       u16 mirror_num;
+
+       /*
+        * The following two members are for dev-replace case only.
+        *
+        * @num_tgtdevs:        Number of duplicated stripes which need to be
+        *                      written to replace target.
+        *                      Should be <= 2 (2 for DUP, otherwise <= 1).
+        * @tgtdev_map:         The array indicates where the duplicated stripes
+        *                      are from. The size is the number of original
+        *                      stripes (num_stripes - num_tgtdevs).
+        *
+        * The @tgtdev_map[] array is mostly for RAID56 cases.
+        * As non-RAID56 stripes share the same contents of the mapped range,
+        * thus no need to bother where the duplicated ones are from.
+        *
+        * But for RAID56 case, all stripes contain different contents, thus
+        * we need a way to know the mapping.
+        *
+        * There is an example for the two members, using a RAID5 write:
+        *
+        *   num_stripes:       4 (3 + 1 duplicated write)
+        *   stripes[0]:        dev = devid 1, physical = X
+        *   stripes[1]:        dev = devid 2, physical = Y
+        *   stripes[2]:        dev = devid 3, physical = Z
+        *   stripes[3]:        dev = devid 0, physical = Y
+        *
+        * num_tgtdevs = 1
+        * tgtdev_map[0] = 0    <- Means stripes[0] is not involved in replace.
+        * tgtdev_map[1] = 3    <- Means stripes[1] is involved in replace,
+        *                         and it's duplicated to stripes[3].
+        * tgtdev_map[2] = 0    <- Means stripes[2] is not involved in replace.
+        */
+       u16 num_tgtdevs;
+       u16 *tgtdev_map;
        /*
         * logical block numbers for the start of each stripe
         * The last one or two are p/q.  These are sorted,