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