]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Build.c
Some support for external metadata.
[thirdparty/mdadm.git] / Build.c
diff --git a/Build.c b/Build.c
index 2fcc47e153f2d3c29c428cf308d27fe966a747f2..d6e20fb84d6acfa57e69c6a9036d13c10bb2c07b 100644 (file)
--- a/Build.c
+++ b/Build.c
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2001-2002 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
@@ -58,6 +58,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
        mddev_dev_t dv;
        int bitmap_fd;
        unsigned long long size = ~0ULL;
+       unsigned long long bitmapsize;
 
        /* scan all devices, make sure they really are block devices */
        for (dv = devlist; dv; dv=dv->next) {
@@ -113,7 +114,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
 
 
        vers = md_get_version(mdfd);
-       
+
        /* looks Ok, go for it */
        if (vers >= 9000) {
                mdu_array_info_t array;
@@ -145,9 +146,15 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                fprintf(stderr, Name ": bitmaps not supported with this kernel\n");
                return 1;
        }
+
+       if (bitmap_file && level <= 0) {
+               fprintf(stderr, Name ": bitmaps not meaningful with level %s\n",
+                       map_num(pers, level)?:"given");
+               return 1;
+       }
        /* now add the devices */
        for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
-               unsigned long dsize;
+               unsigned long long dsize;
                int fd;
                if (strcmp("missing", dv->devname) == 0)
                        continue;
@@ -163,16 +170,13 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                }
                fd = open(dv->devname, O_RDONLY|O_EXCL);
                if (fd < 0) {
-                       fprintf(stderr, Name ": Cannot open %s: %s\n", 
+                       fprintf(stderr, Name ": Cannot open %s: %s\n",
                                dv->devname, strerror(errno));
                        goto abort;
                }
-               if (ioctl(fd, BLKGETSIZE, &dsize) == 0 && dsize > 0) {
-                       unsigned long long ldsize = dsize;
-                       ldsize <<= 9;
-                       if (size== 0 || ldsize < size)
-                               size = ldsize;
-               }
+               if (get_dev_size(fd, NULL, &dsize) &&
+                   (size == 0 || dsize < size))
+                               size = dsize;
                close(fd);
                if (vers>= 9000) {
                        mdu_disk_info_t disk;
@@ -203,20 +207,23 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                        bitmap_fd = open(bitmap_file, O_RDWR);
                        if (bitmap_fd < 0) {
                                int major = BITMAP_MAJOR_HI;
+#if 0
                                if (bitmap_chunk == UnSet) {
                                        fprintf(stderr, Name ": %s cannot be openned.",
                                                bitmap_file);
                                        return 1;
                                }
+#endif
                                if (vers < 9003) {
                                        major = BITMAP_MAJOR_HOSTENDIAN;
 #ifdef __BIG_ENDIAN
                                        fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
-                                               "  between different architectured.  Consider upgrading the Linux kernel.\n");
+                                               "  between different architectures.  Consider upgrading the Linux kernel.\n");
 #endif
                                }
+                               bitmapsize = size>>9; /* FIXME wrong for RAID10 */
                                if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
-                                                delay, write_behind, size>>9, major)) {
+                                                delay, write_behind, bitmapsize, major)) {
                                        return 1;
                                }
                                bitmap_fd = open(bitmap_file, O_RDWR);
@@ -225,7 +232,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                                                bitmap_file);
                                        return 1;
                                }
-                       }                               
+                       }
                        if (bitmap_fd >= 0) {
                                if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
                                        fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
@@ -266,5 +273,4 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
        else
            ioctl(mdfd, STOP_MD, 0);
        return 1;
-               
 }