diff options
author | NeilBrown <neilb@suse.de> | 2010-11-22 10:58:06 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-11-22 10:58:06 +0100 |
commit | 52e965c2969723c80fd50d393a7e15658bc217c9 (patch) | |
tree | da1a15d083cc46e9c84a8787ca13da6da5d64d80 /Incremental.c | |
parent | extension of IncrementalRemove to store location (path-id) of removed device (diff) | |
download | mdadm-52e965c2969723c80fd50d393a7e15658bc217c9.tar.xz mdadm-52e965c2969723c80fd50d393a7e15658bc217c9.zip |
Factor out is_bare test.
Instead of open coding (and using horrible gotos), make this
a separate function.
Also fix the check for end of device - SEEK_END doesn't work on
block devices.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to '')
-rw-r--r-- | Incremental.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/Incremental.c b/Incremental.c index 7b43963c..35ad221a 100644 --- a/Incremental.c +++ b/Incremental.c @@ -1030,6 +1030,34 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, return 0; } +static int is_bare(int dfd) +{ + unsigned long long size = 0; + char bufpad[4096 + 4096]; + char *buf = (char*)(((long)bufpad + 4096) & ~4095); + + if (lseek(dfd, 0, SEEK_SET) != 0 || + read(dfd, buf, 4096) != 4096) + return 0; + + if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff') + return 0; + if (memcmp(buf, buf+1, 4095) != 0) + return 0; + + /* OK, first 4K appear blank, try the end. */ + get_dev_size(dfd, NULL, &size); + if (lseek(dfd, size-4096, SEEK_SET) < 0 || + read(dfd, buf, 4096) != 4096) + return 0; + + if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff') + return 0; + if (memcmp(buf, buf+1, 4095) != 0) + return 0; + + return 1; +} /* adding a spare to a regular array is quite different from adding one to * a set-of-partitions virtual array. @@ -1043,8 +1071,6 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol, int rv; int arrays_ok = 0; int partitions_ok = 0; - char bufpad[4096 + 4096]; - char *buf = (char*)(((long)bufpad + 4096) & ~4095); int dfd = *dfdp; /* Can only add a spare if device has at least one domains */ @@ -1058,28 +1084,12 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol, * yet even if action=-spare */ - if (lseek(dfd, 0, SEEK_SET) != 0 || - read(dfd, buf, 4096) != 4096) { - not_bare: + if (!is_bare(dfd)) { if (verbose > 1) fprintf(stderr, Name ": %s is not bare, so not considering as a spare\n", devname); return 1; } - if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff') - goto not_bare; - if (memcmp(buf, buf+1, 4095) != 0) - goto not_bare; - - /* OK, first 4K appear blank, try the end. */ - if (lseek(dfd, -4096, SEEK_END) < 0 || - read(dfd, buf, 4096) != 4096) - goto not_bare; - - if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff') - goto not_bare; - if (memcmp(buf, buf+1, 4095) != 0) - goto not_bare; /* This device passes our test for 'is bare'. * Let's see what policy allows for such things. |