[systemd-devel] [PATCH 2/6] readahead-common:fs_on_ssd() stat might not get the real device name
harald at redhat.com
harald at redhat.com
Fri Sep 24 03:06:00 PDT 2010
From: Harald Hoyer <harald at redhat.com>
btrfs returns a major(0) for its device, so try to find the mountpoint and real device.
---
src/readahead-common.c | 36 ++++++++++++++++++++++++++++++++++--
1 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/src/readahead-common.c b/src/readahead-common.c
index 8533717..1ff027d 100644
--- a/src/readahead-common.c
+++ b/src/readahead-common.c
@@ -51,6 +51,25 @@ int file_verify(int fd, const char *fn, struct stat *st) {
return 1;
}
+static char *get_devname(const char *mountpoint)
+{
+ FILE *fp;
+ int maj, min;
+ char mp[1024], dev[1024];
+
+ fp = fopen("/proc/self/mountinfo", "r");
+ if (fp == NULL)
+ return NULL;
+ while (fscanf(fp, "%*s %*s %i:%i %*s %1024s %*s %*s %*s %1024s %*[^\n]", &maj, &min, mp, dev) == 4) {
+ if (strcmp(mountpoint, mp) == 0) {
+ fclose(fp);
+ return strdup(dev);
+ }
+ }
+ fclose(fp);
+ return NULL;
+}
+
int fs_on_ssd(const char *p) {
struct stat st;
struct udev *udev = NULL;
@@ -66,8 +85,21 @@ int fs_on_ssd(const char *p) {
if (!(udev = udev_new()))
return -ENOMEM;
- if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
- goto finish;
+ if (major(st.st_dev) == 0) {
+ /* special device, might be on a btrfs */
+ int ret = -1;
+ char *devname = get_devname(p);
+ if (devname == NULL)
+ return -EINVAL;
+ ret = stat(devname, &st);
+ free(devname);
+ if (ret < 0) {
+ return -EINVAL;
+ }
+ }
+
+ if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
+ goto finish;
if ((devtype = udev_device_get_property_value(udev_device, "DEVTYPE")) &&
streq(devtype, "partition"))
--
1.7.3
More information about the systemd-devel
mailing list