diff options
author | Doug Ledford <dledford@redhat.com> | 2010-04-16 17:53:45 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2010-04-16 17:53:45 -0400 |
commit | 0dba81619de300d36684371b7aaf22e69da1df91 (patch) | |
tree | 7d3e3f69b2ea597f11aad82d2140d58c8b639791 | |
parent | eda79540d4fee8b0f2eb872eed9e372091714379 (diff) | |
download | mdadm-0dba81619de300d36684371b7aaf22e69da1df91.tar.gz mdadm-0dba81619de300d36684371b7aaf22e69da1df91.tar.xz mdadm-0dba81619de300d36684371b7aaf22e69da1df91.zip |
Add check_clean() function
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | Incremental.c | 16 | ||||
-rw-r--r-- | mdadm.h | 1 | ||||
-rw-r--r-- | util.c | 29 |
3 files changed, 40 insertions, 6 deletions
diff --git a/Incremental.c b/Incremental.c index 8bc455d..d3dd0c3 100644 --- a/Incremental.c +++ b/Incremental.c @@ -941,7 +941,7 @@ static int IncrementalNewDisk(char *devname, int verbose, int export, struct domain_ent *domain) { struct stat stb; - int dfd; + int dfd, rv; dfd = dev_open_check(devname, O_RDONLY|O_EXCL, &stb); if (dfd < 0) @@ -954,8 +954,11 @@ static int IncrementalNewDisk(char *devname, int verbose, int export, close(dfd); return 1; } - if (domain->handler->check_table(dfd, verbose, export, domain) == 0) + + if (domain->handler->check_table(dfd, verbose, export, domain) == 0) { + close(dfd); return 0; + } /* * OK, at this point we have a valid block device without a * superblock, the partition table doesn't match, and we are a @@ -965,10 +968,11 @@ static int IncrementalNewDisk(char *devname, int verbose, int export, * last 4k of the device must be one of three patterns: 0x00, 0x5a, * or 0xff. */ - if (force(domain)) - return domain->handler->write_table(dfd, verbose, export, - domain); - return 0; + if (check_clean(dfd) || force(domain)) { + rv = domain->handler->write_table(dfd, verbose, export, domain); + } + close(dfd); + return rv; } /* @@ -893,6 +893,7 @@ extern int parse_layout_faulty(char *layout); extern int check_ext2(int fd, char *name); extern int check_reiser(int fd, char *name); extern int check_raid(int fd, char *name); +extern int check_clean(int fd); extern int check_partitions(int fd, char *dname, unsigned long long freesize); extern int get_mdp_major(void); @@ -511,6 +511,35 @@ int check_raid(int fd, char *name) return 1; } +int check_clean(int dfd) +{ + void *head, *tail, *pattern; + int i=0, head_clean=0, tail_clean=0; + unsigned char patterns[]={0x00,0x5a,0xff}; + + head = malloc(4096); + tail = malloc(4096); + pattern = malloc(4096); + if (!head || !tail || !pattern) + return 0; + if (lseek(dfd, 0, SEEK_SET) == -1) + return 0; + if (read(dfd, head, 4096) != 4096) + return 0; + if (lseek(dfd, -4096, SEEK_END) == -1) + return 0; + if (read(dfd, tail, 4096) != 4096) + return 0; + while (i < 3) { + memset(pattern, patterns[i++], 4096); + if (memcmp(head, pattern, 4096) == 0) + head_clean++; + if (memcmp(tail, pattern, 4096) == 0) + tail_clean++; + } + return (head_clean && tail_clean); +} + int ask(char *mesg) { char *add = ""; |