aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf.c39
-rw-r--r--fs/xfs/xfs_buf.h5
2 files changed, 21 insertions, 23 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index ab3c4491777b..942cf5051ab4 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -306,7 +306,7 @@ xfs_buf_allocate_memory(
306 size_t nbytes, offset; 306 size_t nbytes, offset;
307 gfp_t gfp_mask = xb_to_gfp(flags); 307 gfp_t gfp_mask = xb_to_gfp(flags);
308 unsigned short page_count, i; 308 unsigned short page_count, i;
309 xfs_off_t end; 309 xfs_off_t start, end;
310 int error; 310 int error;
311 311
312 /* 312 /*
@@ -314,15 +314,15 @@ xfs_buf_allocate_memory(
314 * the memory from the heap - there's no need for the complexity of 314 * the memory from the heap - there's no need for the complexity of
315 * page arrays to keep allocation down to order 0. 315 * page arrays to keep allocation down to order 0.
316 */ 316 */
317 if (bp->b_length < BTOBB(PAGE_SIZE)) { 317 size = BBTOB(bp->b_length);
318 bp->b_addr = kmem_alloc(BBTOB(bp->b_length), xb_to_km(flags)); 318 if (size < PAGE_SIZE) {
319 bp->b_addr = kmem_alloc(size, xb_to_km(flags));
319 if (!bp->b_addr) { 320 if (!bp->b_addr) {
320 /* low memory - use alloc_page loop instead */ 321 /* low memory - use alloc_page loop instead */
321 goto use_alloc_page; 322 goto use_alloc_page;
322 } 323 }
323 324
324 if (((unsigned long)(bp->b_addr + BBTOB(bp->b_length) - 1) & 325 if (((unsigned long)(bp->b_addr + size - 1) & PAGE_MASK) !=
325 PAGE_MASK) !=
326 ((unsigned long)bp->b_addr & PAGE_MASK)) { 326 ((unsigned long)bp->b_addr & PAGE_MASK)) {
327 /* b_addr spans two pages - use alloc_page instead */ 327 /* b_addr spans two pages - use alloc_page instead */
328 kmem_free(bp->b_addr); 328 kmem_free(bp->b_addr);
@@ -338,14 +338,14 @@ xfs_buf_allocate_memory(
338 } 338 }
339 339
340use_alloc_page: 340use_alloc_page:
341 end = BBTOB(bp->b_bn + bp->b_length); 341 start = BBTOB(bp->b_bn) >> PAGE_SHIFT;
342 page_count = xfs_buf_btoc(end) - xfs_buf_btoct(BBTOB(bp->b_bn)); 342 end = (BBTOB(bp->b_bn + bp->b_length) + PAGE_SIZE - 1) >> PAGE_SHIFT;
343 page_count = end - start;
343 error = _xfs_buf_get_pages(bp, page_count, flags); 344 error = _xfs_buf_get_pages(bp, page_count, flags);
344 if (unlikely(error)) 345 if (unlikely(error))
345 return error; 346 return error;
346 347
347 offset = bp->b_offset; 348 offset = bp->b_offset;
348 size = BBTOB(bp->b_length);
349 bp->b_flags |= _XBF_PAGES; 349 bp->b_flags |= _XBF_PAGES;
350 350
351 for (i = 0; i < bp->b_page_count; i++) { 351 for (i = 0; i < bp->b_page_count; i++) {
@@ -1320,27 +1320,30 @@ xfs_buf_iomove(
1320 void *data, /* data address */ 1320 void *data, /* data address */
1321 xfs_buf_rw_t mode) /* read/write/zero flag */ 1321 xfs_buf_rw_t mode) /* read/write/zero flag */
1322{ 1322{
1323 size_t bend, cpoff, csize; 1323 size_t bend;
1324 struct page *page;
1325 1324
1326 bend = boff + bsize; 1325 bend = boff + bsize;
1327 while (boff < bend) { 1326 while (boff < bend) {
1328 page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)]; 1327 struct page *page;
1329 cpoff = xfs_buf_poff(boff + bp->b_offset); 1328 int page_index, page_offset, csize;
1330 csize = min_t(size_t, 1329
1331 PAGE_SIZE - cpoff, BBTOB(bp->b_io_length) - boff); 1330 page_index = (boff + bp->b_offset) >> PAGE_SHIFT;
1331 page_offset = (boff + bp->b_offset) & ~PAGE_MASK;
1332 page = bp->b_pages[page_index];
1333 csize = min_t(size_t, PAGE_SIZE - page_offset,
1334 BBTOB(bp->b_io_length) - boff);
1332 1335
1333 ASSERT(((csize + cpoff) <= PAGE_SIZE)); 1336 ASSERT((csize + page_offset) <= PAGE_SIZE);
1334 1337
1335 switch (mode) { 1338 switch (mode) {
1336 case XBRW_ZERO: 1339 case XBRW_ZERO:
1337 memset(page_address(page) + cpoff, 0, csize); 1340 memset(page_address(page) + page_offset, 0, csize);
1338 break; 1341 break;
1339 case XBRW_READ: 1342 case XBRW_READ:
1340 memcpy(data, page_address(page) + cpoff, csize); 1343 memcpy(data, page_address(page) + page_offset, csize);
1341 break; 1344 break;
1342 case XBRW_WRITE: 1345 case XBRW_WRITE:
1343 memcpy(page_address(page) + cpoff, data, csize); 1346 memcpy(page_address(page) + page_offset, data, csize);
1344 } 1347 }
1345 1348
1346 boff += csize; 1349 boff += csize;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 9787645fa54c..5b048f7d13ea 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -32,11 +32,6 @@
32 32
33#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL)) 33#define XFS_BUF_DADDR_NULL ((xfs_daddr_t) (-1LL))
34 34
35#define xfs_buf_ctob(pp) ((pp) * PAGE_CACHE_SIZE)
36#define xfs_buf_btoc(dd) (((dd) + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT)
37#define xfs_buf_btoct(dd) ((dd) >> PAGE_CACHE_SHIFT)
38#define xfs_buf_poff(aa) ((aa) & ~PAGE_CACHE_MASK)
39
40typedef enum { 35typedef enum {
41 XBRW_READ = 1, /* transfer into target memory */ 36 XBRW_READ = 1, /* transfer into target memory */
42 XBRW_WRITE = 2, /* transfer from target memory */ 37 XBRW_WRITE = 2, /* transfer from target memory */