Module Name:    src
Committed By:   christos
Date:           Wed Oct 21 21:43:46 UTC 2015

Modified Files:
        src/sys/dev: dksubr.c

Log Message:
Fix dumping code (dk_dump):
    - set DKF_TAKEDUMP on attach, otherwise we can never dump
    - add DKF_DUMP debugging
    - use __func__ instead of hard-coding names
    - only allow dumps on swap partitions


To generate a diff of this commit:
cvs rdiff -u -r1.76 -r1.77 src/sys/dev/dksubr.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/dksubr.c
diff -u src/sys/dev/dksubr.c:1.76 src/sys/dev/dksubr.c:1.77
--- src/sys/dev/dksubr.c:1.76	Fri Aug 28 13:41:49 2015
+++ src/sys/dev/dksubr.c	Wed Oct 21 17:43:46 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dksubr.c,v 1.76 2015/08/28 17:41:49 mlelstv Exp $ */
+/* $NetBSD: dksubr.c,v 1.77 2015/10/21 21:43:46 christos Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.76 2015/08/28 17:41:49 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.77 2015/10/21 21:43:46 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +57,7 @@ int	dkdebug = 0;
 #define DKDB_FOLLOW	0x1
 #define DKDB_INIT	0x2
 #define DKDB_VNODE	0x4
+#define DKDB_DUMP	0x8
 
 #define IFDEBUG(x,y)		if (dkdebug & (x)) y
 #define DPRINTF(x,y)		IFDEBUG(x, printf y)
@@ -67,6 +68,8 @@ int	dkdebug = 0;
 #define DPRINTF_FOLLOW(y)
 #endif
 
+#define DKF_READYFORDUMP	(DKF_INITED|DKF_TAKEDUMP)
+
 static int dk_subr_modcmd(modcmd_t, void *);
 
 #define DKLABELDEV(dev)	\
@@ -92,7 +95,7 @@ void
 dk_attach(struct dk_softc *dksc)
 {
 	mutex_init(&dksc->sc_iolock, MUTEX_DEFAULT, IPL_VM);
-	dksc->sc_flags |= DKF_INITED;
+	dksc->sc_flags |= DKF_READYFORDUMP;
 #ifdef DIAGNOSTIC
 	dksc->sc_flags |= DKF_WARNLABEL | DKF_LABELSANITY;
 #endif
@@ -108,7 +111,7 @@ dk_detach(struct dk_softc *dksc)
 	/* Unhook the entropy source. */
 	rnd_detach_source(&dksc->sc_rnd_source);
 
-	dksc->sc_flags &= ~DKF_INITED;
+	dksc->sc_flags &= ~DKF_READYFORDUMP;
 	mutex_destroy(&dksc->sc_iolock);
 }
 
