diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index 61fe50e012..349a169107 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -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) { diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index 63fc1d0b32..d002618bd8 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -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; diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index d39c3a1356..58777c683b 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -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;