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); }