Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Implement experimental support to pass notifications that a ...



details:   https://anonhg.NetBSD.org/src/rev/7847ef556e97
branches:  trunk
changeset: 782174:7847ef556e97
user:      drochner <drochner%NetBSD.org@localhost>
date:      Fri Oct 19 17:09:06 2012 +0000

description:
Implement experimental support to pass notifications that a file
was deleted from the filesystem to the disk driver, commonly
known as "discard" or "trim".
fs/driver support is in ffs and ata wd for now.
This is what was posted here:
http://mail-index.netbsd.org/tech-kern/2012/02/28/msg012813.html
with minor cleanup, and the global switch replaced by a mount option.

diffstat:

 include/mntopts.h          |    3 +-
 sbin/atactl/atactl.c       |    9 +-
 sbin/mount/mount.8         |    5 +-
 sbin/mount_ffs/mount_ffs.c |    5 +-
 sys/dev/ata/atareg.h       |   12 +-
 sys/dev/ata/wd.c           |   70 +++++++++++++-
 sys/sys/dkio.h             |   13 ++-
 sys/sys/fstypes.h          |   13 +-
 sys/ufs/ffs/ffs_alloc.c    |  234 ++++++++++++++++++++++++++++++++++++++++++--
 sys/ufs/ffs/ffs_extern.h   |    4 +-
 sys/ufs/ffs/ffs_vfsops.c   |   12 +-
 sys/ufs/ufs/ufsmount.h     |    4 +-
 12 files changed, 351 insertions(+), 33 deletions(-)

diffs (truncated from 676 to 300 lines):

diff -r 4f1b39b1742a -r 7847ef556e97 include/mntopts.h
--- a/include/mntopts.h Fri Oct 19 17:01:56 2012 +0000
+++ b/include/mntopts.h Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mntopts.h,v 1.14 2011/06/17 14:23:50 manu Exp $        */
+/*     $NetBSD: mntopts.h,v 1.15 2012/10/19 17:09:06 drochner Exp $    */
 
 /*-
  * Copyright (c) 1994
@@ -58,6 +58,7 @@
 #define MOPT_LOG               { "log",        0, MNT_LOG, 0 }
 #define MOPT_IGNORE            { "hidden",     0, MNT_IGNORE, 0 }
 #define MOPT_EXTATTR           { "extattr",    0, MNT_EXTATTR, 0 }
+#define MOPT_DISCARD           { "discard",    0, MNT_DISCARD, 0 }
 
 /* Control flags. */
 #define MOPT_FORCE             { "force",      0, MNT_FORCE, 0 }
diff -r 4f1b39b1742a -r 7847ef556e97 sbin/atactl/atactl.c
--- a/sbin/atactl/atactl.c      Fri Oct 19 17:01:56 2012 +0000
+++ b/sbin/atactl/atactl.c      Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atactl.c,v 1.66 2011/10/31 15:26:11 jakllsch Exp $     */
+/*     $NetBSD: atactl.c,v 1.67 2012/10/19 17:09:07 drochner Exp $     */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: atactl.c,v 1.66 2011/10/31 15:26:11 jakllsch Exp $");
+__RCSID("$NetBSD: atactl.c,v 1.67 2012/10/19 17:09:07 drochner Exp $");
 #endif
 
 
@@ -177,6 +177,7 @@
        { WDC_VER_ATA5, "ATA-5" },
        { WDC_VER_ATA6, "ATA-6" },
        { WDC_VER_ATA7, "ATA-7" },
+       { WDC_VER_ATA8, "ATA-8" },
        { 0, NULL },
 };
 
@@ -1041,6 +1042,10 @@
                            inqbuf->atap_sata_features_supp, ata_sata_feat);
        }
 
+       if ((inqbuf->atap_ata_major & WDC_VER_ATA8) &&
+           (inqbuf->support_dsm & ATA_SUPPORT_DSM_TRIM))
+               printf("TRIM supported\n");
+
        return;
 }
 
diff -r 4f1b39b1742a -r 7847ef556e97 sbin/mount/mount.8
--- a/sbin/mount/mount.8        Fri Oct 19 17:01:56 2012 +0000
+++ b/sbin/mount/mount.8        Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: mount.8,v 1.77 2012/10/03 19:36:11 wiz Exp $
+.\"    $NetBSD: mount.8,v 1.78 2012/10/19 17:09:07 drochner Exp $
 .\"
 .\" Copyright (c) 1980, 1989, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -190,6 +190,9 @@
 Clear
 .Cm async
 mode.
+.It Cm discard
+Use DISCARD/TRIM commands if disk and driver support it.
+EXPERIMENTAL!
 .It Cm extattr
 Enable extended attributes, if the filesystem supports them and
 does not enable them by default.
