int nfd, fd2;
int d, nd;
struct supertype *st = NULL;
-
+ char *subarray = NULL;
if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
fprintf(stderr, Name ": cannot get array info for %s\n", devname);
return 1;
}
- st = super_by_fd(fd);
+ if (info.array.level != -1) {
+ fprintf(stderr, Name ": can only add devices to linear arrays\n");
+ return 1;
+ }
+
+ st = super_by_fd(fd, &subarray);
if (!st) {
fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", info.array.major_version);
return 1;
}
- if (info.array.level != -1) {
- fprintf(stderr, Name ": can only add devices to linear arrays\n");
- return 1;
+ if (subarray) {
+ fprintf(stderr, Name ": Cannot grow linear sub-arrays yet\n");
+ free(subarray);
+ free(st);
}
nfd = open(newdev, O_RDWR|O_EXCL|O_DIRECT);
if (nfd < 0) {
fprintf(stderr, Name ": cannot open %s\n", newdev);
+ free(st);
return 1;
}
fstat(nfd, &stb);
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
fprintf(stderr, Name ": %s is not a block device!\n", newdev);
close(nfd);
+ free(st);
return 1;
}
/* now check out all the devices and make sure we can read the superblock */
mdu_disk_info_t disk;
char *dv;
+ st->ss->free_super(st);
+
disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
fprintf(stderr, Name ": cannot get device detail for device %d\n",
d);
+ close(nfd);
+ free(st);
return 1;
}
dv = map_dev(disk.major, disk.minor, 1);
if (!dv) {
fprintf(stderr, Name ": cannot find device file for device %d\n",
d);
+ close(nfd);
+ free(st);
return 1;
}
fd2 = dev_open(dv, O_RDWR);
if (!fd2) {
fprintf(stderr, Name ": cannot open device file %s\n", dv);
+ close(nfd);
+ free(st);
return 1;
}
- st->ss->free_super(st);
if (st->ss->load_super(st, fd2, NULL)) {
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
+ close(nfd);
close(fd2);
+ free(st);
return 1;
}
close(fd2);
mdu_bitmap_file_t bmf;
mdu_array_info_t array;
struct supertype *st;
+ char *subarray = NULL;
int major = BITMAP_MAJOR_HI;
int vers = md_get_version(fd);
unsigned long long bitmapsize, array_size;
devname);
return 1;
}
+
+ if (strcmp(file, "none") == 0) {
+ fprintf(stderr, Name ": no bitmap found on %s\n", devname);
+ return 1;
+ }
if (array.level <= 0) {
fprintf(stderr, Name ": Bitmaps not meaningful with level %s\n",
map_num(pers, array.level)?:"of this array");
bitmapsize = bitmapsize * array.raid_disks / ncopies;
}
- st = super_by_fd(fd);
+ st = super_by_fd(fd, &subarray);
if (!st) {
fprintf(stderr, Name ": Cannot understand version %d.%d\n",
array.major_version, array.minor_version);
return 1;
}
- if (strcmp(file, "none") == 0) {
- fprintf(stderr, Name ": no bitmap found on %s\n", devname);
+ if (subarray) {
+ fprintf(stderr, Name ": Cannot add bitmaps to sub-arrays yet\n");
+ free(subarray);
+ free(st);
return 1;
- } else if (strcmp(file, "internal") == 0) {
+ }
+ if (strcmp(file, "internal") == 0) {
int d;
if (st->ss->add_internal_bitmap == NULL) {
fprintf(stderr, Name ": Internal bitmaps not supported "
__u8 pad[512-68-32];
} __attribute__((aligned(512))) bsb, bsb2;
-int bsb_csum(char *buf, int len)
+__u32 bsb_csum(char *buf, int len)
{
int i;
int csum = 0;
char *c;
int rv = 0;
struct supertype *st;
+ char *subarray = NULL;
int nchunk, ochunk;
int nlayout, olayout;
int ndisks, odisks;
- int ndata, odata;
+ unsigned int ndata, odata;
int orig_level = UnSet;
char alt_layout[40];
int *fdlist;
int err;
int frozen;
unsigned long a,b, blocks, stripes;
- int cache;
+ unsigned long cache;
unsigned long long array_size;
int changed = 0;
int done;
if (err == EBUSY &&
(array.state & (1<<MD_SB_BITMAP_PRESENT)))
fprintf(stderr, " Bitmap must be removed before level can be changed\n");
+ rv = 1;
}
}
} else if (!changed && !quiet)
array.layout = parse_layout_faulty(layout_str);
if (array.layout < 0) {
- int rv;
fprintf(stderr, Name ": %s: layout %s not understood for 'faulty' array\n",
devname, layout_str);
rv = 1;
* layout/chunksize/raid_disks can be changed
* though the kernel may not support it all.
*/
- st = super_by_fd(fd);
+ st = super_by_fd(fd, &subarray);
+ if (subarray) {
+ fprintf(stderr, Name ": Cannot reshape subarrays yet\n");
+ break;
+ }
/*
* There are three possibilities.
/* Check that we can hold all the data */
get_dev_size(fd, NULL, &array_size);
- if (ndata * size < (array_size/1024)) {
+ if (ndata * (unsigned long long)size < (array_size/1024)) {
fprintf(stderr, Name ": this change will reduce the size of the array.\n"
" use --grow --array-size first to truncate array.\n"
" e.g. mdadm --grow %s --array-size %llu\n",
rv = 1;
break;
}
- nrdisks = array.nr_disks + sra->array.spare_disks;
+ nrdisks = array.raid_disks + sra->array.spare_disks;
/* Now we need to open all these devices so we can read/write.
*/
fdlist = malloc((1+nrdisks) * sizeof(int));
break;
}
memset(buf, 0, 512);
- for (i=0; i < blocks + 1 ; i++) {
+ for (i=0; i < (signed)blocks + 1 ; i++) {
if (write(fdlist[d], buf, 512) != 512) {
fprintf(stderr, Name ": %s: cannot create backup file %s: %s\n",
devname, backup_file, strerror(errno));
int odata = disks;
int rv = 0;
int i;
- unsigned long long new_degraded;
+ unsigned long long ll;
+ int new_degraded;
//printf("offset %llu\n", offset);
if (level >= 4)
odata--;
odata--;
sysfs_set_num(sra, NULL, "suspend_hi", (offset + stripes * (chunk/512)) * odata);
/* Check that array hasn't become degraded, else we might backup the wrong data */
- sysfs_get_ll(sra, NULL, "degraded", &new_degraded);
+ sysfs_get_ll(sra, NULL, "degraded", &ll);
+ new_degraded = (int)ll;
if (new_degraded != *degraded) {
/* check each device to ensure it is still working */
struct mdinfo *sd;
bsb.sb_csum2 = bsb_csum((char*)&bsb,
((char*)&bsb.sb_csum2)-((char*)&bsb));
- if (lseek64(destfd[i], destoffsets[i] - 4096, 0) != destoffsets[i] - 4096)
- rv = 1;
- rv = rv ?: write(destfd[i], &bsb, 512);
+ rv = -1;
+ if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0)
+ != destoffsets[i] - 4096)
+ break;
+ if (write(destfd[i], &bsb, 512) != 512)
+ break;
if (destoffsets[i] > 4096) {
- if (lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) !=
+ if ((unsigned long long)lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) !=
destoffsets[i]+stripes*chunk*odata)
- rv = 1;
- rv = rv ?: write(destfd[i], &bsb, 512);
+ break;
+ if (write(destfd[i], &bsb, 512) != 512)
+ break;
}
fsync(destfd[i]);
+ rv = 0;
}
return rv;
if (memcmp(bsb.magic, "md_backup_data-2", 16) == 0)
bsb.sb_csum2 = bsb_csum((char*)&bsb,
((char*)&bsb.sb_csum2)-((char*)&bsb));
- if (lseek64(destfd[i], destoffsets[i]-4096, 0) !=
+ if ((unsigned long long)lseek64(destfd[i], destoffsets[i]-4096, 0) !=
destoffsets[i]-4096)
- rv = 1;
- rv = rv ?: write(destfd[i], &bsb, 512);
+ rv = -1;
+ if (rv == 0 &&
+ write(destfd[i], &bsb, 512) != 512)
+ rv = -1;
fsync(destfd[i]);
}
return rv;
static void fail(char *msg)
{
int rv;
- rv = write(2, msg, strlen(msg));
- rv |= write(2, "\n", 1);
+ rv = (write(2, msg, strlen(msg)) != (int)strlen(msg));
+ rv |= (write(2, "\n", 1) != 1);
exit(rv ? 1 : 2);
}
static char *abuf, *bbuf;
-static int abuflen;
+static unsigned long long abuflen;
static void validate(int afd, int bfd, unsigned long long offset)
{
/* check that the data in the backup against the array.
}
lseek64(bfd, offset, 0);
- if (read(bfd, bbuf, len) != len) {
+ if ((unsigned long long)read(bfd, bbuf, len) != len) {
//printf("len %llu\n", len);
fail("read first backup failed");
}
lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0);
- if (read(afd, abuf, len) != len)
+ if ((unsigned long long)read(afd, abuf, len) != len)
fail("read first from array failed");
if (memcmp(bbuf, abuf, len) != 0) {
#if 0
}
lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0);
- if (read(bfd, bbuf, len) != len)
+ if ((unsigned long long)read(bfd, bbuf, len) != len)
fail("read second backup failed");
lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0);
- if (read(afd, abuf, len) != len)
+ if ((unsigned long long)read(afd, abuf, len) != len)
fail("read second from array failed");
if (memcmp(bbuf, abuf, len) != 0)
fail("data2 compare failed");
if (st->ss->load_super(st, fd, NULL))
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
st->ss->free_super(st);
if (lseek64(fd,
* sometimes they aren't... So allow considerable flexability in matching, and allow
* this test to be overridden by an environment variable.
*/
- if (info->array.utime > __le64_to_cpu(bsb.mtime) + 2*60*60 ||
- info->array.utime < __le64_to_cpu(bsb.mtime) - 10*60) {
+ if (info->array.utime > (int)__le64_to_cpu(bsb.mtime) + 2*60*60 ||
+ info->array.utime < (int)__le64_to_cpu(bsb.mtime) - 10*60) {
if (check_env("MDADM_GROW_ALLOW_OLD")) {
fprintf(stderr, Name ": accepting backup with timestamp %lu "
"for array with timestamp %lu\n",
}
/* There should be a duplicate backup superblock 4k before here */
if (lseek64(fd, -4096, 1) < 0 ||
- read(fd, &bsb2, 4096) != 4096)
+ read(fd, &bsb2, sizeof(bsb2)) != sizeof(bsb2))
goto second_fail; /* Cannot find leading superblock */
if (bsb.magic[15] == '1')
bsbsize = offsetof(struct mdp_backup_super, pad1);
if (st->ss->load_super(st, fdlist[j], NULL))
/* FIXME should be this be an error */
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
st->ss->free_super(st);
offsets[j] = dinfo.data_offset * 512;
}
if (fdlist[j] < 0) continue;
if (st->ss->load_super(st, fdlist[j], NULL))
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
dinfo.reshape_progress = info->reshape_progress;
st->ss->update_super(st, &dinfo,
"_reshape_progress",
int d;
struct mdinfo *sra, *sd;
int rv;
- int cache;
+ unsigned long cache;
int done = 0;
- sra = sysfs_read(-1, devname2devnum(info->sys_name),
- GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
- GET_CACHE);
- if (!sra)
- return 1;
-
err = sysfs_set_str(info, NULL, "array_state", "readonly");
if (err)
return err;
/* make sure reshape doesn't progress until we are ready */
sysfs_set_str(info, NULL, "sync_max", "0");
sysfs_set_str(info, NULL, "array_state", "active"); /* FIXME or clean */
-
+
+ sra = sysfs_read(-1, devname2devnum(info->sys_name),
+ GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
+ GET_CACHE);
+ if (!sra)
+ return 1;
+
/* ndisks is not growing, so raid_disks is old and +delta is new */
odisks = info->array.raid_disks;
ndisks = odisks + info->delta_disks;