I had an idea about how we might do this and still keep a single .pwrite method for plugins. Maybe it's too complicated but here goes: (1) Rename the pwrite method as pwrite_old1, and add new pwrite method with either the FUA flag or general flags: int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset); - int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset); + int (*pwrite_old1) (void *handle, const void *buf, uint32_t count, uint64_t offset); int (*flush) (void *handle); int (*trim) (void *handle, uint32_t count, uint64_t offset); int (*zero) (void *handle, uint32_t count, uint64_t offset, int may_trim); int errno_is_preserved; void (*dump_plugin) (void); + int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags); This is binary-compatible with old plugins, but not source compatible, so: (2) Plugsin may optionally define NBDKIT_PLUGIN_LEVEL before including <nbdkit-plugin.h>. Code wishing to use the flags variant of pwrite can do: #define NBDKIT_PLUGIN_LEVEL 2 #include <nbdkit-plugin.h> which would modify the definition of the struct (again), something like: #ifndef NBDKIT_PLUGIN_LEVEL #define NBDKIT_PLUGIN_LEVEL 1 #endif ... int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset); #if NBDKIT_PLUGIN_LEVEL <= 1 int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset); #else int (*pwrite_old1) (void *handle, const void *buf, uint32_t count, uint64_t offset); #endif int (*flush) (void *handle); int (*trim) (void *handle, uint32_t count, uint64_t offset); int (*zero) (void *handle, uint32_t count, uint64_t offset, int may_trim); int errno_is_preserved; void (*dump_plugin) (void); #if NBDKIT_PLUGIN_LEVEL <= 1 int (*never_used1) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags); #else int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset, unsigned flags); #endif (3) Core nbdkit code always defines NBDKIT_PLUGIN_LEVEL == 2 so that it always sees the new function, but it may need to call the old function: int plugin_pwrite (...) { if (plugin.pwrite != NULL) plugin.pwrite (handle, buf, count, offset, flags); else if (plugin.pwrite_old1 != NULL) plugin.pwrite_old1 (handle, buf, count, offset); } (4) Internal plugins which don't need the FUA flag can continue to use the level 1 API, which means that we keep checking that the old API still works. What do you think? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v