diff options
author | Jan Kara <jack@suse.cz> | 2012-06-05 18:32:26 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-06-21 14:38:25 -0400 |
commit | bcf62ab64d1ba257dd9d4283a077a7219a05073a (patch) | |
tree | b4de28d5e5978de675440e966384f0c4c01ff0e3 /fs/xfs | |
parent | 079da28c64ebeca357adae77aea3ae7160e45d98 (diff) |
xfs: Fix overallocation in xfs_buf_allocate_memory()
Commit de1cbee which removed b_file_offset in favor of b_bn introduced a bug
causing xfs_buf_allocate_memory() to overestimate the number of necessary
pages. The problem is that xfs_buf_alloc() sets b_bn to -1 and thus effectively
every buffer is straddling a page boundary which causes
xfs_buf_allocate_memory() to allocate two pages and use vmalloc() for access
which is unnecessary.
Dave says xfs_buf_alloc() doesn't need to set b_bn to -1 anymore since the
buffer is inserted into the cache only after being fully initialized now.
So just make xfs_buf_alloc() fill in proper block number from the beginning.
CC: David Chinner <dchinner@redhat.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_buf.c | 16 |
1 files changed, 2 insertions, 14 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 172d3cc8f8cb..a4beb421018a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -201,14 +201,7 @@ xfs_buf_alloc( | |||
201 | bp->b_length = numblks; | 201 | bp->b_length = numblks; |
202 | bp->b_io_length = numblks; | 202 | bp->b_io_length = numblks; |
203 | bp->b_flags = flags; | 203 | bp->b_flags = flags; |
204 | 204 | bp->b_bn = blkno; | |
205 | /* | ||
206 | * We do not set the block number here in the buffer because we have not | ||
207 | * finished initialising the buffer. We insert the buffer into the cache | ||
208 | * in this state, so this ensures that we are unable to do IO on a | ||
209 | * buffer that hasn't been fully initialised. | ||
210 | */ | ||
211 | bp->b_bn = XFS_BUF_DADDR_NULL; | ||
212 | atomic_set(&bp->b_pin_count, 0); | 205 | atomic_set(&bp->b_pin_count, 0); |
213 | init_waitqueue_head(&bp->b_waiters); | 206 | init_waitqueue_head(&bp->b_waiters); |
214 | 207 | ||
@@ -567,11 +560,6 @@ xfs_buf_get( | |||
567 | if (bp != new_bp) | 560 | if (bp != new_bp) |
568 | xfs_buf_free(new_bp); | 561 | xfs_buf_free(new_bp); |
569 | 562 | ||
570 | /* | ||
571 | * Now we have a workable buffer, fill in the block number so | ||
572 | * that we can do IO on it. | ||
573 | */ | ||
574 | bp->b_bn = blkno; | ||
575 | bp->b_io_length = bp->b_length; | 563 | bp->b_io_length = bp->b_length; |
576 | 564 | ||
577 | found: | 565 | found: |
@@ -772,7 +760,7 @@ xfs_buf_get_uncached( | |||
772 | int error, i; | 760 | int error, i; |
773 | xfs_buf_t *bp; | 761 | xfs_buf_t *bp; |
774 | 762 | ||
775 | bp = xfs_buf_alloc(target, 0, numblks, 0); | 763 | bp = xfs_buf_alloc(target, XFS_BUF_DADDR_NULL, numblks, 0); |
776 | if (unlikely(bp == NULL)) | 764 | if (unlikely(bp == NULL)) |
777 | goto fail; | 765 | goto fail; |
778 | 766 | ||