From: NeilBrown Date: Fri, 17 Oct 2008 01:46:23 +0000 (+1100) Subject: Merge branch 'master' into devel-3.0 X-Git-Tag: mdadm-3.0-devel2~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=492350045c7e40741069caa7d017209439db665b;p=thirdparty%2Fmdadm.git Merge branch 'master' into devel-3.0 Conflicts: Manage.c --- 492350045c7e40741069caa7d017209439db665b diff --cc Manage.c index a6e10725,7b3fabe1..0018d8d3 --- a/Manage.c +++ b/Manage.c @@@ -445,23 -347,12 +445,16 @@@ int Manage_subdevs(char *devname, int f return 1; } - if (array.not_persistent == 0) { + if (array.not_persistent == 0 || tst->ss->external) { - /* Make sure device is large enough */ - if (tst->ss->avail_size(tst, ldsize/512) < - array_size) { - fprintf(stderr, Name ": %s not large enough to join array\n", - dv->devname); - return 1; - } /* need to find a sample superblock to copy, and - * a spare slot to use + * a spare slot to use. + * For 'external' array (well, container based), + * We can just load the metadata for the array. */ - for (j = 0; j < tst->max_devs; j++) { + if (tst->ss->external) { + tst->ss->load_super(tst, fd, NULL); + } else for (j = 0; j < tst->max_devs; j++) { char *dev; int dfd; disc.number = j; diff --cc mdadm.h index aea72281,174ea395..ed0c1153 --- a/mdadm.h +++ b/mdadm.h @@@ -778,17 -510,11 +779,18 @@@ extern int enough(int level, int raid_d extern int ask(char *mesg); extern unsigned long long get_component_size(int fd); extern void remove_partitions(int fd); +extern unsigned long long calc_array_size(int level, int raid_disks, int layout, + int chunksize, unsigned long long devsize); +extern int flush_metadata_updates(struct supertype *st); +extern void append_metadata_update(struct supertype *st, void *buf, int len); +extern int add_disk(int mdfd, struct supertype *st, + struct mdinfo *sra, struct mdinfo *info); +extern int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info); extern char *human_size(long long bytes); - char *human_size_brief(long long bytes); + extern char *human_size_brief(long long bytes); + extern void print_r10_layout(int layout); #define NoMdDev (1<<23) extern int find_free_devnum(int use_partitions); diff --cc util.c index f6e4dd0e,2d51de02..379403d0 --- a/util.c +++ b/util.c @@@ -640,25 -606,26 +640,42 @@@ char *human_size_brief(long long bytes ); return buf; } + + void print_r10_layout(int layout) + { + int near = layout & 255; + int far = (layout >> 8) & 255; + int offset = (layout&0x10000); + char *sep = ""; + + if (near != 1) { + printf("%s near=%d", sep, near); + sep = ","; + } + if (far != 1) + printf("%s %s=%d", sep, offset?"offset":"far", far); + if (near*far == 1) + printf("NO REDUNDANCY"); + } #endif -#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) +unsigned long long calc_array_size(int level, int raid_disks, int layout, + int chunksize, unsigned long long devsize) +{ + int data_disks = 0; + switch (level) { + case 0: data_disks = raid_disks; break; + case 1: data_disks = 1; break; + case 4: + case 5: data_disks = raid_disks - 1; break; + case 6: data_disks = raid_disks - 2; break; + case 10: data_disks = raid_disks / (layout & 255) / ((layout>>8)&255); + break; + } + devsize &= ~(unsigned long long)((chunksize>>9)-1); + return data_disks * devsize; +} + int get_mdp_major(void) { static int mdp_major = -1;