Subject: Overlapping bread(9) behaviour
To: None <tech-kern@netbsd.org>
From: Stephen M. Rumble <stephen.rumble@utoronto.ca>
List: tech-kern
Date: 07/01/2007 12:53:37
Hi all,
I'm running into a strange behaviour while using bread(9) and am
unsure whether I misunderstand how it's supposed to behave, am running
into some sort of bug, or have otherwise misused the subsystem.
The problem is that if I read one block from offset X, and then later
read more than one block from the same offset X, the overlapping block
contents are fine, but the rest is garbage. Here's a short code example:
struct buf *bp = NULL;
struct buf *bp2 = NULL;
struct efs_sb sb;
#if 0 /* works fine - magic is okay */
bread(devvp, 0, 1024, NOCRED, &bp);
memcpy(&sb, ((char *)bp->b_data) + 512, sizeof(struct efs_sb));
brelse(bp);
printf("superblock magic (no overlap %s): 0x%x\n", __func__,
be32toh(sb.sb_magic));
(void)bp2;
#else /* broken - magic is garbage */
bread(devvp, 0, 512, NOCRED, &bp);
brelse(bp);
bread(devvp, 0, 1024, NOCRED, &bp2);
memcpy(&sb, ((char *)bp2->b_data) + 512, sizeof(struct efs_sb));
brelse(bp2);
printf("superblock magic (overlap %s): 0x%x\n", __func__,
be32toh(sb.sb_magic));
#endif
I've put this code in my VFS_MOUNT routine directly after opening
device devvp. So long as I don't do these sorts of overlapping reads,
everything works fine.
Additional data points: b_bcount and b_resid are fine in both
instances, and in the case of doing overlapping reads, bp->b_data and
bp2->b_data are different pointers.
Any input would be appreciated,
Steve