*/
int parse_uuid(char *str, int uuid[4])
{
- int hit = 0; /* number of Hex digIT */
- int i;
- char c;
- for (i=0; i<4; i++) uuid[i]=0;
-
- while ((c= *str++)) {
- int n;
- if (c>='0' && c<='9')
- n = c-'0';
- else if (c>='a' && c <= 'f')
- n = 10 + c - 'a';
- else if (c>='A' && c <= 'F')
- n = 10 + c - 'A';
- else if (strchr(":. -", c))
- continue;
- else return 0;
-
- if (hit<32) {
- uuid[hit/8] <<= 4;
- uuid[hit/8] += n;
+ int hit = 0; /* number of Hex digIT */
+ int i;
+ char c;
+ for (i=0; i<4; i++) uuid[i]=0;
+
+ while ((c= *str++)) {
+ int n;
+ if (c>='0' && c<='9')
+ n = c-'0';
+ else if (c>='a' && c <= 'f')
+ n = 10 + c - 'a';
+ else if (c>='A' && c <= 'F')
+ n = 10 + c - 'A';
+ else if (strchr(":. -", c))
+ continue;
+ else return 0;
+
+ if (hit<32) {
+ uuid[hit/8] <<= 4;
+ uuid[hit/8] += n;
+ }
+ hit++;
}
- hit++;
- }
- if (hit == 32)
- return 1;
- return 0;
-
+ if (hit == 32)
+ return 1;
+ return 0;
}
return -1;
}
-
int get_linux_version()
{
struct utsname name;
if (swapuuid) {
/* parse uuids are hostendian.
* uuid's from some superblocks are big-ending
- * if there is a difference, we need to swap..
+ * if there is a difference, we need to swap..
*/
unsigned char *ac = (unsigned char *)a;
unsigned char *bc = (unsigned char *)b;
fprintf(stderr, Name ": %s appears to contain a reiserfs file system\n",name);
size = sb[0]|(sb[1]|(sb[2]|sb[3]<<8)<<8)<<8;
fprintf(stderr, " size = %luK\n", size*4);
-
+
return 1;
}
int check_raid(int fd, char *name)
{
- void *super;
struct mdinfo info;
time_t crtime;
char *level;
struct supertype *st = guess_super(fd);
if (!st) return 0;
- st->ss->load_super(st, fd, &super, name);
+ st->ss->load_super(st, fd, name);
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
- st->ss->getinfo_super(&info, super);
- free(super);
+ st->ss->getinfo_super(st, &info);
+ st->ss->free_super(st);
crtime = info.array.ctime;
level = map_num(pers, info.array.level);
if (!level) level = "-unknown-";
{
/* tests if dev is a "standard" md dev name.
* i.e if the last component is "/dNN" or "/mdNN",
- * where NN is a string of digits
+ * where NN is a string of digits
*/
char *d = strrchr(dev, '/');
int type=0;
newcsum+= superc[i];
csum = (newcsum& 0xffffffff) + (newcsum>>32);
#ifdef __alpha__
-/* The in-kernel checksum calculation is always 16bit on
+/* The in-kernel checksum calculation is always 16bit on
* the alpha, though it is 32 bit on i386...
* I wonder what it is elsewhere... (it uses and API in
* a way that it shouldn't).
char *human_size_brief(long long bytes)
{
static char buf[30];
-
if (bytes < 5000*1024)
snprintf(buf, sizeof(buf), "%ld.%02ldKiB",
struct superswitch *superlist[] = { &super0, &super1, NULL };
-struct supertype *super_by_version(int vers, int minor)
+struct supertype *super_by_fd(int fd)
{
- struct supertype *st = malloc(sizeof(*st));
- if (!st) return st;
- if (vers == 0) {
- st->ss = &super0;
- st->max_devs = MD_SB_DISKS;
+ mdu_array_info_t array;
+ int vers;
+ int minor;
+ struct supertype *st = NULL;
+ struct mdinfo *sra;
+ char *verstr;
+ char version[20];
+ int i;
+
+ sra = sysfs_read(fd, 0, GET_VERSION);
+
+ if (sra) {
+ vers = sra->array.major_version;
+ minor = sra->array.minor_version;
+ verstr = sra->text_version;
+ } else {
+ if (ioctl(fd, GET_ARRAY_INFO, &array))
+ array.major_version = array.minor_version = 0;
+ vers = array.major_version;
+ minor = array.minor_version;
+ verstr = "";
}
- if (vers == 1) {
- st->ss = &super1;
- st->max_devs = 384;
+ if (vers != -1) {
+ sprintf(version, "%d.%d", vers, minor);
+ verstr = version;
}
- st->minor_version = minor;
+ for (i = 0; st == NULL && superlist[i] ; i++)
+ st = superlist[i]->match_metadata_desc(verstr);
+
+ if (sra)
+ sysfs_free(sra);
+ st->sb = NULL;
return st;
}
+struct supertype *dup_super(struct supertype *st)
+{
+ struct supertype *stnew = NULL;
+ char *verstr = NULL;
+ char version[20];
+ int i;
+
+ if (!st)
+ return st;
+
+ if (st->minor_version == -1)
+ sprintf(version, "%d", st->ss->major);
+ else
+ sprintf(version, "%d.%d", st->ss->major, st->minor_version);
+ verstr = version;
+
+ for (i = 0; stnew == NULL && superlist[i] ; i++)
+ stnew = superlist[i]->match_metadata_desc(verstr);
+
+ stnew->sb = NULL;
+ return stnew;
+}
+
struct supertype *guess_super(int fd)
{
/* try each load_super to find the best match,
struct supertype *st;
unsigned long besttime = 0;
int bestsuper = -1;
-
- void *sbp = NULL;
int i;
st = malloc(sizeof(*st));
int rv;
ss = superlist[i];
st->ss = NULL;
- rv = ss->load_super(st, fd, &sbp, NULL);
+ rv = ss->load_super(st, fd, NULL);
if (rv == 0) {
struct mdinfo info;
- ss->getinfo_super(&info, sbp);
+ st->ss->getinfo_super(st, &info);
if (bestsuper == -1 ||
besttime < info.array.ctime) {
bestsuper = i;
besttime = info.array.ctime;
}
- free(sbp);
+ ss->free_super(st);
}
}
if (bestsuper != -1) {
int rv;
st->ss = NULL;
- rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL);
+ rv = superlist[bestsuper]->load_super(st, fd, NULL);
if (rv == 0) {
- free(sbp);
+ superlist[bestsuper]->free_super(st);
return st;
}
}
int get_dev_size(int fd, char *dname, unsigned long long *sizep)
{
unsigned long long ldsize;
+ struct stat st;
+
+ if (fstat(fd, &st) != -1 && S_ISREG(st.st_mode))
+ ldsize = (unsigned long long)st.st_size;
+ else
#ifdef BLKGETSIZE64
if (ioctl(fd, BLKGETSIZE64, &ldsize) != 0)
#endif