All of lore.kernel.org
 help / color / mirror / Atom feed
From: "James Johnston" <johnstonj.public@codenest.com>
To: <grub-devel@gnu.org>
Subject: [PATCH] getroot: Correctly handle missing btrfs device identifiers.
Date: Thu, 17 Mar 2016 15:32:18 -0000	[thread overview]
Message-ID: <026101d18062$31bd87b0$95389710$@codenest.com> (raw)

From 97bcb9eb8c34329a8ca1ec88fd89296e273ceb24 Mon Sep 17 00:00:00 2001
From: James Johnston <johnstonj.public@codenest.com>
Date: Thu, 17 Mar 2016 15:10:49 +0000
Subject: [PATCH] getroot: Correctly handle missing btrfs device identifiers.

The btrfs driver's BTRFS_IOC_FS_INFO ioctl only tells you the maximum
device ID and the number of devices.  It does not tell you which
device IDs may no longer be allocated - for example, if a device is
later deleted from the file system, its device ID won't be allocated
any more.

You must then probe each device ID with BTRFS_IOC_DEV_INFO to see if
it is a valid device or not.  It is not an error condition for this
ioctl to return ENODEV: it seems to mean that the device was deleted
by the user.

Signed-off-by: James Johnston <johnstonj.public@codenest.com>
---
 grub-core/osdep/linux/getroot.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
index 10480b6..852f3a2 100644
--- a/grub-core/osdep/linux/getroot.c
+++ b/grub-core/osdep/linux/getroot.c
@@ -242,15 +242,29 @@ grub_find_root_devices_from_btrfs (const char *dir)
       struct btrfs_ioctl_dev_info_args devi;
       memset (&devi, 0, sizeof (devi));
       devi.devid = i;
+      /* We have to probe all possible device IDs, since btrfs doesn't
+	 give us a list of all the valid ones.  */
       if (ioctl (fd, BTRFS_IOC_DEV_INFO, &devi) < 0)
 	{
-	  close (fd);
-	  free (ret);
-	  return NULL;
+	  /* ENODEV is normal, e.g. if the first device is deleted from
+	     an array. */
+	  int last_error = errno;
+	  if (last_error != ENODEV)
+	    {
+	      grub_util_warn(_("btrfs device info could not be read "
+			       "for %s, device %d: errno %d"), dir, i,
+			       last_error);
+	      close (fd);
+	      free (ret);
+	      return NULL;
+	    }
+	}
+      else
+	{
+	  ret[j++] = xstrdup ((char *) devi.path);
+	  if (j >= fsi.num_devices)
+	    break;
 	}
-      ret[j++] = xstrdup ((char *) devi.path);
-      if (j >= fsi.num_devices)
-	break;
     }
   close (fd);
   ret[j] = 0;
-- 
1.9.5.msysgit.1





             reply	other threads:[~2016-03-17 15:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-17 15:32 James Johnston [this message]
  -- strict thread matches above, loose matches on Subject: below --
2016-03-17 15:41 [PATCH] getroot: Correctly handle missing btrfs device identifiers James Johnston
2016-03-17 17:11 ` Andrei Borzenkov
2016-03-18  4:48 James Johnston

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='026101d18062$31bd87b0$95389710$@codenest.com' \
    --to=johnstonj.public@codenest.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.