mirror of
https://github.com/systemd/systemd
synced 2025-10-06 00:13:24 +02:00
btrfs: use unpriv subvol info ioctl (#38230)
Let's stop doing privileged low-level ioctls, if we also can get unprivileged high-level ioctls for the same.
This commit is contained in:
@@ -299,23 +299,6 @@ static int btrfs_iterate(BtrfsForeachIterator *i) {
|
||||
btrfs_iterate(&iterator) > 0; )
|
||||
|
||||
int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *ret) {
|
||||
struct btrfs_ioctl_search_args args = {
|
||||
/* Tree of tree roots */
|
||||
.key.tree_id = BTRFS_ROOT_TREE_OBJECTID,
|
||||
|
||||
/* Look precisely for the subvolume items */
|
||||
.key.min_type = BTRFS_ROOT_ITEM_KEY,
|
||||
.key.max_type = BTRFS_ROOT_ITEM_KEY,
|
||||
|
||||
.key.min_offset = 0,
|
||||
.key.max_offset = UINT64_MAX,
|
||||
|
||||
/* No restrictions on the other components */
|
||||
.key.min_transid = 0,
|
||||
.key.max_transid = UINT64_MAX,
|
||||
};
|
||||
|
||||
bool found = false;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
@@ -327,66 +310,30 @@ int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *ret) {
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if (subvol_id == 0) {
|
||||
r = btrfs_subvol_get_id_fd(fd, &subvol_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
r = fd_is_fs_type(fd, BTRFS_SUPER_MAGIC);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -ENOTTY;
|
||||
}
|
||||
r = fd_is_fs_type(fd, BTRFS_SUPER_MAGIC);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -ENOTTY;
|
||||
|
||||
args.key.min_objectid = args.key.max_objectid = subvol_id;
|
||||
struct btrfs_ioctl_get_subvol_info_args info;
|
||||
if (ioctl(fd, BTRFS_IOC_GET_SUBVOL_INFO, &info) < 0)
|
||||
return -errno;
|
||||
|
||||
while (btrfs_ioctl_search_args_compare(&args) <= 0) {
|
||||
struct btrfs_ioctl_search_header sh;
|
||||
const void *body;
|
||||
*ret = (BtrfsSubvolInfo) {
|
||||
.subvol_id = info.treeid,
|
||||
.otime = info.otime.sec * USEC_PER_SEC + (info.otime.nsec / NSEC_PER_USEC),
|
||||
.ctime = info.ctime.sec * USEC_PER_SEC + (info.ctime.nsec / NSEC_PER_USEC),
|
||||
.read_only = FLAGS_SET(info.flags, BTRFS_SUBVOL_RDONLY),
|
||||
};
|
||||
|
||||
args.key.nr_items = 256;
|
||||
if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0)
|
||||
return -errno;
|
||||
assert_cc(sizeof(info.uuid) == sizeof(sd_id128_t));
|
||||
memcpy(&ret->uuid, info.uuid, sizeof(sd_id128_t));
|
||||
|
||||
if (args.key.nr_items <= 0)
|
||||
break;
|
||||
assert_cc(sizeof(info.parent_uuid) == sizeof(sd_id128_t));
|
||||
memcpy(&ret->parent_uuid, info.parent_uuid, sizeof(sd_id128_t));
|
||||
|
||||
FOREACH_BTRFS_IOCTL_SEARCH_HEADER(sh, body, args) {
|
||||
/* Make sure we start the next search at least from this entry */
|
||||
btrfs_ioctl_search_args_set(&args, &sh);
|
||||
|
||||
if (sh.objectid != subvol_id)
|
||||
continue;
|
||||
if (sh.type != BTRFS_ROOT_ITEM_KEY)
|
||||
continue;
|
||||
|
||||
/* Older versions of the struct lacked the otime setting */
|
||||
if (sh.len < offsetof(struct btrfs_root_item, otime) + sizeof(struct btrfs_timespec))
|
||||
continue;
|
||||
|
||||
const struct btrfs_root_item *ri = body;
|
||||
ret->otime = (usec_t) le64toh(ri->otime.sec) * USEC_PER_SEC +
|
||||
(usec_t) le32toh(ri->otime.nsec) / NSEC_PER_USEC;
|
||||
|
||||
ret->subvol_id = subvol_id;
|
||||
ret->read_only = le64toh(ri->flags) & BTRFS_ROOT_SUBVOL_RDONLY;
|
||||
|
||||
assert_cc(sizeof(ri->uuid) == sizeof(ret->uuid));
|
||||
memcpy(&ret->uuid, ri->uuid, sizeof(ret->uuid));
|
||||
memcpy(&ret->parent_uuid, ri->parent_uuid, sizeof(ret->parent_uuid));
|
||||
|
||||
found = true;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Increase search key by one, to read the next item, if we can. */
|
||||
if (!btrfs_ioctl_search_args_inc(&args))
|
||||
break;
|
||||
}
|
||||
|
||||
finish:
|
||||
return found ? 0 : -ENODATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *ret) {
|
||||
|
@@ -8,7 +8,8 @@
|
||||
|
||||
typedef struct BtrfsSubvolInfo {
|
||||
uint64_t subvol_id;
|
||||
usec_t otime;
|
||||
usec_t otime; /* creation time */
|
||||
usec_t ctime; /* change time */
|
||||
|
||||
sd_id128_t uuid;
|
||||
sd_id128_t parent_uuid;
|
||||
|
@@ -430,7 +430,7 @@ static int image_make(
|
||||
filename,
|
||||
info.read_only || read_only,
|
||||
info.otime,
|
||||
0,
|
||||
info.ctime,
|
||||
ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
Reference in New Issue
Block a user