]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: disallow placing backup file on array being reshaped.
authorNeilBrown <neilb@suse.de>
Wed, 1 Dec 2010 00:58:32 +0000 (11:58 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 10 Mar 2011 06:19:20 +0000 (17:19 +1100)
the tests here aren't perfect, but they could catch some cases.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c

diff --git a/Grow.c b/Grow.c
index bcb84a882bb995a189082b2026aba01352459f77..61e7ab89425699bb4dbdc8d69dd742a7a1345795 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1051,6 +1051,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                } 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;
@@ -1060,6 +1062,22 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                                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 < (signed)blocks + 8 ; i++) {
                                if (write(fdlist[d], buf, 512) != 512) {