Module Name: src
Committed By: riastradh
Date: Thu Aug 28 19:37:46 UTC 2014
Modified Files:
src/sys/dev/dkwedge: dk.c
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.72 -r1.73 src/sys/dev/dkwedge/dk.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/dkwedge/dk.c
diff -u src/sys/dev/dkwedge/dk.c:1.72 src/sys/dev/dkwedge/dk.c:1.73
--- src/sys/dev/dkwedge/dk.c:1.72 Fri Jul 25 08:23:56 2014
+++ src/sys/dev/dkwedge/dk.c Thu Aug 28 19:37:46 2014
@@ -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 @@ static int
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 @@ dkdiscard(dev_t dev, off_t pos, off_t le
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);
}