X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super1.c;h=b7974031f232b7620c837c144f1e36ddd83ca9e8;hb=36138e4e4b6c3f9db21e65ac8962bf22d4b2c274;hp=baa9a96ed4c7ca13c72e6d288fcb0917acbc3359;hpb=4b3eb4d2c5fd4c8eb3ad31fa494d243a886a9702;p=thirdparty%2Fmdadm.git diff --git a/super1.c b/super1.c index baa9a96e..b7974031 100644 --- a/super1.c +++ b/super1.c @@ -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", @@ -2268,7 +2271,7 @@ add_internal_bitmap1(struct supertype *st, } break; default: - return 0; + return -ENOSPC; } room -= bbl_size; @@ -2278,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; @@ -2296,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 @@ -2334,7 +2337,7 @@ add_internal_bitmap1(struct supertype *st, } *chunkp = chunk; - return 1; + return 0; } static int locate_bitmap1(struct supertype *st, int fd, int node_num) @@ -2387,11 +2390,32 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update 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);