>
> I'm just checking out the "XFS with other blocksizes etc" work item,
> and it looks pretty good, but I've come across a bug which looks like
> another page_buf hiccup.
>
> This chunk takes the list of pages and maps it into a contiguous block
> and points pb_addr at it, right?
>
> page_buf.c:601
>
> if (all_mapped) {
> pb->pb_flags |= _PBF_ALL_PAGES_MAPPED;
> /* A single page buffer is always mappable */
> if ((page_count == 1) && (flags & PBF_MAPPED)) {
> pb->pb_addr =
> (caddr_t) page_address(kp->maplist[0]) + kp->
> offset;
> pb->pb_flags |= PBF_MAPPED;
> } else if ((flags & PBF_MAPPED) && (kp->offset == 0)) {
> pb->pb_addr = (caddr_t) remap_page_array(kp->maplist,
> page_count);
> if (pb->pb_addr) {
> pb->pb_flags |= PBF_MAPPED |
> _PBF_ADDR_ALLOCATED;
> }
> }
> }
>
> I'm hitting a case where all_mapped is true, as is (flags & PBF_MAPPED),
> but (kp->offset == 0) isn't. At the same time, pb_addr is NULL.
>
> So when I get out of the block above, pb_addr is still NULL and it doesn't
> look like it should be (NULL dereference later on).
>
> Does this ring any bells, guys? I'll keep working on it tomorrow...
>
Where is the pagebuf coming from, are you working with a block size smaller
than a page size? In this case I suppose a metadata block could start on a
2K boundary and cross page boundaries. In this case the remapping call would
be needed, and pb_addr would need to be setup.
The whole remap_page_array code probably has to go away at some point, it
causes tlb flushes and too costly to use. If the cost was just to XFS then
we could probably keep it, but it will slow down the whole system, not just
a thread in XFS.
Steve
p.s. Ananth was looking into the XFS with other block sizes issue.....
|