Commit d44d9bc6 authored by Mark Tinguely's avatar Mark Tinguely Committed by Ben Myers

xfs: use b_maps[] for discontiguous buffers

Commits starting at 77c1a08f introduced a multiple segment support
to xfs_buf. xfs_trans_buf_item_match() could not find a multi-segment
buffer in the transaction because it was looking at the single segment
block number rather than the multi-segment b_maps[0].bm.bn. This
results on a recursive buffer lock that can never be satisfied.

This patch:
 1) Changed the remaining b_map accesses to be b_maps[0] accesses.
 2) Renames the single segment b_map structure to __b_map to avoid
    future confusion.
Signed-off-by: default avatarMark Tinguely <tinguely@sgi.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent a49f0d1e
...@@ -175,7 +175,7 @@ xfs_buf_get_maps( ...@@ -175,7 +175,7 @@ xfs_buf_get_maps(
bp->b_map_count = map_count; bp->b_map_count = map_count;
if (map_count == 1) { if (map_count == 1) {
bp->b_maps = &bp->b_map; bp->b_maps = &bp->__b_map;
return 0; return 0;
} }
...@@ -193,7 +193,7 @@ static void ...@@ -193,7 +193,7 @@ static void
xfs_buf_free_maps( xfs_buf_free_maps(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
if (bp->b_maps != &bp->b_map) { if (bp->b_maps != &bp->__b_map) {
kmem_free(bp->b_maps); kmem_free(bp->b_maps);
bp->b_maps = NULL; bp->b_maps = NULL;
} }
...@@ -377,8 +377,8 @@ xfs_buf_allocate_memory( ...@@ -377,8 +377,8 @@ xfs_buf_allocate_memory(
} }
use_alloc_page: use_alloc_page:
start = BBTOB(bp->b_map.bm_bn) >> PAGE_SHIFT; start = BBTOB(bp->b_maps[0].bm_bn) >> PAGE_SHIFT;
end = (BBTOB(bp->b_map.bm_bn + bp->b_length) + PAGE_SIZE - 1) end = (BBTOB(bp->b_maps[0].bm_bn + bp->b_length) + PAGE_SIZE - 1)
>> PAGE_SHIFT; >> PAGE_SHIFT;
page_count = end - start; page_count = end - start;
error = _xfs_buf_get_pages(bp, page_count, flags); error = _xfs_buf_get_pages(bp, page_count, flags);
...@@ -640,7 +640,7 @@ _xfs_buf_read( ...@@ -640,7 +640,7 @@ _xfs_buf_read(
xfs_buf_flags_t flags) xfs_buf_flags_t flags)
{ {
ASSERT(!(flags & XBF_WRITE)); ASSERT(!(flags & XBF_WRITE));
ASSERT(bp->b_map.bm_bn != XFS_BUF_DADDR_NULL); ASSERT(bp->b_maps[0].bm_bn != XFS_BUF_DADDR_NULL);
bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD);
bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD);
...@@ -1709,7 +1709,7 @@ xfs_buf_cmp( ...@@ -1709,7 +1709,7 @@ xfs_buf_cmp(
struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list); struct xfs_buf *bp = container_of(b, struct xfs_buf, b_list);
xfs_daddr_t diff; xfs_daddr_t diff;
diff = ap->b_map.bm_bn - bp->b_map.bm_bn; diff = ap->b_maps[0].bm_bn - bp->b_maps[0].bm_bn;
if (diff < 0) if (diff < 0)
return -1; return -1;
if (diff > 0) if (diff > 0)
......
...@@ -151,7 +151,7 @@ typedef struct xfs_buf { ...@@ -151,7 +151,7 @@ typedef struct xfs_buf {
struct page **b_pages; /* array of page pointers */ struct page **b_pages; /* array of page pointers */
struct page *b_page_array[XB_PAGES]; /* inline pages */ struct page *b_page_array[XB_PAGES]; /* inline pages */
struct xfs_buf_map *b_maps; /* compound buffer map */ struct xfs_buf_map *b_maps; /* compound buffer map */
struct xfs_buf_map b_map; /* inline compound buffer map */ struct xfs_buf_map __b_map; /* inline compound buffer map */
int b_map_count; int b_map_count;
int b_io_length; /* IO size in BBs */ int b_io_length; /* IO size in BBs */
atomic_t b_pin_count; /* pin count */ atomic_t b_pin_count; /* pin count */
...@@ -330,8 +330,8 @@ void xfs_buf_stale(struct xfs_buf *bp); ...@@ -330,8 +330,8 @@ void xfs_buf_stale(struct xfs_buf *bp);
* In future, uncached buffers will pass the block number directly to the io * In future, uncached buffers will pass the block number directly to the io
* request function and hence these macros will go away at that point. * request function and hence these macros will go away at that point.
*/ */
#define XFS_BUF_ADDR(bp) ((bp)->b_map.bm_bn) #define XFS_BUF_ADDR(bp) ((bp)->b_maps[0].bm_bn)
#define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_map.bm_bn = (xfs_daddr_t)(bno)) #define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_maps[0].bm_bn = (xfs_daddr_t)(bno))
static inline void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref) static inline void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment