Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/dkwedge Make dk(4) discard from partition start, not...



details:   https://anonhg.NetBSD.org/src/rev/5f775bce09a4
branches:  trunk
changeset: 802025:5f775bce09a4
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Thu Aug 28 19:37:46 2014 +0000

description:
Make dk(4) discard from partition start, not from disk start.

Otherwise, anything mounted with `-o discard' will pretty quickly
munch itself up and barf up an unrecoverably corrupted file system!

XXX pullup to netbsd-7

diffstat:

 sys/dev/dkwedge/dk.c |  21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diffs (49 lines):

diff -r 73456b0d5e8d -r 5f775bce09a4 sys/dev/dkwedge/dk.c
--- a/sys/dev/dkwedge/dk.c      Thu Aug 28 18:02:36 2014 +0000
+++ b/sys/dev/dkwedge/dk.c      Thu Aug 28 19:37:46 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dk.c,v 1.72 2014/07/25 08:23:56 dholland Exp $ */
+/*     $NetBSD: dk.c,v 1.73 2014/08/28 19:37:46 riastradh Exp $        */
 
 /*-
  * Copyright (c) 2004, 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.72 2014/07/25 08:23:56 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.73 2014/08/28 19:37:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_dkwedge.h"
@@ -1350,6 +1350,8 @@
 dkdiscard(dev_t dev, off_t pos, off_t len)
 {
        struct dkwedge_softc *sc = dkwedge_lookup(dev);
+       unsigned shift;
+       off_t offset, maxlen;
 
        if (sc == NULL)
                return (ENODEV);
@@ -1358,6 +1360,21 @@
        if (sc->sc_parent->dk_rawvp == NULL)
                return (ENXIO);
 
+       shift = (sc->sc_parent->dk_blkshift + DEV_BSHIFT);
+       KASSERT(__type_fit(off_t, sc->sc_size));
+       KASSERT(__type_fit(off_t, sc->sc_offset));
+       KASSERT(0 <= sc->sc_offset);
+       KASSERT(sc->sc_size <= (__type_max(off_t) >> shift));
+       KASSERT(sc->sc_offset <= ((__type_max(off_t) >> shift) - sc->sc_size));
+       offset = ((off_t)sc->sc_offset << shift);
+       maxlen = ((off_t)sc->sc_size << shift);
+
+       if (len > maxlen)
+               return (EINVAL);
+       if (pos > (maxlen - len))
+               return (EINVAL);
+
+       pos += offset;
        return VOP_FDISCARD(sc->sc_parent->dk_rawvp, pos, len);
 }
 



Home | Main Index | Thread Index | Old Index