g_vfs_open and bread(devvp, ...)

Andriy Gapon avg at freebsd.org
Thu Apr 1 17:38:09 UTC 2010


Some bad news.
Apparently I missed the fact that in some places bo_bsize is used as sectorsize
value of underlying provider.  That is, there is code that assumes that devvp's
bo_bsize == sectorsize.

One such place is vnode_pager_generic_getpages() in sys/vm/vnode_pager.c.
That code directly calls bstrategy() on bufobj of devvp and because of that it
wants to round up read size to media sectorsize (there would be a KASSERT panic in
GEOM if I/O size is not multiple of sectorsize).
Thus the code needs to know sectorsize.

The other possible place is ffs_rawread.

I am not sure how to get sectorsize value in those places in a nice way, i.e.
without kludges or violating logical layering.
I.e. I could access bo_private->provider->sectorsize, but that seems to be too
hack-ish.
If anyone knows of a proper way to do this, please let me know.

For now I am thinking about resorting to a different, slightly less kludgy (IMO)
approach.
Leave devvp's bo_bsize to mean provider's sectorsize, but instead in getblk()
account for devvp's blkno being in units of DEV_BSIZE:
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -2700,7 +2700,7 @@
 		 */
 		if (flags & GB_NOCREAT)
 			return NULL;
-		bsize = bo->bo_bsize;
+		bsize = vn_isdisk(vp, NULL) ? DEV_BSIZE : bo->bo_bsize;
 		offset = blkno * bsize;
 		vmio = vp->v_object != NULL;
 		maxsize = vmio ? size + (offset & PAGE_MASK) : size;

-- 
Andriy Gapon


More information about the freebsd-fs mailing list