diff -r 4f1b39b1742a -r 7847ef556e97 sbin/mount_ffs/mount_ffs.c
--- a/sbin/mount_ffs/mount_ffs.c        Fri Oct 19 17:01:56 2012 +0000
+++ b/sbin/mount_ffs/mount_ffs.c        Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mount_ffs.c,v 1.27 2011/08/29 14:35:01 joerg Exp $     */
+/*     $NetBSD: mount_ffs.c,v 1.28 2012/10/19 17:09:07 drochner Exp $  */
 
 /*-
  * Copyright (c) 1993, 1994
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)mount_ufs.c        8.4 (Berkeley) 4/26/95";
 #else
-__RCSID("$NetBSD: mount_ffs.c,v 1.27 2011/08/29 14:35:01 joerg Exp $");
+__RCSID("$NetBSD: mount_ffs.c,v 1.28 2012/10/19 17:09:07 drochner Exp $");
 #endif
 #endif /* not lint */
 
@@ -75,6 +75,7 @@
        MOPT_LOG,
        MOPT_GETARGS,
        MOPT_EXTATTR,
+       MOPT_DISCARD,
        MOPT_NULL,
 };
 
diff -r 4f1b39b1742a -r 7847ef556e97 sys/dev/ata/atareg.h
--- a/sys/dev/ata/atareg.h      Fri Oct 19 17:01:56 2012 +0000
+++ b/sys/dev/ata/atareg.h      Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atareg.h,v 1.40 2011/10/24 20:52:34 jakllsch Exp $     */
+/*     $NetBSD: atareg.h,v 1.41 2012/10/19 17:09:07 drochner Exp $     */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -90,6 +90,7 @@
 
 /* Commands for Disk Controller. */
 #define        WDCC_NOP                0x00    /* Always fail with "aborted command" */
+#define ATA_DATA_SET_MANAGEMENT        0x06
 #define        WDCC_RECAL              0x10    /* disk restore code -- resets cntlr */
 
 #define        WDCC_READ               0x20    /* disk read code */
@@ -387,6 +388,7 @@
 #define        WDC_VER_ATA5    0x0020
 #define        WDC_VER_ATA6    0x0040
 #define        WDC_VER_ATA7    0x0080
+#define        WDC_VER_ATA8    0x0100
     uint16_t   atap_ata_minor;         /* 81: Minor version number */
     uint16_t   atap_cmd_set1;          /* 82: command set supported */
 #define        WDC_CMD1_NOP    0x4000          /*      NOP */
@@ -451,7 +453,8 @@
     uint16_t   atap_apm_val;           /* 91: current APM value */
     uint16_t   __reserved5[8];         /* 92-99: reserved */
     uint16_t   atap_max_lba[4];        /* 100-103: Max. user LBA addr */
-    uint16_t   __reserved6[2];         /* 104-105: reserved */
+    uint16_t   __reserved6;            /* 104: reserved */
+    uint16_t   max_dsm_blocks;         /* 105: DSM (ATA-8/ACS-2) */
     uint16_t   atap_secsz;             /* 106: physical/logical sector size */
 #define ATA_SECSZ_VALID_MASK 0xc000
 #define ATA_SECSZ_VALID      0x4000
@@ -480,7 +483,10 @@
 #define ATA_CFA_MODE1_DIS 0x1000       /* CFA Mode 1 Disabled */
 #define ATA_CFA_MODE1_REQ 0x2000       /* CFA Mode 1 Required */
 #define ATA_CFA_WORD160   0x8000       /* Word 160 supported */
-    uint16_t   __reserved10[15];       /* 161-175: reserved for CFA */
+    uint16_t   __reserved10[8];        /* 161-168: reserved for CFA */
+    uint16_t   support_dsm;            /* 169: DSM (ATA-8/ACS-2) */
+#define ATA_SUPPORT_DSM_TRIM   0x0001
+    uint16_t   __reserved10a[6];       /* 170-175: reserved for CFA */
     uint8_t    atap_media_serial[60];  /* 176-205: media serial number */
     uint16_t   __reserved11[3];        /* 206-208: */
     uint16_t   atap_logical_align;     /* 209: logical/physical alignment */
diff -r 4f1b39b1742a -r 7847ef556e97 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Fri Oct 19 17:01:56 2012 +0000
+++ b/sys/dev/ata/wd.c  Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.400 2012/07/31 15:50:34 bouyer Exp $ */
+/*     $NetBSD: wd.c,v 1.401 2012/10/19 17:09:07 drochner Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.400 2012/07/31 15:50:34 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.401 2012/10/19 17:09:07 drochner Exp $");
 
 #include "opt_ata.h"
 
@@ -178,6 +178,7 @@
 void  wddone(void *);
 int   wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
 int   wd_flushcache(struct wd_softc *, int);
+int   wd_trim(struct wd_softc *, int, struct disk_discard_range *);
 bool  wd_shutdown(device_t, int);
 
 int   wd_getcache(struct wd_softc *, int *);
@@ -1526,6 +1527,20 @@
                return 0;
            }
 
+       case DIOCGDISCARDPARAMS: {
+               struct disk_discard_params * tp;
+
+               if (!(wd->sc_params.atap_ata_major & WDC_VER_ATA8)
+                   || !(wd->sc_params.support_dsm & ATA_SUPPORT_DSM_TRIM))
+                       return ENOTTY;
+               tp = (struct disk_discard_params *)addr;
+               tp->maxsize = 0xffff; /*wd->sc_params.max_dsm_blocks*/
+               printf("wd: maxtrimsize %ld\n", tp->maxsize);
+               return 0;
+       }
+       case DIOCDISCARD:
+               return wd_trim(wd, WDPART(dev), (struct disk_discard_range *)addr);
+
        default:
                return ENOTTY;
        }
