DIR *dir = NULL;
struct dirent *de;
- sra = malloc(sizeof(*sra));
- if (sra == NULL)
- return sra;
- memset(sra, 0, sizeof(*sra));
+ sra = xcalloc(1, sizeof(*sra));
sysfs_init(sra, fd, devnum);
if (sra->sys_name[0] == 0) {
free(sra);
if (options & GET_CACHE) {
strcpy(base, "stripe_cache_size");
if (load_sys(fname, buf))
- goto abort;
- sra->cache_size = strtoul(buf, NULL, 0);
+ /* Probably level doesn't support it */
+ sra->cache_size = 0;
+ else
+ sra->cache_size = strtoul(buf, NULL, 0);
}
if (options & GET_MISMATCH) {
strcpy(base, "mismatch_cnt");
else if (strncmp(buf, "none", 4) == 0)
sra->bitmap_offset = 0;
else if (buf[0] == '+')
- sra->bitmap_offset = strtoul(buf+1, NULL, 10);
+ sra->bitmap_offset = strtol(buf+1, NULL, 10);
else
goto abort;
}
dbase = base + strlen(base);
*dbase++ = '/';
- dev = malloc(sizeof(*dev));
- if (!dev)
- goto abort;
+ dev = xmalloc(sizeof(*dev));
/* Always get slot, major, minor */
strcpy(dbase, "slot");
if (load_sys(fname, buf))
goto abort;
dev->data_offset = strtoull(buf, NULL, 0);
+ strcpy(dbase, "new_offset");
+ if (load_sys(fname, buf) == 0)
+ dev->new_data_offset = strtoull(buf, NULL, 0);
+ else
+ dev->new_data_offset = dev->data_offset;
}
if (options & GET_SIZE) {
strcpy(dbase, "size");
return sysfs_set_str(sra, dev, name, valstr);
}
+int sysfs_set_num_signed(struct mdinfo *sra, struct mdinfo *dev,
+ char *name, long long val)
+{
+ char valstr[50];
+ sprintf(valstr, "%lli", val);
+ return sysfs_set_str(sra, dev, name, valstr);
+}
+
int sysfs_uevent(struct mdinfo *sra, char *event)
{
char fname[50];
if ((vers % 100) < 2 ||
sysfs_set_str(info, NULL, "metadata_version",
ver) < 0) {
- fprintf(stderr, Name ": This kernel does not "
+ pr_err("This kernel does not "
"support external metadata.\n");
return 1;
}
rc = sysfs_set_num(info, NULL, "array_size",
info->custom_array_size/2);
if (rc && errno == ENOENT) {
- fprintf(stderr, Name ": This kernel does not "
+ pr_err("This kernel does not "
"have the md/array_size attribute, "
"the array may be larger than expected\n");
rc = 0;
* and is the only holder.
* we should be locked against races by
* an O_EXCL on devnum
+ * Return values:
+ * 0 - not unique, not even a holder
+ * 1 - unique, this is the only holder.
+ * 2/3 - not unique, there is another holder
+ * -1 - error, cannot find the holders
*/
DIR *dir;
struct dirent *de;
char dirname[100];
char l;
- int found = 0;
+ int ret = 0;
sprintf(dirname, "/sys/dev/block/%d:%d/holders",
major(rdev), minor(rdev));
dir = opendir(dirname);
- errno = ENOENT;
if (!dir)
- return 0;
+ return -1;
l = strlen(dirname);
while ((de = readdir(dir)) != NULL) {
char buf[10];
strcat(dirname+l, "/dev");
fd = open(dirname, O_RDONLY);
if (fd < 0) {
- errno = ENOENT;
- break;
+ /* Probably a race, just ignore this */
+ continue;
}
n = read(fd, buf, sizeof(buf)-1);
close(fd);
continue;
buf[n] = 0;
if (sscanf(buf, "%d:%d%c", &mj, &mn, &c) != 3 ||
- c != '\n') {
- errno = ENOENT;
- break;
- }
+ c != '\n')
+ continue;
if (mj != MD_MAJOR)
mn = -1-(mn>>6);
- if (devnum != mn) {
- errno = EEXIST;
- break;
- }
- found = 1;
+ if (devnum == mn)
+ ret |= 1;
+ else
+ ret |= 2;
}
closedir(dir);
- if (de)
- return 0;
- else
- return found;
+ return ret;
}
int sysfs_freeze_array(struct mdinfo *sra)