Checking if the underlying file system supports VOP_BMAP and VOP_STRATEGY does not imply that works.
Test if VOP_BMAP actually works before using bmap/strategy. When you create an image with dd if=/dev/zero of=./netbsd.img bs=1m count=1 seek=1000 then the current check actually determines the "file system" in the image supports VOP_BMAP and VOP_STRATEGY, but VOP_BMAP can't translate any logical block numbers which results in EIO failures. When you try to access the image in a Xen DomU you see all disk operations failing. Therefore test if VOP_BMAP actually works and fall back to VOP_READ/VOP_WRITE if it doesn't. This makes a Xen DomU installation working. When you boot your fresh installed Xen DomU with a valid disklabel and file system in the image, VOP_BMAP actually works and is used. This allows you to create an image with dd as above on the Dom0 and run a DomU installation or to quickly create another virtual disk for an existing DomU without having to create a disklabel and file system by hand.
This commit is contained in:
parent
826cd7b39b
commit
75946855ff
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vnd.c,v 1.183 2008/06/14 07:52:36 cegger Exp $ */
|
||||
/* $NetBSD: vnd.c,v 1.184 2008/06/14 11:44:57 cegger Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
|
||||
@ -130,7 +130,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.183 2008/06/14 07:52:36 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.184 2008/06/14 11:44:57 cegger Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "fs_nfs.h"
|
||||
@ -526,6 +526,37 @@ done:
|
||||
splx(s);
|
||||
}
|
||||
|
||||
static bool
|
||||
vnode_has_strategy(struct vnd_softc *vnd)
|
||||
{
|
||||
return vnode_has_op(vnd->sc_vp, VOFFSET(vop_bmap)) &&
|
||||
vnode_has_op(vnd->sc_vp, VOFFSET(vop_strategy));
|
||||
}
|
||||
|
||||
static bool
|
||||
vnode_strategy_probe(struct vnd_softc *vnd)
|
||||
{
|
||||
int error;
|
||||
daddr_t nbn;
|
||||
|
||||
if (!vnode_has_strategy(vnd))
|
||||
return false;
|
||||
|
||||
/* Convert the first logical block number to its
|
||||
* physical block number.
|
||||
*/
|
||||
error = 0;
|
||||
vn_lock(vnd->sc_vp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
|
||||
error = VOP_BMAP(vnd->sc_vp, 0, NULL, &nbn, NULL);
|
||||
VOP_UNLOCK(vnd->sc_vp, 0);
|
||||
|
||||
/* Test if that worked. */
|
||||
if (error == 0 && (long)nbn == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
vndthread(void *arg)
|
||||
{
|
||||
@ -533,13 +564,12 @@ vndthread(void *arg)
|
||||
bool usestrategy;
|
||||
int s;
|
||||
|
||||
/* Determine whether we can use VOP_BMAP and VOP_STRATEGY to
|
||||
/* Determine whether we can *use* VOP_BMAP and VOP_STRATEGY to
|
||||
* directly access the backing vnode. If we can, use these two
|
||||
* operations to avoid messing with the local buffer cache.
|
||||
* Otherwise fall back to regular VOP_READ/VOP_WRITE operations
|
||||
* which are guaranteed to work with any file system. */
|
||||
usestrategy = vnode_has_op(vnd->sc_vp, VOFFSET(vop_bmap)) &&
|
||||
vnode_has_op(vnd->sc_vp, VOFFSET(vop_strategy));
|
||||
usestrategy = vnode_strategy_probe(vnd);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (vnddebug & VDB_INIT)
|
||||
|
Loading…
Reference in New Issue
Block a user