Whamcloud - gitweb
create_iam: add ability to create files of different formats
authornikita <nikita>
Sun, 2 Jul 2006 21:17:19 +0000 (21:17 +0000)
committernikita <nikita>
Sun, 2 Jul 2006 21:17:19 +0000 (21:17 +0000)
lustre/utils/create_iam.c

index ff7544a..6b0f258 100644 (file)
@@ -49,7 +49,8 @@ void usage(void)
 }
 
 enum {
-        IAM_LFIX_ROOT_MAGIC = 0xbedabb1edULL
+        IAM_LFIX_ROOT_MAGIC = 0xbedabb1edULL,
+        IAM_LVAR_ROOT_MAGIC = 0xb01dface
 };
 
 struct iam_lfix_root {
@@ -61,7 +62,8 @@ struct iam_lfix_root {
 };
 
 enum {
-        IAM_LEAF_HEADER_MAGIC = 0x1976
+        IAM_LEAF_HEADER_MAGIC = 0x1976,
+        IAM_LVAR_LEAF_MAGIC   = 0x1973
 };
 
 struct iam_leaf_head {
@@ -74,6 +76,167 @@ struct dx_countlimit {
         u_int16_t count;
 };
 
+typedef __u32 lvar_hash_t;
+
+struct lvar_leaf_header {
+        u_int16_t vlh_magic; /* magic number IAM_LVAR_LEAF_MAGIC */
+        u_int16_t vlh_used;  /* used bytes, including header */
+};
+
+struct lvar_root {
+        u_int32_t vr_magic;
+        u_int16_t vr_recsize;
+        u_int16_t vr_ptrsize;
+        u_int8_t  vr_indirect_levels;
+        u_int8_t  vr_padding0;
+        u_int16_t vr_padding1;
+};
+
+struct lvar_leaf_entry {
+        u_int32_t vle_hash;
+        u_int16_t vle_keysize;
+        u_int8_t  vle_key[0];
+};
+
+enum {
+        LVAR_PAD   = 4,
+        LVAR_ROUND = LVAR_PAD - 1
+};
+
+static void lfix_root(void *buf,
+                      int blocksize, int keysize, int ptrsize, int recsize)
+{
+        struct iam_lfix_root *root;
+        struct dx_countlimit *limit;
+        void                 *entry;
+
+        root = buf;
+        *root = (typeof(*root)) {
+                .ilr_magic           = cpu_to_le64(IAM_LFIX_ROOT_MAGIC),
+                .ilr_keysize         = cpu_to_le16(keysize),
+                .ilr_recsize         = cpu_to_le16(recsize),
+                .ilr_ptrsize         = cpu_to_le16(ptrsize),
+                .ilr_indirect_levels = 0
+        };
+
+        limit = (void *)(root + 1);
+        *limit = (typeof(*limit)){
+                /*
+                 * limit itself + one pointer to the leaf.
+                 */
+                .count = cpu_to_le16(2),
+                .limit = (blocksize - sizeof *root) / (keysize + ptrsize)
+        };
+
+        entry = root + 1;
+        /*
+         * Skip over @limit.
+         */
+        entry += keysize + ptrsize;
+
+        /*
+         * Entry format is <key> followed by <ptr>. In the minimal tree
+         * consisting of a root and single node, <key> is a minimal possible
+         * key.
+         *
+         * XXX: this key is hard-coded to be a sequence of 0's.
+         */
+        entry += keysize;
+        /* now @entry points to <ptr> */
+        if (ptrsize == 4)
+                *(u_int32_t *)entry = cpu_to_le32(1);
+        else
+                *(u_int64_t *)entry = cpu_to_le64(1);
+}
+
+static void lfix_leaf(void *buf,
+                      int blocksize, int keysize, int ptrsize, int recsize)
+{
+        struct iam_leaf_head *head;
+
+        /* form leaf */
+        head = buf;
+        *head = (struct iam_leaf_head) {
+                .ill_magic = cpu_to_le16(IAM_LEAF_HEADER_MAGIC),
+                /*
+                 * Leaf contains an entry with the smallest possible key
+                 * (created by zeroing).
+                 */
+                .ill_count = cpu_to_le16(1),
+        };
+}
+
+static void lvar_root(void *buf,
+                      int blocksize, int keysize, int ptrsize, int recsize)
+{
+        struct lvar_root *root;
+        struct dx_countlimit *limit;
+        void                 *entry;
+        int isize;
+
+        isize = sizeof(lvar_hash_t) + ptrsize;
+        root = buf;
+        *root = (typeof(*root)) {
+                .vr_magic            = cpu_to_le32(IAM_LVAR_ROOT_MAGIC),
+                .vr_recsize          = cpu_to_le16(recsize),
+                .vr_ptrsize          = cpu_to_le16(ptrsize),
+                .vr_indirect_levels  = 0
+        };
+
+        limit = (void *)(root + 1);
+        *limit = (typeof(*limit)){
+                /*
+                 * limit itself + one pointer to the leaf.
+                 */
+                .count = cpu_to_le16(2),
+                .limit = (blocksize - sizeof *root) / isize
+        };
+
+        entry = root + 1;
+        /*
+         * Skip over @limit.
+         */
+        entry += isize;
+
+        /*
+         * Entry format is <key> followed by <ptr>. In the minimal tree
+         * consisting of a root and single node, <key> is a minimal possible
+         * key.
+         *
+         * XXX: this key is hard-coded to be a sequence of 0's.
+         */
+        entry += sizeof(lvar_hash_t);
+        /* now @entry points to <ptr> */
+        if (ptrsize == 4)
+                *(u_int32_t *)entry = cpu_to_le32(1);
+        else
+                *(u_int64_t *)entry = cpu_to_le64(1);
+}
+
+static int lvar_esize(int namelen, int recsize)
+{
+        return (offsetof(struct lvar_leaf_entry, vle_key) +
+                namelen + recsize + LVAR_ROUND) & ~LVAR_ROUND;
+}
+
+static void lvar_leaf(void *buf,
+                      int blocksize, int keysize, int ptrsize, int recsize)
+{
+        struct lvar_leaf_header *head;
+
+        /* form leaf */
+        head = buf;
+        *head = (typeof(*head)) {
+                .vlh_magic = cpu_to_le16(IAM_LVAR_LEAF_MAGIC),
+                .vlh_used  = cpu_to_le16(sizeof *head + lvar_esize(0, recsize))
+        };
+}
+
+enum iam_fmt_t {
+        FMT_LFIX,
+        FMT_LVAR
+};
+
 int main(int argc, char **argv)
 {
         int rc;
@@ -84,14 +247,11 @@ int main(int argc, char **argv)
         int ptrsize   = 4;
         int verbose   = 0;
         void *buf;
-
-        struct iam_lfix_root *root;
-        struct iam_leaf_head *head;
-        struct dx_countlimit *limit;
-        void *entry;
+        char *fmtstr = "lfix";
+        enum iam_fmt_t fmt;
 
         do {
-                opt = getopt(argc, argv, "hb:k:r:p:v");
+                opt = getopt(argc, argv, "hb:k:r:p:vf:");
                 switch (opt) {
                 case 'v':
                         verbose++;
@@ -109,6 +269,9 @@ int main(int argc, char **argv)
                 case 'p':
                         ptrsize = atoi(optarg);
                         break;
+                case 'f':
+                        fmtstr = optarg;
+                        break;
                 case '?':
                 default:
                         fprintf(stderr, "Unable to parse options.");
@@ -133,10 +296,20 @@ int main(int argc, char **argv)
                 fprintf(stderr, "Too large (record, key) or too small block\n");
                 return 1;
         }
+
+        if (!strcmp(fmtstr, "lfix"))
+                fmt = FMT_LFIX;
+        else if (!strcmp(fmtstr, "lvar"))
+                fmt = FMT_LVAR;
+        else {
+                fprintf(stderr, "Wrong format `%s'\n", fmtstr);
+                return 1;
+        }
+
         if (verbose > 0) {
                 fprintf(stderr,
-                        "key: %i, rec: %i, ptr: %i, block: %i\n",
-                        keysize, recsize, ptrsize, blocksize);
+                        "fmt: %s, key: %i, rec: %i, ptr: %i, block: %i\n",
+                        fmtstr, keysize, recsize, ptrsize, blocksize);
         }
         buf = malloc(blocksize);
         if (buf == NULL) {
@@ -144,45 +317,13 @@ int main(int argc, char **argv)
                 return 1;
         }
 
-        root = memset(buf, 0, blocksize);
+        memset(buf, 0, blocksize);
 
-        *root = (typeof(*root)) {
-                .ilr_magic           = cpu_to_le64(IAM_LFIX_ROOT_MAGIC),
-                .ilr_keysize         = cpu_to_le16(keysize),
-                .ilr_recsize         = cpu_to_le16(recsize),
-                .ilr_ptrsize         = cpu_to_le16(ptrsize),
-                .ilr_indirect_levels = 0
-        };
-
-        limit = (void *)(root + 1);
-        *limit = (typeof(*limit)){
-                /*
-                 * limit itself + one pointer to the leaf.
-                 */
-                .count = cpu_to_le16(2),
-                .limit = (blocksize -
-                          sizeof(struct iam_lfix_root)) / (keysize + ptrsize)
-        };
-
-        entry = root + 1;
-        /*
-         * Skip over @limit.
-         */
-        entry += keysize + ptrsize;
-
-        /*
-         * Entry format is <key> followed by <ptr>. In the minimal tree
-         * consisting of a root and single node, <key> is a minimal possible
-         * key.
-         *
-         * XXX: this key is hard-coded to be a sequence of 0's.
-         */
-        entry += keysize;
-        /* now @entry points to <ptr> */
-        if (ptrsize == 4)
-                *(u_int32_t *)entry = cpu_to_le32(1);
+        if (fmt == FMT_LFIX)
+                lfix_root(buf, blocksize, keysize, ptrsize, recsize);
         else
-                *(u_int64_t *)entry = cpu_to_le64(1);
+                lvar_root(buf, blocksize, keysize, ptrsize, recsize);
+
         rc = write(1, buf, blocksize);
         if (rc != blocksize) {
                 fprintf(stderr, "Unable to write root node: %m (%i)\n", rc);
@@ -190,15 +331,12 @@ int main(int argc, char **argv)
         }
 
         /* form leaf */
-        head = memset(buf, 0, blocksize);
-        *head = (struct iam_leaf_head) {
-                .ill_magic = cpu_to_le16(IAM_LEAF_HEADER_MAGIC),
-                /*
-                 * Leaf contains an entry with the smallest possible key
-                 * (created by zeroing).
-                 */
-                .ill_count = cpu_to_le16(1),
-        };
+        memset(buf, 0, blocksize);
+
+        if (fmt == FMT_LFIX)
+                lfix_leaf(buf, blocksize, keysize, ptrsize, recsize);
+        else
+                lvar_leaf(buf, blocksize, keysize, ptrsize, recsize);
 
         rc = write(1, buf, blocksize);
         if (rc != blocksize) {