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