Subject: bread() returns EINVAL during vfs mount
To: None <tech-kern@NetBSD.org>
From: Yevgeny Binder <yevbee@comcast.net>
List: tech-kern
Date: 08/20/2005 21:47:18
I've tried to follow the ffs code closely while developing hfs+
support, so it stumped me when I found that bread() invariably
returns EINVAL in my VFS mount routine. I have a valid pointer to the
volume's device node, devvp, obtained using the same ffs code:
NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
if ((error = namei(ndp)) != 0)
return error;
devvp = ndp->ni_vp;
ndp comes from the mount arguments, and args.fspec is presently set
to "/dev/cd0a". I open this node and flush it:
if ((error = VOP_OPEN(devvp, FREAD, FSCRED, p)) != 0)
goto error;
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0);
VOP_UNLOCK(devvp, 0);
if (error != 0)
goto error;
p also comes from the mount arguments, and cred = p ? p->p_ucred :
NOCRED. Finally,
struct buf *bp = NULL;
error = bread(devvp, 16, 1536, cred, &bp);
if (bp != NULL) {
/* memcpy() would take the place of the printf() below in
the real implementation */
printf("bp->b_un.b_addr = %#x\n", (unsigned)bp->b_un.b_addr);
brelse(bp);
}
(The block number and length are temporarily hardcoded for testing.)
This always produces an error 22, EINVAL. Interestingly, bp is not
NULL, and bp->b_un.b_addr points to a seemingly valid location,
albeit one with meaningless data (always 0xDEADBEEF, followed by two
pointers, followed by a bunch of zeroes). I know that the device and
its contents at the specified block range are good, because I have
userland code which calls pread() on that range and returns perfectly
correct data.
After trying dozens of changes that all resulted in the same error,
the only possibility I can imagine is that I've somehow missed a
subtle VFS call or preprocessor macro somewhere. But I've pored over
the ffs code and I don't think I've left anything out. Could someone
please outline the essential steps needed to go from receiving a VFS
mount call to being able to call bread() successfully, including any
vital preprocessor commands? I thought the above code was it, but
then what's causing bread() to fail?
Thank you,
Yevgeny Binder