X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fpath-util.c;h=8f49d652664fcf2b63aa29740da6c61f741e350f;hp=8be479cd7fcab6b4ee6d03695127abda1fb780bf;hb=ebbac6d948b9d323b3d57bfd7c3513776e591dc1;hpb=07db2f78ec6a39bdd05a8481578a641efbab3a2c diff --git a/src/shared/path-util.c b/src/shared/path-util.c index 8be479cd7..8f49d6526 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -528,7 +528,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { * * If that didn't work we will try to read the mount id from * /proc/self/fdinfo/. This is almost as good as - * name_to_handle_at(), however, does not return the the + * name_to_handle_at(), however, does not return the * opaque file handle. The opaque file handle is pretty useful * to detect the root directory, which we should always * consider a mount point. Hence we use this only as @@ -637,9 +637,10 @@ fallback_fstat: return check_st_dev && (a.st_dev != b.st_dev); } -int path_is_mount_point(const char *t, bool allow_symlink) { +/* flags can be AT_SYMLINK_FOLLOW or 0 */ +int path_is_mount_point(const char *t, int flags) { _cleanup_close_ int fd = -1; - _cleanup_free_ char *parent = NULL; + _cleanup_free_ char *canonical = NULL, *parent = NULL; int r; assert(t); @@ -647,7 +648,17 @@ int path_is_mount_point(const char *t, bool allow_symlink) { if (path_equal(t, "/")) return 1; - r = path_get_parent(t, &parent); + /* we need to resolve symlinks manually, we can't just rely on + * fd_is_mount_point() to do that for us; if we have a structure like + * /bin -> /usr/bin/ and /usr is a mount point, then the parent that we + * look at needs to be /usr, not /. */ + if (flags & AT_SYMLINK_FOLLOW) { + canonical = canonicalize_file_name(t); + if (!canonical) + return -errno; + } + + r = path_get_parent(canonical ?: t, &parent); if (r < 0) return r; @@ -655,7 +666,7 @@ int path_is_mount_point(const char *t, bool allow_symlink) { if (fd < 0) return -errno; - return fd_is_mount_point(fd, basename(t), (allow_symlink ? AT_SYMLINK_FOLLOW : 0)); + return fd_is_mount_point(fd, basename(canonical ?: t), flags); } int path_is_read_only_fs(const char *path) {