diff --git a/control/tap-ctl-info.c b/control/tap-ctl-info.c index 813de389..276b7d7e 100644 --- a/control/tap-ctl-info.c +++ b/control/tap-ctl-info.c @@ -25,7 +25,8 @@ #include "tap-ctl.h" int tap_ctl_info(pid_t pid, unsigned long long *sectors, - unsigned int *sector_size, unsigned int *info, const int minor) + unsigned int *sector_size, unsigned int *info, + bool * discard_supported, const int minor) { tapdisk_message_t message; int err; @@ -49,6 +50,7 @@ int tap_ctl_info(pid_t pid, unsigned long long *sectors, *sectors = message.u.image.sectors; *sector_size = message.u.image.sector_size; *info = message.u.image.info; + *discard_supported = message.u.image.discard_supported; return 0; } else if (TAPDISK_MESSAGE_ERROR == message.type) { return -message.u.response.error; diff --git a/drivers/tapdisk-control.c b/drivers/tapdisk-control.c index 70bcb67e..8f11564c 100644 --- a/drivers/tapdisk-control.c +++ b/drivers/tapdisk-control.c @@ -1193,6 +1193,7 @@ tapdisk_control_disk_info( image->sectors = vbd->disk_info.size; image->sector_size = vbd->disk_info.sector_size; image->info = vbd->disk_info.info; + image->discard_supported = vbd->disk_info.discard_supported; } return err; } diff --git a/include/tap-ctl.h b/include/tap-ctl.h index b4248ffa..8d6db30b 100644 --- a/include/tap-ctl.h +++ b/include/tap-ctl.h @@ -176,7 +176,8 @@ int tap_ctl_disconnect_xenblkif(const pid_t pid, const domid_t domid, * */ int tap_ctl_info(pid_t pid, unsigned long long *sectors, unsigned int - *sector_size, unsigned int *info, const int minor); + *sector_size, unsigned int *info, bool *discard_supported, + const int minor); /** * Parses a type:/path/to/file string, storing the type and path to the output diff --git a/include/tapdisk-message.h b/include/tapdisk-message.h index 7d9bda77..388bd613 100644 --- a/include/tapdisk-message.h +++ b/include/tapdisk-message.h @@ -19,6 +19,7 @@ #define _TAPDISK_MESSAGE_H_ #include +#include #include /* @@ -70,6 +71,7 @@ struct tapdisk_message_image { uint64_t sectors; uint32_t sector_size; uint32_t info; + bool discard_supported; }; struct tapdisk_message_string { diff --git a/tapback/backend.c b/tapback/backend.c index 516fc430..426d284e 100644 --- a/tapback/backend.c +++ b/tapback/backend.c @@ -344,7 +344,7 @@ physical_device_changed(vbd_t *device) { * get the VBD parameters from the tapdisk */ if ((err = tap_ctl_info(device->tap->pid, &device->sectors, - &device->sector_size, &info, + &device->sector_size, &info, &device->discard_supported, device->minor))) { WARN(device, "error retrieving disk characteristics: %s\n", strerror(-err)); diff --git a/tapback/frontend.c b/tapback/frontend.c index 204687de..08c8767d 100644 --- a/tapback/frontend.c +++ b/tapback/frontend.c @@ -259,6 +259,10 @@ connect_frontend(vbd_t *device) { int err = 0; xs_transaction_t xst = XBT_NULL; bool abort_transaction = false; + unsigned int discard_granularity = 0; + unsigned int discard_alignment = 0; + int discard_secure = 0; + int feature_discard = 0; ASSERT(device); @@ -272,9 +276,47 @@ connect_frontend(vbd_t *device) { abort_transaction = true; /* - * FIXME blkback writes discard-granularity, discard-alignment, - * discard-secure, feature-discard but we don't. + * Prepare for discard */ + if (device->discard_supported == true && /* backing driver supports */ + device->backend->discard == true && /* discard enabled */ + device->mode == true && /* writable vbd */ + device->cdrom == false) { /* not a CD */ + INFO(device, "Discard enabled."); + discard_granularity = device->sector_size; + discard_alignment = 0; + discard_secure = 0; + feature_discard = 1; + } else + INFO(device, "Discard disabled."); + if ((err = tapback_device_printf(device, xst, "discard-granularity", + true, "%u", discard_granularity ))) { + WARN(device, "failed to write discard_granularity: %s\n", + strerror(-err)); + break; + } + + if ((err = tapback_device_printf(device, xst, "discard-alignment", + true, "%u", discard_alignment ))) { + WARN(device, "failed to write discard_alignment: %s\n", + strerror(-err)); + break; + } + + if ((err = tapback_device_printf(device, xst, "discard-secure", + true, "%d", discard_secure ))) { + WARN(device, "failed to write discard-secure: %s\n", + strerror(-err)); + break; + } + + if ((err = tapback_device_printf(device, xst, "feature-discard", + true, "%d", feature_discard ))) { + WARN(device, "failed to write feature_discard: %s\n", + strerror(-err)); + break; + } + /* * Write the number of sectors, sector size, info, and barrier support diff --git a/tapback/tapback.c b/tapback/tapback.c index 4cfd3217..8335e40c 100644 --- a/tapback/tapback.c +++ b/tapback/tapback.c @@ -219,7 +219,8 @@ tapback_write_pid(const char *pidfile) */ static inline backend_t * tapback_backend_create(const char *name, const char *pidfile, - const domid_t domid, const bool barrier) + const domid_t domid, const bool barrier, + const bool discard) { int err; int len; @@ -254,7 +255,8 @@ tapback_backend_create(const char *name, const char *pidfile, goto out; } - backend->barrier = barrier; + backend->barrier = barrier; + backend->discard = discard; backend->path = NULL; @@ -501,7 +503,8 @@ usage(FILE * const stream, const char * const prog) "\t[-d|--debug]\n" "\t[-h|--help]\n" "\t[-v|--verbose]\n" - "\t[-b]--nobarrier]\n" + "\t[-b]--nobarrier]\n" + "\t[-s]--nodiscard]\n" "\t[-n|--name]\n", prog); } @@ -567,7 +570,8 @@ int main(int argc, char **argv) int err = 0; backend_t *backend = NULL; domid_t opt_domid = 0; - bool opt_barrier = true; + bool opt_barrier = true; + bool opt_discard = true; if (access("/dev/xen/gntdev", F_OK ) == -1) { WARN(NULL, "grant device does not exist\n"); @@ -594,12 +598,13 @@ int main(int argc, char **argv) {"name", 0, NULL, 'n'}, {"pidfile", 0, NULL, 'p'}, {"domain", 0, NULL, 'x'}, - {"nobarrier", 0, NULL, 'b'}, + {"nobarrier", 0, NULL, 'b'}, + {"nodiscard", 0, NULL, 's'}, }; int c; - c = getopt_long(argc, argv, "hdvn:p:x:b", longopts, NULL); + c = getopt_long(argc, argv, "hdvn:p:x:b:s", longopts, NULL); if (c < 0) break; @@ -636,9 +641,14 @@ int main(int argc, char **argv) } INFO(NULL, "only serving domain %d\n", opt_domid); break; - case 'b': - opt_barrier = false; - break; + case 'b': + /* nobarrier */ + opt_barrier = false; + break; + case 's': + /* nodiscard */ + opt_discard = false; + break; case '?': goto usage; } @@ -673,7 +683,7 @@ int main(int argc, char **argv) } backend = tapback_backend_create(opt_name, opt_pidfile, opt_domid, - opt_barrier); + opt_barrier, opt_discard); if (!backend) { err = errno; WARN(NULL, "error creating back-end: %s\n", strerror(err)); diff --git a/tapback/tapback.h b/tapback/tapback.h index c28117e2..8659b3ef 100644 --- a/tapback/tapback.h +++ b/tapback/tapback.h @@ -195,6 +195,12 @@ typedef struct backend { * Tells whether we support write I/O barriers. */ bool barrier; + + /** + * Whether discard is supposed to be enabled if supported by the + * tapdisk. + */ + bool discard; } backend_t; /** @@ -271,6 +277,11 @@ typedef struct vbd { */ unsigned long long sectors; + /** + * Whether the backing driver supports discard, supplied by the tapdisk. + */ + bool discard_supported; + /** * VDISK_???, defined in include/xen/interface/io/blkif.h. */