@@ -1934,6 +1949,57 @@
        return 0;
 }
 
+int
+wd_trim(struct wd_softc *wd, int part, struct disk_discard_range *tr)
+{
+       struct ata_command ata_c;
+       unsigned char *req;
+       daddr_t bno = tr->bno;
+
+       if (part != RAW_PART)
+               bno += wd->sc_dk.dk_label->d_partitions[part].p_offset;;
+
+       req = kmem_zalloc(512, KM_SLEEP);
+       req[0] = bno & 0xff;
+       req[1] = (bno >> 8) & 0xff;
+       req[2] = (bno >> 16) & 0xff;
+       req[3] = (bno >> 24) & 0xff;
+       req[4] = (bno >> 32) & 0xff;
+       req[5] = (bno >> 40) & 0xff;
+       req[6] = tr->size & 0xff;
+       req[7] = (tr->size >> 8) & 0xff;
+
+       memset(&ata_c, 0, sizeof(struct ata_command));
+       ata_c.r_command = ATA_DATA_SET_MANAGEMENT;
+       ata_c.r_count = 1;
+       ata_c.r_features = ATA_SUPPORT_DSM_TRIM;
+       ata_c.r_st_bmask = WDCS_DRDY;
+       ata_c.r_st_pmask = WDCS_DRDY;
+       ata_c.timeout = 30000; /* 30s timeout */
+       ata_c.data = req;
+       ata_c.bcount = 512;
+       ata_c.flags |= AT_WRITE | AT_WAIT;
+       if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
+               aprint_error_dev(wd->sc_dev,
+                   "trim command didn't complete\n");
+               kmem_free(req, 512);
+               return EIO;
+       }
+       kmem_free(req, 512);
+       if (ata_c.flags & AT_ERROR) {
+               if (ata_c.r_error == WDCE_ABRT) /* command not supported */
+                       return ENODEV;
+       }
+       if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+               char sbuf[sizeof(at_errbits) + 64];
+               snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
+               aprint_error_dev(wd->sc_dev, "wd_trim: status=%s\n",
+                   sbuf);
+               return EIO;
+       }
+       return 0;
+}
+
 bool
 wd_shutdown(device_t dev, int how)
 {
diff -r 4f1b39b1742a -r 7847ef556e97 sys/sys/dkio.h
--- a/sys/sys/dkio.h    Fri Oct 19 17:01:56 2012 +0000
+++ b/sys/sys/dkio.h    Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dkio.h,v 1.17 2011/01/18 19:52:24 matt Exp $   */
+/*     $NetBSD: dkio.h,v 1.18 2012/10/19 17:09:07 drochner Exp $       */
 
 /*
  * Copyright (c) 1987, 1988, 1993
@@ -109,4 +109,15 @@
 
 #define        DIOCTUR         _IOR('d', 128, int)     /* test unit ready */
 
+struct disk_discard_params {
+       long maxsize; /* in DEV_BSIZE units */
+};
+#define DIOCGDISCARDPARAMS _IOR('d', 129, struct disk_discard_params)
+
+struct disk_discard_range {
+       daddr_t bno;
+       long size;
+};
+#define DIOCDISCARD    _IOW('d', 130, struct disk_discard_range)
+
 #endif /* _SYS_DKIO_H_ */
diff -r 4f1b39b1742a -r 7847ef556e97 sys/sys/fstypes.h
--- a/sys/sys/fstypes.h Fri Oct 19 17:01:56 2012 +0000
+++ b/sys/sys/fstypes.h Fri Oct 19 17:09:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fstypes.h,v 1.30 2011/11/18 21:17:45 christos Exp $    */
+/*     $NetBSD: fstypes.h,v 1.31 2012/10/19 17:09:07 drochner Exp $    */
 
 /*
  * Copyright (c) 1989, 1991, 1993
@@ -84,7 +84,6 @@
  */
 
 #define        __MNT_UNUSED1   0x00200000
-#define        __MNT_UNUSED2   0x00800000
 
 #define        MNT_RDONLY      0x00000001      /* read only filesystem */
 #define        MNT_SYNCHRONOUS 0x00000002      /* file system written synchronously */
@@ -96,6 +95,7 @@
 #define        MNT_NOCOREDUMP  0x00008000      /* don't write core dumps to this FS */
 #define        MNT_RELATIME    0x00020000      /* only update access time if mod/ch */
 #define        MNT_IGNORE      0x00100000      /* don't show entry in df */
+#define        MNT_DISCARD     0x00800000      /* use DISCARD/TRIM if supported */
 #define        MNT_EXTATTR     0x01000000      /* enable extended attributes */
 #define        MNT_LOG         0x02000000      /* Use logging */



Home | Main Index | Thread Index | Old Index