]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Fix "--remove faulty" and similar commands.
authorNeilBrown <neilb@suse.de>
Tue, 27 Nov 2012 23:12:09 +0000 (10:12 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 27 Nov 2012 23:12:09 +0000 (10:12 +1100)
A recent change to improve error messages for subdev management broken
all use cases were device names like %d:%d were used.
Re-arrange the code again so we use dev_open first - which understands
those names - and then only try 'stat' if that failed.
The important thing is to base the 'Cannot find' message on the result
of 'stat', not on the result of 'open'.

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

index 8ed1a1a7fe34b9c220e9363df36d522fe49ea38d..3d713a32a3520eb6e3259482b49836bc956e0576 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -1205,38 +1205,37 @@ int Manage_subdevs(char *devname, int fd,
                                }
                        }
                } else {
-                       if (stat(dv->devname, &stb) != 0) {
-                               pr_err("Cannot find %s: %s\n",
-                                      dv->devname, strerror(errno));
-                               goto abort;
-                       }
-                       if ((stb.st_mode & S_IFMT) != S_IFBLK) {
-                               if (dv->disposition == 'M')
-                                       /* non-fatal. Also improbable */
-                                       continue;
-                               pr_err("%s is not a block device.\n",
-                                       dv->devname);
-                               goto abort;
-                       }
                        tfd = dev_open(dv->devname, O_RDONLY);
-                       if (tfd < 0 && dv->disposition == 'r')
-                               /* Be happy, the stat worked, that is
-                                * enough for --remove
-                                */
-                               ;
+                       if (tfd >= 0)
+                               fstat(tfd, &stb);
                        else {
-                               if (tfd < 0 || fstat(tfd, &stb) != 0) {
-                                       if (tfd >= 0)
-                                               close(tfd);
+                               int open_err = errno;
+                               if (stat(dv->devname, &stb) != 0) {
+                                       pr_err("Cannot find %s: %s\n",
+                                              dv->devname, strerror(errno));
+                                       goto abort;
+                               }
+                               if ((stb.st_mode & S_IFMT) != S_IFBLK) {
+                                       if (dv->disposition == 'M')
+                                               /* non-fatal. Also improbable */
+                                               continue;
+                                       pr_err("%s is not a block device.\n",
+                                              dv->devname);
+                                       goto abort;
+                               }
+                               if (dv->disposition == 'r')
+                                       /* Be happy, the stat worked, that is
+                                        * enough for --remove
+                                        */
+                                       ;
+                               else {
                                        if (dv->disposition == 'M')
                                                /* non-fatal */
                                                continue;
                                        pr_err("Cannot open %s: %s\n",
-                                               dv->devname, strerror(errno));
+                                              dv->devname, strerror(open_err));
                                        goto abort;
                                }
-                               close(tfd);
-                               tfd = -1;
                        }
                }
                switch(dv->disposition){