From: Matthew Dillon Date: Wed, 1 Aug 2018 21:38:34 +0000 (-0700) Subject: fdisk, gpt - Support trim on recent kernels X-Git-Tag: v5.5.0~327 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/d9306807fd00040e0598140bd4c634685f805510?ds=sidebyside fdisk, gpt - Support trim on recent kernels * Recent kernels removed the 'trim' sysctls. Devices now allow trim by default. * Fix the fdisk -E option to no longer try to use the sysctls. * Add trim support to gpt init (-E). * Fix swapon -e, change option to -E to match gpt and fdisk (-e still supported and does the same thing). --- diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index 056b5e0f28..57a52dbaa6 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -778,12 +778,14 @@ erase_partition(int i) struct dos_partition *partp; off_t ioarg[2]; - char sysctl_name[64]; - int trim_enabled = 0; - size_t olen = sizeof(trim_enabled); char *dev_name = strdup(disk); dev_name = strtok(dev_name + strlen("/dev/da"),"s"); +#if 0 + int trim_enabled = 0; + char sysctl_name[64]; + size_t olen = sizeof(trim_enabled); + sprintf(sysctl_name, "kern.cam.da.%s.trim_enabled", dev_name); if (sysctlbyname(sysctl_name, &trim_enabled, &olen, NULL, 0) < 0) { printf("Device:%s does not support the TRIM command\n", disk); @@ -794,6 +796,7 @@ erase_partition(int i) "is not enabled\n",sysctl_name); usage(); } +#endif partp = ((struct dos_partition *) &mboot.parts) + i; printf("erase sectors:%u %u\n", partp->dp_start, diff --git a/sbin/gpt/create.c b/sbin/gpt/create.c index f9fd58660d..ce58e6847b 100644 --- a/sbin/gpt/create.c +++ b/sbin/gpt/create.c @@ -31,6 +31,9 @@ #include #include +#include +#include +#include #include #include @@ -46,6 +49,8 @@ static int force; static int primary_only; +static void do_erase(int fd); + static void usage_create(void) { @@ -56,7 +61,7 @@ usage_create(void) static void usage_init(void) { - fprintf(stderr, "usage: %s -f [-B] device ...\n", getprogname()); + fprintf(stderr, "usage: %s -f [-B] [-E] device ...\n", getprogname()); fprintf(stderr, "\tnote: -f is mandatory for this command\n"); exit(1); } @@ -284,8 +289,9 @@ cmd_init(int argc, char *argv[]) { int ch, fd; int with_boot = 0; + int with_trim = 0; - while ((ch = getopt(argc, argv, "fIB")) != -1) { + while ((ch = getopt(argc, argv, "fBEI")) != -1) { switch(ch) { case 'f': force = 1; @@ -297,6 +303,9 @@ cmd_init(int argc, char *argv[]) usage_init(); /* NOT REACHED */ break; + case 'E': + with_trim = 1; + break; case 'B': with_boot = 1; break; @@ -322,11 +331,22 @@ cmd_init(int argc, char *argv[]) */ fd = gpt_open(path); if (fd == -1) { - warn("unable to open device '%s'", device_name); + warn("unable to open device '%s'", path); continue; } + if (with_trim) { + do_erase(fd); + gpt_close(fd); + sleep(1); + fd = gpt_open(path); + if (fd == -1) { + warn("unable to reopen device '%s'", path); + continue; + } + } do_destroy(fd); gpt_close(fd); + sleep(1); fd = gpt_open(path); if (fd == -1) { @@ -336,6 +356,7 @@ cmd_init(int argc, char *argv[]) create(fd); add_defaults(fd); gpt_close(fd); + sleep(1); /* * Setup slices @@ -353,10 +374,10 @@ cmd_init(int argc, char *argv[]) /* * Label slice1 */ - sleep(1); dosys("disklabel -r -w %s %s auto", (with_boot ? "-B" : ""), slice1); + sleep(1); /* * newfs_msdos slice0 @@ -393,3 +414,19 @@ cmd_init(int argc, char *argv[]) return (0); } + +static void +do_erase(int fd) +{ + off_t ioarg[2]; + + ioarg[0] = 0; + ioarg[1] = mediasz; + + if (ioctl(fd, DAIOCTRIM, ioarg) < 0) { + printf("Trim error %s\n", strerror(errno)); + printf("Continuing\n"); + } else { + printf("Trim completed ok\n"); + } +} diff --git a/sbin/gpt/gpt.8 b/sbin/gpt/gpt.8 index 6e691c44b7..3c94b31fcf 100644 --- a/sbin/gpt/gpt.8 +++ b/sbin/gpt/gpt.8 @@ -237,7 +237,7 @@ option instructs .Nm to destroy the table in a way that it can be recovered. .\" ==== init ==== -.It Nm Ic init Fl f Oo Fl B Oc Ar device ... +.It Nm Ic init Fl f Oo Fl B Oc Oo Fl E Oc Ar device ... The .Ic init command allows the user to create a new GPT similar @@ -257,6 +257,13 @@ If the option is specified, /boot/bootx64.efi will be copied into the msdos slice (s0), and the disklabel will be initialized with -B in addition to the normal -r -w. +.Pp +If the +.Fl E +option is specified, the drive is TRIMed prior to the installation +of the new label, if supported. The operation will continue if not +supported. Note that this will complete destroy the contents of the +drive. .\" ==== label ==== .It Xo .Nm diff --git a/sbin/swapon/swapon.8 b/sbin/swapon/swapon.8 index a32cf64d5a..87a8304c88 100644 --- a/sbin/swapon/swapon.8 +++ b/sbin/swapon/swapon.8 @@ -35,7 +35,7 @@ .Nm swapon , swapoff , swapctl .Nd "specify devices for paging and swapping" .Sh SYNOPSIS -.Nm swapon Fl aceiq | Ar +.Nm swapon Fl acEiq | Ar .Nm swapoff Fl aq | Ar .Nm swapctl .Op Fl AeghklmsU @@ -90,7 +90,7 @@ If the option is used, the device will be encrypted with a random key. If the -.Fl e +.Fl E option is used, the device will be trimmed if it supports trim and the trim_enabled sysctl is on. The @@ -183,7 +183,9 @@ Print a summary line for system swap. .If Fl c The swap is or should be crypted. .It Fl e -Attempts to Trim the device if -[Aa] is used. +.It Fl E +Attempts to Trim the device if -[Aa] is used. The lower-case version +of this option is deprecated. .It Fl i Asks user confirmation when -a is used. .It Fl q diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c index 2f9e843783..3c7fdd7aa9 100644 --- a/sbin/swapon/swapon.c +++ b/sbin/swapon/swapon.c @@ -77,7 +77,7 @@ main(int argc, char **argv) orig_prog = which_prog; sflag = lflag = hflag = doall = eflag = cflag = iflag = 0; - while ((ch = getopt(argc, argv, "AacdeghiklmqsU")) != -1) { + while ((ch = getopt(argc, argv, "acdeghiklmqsAEU")) != -1) { switch((char)ch) { case 'A': if (which_prog == SWAPCTL) { @@ -102,6 +102,7 @@ main(int argc, char **argv) case 'c': cflag = 1; break; + case 'E': case 'e': eflag = 1; break; @@ -340,9 +341,8 @@ trim_volume(char * name) /*Trim the Device*/ ioarg[0] = pinfo.media_offset; ioarg[1] = pinfo.media_size; - printf("Trimming Device:%s, sectors (%llu -%llu)\n",name, - (unsigned long long)ioarg[0]/512, - (unsigned long long)ioarg[1]/512); + printf("Trimming Device:%s, start=%jd bytes=%jd)\n", + name, (intmax_t)ioarg[0], (intmax_t)ioarg[1]); if (ioctl(fd, DAIOCTRIM, ioarg) < 0) { printf("Device trim failed\n"); usage (); @@ -365,28 +365,7 @@ swap_on_off(char *name, int doingall, int trim, int ask) } if (which_prog == SWAPON && trim) { - char sysctl_name[64]; - int trim_enabled = 0; - size_t olen = sizeof(trim_enabled); - char *dev_name = strdup(name); - dev_name = strtok(dev_name + strlen("/dev/da"),"s"); - sprintf(sysctl_name, "kern.cam.da.%s.trim_enabled", dev_name); - if (sysctlbyname(sysctl_name, &trim_enabled, &olen, NULL, 0) < 0) { - if (qflag == 0) { - printf("TRIM not supported on %s, " - "ignoring\n", - name); - } - errno = 0; - } else if (!trim_enabled) { - if (qflag == 0) { - printf("TRIM not enabled on %s (%s), " - "ignoring\n", - name, sysctl_name); - } - } else { - trim_volume(name); - } + trim_volume(name); } if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) { switch(errno) { diff --git a/sys/bus/cam/scsi/scsi_da.c b/sys/bus/cam/scsi/scsi_da.c index c696530b27..e8d0d98e63 100644 --- a/sys/bus/cam/scsi/scsi_da.c +++ b/sys/bus/cam/scsi/scsi_da.c @@ -1309,11 +1309,6 @@ dastart(struct cam_periph *periph, union ccb *start_ccb) count = bp->b_bcount / softc->params.secsize; lba = bio1->bio_offset/softc->params.secsize; - kprintf("trim lba:%llu boff:%llu count:%d\n", - (unsigned long long) lba, - (unsigned long long) bio1->bio_offset, - count); - bioq_remove(&softc->bio_queue_trim, bio1); while (count > 0) { int c = min(count, 0xffff);