diff --git a/fish/options.c b/fish/options.c index cfdbdfec7..80b71ecfd 100644 --- a/fish/options.c +++ b/fish/options.c @@ -134,6 +134,10 @@ add_drives_handle (guestfs_h *g, struct drv *drv, char next_drive) ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_CACHEMODE_BITMASK; ad_optargs.cachemode = drv->a.cachemode; } + if (drv->a.discard) { + ad_optargs.bitmask |= GUESTFS_ADD_DRIVE_OPTS_DISCARD_BITMASK; + ad_optargs.discard = drv->a.discard; + } r = guestfs_add_drive_opts_argv (g, drv->a.filename, &ad_optargs); if (r == -1) @@ -279,6 +283,7 @@ free_drives (struct drv *drv) free (drv->a.filename); /* a.format is an optarg, so don't free it */ /* a.cachemode is a static string, so don't free it */ + /* a.discard is a static string, so don't free it */ break; case drv_uri: free (drv->uri.path); diff --git a/fish/options.h b/fish/options.h index a7b8277f9..dbf9163ea 100644 --- a/fish/options.h +++ b/fish/options.h @@ -61,6 +61,7 @@ struct drv { char *filename; /* disk filename */ const char *format; /* format (NULL == autodetect) */ const char *cachemode;/* cachemode (NULL == default) */ + const char *discard; /* discard (NULL == disable) */ } a; struct { char *path; /* disk path */ diff --git a/format/format.c b/format/format.c index cff0d8252..684bffd1a 100644 --- a/format/format.c +++ b/format/format.c @@ -188,6 +188,11 @@ main (int argc, char *argv[]) case 'a': OPTION_a; + + /* Enable discard on all drives added on the command line. */ + assert (drvs != NULL); + assert (drvs->type == drv_a); + drvs->a.discard = "besteffort"; break; case 'v': @@ -342,6 +347,14 @@ do_format (void) } } + /* Send TRIM/UNMAP to all block devices, to give back the space to + * the host. However don't fail if this doesn't work. + */ + guestfs_push_error_handler (g, NULL, NULL); + for (i = 0; devices[i] != NULL; ++i) + guestfs_blkdiscard (g, devices[i]); + guestfs_pop_error_handler (g); + if (do_rescan (devices)) return 1; /* which means, reopen the handle and retry */