}
typedef struct BtrfsForeachIterator {
- const void *p;
- size_t i;
+ const struct btrfs_ioctl_search_args *args;
+ size_t offset;
+ unsigned index;
+ struct btrfs_ioctl_search_header *header;
+ const void **body;
} BtrfsForeachIterator;
+static int btrfs_iterate(BtrfsForeachIterator *i) {
+ assert(i);
+ assert(i->args);
+ assert(i->header);
+ assert(i->body);
+
+ if (i->index >= i->args->key.nr_items)
+ return 0; /* end */
+
+ assert_cc(BTRFS_SEARCH_ARGS_BUFSIZE >= sizeof(struct btrfs_ioctl_search_header));
+ if (i->offset > BTRFS_SEARCH_ARGS_BUFSIZE - sizeof(struct btrfs_ioctl_search_header))
+ return -EBADMSG;
+
+ struct btrfs_ioctl_search_header h;
+ memcpy(&h, (const uint8_t*) i->args->buf + i->offset, sizeof(struct btrfs_ioctl_search_header));
+
+ if (i->offset > BTRFS_SEARCH_ARGS_BUFSIZE - sizeof(struct btrfs_ioctl_search_header) - h.len)
+ return -EBADMSG;
+
+ *i->body = (const uint8_t*) i->args->buf + i->offset + sizeof(struct btrfs_ioctl_search_header);
+ *i->header = h;
+ i->offset += sizeof(struct btrfs_ioctl_search_header) + h.len;
+ i->index++;
+
+ return 1;
+}
+
/* Iterates through a series of struct btrfs_file_extent_item elements. They are unfortunately not aligned,
* hence we copy out the header from them */
-#define FOREACH_BTRFS_IOCTL_SEARCH_HEADER(sh, body, args) \
+#define FOREACH_BTRFS_IOCTL_SEARCH_HEADER(_sh, _body, _args) \
for (BtrfsForeachIterator iterator = { \
- .p = ({ \
- memcpy(&(sh), (args).buf, sizeof(struct btrfs_ioctl_search_header)); \
- (body) = (const void*) ((const uint8_t*) (args).buf + sizeof(struct btrfs_ioctl_search_header)); \
- (args).buf; \
- }), \
+ .args = &(_args), \
+ .header = &(_sh), \
+ .body = &(_body), \
}; \
- iterator.i < (args).key.nr_items; \
- iterator.i++, \
- memcpy(&(sh), iterator.p = (const uint8_t*) iterator.p + sizeof(struct btrfs_ioctl_search_header) + (sh).len, sizeof(struct btrfs_ioctl_search_header)), \
- (body) = (const void*) ((const uint8_t*) iterator.p + sizeof(struct btrfs_ioctl_search_header)))
+ btrfs_iterate(&iterator) > 0; )
int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *ret) {
struct btrfs_ioctl_search_args args = {