Author: Allan Jude Language: c
Description: (v2) Timestamp: 2018-04-02 04:32:00 +0000
View raw paste Parent paste by: Allan Jude Reply
  1. #include <sys/param.h>
  2. #include <err.h>
  3. #include <stdalign.h>
  4. #include <stdio.h>
  5. #include <stdint.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. #define UBERBLOCK_SHIFT         (10)                    /* Each uberblock should be padded to 1KB */
  10.  
  11. #define VDEV_UBERRING_SHIFT     (17)                    /* The entire ring of uberblocks is 128KB */
  12. #define VDEV_UBERBLOCK_RING     (128 << 10)
  13.  
  14. #define MAX_UBERBLOCK_SHIFT     (15)                    /* The largest sector size we support is 32KB. Was 13 (8KB) */
  15.  
  16.                                                         /* Calculate the uberblock shift based on ashift bounded by UBERBLOCK_SHIFT and MAX_UBERBLOCK_SHIFT */
  17. #define VDEV_UBERBLOCK_SHIFT(ashift)            \
  18.         MIN(MAX(ashift, UBERBLOCK_SHIFT),       \
  19.             MAX_UBERBLOCK_SHIFT)
  20.  
  21.                                                         /* How many sectors are available for uberblocks. This used to determine the number of uberblocks */
  22. #define VDEV_UBERBLOCK_COUNT(ashift)            \
  23.         (VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(ashift))
  24.  
  25.                                                         /* How big is an uberblock, this will need to be renamed to ubersector or something */
  26. #define VDEV_UBERBLOCK_SIZE(ashift)             (1ULL << VDEV_UBERBLOCK_SHIFT(ashift))
  27.  
  28. /*
  29.  * Mask the transaction id [txg] to calculate the offset within the selected
  30.  * ubersector to write the next uberblock. This is done round-robin to avoid
  31.  * writing to the same ubersector for sequential uberblocks.
  32.  * The transaction is shifted right X bits, where X is the difference between
  33.  * VDEV_UBERRING_SHIFT [size of the uber ring] and
  34.  * VDEV_UBERBLOCK_SHIFT(ashift) [size of each ubersector], to account for the
  35.  * previous masking operation to select the ubersector.
  36.  * It is then masked with the Y bits, where Y is the difference in between
  37.  * VDEV_UBERBLOCK_SHIFT [size of each ubersector] and
  38.  * UBERBLOCK_SHIFT [size of a single uberblock]
  39.  *
  40.  * ashift=9:  X=17-10=7, Y=10-10=0
  41.  * ashift=12: X=17-12=5, Y=12-10=2
  42.  * ashift=14: X=17-14=3, Y=14-10=4
  43.  */
  44. #define VDEV_SUBBLOCK(txg, ashift)              \
  45.         ( (txg >> (VDEV_UBERRING_SHIFT - VDEV_UBERBLOCK_SHIFT(ashift)) ) & \
  46.                 ((1ULL << (VDEV_UBERBLOCK_SHIFT(ashift) - UBERBLOCK_SHIFT)) - 1) \
  47.         )
  48.  
  49. int
  50. main(int argc, char *argv[])
  51. {
  52.         unsigned long long txg, n, ashift;
  53.         const char *errstr;
  54.  
  55.         txg = 0;
  56.  
  57.         if (argc > 1) {
  58.                 ashift = strtonum(argv[1], 9, 15, &errstr);
  59.                 if (errstr != NULL) {
  60.                         errx(1, "ashift is %s: %s", errstr, argv[1]);
  61.                 }
  62.         } else {
  63.                 ashift = 12;
  64.         }
  65.  
  66.         for (txg = 0; txg < 256; txg++) {
  67.                 printf("txg=%llu n=%llu\tblock=%2llu\tsubblock=%llu\n",
  68.                     txg,
  69.                     txg & (VDEV_UBERBLOCK_COUNT(UBERBLOCK_SHIFT) - 1),
  70.                     txg & (VDEV_UBERBLOCK_COUNT(ashift) - 1),
  71.                     VDEV_SUBBLOCK(txg, ashift)
  72.                 );
  73.         }
  74. }
  75.  
View raw paste Parent paste by: Allan Jude Reply