]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super1.c
sysfs: Avoid if and return on the same line
[thirdparty/mdadm.git] / super1.c
index 9b877e504c4bd05c255e5cdddf996effc84ae72b..b7974031f232b7620c837c144f1e36ddd83ca9e8 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1548,7 +1548,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
 }
 #endif
 
-static int locate_bitmap1(struct supertype *st, int fd);
+static int locate_bitmap1(struct supertype *st, int fd, int node_num);
 
 static int store_super1(struct supertype *st, int fd)
 {
@@ -1622,7 +1622,7 @@ static int store_super1(struct supertype *st, int fd)
                struct bitmap_super_s *bm = (struct bitmap_super_s*)
                        (((char*)sb)+MAX_SB_SIZE);
                if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
-                       locate_bitmap1(st, fd);
+                       locate_bitmap1(st, fd, 0);
                        if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm))
                                return 5;
                }
@@ -1643,7 +1643,8 @@ static unsigned long choose_bm_space(unsigned long devsize)
         * NOTE: result must be multiple of 4K else bad things happen
         * on 4K-sector devices.
         */
-       if (devsize < 64*2) return 0;
+       if (devsize < 64*2)
+               return 0;
        if (devsize - 64*2 >= 200*1024*1024*2)
                return 128*2;
        if (devsize - 4*2 > 8*1024*1024*2)
@@ -1867,7 +1868,7 @@ static int write_init_super1(struct supertype *st)
                }
 
                if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
-                       rv = st->ss->write_bitmap(st, di->fd, NoUpdate);
+                       rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate);
                close(di->fd);
                di->fd = -1;
                if (rv)
@@ -2016,6 +2017,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
                return 1;
        }
 
+       memset(super, 0, SUPER1_SIZE);
+
        if (aread(&afd, super, MAX_SB_SIZE) != MAX_SB_SIZE) {
                if (devname)
                        pr_err("Cannot read superblock on %s\n",
@@ -2062,7 +2065,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
         * valid.  If it doesn't clear the bit.  An --assemble --force
         * should get that written out.
         */
-       locate_bitmap1(st, fd);
+       locate_bitmap1(st, fd, 0);
        if (aread(&afd, bsb, 512) != 512)
                goto no_bitmap;
 
@@ -2201,6 +2204,7 @@ add_internal_bitmap1(struct supertype *st,
        unsigned long long chunk = *chunkp;
        int room = 0;
        int creating = 0;
+       int len;
        struct mdp_superblock_1 *sb = st->sb;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
        int uuid[4];
@@ -2267,7 +2271,7 @@ add_internal_bitmap1(struct supertype *st,
                }
                break;
        default:
-               return 0;
+               return -ENOSPC;
        }
 
        room -= bbl_size;
@@ -2277,7 +2281,7 @@ add_internal_bitmap1(struct supertype *st,
 
        if (room <= 1)
                /* No room for a bitmap */
-               return 0;
+               return -ENOSPC;
 
        max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8;
 
@@ -2295,9 +2299,9 @@ add_internal_bitmap1(struct supertype *st,
                if (chunk < 64*1024*1024)
                        chunk = 64*1024*1024;
        } else if (chunk < min_chunk)
-               return 0; /* chunk size too small */
+               return -EINVAL; /* chunk size too small */
        if (chunk == 0) /* rounding problem */
-               return 0;
+               return -EINVAL;
 
        if (offset == 0) {
                /* start bitmap on a 4K boundary with enough space for
@@ -2326,15 +2330,17 @@ add_internal_bitmap1(struct supertype *st,
        if (st->nodes)
                sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
                                                | MD_FEATURE_BITMAP_VERSIONED);
-       if (st->cluster_name)
-               strncpy((char *)bms->cluster_name,
-                       st->cluster_name, strlen(st->cluster_name));
+       if (st->cluster_name) {
+               len = sizeof(bms->cluster_name);
+               strncpy((char *)bms->cluster_name, st->cluster_name, len);
+               bms->cluster_name[len - 1] = '\0';
+       }
 
        *chunkp = chunk;
-       return 1;
+       return 0;
 }
 
-static int locate_bitmap1(struct supertype *st, int fd)
+static int locate_bitmap1(struct supertype *st, int fd, int node_num)
 {
        unsigned long long offset;
        struct mdp_superblock_1 *sb;
@@ -2353,7 +2359,7 @@ static int locate_bitmap1(struct supertype *st, int fd)
        else
                ret = -1;
        offset = __le64_to_cpu(sb->super_offset);
-       offset += (int32_t) __le32_to_cpu(sb->bitmap_offset);
+       offset += (int32_t) __le32_to_cpu(sb->bitmap_offset) * (node_num + 1);
        if (mustfree)
                free(sb);
        lseek64(fd, offset<<9, 0);
@@ -2366,7 +2372,7 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
        int rv = 0;
        void *buf;
-       int towrite, n;
+       int towrite, n, len;
        struct align_fd afd;
        unsigned int i = 0;
        unsigned long long total_bm_space, bm_space_per_node;
@@ -2375,17 +2381,41 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
        case NameUpdate:
                /* update cluster name */
                if (st->cluster_name) {
-                       memset((char *)bms->cluster_name, 0, sizeof(bms->cluster_name));
-                       strncpy((char *)bms->cluster_name, st->cluster_name, 64);
+                       len = sizeof(bms->cluster_name);
+                       memset((char *)bms->cluster_name, 0, len);
+                       strncpy((char *)bms->cluster_name,
+                               st->cluster_name, len);
+                       bms->cluster_name[len - 1] = '\0';
                }
                break;
        case NodeNumUpdate:
                /* cluster md only supports superblock 1.2 now */
-               if (st->minor_version != 2) {
+               if (st->minor_version != 2 && bms->version == BITMAP_MAJOR_CLUSTERED) {
                        pr_err("Warning: cluster md only works with superblock 1.2\n");
                        return -EINVAL;
                }
 
+               if (bms->version == BITMAP_MAJOR_CLUSTERED) {
+                       if (st->nodes == 1) {
+                               /* the parameter for nodes is not valid */
+                               pr_err("Warning: cluster-md at least needs two nodes\n");
+                               return -EINVAL;
+                       } else if (st->nodes == 0)
+                               /* --nodes is not specified */
+                               break;
+                       else if (__cpu_to_le32(st->nodes) < bms->nodes) {
+                               /* Since the nodes num is not increased, no need to check the space
+                                * is enough or not, just update bms->nodes */
+                               bms->nodes = __cpu_to_le32(st->nodes);
+                               break;
+                       }
+               } else {
+                       /* no need to change bms->nodes for other bitmap types */
+                       if (st->nodes)
+                               pr_err("Warning: --nodes option is only suitable for clustered bitmap\n");
+                       break;
+               }
+
                /* Each node has an independent bitmap, it is necessary to calculate the
                 * space is enough or not, first get how many bytes for the total bitmap */
                bm_space_per_node = calc_bitmap_size(bms, 4096);
@@ -2408,7 +2438,7 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
 
        init_afd(&afd, fd);
 
-       locate_bitmap1(st, fd);
+       locate_bitmap1(st, fd, 0);
 
        if (posix_memalign(&buf, 4096, 4096))
                return -ENOMEM;