@@ -123,7 +126,7 @@ dk_open(struct dk_softc *dksc, dev_t dev
 	int	ret = 0;
 	struct disk *dk = &dksc->sc_dkdev;
 
-	DPRINTF_FOLLOW(("dk_open(%s, %p, 0x%"PRIx64", 0x%x)\n",
+	DPRINTF_FOLLOW(("%s(%s, %p, 0x%"PRIx64", 0x%x)\n", __func__,
 	    dksc->sc_xname, dksc, dev, flags));
 
 	mutex_enter(&dk->dk_openlock);
@@ -184,7 +187,7 @@ dk_close(struct dk_softc *dksc, dev_t de
 	int	pmask = 1 << part;
 	struct disk *dk = &dksc->sc_dkdev;
 
-	DPRINTF_FOLLOW(("dk_close(%s, %p, 0x%"PRIx64", 0x%x)\n",
+	DPRINTF_FOLLOW(("%s(%s, %p, 0x%"PRIx64", 0x%x)\n", __func__,
 	    dksc->sc_xname, dksc, dev, flags));
 
 	mutex_enter(&dk->dk_openlock);
@@ -275,11 +278,11 @@ dk_strategy(struct dk_softc *dksc, struc
 {
 	int error;
 
-	DPRINTF_FOLLOW(("dk_strategy(%s, %p, %p)\n",
+	DPRINTF_FOLLOW(("%s(%s, %p, %p)\n", __func__,
 	    dksc->sc_xname, dksc, bp));
 
 	if (!(dksc->sc_flags & DKF_INITED)) {
-		DPRINTF_FOLLOW(("dk_strategy: not inited\n"));
+		DPRINTF_FOLLOW(("%s: not inited\n", __func__));
 		bp->b_error  = ENXIO;
 		biodone(bp);
 		return;
@@ -409,11 +412,11 @@ dk_discard(struct dk_softc *dksc, dev_t 
 	struct buf tmp, *bp = &tmp;
 	int error;
 
-	DPRINTF_FOLLOW(("dk_discard(%s, %p, 0x"PRIx64", %jd, %jd)\n",
+	DPRINTF_FOLLOW(("%s(%s, %p, 0x"PRIx64", %jd, %jd)\n", __func__,
 	    dksc->sc_xname, dksc, (intmax_t)pos, (intmax_t)len));
 
 	if (!(dksc->sc_flags & DKF_INITED)) {
-		DPRINTF_FOLLOW(("dk_discard: not inited\n"));
+		DPRINTF_FOLLOW(("%s: not inited\n", __func__));
 		return ENXIO;
 	}
 
@@ -480,7 +483,7 @@ dk_ioctl(struct dk_softc *dksc, dev_t de
 #endif
 	int	error;
 
-	DPRINTF_FOLLOW(("dk_ioctl(%s, %p, 0x%"PRIx64", 0x%lx)\n",
+	DPRINTF_FOLLOW(("%s(%s, %p, 0x%"PRIx64", 0x%lx)\n", __func__,
 	    dksc->sc_xname, dksc, dev, cmd));
 
 	/* ensure that the pseudo disk is open for writes for these commands */
@@ -645,7 +648,6 @@ dk_ioctl(struct dk_softc *dksc, dev_t de
  *
  */
 
-#define DKF_READYFORDUMP	(DKF_INITED|DKF_TAKEDUMP)
 #define DKFF_READYFORDUMP(x)	(((x) & DKF_READYFORDUMP) == DKF_READYFORDUMP)
 static volatile int	dk_dumping = 0;
 
@@ -657,6 +659,7 @@ dk_dump(struct dk_softc *dksc, dev_t dev
 	const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver;
 	char *va = vav;
 	struct disklabel *lp;
+	struct partition *p;
 	int part, towrt, nsects, sectoff, maxblkcnt, nblk;
 	int maxxfer, rv = 0;
 
@@ -664,16 +667,21 @@ dk_dump(struct dk_softc *dksc, dev_t dev
 	 * ensure that we consider this device to be safe for dumping,
 	 * and that the device is configured.
 	 */
-	if (!DKFF_READYFORDUMP(dksc->sc_flags))
+	if (!DKFF_READYFORDUMP(dksc->sc_flags)) {
+		DPRINTF(DKF_DUMP, ("%s: bad dump flags 0x%x\n", __func__,
+		    dksc->sc_flags));
 		return ENXIO;
+	}
 
 	/* ensure that we are not already dumping */
 	if (dk_dumping)
 		return EFAULT;
 	dk_dumping = 1;
 
-	if (dkd->d_dumpblocks == NULL)
+	if (dkd->d_dumpblocks == NULL) {
+		DPRINTF(DKF_DUMP, ("%s: no dumpblocks\n", __func__));
 		return ENXIO;
+	}
 
 	/* device specific max transfer size */
 	maxxfer = MAXPHYS;
@@ -683,17 +691,28 @@ dk_dump(struct dk_softc *dksc, dev_t dev
 	/* Convert to disk sectors.  Request must be a multiple of size. */
 	part = DISKPART(dev);
 	lp = dksc->sc_dkdev.dk_label;
-	if ((size % lp->d_secsize) != 0)
-		return (EFAULT);
+	if ((size % lp->d_secsize) != 0) {
+		DPRINTF(DKF_DUMP, ("%s: odd size %zu\n", __func__, size));
+		return EFAULT;
+	}
 	towrt = size / lp->d_secsize;
 	blkno = dbtob(blkno) / lp->d_secsize;   /* blkno in secsize units */
 
-	nsects = lp->d_partitions[part].p_size;
-	sectoff = lp->d_partitions[part].p_offset;
+	p = &lp->d_partitions[part];
+	if (p->p_fstype != FS_SWAP) {
+		DPRINTF(DKF_DUMP, ("%s: bad fstype %d\n", __func__,
+		    p->p_fstype));
+		return ENXIO;
+	}
+	nsects = p->p_size;
+	sectoff = p->p_offset;
 
 	/* Check transfer bounds against partition size. */
-	if ((blkno < 0) || ((blkno + towrt) > nsects))
-		return (EINVAL);
+	if ((blkno < 0) || ((blkno + towrt) > nsects)) {
+		DPRINTF(DKF_DUMP, ("%s: out of bounds blkno=%d, towrt=%d, "
+		    "nsects=%d\n", __func__, blkno, towrt, nsects));
+		return EINVAL;
+	}
 
 	/* Offset block number to start of partition. */
 	blkno += sectoff;
@@ -703,8 +722,12 @@ dk_dump(struct dk_softc *dksc, dev_t dev
 	while (towrt > 0) {
 		nblk = min(maxblkcnt, towrt);
 
-		if ((rv = (*dkd->d_dumpblocks)(dksc->sc_dev, va, blkno, nblk)) != 0)
-			return (rv);
+		if ((rv = (*dkd->d_dumpblocks)(dksc->sc_dev, va, blkno, nblk))
+		    != 0) {
+			DPRINTF(DKF_DUMP, ("%s: dumpblocks %d\n", __func__,
+			    rv));
+			return rv;
+		}
 
 		towrt -= nblk;
 		blkno += nblk;
@@ -832,7 +855,7 @@ dk_lookup(struct pathbuf *pb, struct lwp
 	NDINIT(&nd, LOOKUP, FOLLOW, pb);
 	if ((error = vn_open(&nd, FREAD | FWRITE, 0)) != 0) {
 		DPRINTF((DKDB_FOLLOW|DKDB_INIT),
-		    ("dk_lookup: vn_open error = %d\n", error));
+		    ("%s: vn_open error = %d\n", __func__, error));
 		return error;
 	}
 

Reply via email to