summaryrefslogtreecommitdiff
path: root/c_src
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-04-15 11:04:11 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-04-15 11:28:47 -0400
commit0335994507e6482e42a176d52c484f2ec4fc12ba (patch)
tree15006870aaf3dd7bcfc665e3741d070e8193b708 /c_src
parentae29e3069f0ba123967b597119a480cafb4c8e69 (diff)
Fix bchu_fs_open_by_dev()
- we can now correctly open by parsing sysfs, instead of falling back to reading the superblock and grabbing the UUID - non-UUID filesystem names now work Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'c_src')
-rw-r--r--c_src/libbcachefs.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/c_src/libbcachefs.c b/c_src/libbcachefs.c
index 31644ea1..e2664642 100644
--- a/c_src/libbcachefs.c
+++ b/c_src/libbcachefs.c
@@ -407,12 +407,12 @@ void bcache_fs_close(struct bchfs_handle fs)
xclose(fs.sysfs_fd);
}
-static int bcache_fs_open_by_uuid(const char *uuid_str, struct bchfs_handle *fs)
+static int bcache_fs_open_by_name(const char *name, struct bchfs_handle *fs)
{
- if (uuid_parse(uuid_str, fs->uuid.b))
- return -1;
+ if (uuid_parse(name, fs->uuid.b))
+ memset(&fs->uuid, 0, sizeof(fs->uuid));
- char *sysfs = mprintf(SYSFS_BASE "%s", uuid_str);
+ char *sysfs = mprintf(SYSFS_BASE "%s", name);
fs->sysfs_fd = open(sysfs, O_RDONLY);
free(sysfs);
@@ -434,7 +434,7 @@ int bcache_fs_open_fallible(const char *path, struct bchfs_handle *fs)
fs->dev_idx = -1;
if (!uuid_parse(path, fs->uuid.b))
- return bcache_fs_open_by_uuid(path, fs);
+ return bcache_fs_open_by_name(path, fs);
/* It's a path: */
int path_fd = open(path, O_RDONLY);
@@ -505,7 +505,7 @@ read_super:
bch2_free_super(&sb);
}
- return bcache_fs_open_by_uuid(uuid_str, fs);
+ return bcache_fs_open_by_name(uuid_str, fs);
}
struct bchfs_handle bcache_fs_open(const char *path)
@@ -524,14 +524,14 @@ struct bchfs_handle bcache_fs_open(const char *path)
struct bchfs_handle bchu_fs_open_by_dev(const char *path, int *idx)
{
struct bch_opts opts = bch2_opts_empty();
- char buf[1024], *uuid_str;
+ char buf[1024], *fs_str;
struct stat stat = xstat(path);
if (S_ISBLK(stat.st_mode)) {
char *sysfs = mprintf("/sys/dev/block/%u:%u/bcachefs",
- major(stat.st_dev),
- minor(stat.st_dev));
+ major(stat.st_rdev),
+ minor(stat.st_rdev));
ssize_t len = readlink(sysfs, buf, sizeof(buf));
free(sysfs);
@@ -539,13 +539,19 @@ struct bchfs_handle bchu_fs_open_by_dev(const char *path, int *idx)
if (len <= 0)
goto read_super;
- char *p = strrchr(buf, '/');
- if (!p || sscanf(p + 1, "dev-%u", idx) != 1)
+ fs_str = strstr(buf, "bcachefs/");
+ if (!fs_str)
die("error parsing sysfs");
- *p = '\0';
- p = strrchr(buf, '/');
- uuid_str = p + 1;
+ fs_str += 9;
+ char *dev_str = strchr(fs_str, '/');
+ if (!dev_str)
+ die("error parsing sysfs");
+
+ *dev_str = '\0';
+ dev_str++;
+ if (sscanf(dev_str, "dev-%u", idx) != 1)
+ die("error parsing sysfs");
} else {
read_super:
opt_set(opts, noexcl, true);
@@ -557,13 +563,18 @@ read_super:
die("Error opening %s: %s", path, strerror(-ret));
*idx = sb.sb->dev_idx;
- uuid_str = buf;
- uuid_unparse(sb.sb->user_uuid.b, uuid_str);
+ fs_str = buf;
+ uuid_unparse(sb.sb->user_uuid.b, fs_str);
bch2_free_super(&sb);
}
- return bcache_fs_open(uuid_str);
+ struct bchfs_handle fs;
+ int ret = bcache_fs_open_by_name(fs_str, &fs);
+ if (ret)
+ die("Error opening filesystem at %s (%s): %s",
+ path, fs_str, strerror(-ret));
+ return fs;
}
int bchu_dev_path_to_idx(struct bchfs_handle fs, const char *dev_path)