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");
-#endif
+ fprintf(stderr, Name ": Warning - bitmaps created on this kernel"
+ " are not portable\n"
+ " between different architectures. Consider upgrading"
+ " the Linux kernel.\n");
}
if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
}
array.state |= (1<<MD_SB_BITMAP_PRESENT);
if (ioctl(fd, SET_ARRAY_INFO, &array)!= 0) {
+ if (errno == EBUSY)
+ fprintf(stderr, Name
+ ": Cannot add bitmap while array is"
+ " resyncing or reshaping etc.\n");
fprintf(stderr, Name ": failed to set internal bitmap.\n");
return 1;
}
return 1;
}
if (ioctl(fd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+ int err = errno;
+ if (errno == EBUSY)
+ fprintf(stderr, Name
+ ": Cannot add bitmap while array is"
+ " resyncing or reshaping etc.\n");
fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
- devname, strerror(errno));
+ devname, strerror(err));
return 1;
}
}
__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;
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;
*/
st = super_by_fd(fd);
+ if (raid_disks > st->max_devs) {
+ fprintf(stderr, Name ": Cannot increase raid-disks on "
+ "this array beyond %d\n", st->max_devs);
+ rv = 1;
+ break;
+ }
+
/*
* There are three possibilities.
* 1/ The array will shrink.
/* 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));
} else {
/* need to check backup file is large enough */
char buf[512];
+ struct stat stb;
+ unsigned int dev;
fdlist[d] = open(backup_file, O_RDWR|O_CREAT|O_EXCL,
S_IRUSR | S_IWUSR);
offsets[d] = 8 * 512;
rv = 1;
break;
}
+ /* Guard against backup file being on array device.
+ * If array is partitioned or if LVM etc is in the
+ * way this will not notice, but it is better than
+ * nothing.
+ */
+ fstat(fdlist[d], &stb);
+ dev = stb.st_dev;
+ fstat(fd, &stb);
+ if (stb.st_rdev == dev) {
+ fprintf(stderr, Name ": backup file must NOT be"
+ " on the array being reshaped.\n");
+ rv = 1;
+ close(fdlist[d]);
+ break;
+ }
+
memset(buf, 0, 512);
- for (i=0; i < blocks + 1 ; i++) {
+ for (i=0; i < (signed)blocks + 8 ; 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);
+ if (sysfs_get_ll(sra, NULL, "degraded", &ll) < 0)
+ return -1; /* FIXME this error is ignored */
+ 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");
* 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);
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;