Module Name: src Committed By: mlelstv Date: Mon Nov 30 06:04:47 UTC 2015
Modified Files: src/sys/dev: vnd.c Log Message: Fall back to VOP_READ/VOP_WRITE if the simulated disk has smaller sectors than the underlying filesystem and VOP_STRATEGY would fail. To generate a diff of this commit: cvs rdiff -u -r1.254 -r1.255 src/sys/dev/vnd.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/vnd.c diff -u src/sys/dev/vnd.c:1.254 src/sys/dev/vnd.c:1.255 --- src/sys/dev/vnd.c:1.254 Thu Nov 12 15:28:07 2015 +++ src/sys/dev/vnd.c Mon Nov 30 06:04:47 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: vnd.c,v 1.254 2015/11/12 15:28:07 christos Exp $ */ +/* $NetBSD: vnd.c,v 1.255 2015/11/30 06:04:47 mlelstv Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.254 2015/11/12 15:28:07 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.255 2015/11/30 06:04:47 mlelstv Exp $"); #if defined(_KERNEL_OPT) #include "opt_vnd.h" @@ -573,6 +573,22 @@ vnode_has_strategy(struct vnd_softc *vnd vnode_has_op(vnd->sc_vp, VOFFSET(vop_strategy)); } +static bool +vnode_has_large_blocks(struct vnd_softc *vnd) +{ + u_int32_t vnd_secsize, mnt_secsize; + uint64_t numsec; + unsigned secsize; + + if (getdisksize(vnd->sc_vp, &numsec, &secsize)) + return true; + + vnd_secsize = vnd->sc_geom.vng_secsize; + mnt_secsize = secsize; + + return vnd_secsize % mnt_secsize != 0; +} + /* XXX this function needs a reliable check to detect * sparse files. Otherwise, bmap/strategy may be used * and fail on non-allocated blocks. VOP_READ/VOP_WRITE @@ -588,6 +604,9 @@ vnode_strategy_probe(struct vnd_softc *v if (!vnode_has_strategy(vnd)) return false; + if (vnode_has_large_blocks(vnd)) + return false; + /* Convert the first logical block number to its * physical block number. */ @@ -619,6 +638,13 @@ vndthread(void *arg) ! vnode_has_strategy(vnd)) vnd->sc_flags |= VNF_USE_VN_RDWR; + /* VOP_STRATEGY can only be used if the backing vnode allows + * to access blocks as small as defined by the vnd geometry. + */ + if ((vnd->sc_flags & VNF_USE_VN_RDWR) == 0 && + vnode_has_large_blocks(vnd)) + vnd->sc_flags |= VNF_USE_VN_RDWR; + #ifdef DEBUG if (vnddebug & VDB_INIT) printf("vndthread: vp %p, %s\n", vnd->sc_vp,