#include <linux/magic.h>
#include <getopt.h>
+#include <btrfsutil.h>
+
#include "kerncompat.h"
#include "radix-tree.h"
#include "ctree.h"
memset(buf, 0, len);
ret = pwrite(fd, buf, len, offset);
if (ret < 0) {
- error("cannot wipe existing superblock: %s", strerror(errno));
+ error("cannot wipe existing superblock: %m");
ret = -1;
} else if (ret != len) {
error("cannot wipe existing superblock: wrote %d of %zd", ret, len);
ret = fstat(fd, &st);
if (ret < 0) {
- error("unable to stat %s: %s", file, strerror(errno));
+ error("unable to stat %s: %m", file);
return 1;
}
fd = open(dev, O_RDONLY);
if (fd < 0) {
ret = -errno;
- error("cannot open %s: %s", dev, strerror(errno));
+ error("cannot open %s: %m", dev);
goto out;
}
return -1;
}
ret = open_file_or_dir(mp, dirstream);
- error_on(verbose && ret < 0, "can't access '%s': %s",
- path, strerror(errno));
+ error_on(verbose && ret < 0, "can't access '%s': %m",
+ path);
} else {
ret = btrfs_open_dir(path, dirstream, 1);
}
int ret;
if (statfs(path, &stfs) != 0) {
- error_on(verbose, "cannot access '%s': %s", path,
- strerror(errno));
+ error_on(verbose, "cannot access '%s': %m", path);
return -1;
}
}
if (stat(path, &st) != 0) {
- error_on(verbose, "cannot access '%s': %s", path,
- strerror(errno));
+ error_on(verbose, "cannot access '%s': %m", path);
return -1;
}
ret = open_file_or_dir(path, dirstream);
if (ret < 0) {
- error_on(verbose, "cannot access '%s': %s", path,
- strerror(errno));
+ error_on(verbose, "cannot access '%s': %m", path);
}
return ret;
fd = open(file, O_RDONLY);
if (fd < 0) {
- error("mount check: cannot open %s: %s", file,
- strerror(errno));
+ error("mount check: cannot open %s: %m", file);
return -errno;
}
fd = open("/dev/btrfs-control", O_RDWR);
if (fd < 0) {
warning(
- "failed to open /dev/btrfs-control, skipping device registration: %s",
- strerror(errno));
+ "failed to open /dev/btrfs-control, skipping device registration: %m");
return -errno;
}
memset(&args, 0, sizeof(args));
strncpy_null(args.name, fname);
ret = ioctl(fd, BTRFS_IOC_SCAN_DEV, &args);
if (ret < 0) {
- error("device scan failed on '%s': %s", fname,
- strerror(errno));
+ error("device scan failed on '%s': %m", fname);
ret = -errno;
}
close(fd);
fd = open(mount_path, O_RDONLY | O_NOATIME);
if (fd < 0) {
- error("unable to access %s: %s", mount_path, strerror(errno));
+ error("unable to access %s: %m", mount_path);
return -1;
}
memset(label, 0, sizeof(label));
__strncpy_null(label, labelp, BTRFS_LABEL_SIZE - 1);
if (ioctl(fd, BTRFS_IOC_SET_FSLABEL, label) < 0) {
- error("unable to set label of %s: %s", mount_path,
- strerror(errno));
+ error("unable to set label of %s: %m", mount_path);
close(fd);
return -1;
}
fd = open(mount_path, O_RDONLY | O_NOATIME);
if (fd < 0) {
- error("unable to access %s: %s", mount_path, strerror(errno));
+ error("unable to access %s: %m", mount_path);
return -1;
}
ret = ioctl(fd, BTRFS_IOC_GET_FSLABEL, label);
if (ret < 0) {
if (errno != ENOTTY)
- error("unable to get label of %s: %s", mount_path,
- strerror(errno));
+ error("unable to get label of %s: %m", mount_path);
ret = -errno;
close(fd);
return ret;
char *s = strchr(p, '/');
const char *ptr_src_end = p + strlen(p);
char *ptr_parse_end = NULL;
+ enum btrfs_util_error err;
u64 level;
u64 id;
int fd;
path:
/* Path format like subv at 'my_subvol' is the fallback case */
- ret = test_issubvolume(p);
- if (ret < 0 || !ret)
+ err = btrfs_util_is_subvolume(p);
+ if (err)
goto err;
fd = open(p, O_RDONLY);
if (fd < 0)
fd = open(path, O_RDONLY);
if (fd < 0) {
ret = -errno;
- error("cannot open %s: %s", path, strerror(errno));
+ error("cannot open %s: %m", path);
goto out;
}
ret = check_mounted_where(fd, path, mp, sizeof(mp),
fd = open(path, O_RDONLY);
if (fd < 0) {
- error("cannot open %s: %s", path, strerror(errno));
+ error("cannot open %s: %m", path);
continue;
}
ret = btrfs_scan_one_device(fd, path, &tmp_devices,
strcmp(name, ".") && strcmp(name, "..");
}
-/*
- * Test if path is a subvolume
- * Returns:
- * 0 - path exists but it is not a subvolume
- * 1 - path exists and it is a subvolume
- * < 0 - error
- */
-int test_issubvolume(const char *path)
-{
- struct stat st;
- struct statfs stfs;
- int res;
-
- res = stat(path, &st);
- if (res < 0)
- return -errno;
-
- if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode))
- return 0;
-
- res = statfs(path, &stfs);
- if (res < 0)
- return -errno;
-
- return (int)stfs.f_type == BTRFS_SUPER_MAGIC;
-}
-
const char *subvol_strip_mountpoint(const char *mnt, const char *full_path)
{
int len = strlen(mnt);
if (!len)
return full_path;
+ if ((strncmp(mnt, full_path, len) != 0) || (full_path[len] != '/')) {
+ error("not on mount point: %s", mnt);
+ exit(1);
+ }
+
if (mnt[len - 1] != '/')
len += 1;
return full_path + len;
}
-/*
- * Returns
- * <0: Std error
- * 0: All fine
- * 1: Error; and error info printed to the terminal. Fixme.
- * 2: If the fullpath is root tree instead of subvol tree
- */
-int get_subvol_info(const char *fullpath, struct root_info *get_ri)
-{
- u64 sv_id;
- int ret = 1;
- int fd = -1;
- int mntfd = -1;
- char *mnt = NULL;
- const char *svpath = NULL;
- DIR *dirstream1 = NULL;
- DIR *dirstream2 = NULL;
-
- ret = test_issubvolume(fullpath);
- if (ret < 0)
- return ret;
- if (!ret) {
- error("not a subvolume: %s", fullpath);
- return 1;
- }
-
- ret = find_mount_root(fullpath, &mnt);
- if (ret < 0)
- return ret;
- if (ret > 0) {
- error("%s doesn't belong to btrfs mount point", fullpath);
- return 1;
- }
- ret = 1;
- svpath = subvol_strip_mountpoint(mnt, fullpath);
-
- fd = btrfs_open_dir(fullpath, &dirstream1, 1);
- if (fd < 0)
- goto out;
-
- ret = btrfs_list_get_path_rootid(fd, &sv_id);
- if (ret)
- goto out;
-
- mntfd = btrfs_open_dir(mnt, &dirstream2, 1);
- if (mntfd < 0)
- goto out;
-
- memset(get_ri, 0, sizeof(*get_ri));
- get_ri->root_id = sv_id;
-
- if (sv_id == BTRFS_FS_TREE_OBJECTID)
- ret = btrfs_get_toplevel_subvol(mntfd, get_ri);
- else
- ret = btrfs_get_subvol(mntfd, get_ri);
- if (ret)
- error("can't find '%s': %d", svpath, ret);
-
-out:
- close_file_or_dir(mntfd, dirstream2);
- close_file_or_dir(fd, dirstream1);
- free(mnt);
-
- return ret;
-}
-
-int get_subvol_info_by_rootid(const char *mnt, struct root_info *get_ri, u64 r_id)
-{
- int fd;
- int ret;
- DIR *dirstream = NULL;
-
- fd = btrfs_open_dir(mnt, &dirstream, 1);
- if (fd < 0)
- return -EINVAL;
-
- memset(get_ri, 0, sizeof(*get_ri));
- get_ri->root_id = r_id;
-
- if (r_id == BTRFS_FS_TREE_OBJECTID)
- ret = btrfs_get_toplevel_subvol(fd, get_ri);
- else
- ret = btrfs_get_subvol(fd, get_ri);
-
- if (ret)
- error("can't find rootid '%llu' on '%s': %d", r_id, mnt, ret);
-
- close_file_or_dir(fd, dirstream);
-
- return ret;
-}
-
-int get_subvol_info_by_uuid(const char *mnt, struct root_info *get_ri, u8 *uuid_arg)
-{
- int fd;
- int ret;
- DIR *dirstream = NULL;
-
- fd = btrfs_open_dir(mnt, &dirstream, 1);
- if (fd < 0)
- return -EINVAL;
-
- memset(get_ri, 0, sizeof(*get_ri));
- uuid_copy(get_ri->uuid, uuid_arg);
-
- ret = btrfs_get_subvol(fd, get_ri);
- if (ret) {
- char uuid_parsed[BTRFS_UUID_UNPARSED_SIZE];
- uuid_unparse(uuid_arg, uuid_parsed);
- error("can't find uuid '%s' on '%s': %d",
- uuid_parsed, mnt, ret);
- }
-
- close_file_or_dir(fd, dirstream);
-
- return ret;
-}
-
/* Set the seed manually */
void init_rand_seed(u64 seed)
{