#define RBD_COMP_NONE 0
#define RBD_CRYPT_NONE 0
+#define RBD_FLAGS_ORDER_MASK 0x000000FF
+#define RBD_FLAGS_CRYPT_TYPE_MASK 0x0000FF00
+#define RBD_FLAGS_COMP_TYPE_MASK 0x00FF0000
+
+#define RBD_FLAGS_ORDER_SHIFT 0
+#define RBD_FLAGS_CRYPT_TYPE_SHIFT 1
+#define RBD_FLAGS_COMP_TYPE_SHIFT 2
+
static const char rbd_text[] = "<<< Rados Block Device Image >>>\n";
static const char rbd_signature[] = "RBD";
-static const char rbd_version[] = "001.002";
+static const char rbd_version[] = "001.004";
struct rbd_obj_snap_ondisk {
__le64 id;
char text[64];
char signature[4];
char version[8];
+ __le32 flags;
__le64 image_size;
- __u8 obj_order;
- __u8 crypt_type;
- __u8 comp_type;
__le64 snap_seq;
__le32 snap_count;
+ __le32 reserved;
__le64 snap_names_len;
struct rbd_obj_snap_ondisk snaps[0];
} __attribute__((packed));
+
+static inline int rbd_get_obj_order(__u32 flags)
+{
+ return flags & RBD_FLAGS_ORDER_MASK;
+}
+
#endif
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+
+my $usage = "./push_to_qemu.pl <path_to_qemu>\n";
+
+my $qemu = shift @ARGV || die $usage;
+die $usage unless -d $qemu;
+
+die "not in a git tree" unless `cd $qemu && git rev-parse HEAD`;
+
+my $dir = '.';
+until (-d "$dir/.git") {
+ $dir .= "/..";
+}
+
+print "pushing changed shared files from $dir to $qemu...\n";
+system "cat $dir/src/include/rbd_types.h | sed 's/u32/uint32_t/g; s/__u8/uint8_t/g; s/__.*16/uint16_t/g; s/__.*32/uint32_t/g; s/__.*64/uint64_t/g; s/_FS_CEPH_RBD/QEMU_BLOCK_RBD_TYPES_H/g' | grep -v \"linux/types.h\" > $qemu/block/rbd_types.h";
+
+print "done.\n";
+
memcpy(&ondisk.version, rbd_version, sizeof(rbd_version));
ondisk.image_size = size;
+ ondisk.flags = 0;
if (order)
- ondisk.obj_order = order;
+ ondisk.flags = order << RBD_FLAGS_ORDER_SHIFT;
else
- ondisk.obj_order = RBD_DEFAULT_OBJ_ORDER;
- ondisk.crypt_type = RBD_CRYPT_NONE;
- ondisk.comp_type = RBD_COMP_NONE;
+ ondisk.flags = RBD_DEFAULT_OBJ_ORDER;
+ ondisk.flags = ondisk.flags | (RBD_CRYPT_NONE << RBD_FLAGS_CRYPT_TYPE_SHIFT) |
+ (RBD_COMP_NONE << RBD_FLAGS_COMP_TYPE_SHIFT);
ondisk.snap_seq = 0;
ondisk.snap_count = 0;
+ ondisk.reserved = 0;
ondisk.snap_names_len = 0;
}
void print_header(char *imgname, rbd_obj_header_ondisk *header)
{
+ int obj_order = rbd_get_obj_order(header->flags);
cout << "rbd image '" << imgname << "':\n"
<< "\tsize " << prettybyte_t(header->image_size) << " in "
- << (header->image_size >> header->obj_order) << " objects\n"
- << "\torder " << (int)header->obj_order << " (" << prettybyte_t(1 << (header->obj_order)) << " objects)"
+ << (header->image_size >> obj_order) << " objects\n"
+ << "\torder " << obj_order
+ << " (" << prettybyte_t(1 << obj_order) << " objects)"
<< std::endl;
}
void trim_image(const char *imgname, rbd_obj_header_ondisk *header, uint64_t newsize)
{
uint64_t size = header->image_size;
- uint64_t numseg = size >> header->obj_order;
- uint64_t start = newsize >> header->obj_order;
+ int obj_order = rbd_get_obj_order(header->flags);
+ uint64_t numseg = size >> obj_order;
+ uint64_t start = newsize >> obj_order;
cout << "trimming image data from " << numseg << " to " << start << " objects..." << std::endl;
for (uint64_t i=start; i<numseg; i++) {