|
|
740027 |
diff -urNp coreutils-8.22-orig/src/df.c coreutils-8.22/src/df.c
|
|
|
740027 |
--- coreutils-8.22-orig/src/df.c 2015-07-03 15:51:44.293116375 +0200
|
|
|
740027 |
+++ coreutils-8.22/src/df.c 2015-07-03 16:02:48.743390691 +0200
|
|
|
740027 |
@@ -1057,6 +1057,33 @@ get_dev (char const *disk, char const *m
|
|
|
740027 |
free (dev_name);
|
|
|
740027 |
}
|
|
|
740027 |
|
|
|
740027 |
+/* Scan the mount list returning the _last_ device found for MOUNT.
|
|
|
740027 |
+ NULL is returned if MOUNT not found. The result is malloced. */
|
|
|
740027 |
+static char *
|
|
|
740027 |
+last_device_for_mount (char const* mount)
|
|
|
740027 |
+{
|
|
|
740027 |
+ struct mount_entry const *me;
|
|
|
740027 |
+ struct mount_entry const *le = NULL;
|
|
|
740027 |
+
|
|
|
740027 |
+ for (me = mount_list; me; me = me->me_next)
|
|
|
740027 |
+ {
|
|
|
740027 |
+ if (STREQ (me->me_mountdir, mount))
|
|
|
740027 |
+ le = me;
|
|
|
740027 |
+ }
|
|
|
740027 |
+
|
|
|
740027 |
+ if (le)
|
|
|
740027 |
+ {
|
|
|
740027 |
+ char *devname = le->me_devname;
|
|
|
740027 |
+ char *canon_dev = canonicalize_file_name (devname);
|
|
|
740027 |
+ if (canon_dev && IS_ABSOLUTE_FILE_NAME (canon_dev))
|
|
|
740027 |
+ return canon_dev;
|
|
|
740027 |
+ free (canon_dev);
|
|
|
740027 |
+ return xstrdup (le->me_devname);
|
|
|
740027 |
+ }
|
|
|
740027 |
+ else
|
|
|
740027 |
+ return NULL;
|
|
|
740027 |
+}
|
|
|
740027 |
+
|
|
|
740027 |
/* If DISK corresponds to a mount point, show its usage
|
|
|
740027 |
and return true. Otherwise, return false. */
|
|
|
740027 |
static bool
|
|
|
740027 |
@@ -1064,27 +1091,57 @@ get_disk (char const *disk)
|
|
|
740027 |
{
|
|
|
740027 |
struct mount_entry const *me;
|
|
|
740027 |
struct mount_entry const *best_match = NULL;
|
|
|
740027 |
+ bool best_match_accessible = false;
|
|
|
740027 |
+ bool eclipsed_device = false;
|
|
|
740027 |
char const *file = disk;
|
|
|
740027 |
|
|
|
740027 |
char *resolved = canonicalize_file_name (disk);
|
|
|
740027 |
- if (resolved && resolved[0] == '/')
|
|
|
740027 |
+ if (resolved && IS_ABSOLUTE_FILE_NAME (resolved))
|
|
|
740027 |
disk = resolved;
|
|
|
740027 |
|
|
|
740027 |
size_t best_match_len = SIZE_MAX;
|
|
|
740027 |
for (me = mount_list; me; me = me->me_next)
|
|
|
740027 |
{
|
|
|
740027 |
- if (STREQ (disk, me->me_devname))
|
|
|
740027 |
+ /* TODO: Should cache canon_dev in the mount_entry struct. */
|
|
|
740027 |
+ char *devname = me->me_devname;
|
|
|
740027 |
+ char *canon_dev = canonicalize_file_name (me->me_devname);
|
|
|
740027 |
+ if (canon_dev && IS_ABSOLUTE_FILE_NAME (canon_dev))
|
|
|
740027 |
+ devname = canon_dev;
|
|
|
740027 |
+
|
|
|
740027 |
+ if (STREQ (disk, devname))
|
|
|
740027 |
{
|
|
|
740027 |
+ char *last_device = last_device_for_mount (me->me_mountdir);
|
|
|
740027 |
+ eclipsed_device = last_device && ! STREQ (last_device, devname);
|
|
|
740027 |
size_t len = strlen (me->me_mountdir);
|
|
|
740027 |
- if (len < best_match_len)
|
|
|
740027 |
+
|
|
|
740027 |
+ if (! eclipsed_device
|
|
|
740027 |
+ && (! best_match_accessible || len < best_match_len))
|
|
|
740027 |
{
|
|
|
740027 |
- best_match = me;
|
|
|
740027 |
- if (len == 1) /* Traditional root. */
|
|
|
740027 |
- break;
|
|
|
740027 |
- else
|
|
|
740027 |
- best_match_len = len;
|
|
|
740027 |
+ struct stat disk_stats;
|
|
|
740027 |
+ bool this_match_accessible = false;
|
|
|
740027 |
+
|
|
|
740027 |
+ if (stat (me->me_mountdir, &disk_stats) == 0)
|
|
|
740027 |
+ best_match_accessible = this_match_accessible = true;
|
|
|
740027 |
+
|
|
|
740027 |
+ if (this_match_accessible
|
|
|
740027 |
+ || (! best_match_accessible && len < best_match_len))
|
|
|
740027 |
+ {
|
|
|
740027 |
+ best_match = me;
|
|
|
740027 |
+ if (len == 1) /* Traditional root. */
|
|
|
740027 |
+ {
|
|
|
740027 |
+ free (last_device);
|
|
|
740027 |
+ free (canon_dev);
|
|
|
740027 |
+ break;
|
|
|
740027 |
+ }
|
|
|
740027 |
+ else
|
|
|
740027 |
+ best_match_len = len;
|
|
|
740027 |
+ }
|
|
|
740027 |
}
|
|
|
740027 |
+
|
|
|
740027 |
+ free (last_device);
|
|
|
740027 |
}
|
|
|
740027 |
+
|
|
|
740027 |
+ free (canon_dev);
|
|
|
740027 |
}
|
|
|
740027 |
|
|
|
740027 |
free (resolved);
|
|
|
740027 |
@@ -1096,6 +1153,13 @@ get_disk (char const *disk)
|
|
|
740027 |
best_match->me_remote, NULL, false);
|
|
|
740027 |
return true;
|
|
|
740027 |
}
|
|
|
740027 |
+ else if (eclipsed_device)
|
|
|
740027 |
+ {
|
|
|
740027 |
+ error (0, 0, _("cannot access %s: over-mounted by another device"),
|
|
|
740027 |
+ quote (file));
|
|
|
740027 |
+ exit_status = EXIT_FAILURE;
|
|
|
740027 |
+ return true;
|
|
|
740027 |
+ }
|
|
|
740027 |
|
|
|
740027 |
return false;
|
|
|
740027 |
}
|