From d5bd0a1f8461132af3a7d1d681d836a2e4807cf4 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Tue, 12 Nov 2013 13:41:44 +0000 Subject: Btrfs-progs: fix detection of root objects in cmds-property.c Several fixes: 1) The function check_is_root() returns 0 if the object is root; 2) Don't treat any error from get fsid ioctl as meaning the target is root. Only -ENOTTY means it's a root (parent directory is not a btrfs fs) and a -ENOTDIR means our target object is not a directory, therefore it can be the root; 3) Fix the comparison of the target and target's parent fs ids. If they are different, it means the target is a mount point in a btrfs fs, therefore it's a root, otherwise it isn't. Signed-off-by: Filipe David Borba Manana Signed-off-by: David Sterba Signed-off-by: Chris Mason --- cmds-property.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'cmds-property.c') diff --git a/cmds-property.c b/cmds-property.c index 6699e615..3d1f18cf 100644 --- a/cmds-property.c +++ b/cmds-property.c @@ -75,7 +75,7 @@ static int parse_prop(const char *arg, const struct prop_handler *props, return -1; } -static int get_fsid(const char *path, u8 *fsid) +static int get_fsid(const char *path, u8 *fsid, int silent) { int ret; int fd; @@ -84,7 +84,8 @@ static int get_fsid(const char *path, u8 *fsid) fd = open(path, O_RDONLY); if (fd < 0) { ret = -errno; - fprintf(stderr, "ERROR: open %s failed. %s\n", path, + if (!silent) + fprintf(stderr, "ERROR: open %s failed. %s\n", path, strerror(-ret)); goto out; } @@ -109,7 +110,7 @@ static int check_btrfs_object(const char *object) int ret; u8 fsid[BTRFS_FSID_SIZE]; - ret = get_fsid(object, fsid); + ret = get_fsid(object, fsid, 0); if (ret < 0) ret = 0; else @@ -134,20 +135,27 @@ static int check_is_root(const char *object) strcat(tmp, "/"); strcat(tmp, ".."); - ret = get_fsid(object, fsid); + ret = get_fsid(object, fsid, 0); if (ret < 0) { fprintf(stderr, "ERROR: get_fsid for %s failed. %s\n", object, strerror(-ret)); goto out; } - ret = get_fsid(tmp, fsid2); - if (ret < 0) { + ret = get_fsid(tmp, fsid2, 1); + if (ret == -ENOTTY) { ret = 0; goto out; + } else if (ret == -ENOTDIR) { + ret = 1; + goto out; + } else if (ret < 0) { + fprintf(stderr, "ERROR: get_fsid for %s failed. %s\n", tmp, + strerror(-ret)); + goto out; } - if (!memcmp(fsid, fsid2, BTRFS_FSID_SIZE)) { + if (memcmp(fsid, fsid2, BTRFS_FSID_SIZE)) { ret = 0; goto out; } @@ -195,7 +203,7 @@ static int autodetect_object_types(const char *object, int *types_out) ret = check_is_root(object); if (ret < 0) goto out; - if (ret) + if (!ret) types |= prop_object_root; } -- cgit v1.2.3