diff options
author | Dave Chinner <dchinner@redhat.com> | 2010-09-24 07:58:31 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-10-18 16:07:47 -0400 |
commit | 5adc94c247c3779782c7b0b8b5e28cf50596eb37 (patch) | |
tree | 95c2fac56cf6b9559b70aeaa43dae5a18b3c3fec /fs | |
parent | 686865f76e35b28ba7aa6afa19209426f0da6201 (diff) |
xfs: introduced uncached buffer read primitve
To avoid the need to use cached buffers for single-shot or buffers
cached at the filesystem level, introduce a new buffer read
primitive that bypasses the cache an reads directly from disk.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 34 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 3 |
2 files changed, 37 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index eca945b0f88f..22c7bff77ad2 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -638,6 +638,40 @@ xfs_buf_readahead( | |||
638 | xfs_buf_read(target, ioff, isize, flags); | 638 | xfs_buf_read(target, ioff, isize, flags); |
639 | } | 639 | } |
640 | 640 | ||
641 | /* | ||
642 | * Read an uncached buffer from disk. Allocates and returns a locked | ||
643 | * buffer containing the disk contents or nothing. | ||
644 | */ | ||
645 | struct xfs_buf * | ||
646 | xfs_buf_read_uncached( | ||
647 | struct xfs_mount *mp, | ||
648 | struct xfs_buftarg *target, | ||
649 | xfs_daddr_t daddr, | ||
650 | size_t length, | ||
651 | int flags) | ||
652 | { | ||
653 | xfs_buf_t *bp; | ||
654 | int error; | ||
655 | |||
656 | bp = xfs_buf_get_uncached(target, length, flags); | ||
657 | if (!bp) | ||
658 | return NULL; | ||
659 | |||
660 | /* set up the buffer for a read IO */ | ||
661 | xfs_buf_lock(bp); | ||
662 | XFS_BUF_SET_ADDR(bp, daddr); | ||
663 | XFS_BUF_READ(bp); | ||
664 | XFS_BUF_BUSY(bp); | ||
665 | |||
666 | xfsbdstrat(mp, bp); | ||
667 | error = xfs_iowait(bp); | ||
668 | if (error || bp->b_error) { | ||
669 | xfs_buf_relse(bp); | ||
670 | return NULL; | ||
671 | } | ||
672 | return bp; | ||
673 | } | ||
674 | |||
641 | xfs_buf_t * | 675 | xfs_buf_t * |
642 | xfs_buf_get_empty( | 676 | xfs_buf_get_empty( |
643 | size_t len, | 677 | size_t len, |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index fb30447091d8..57eedc750ee6 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -218,6 +218,9 @@ extern int xfs_buf_associate_memory(xfs_buf_t *, void *, size_t); | |||
218 | extern void xfs_buf_hold(xfs_buf_t *); | 218 | extern void xfs_buf_hold(xfs_buf_t *); |
219 | extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, | 219 | extern void xfs_buf_readahead(xfs_buftarg_t *, xfs_off_t, size_t, |
220 | xfs_buf_flags_t); | 220 | xfs_buf_flags_t); |
221 | struct xfs_buf *xfs_buf_read_uncached(struct xfs_mount *mp, | ||
222 | struct xfs_buftarg *target, | ||
223 | xfs_daddr_t daddr, size_t length, int flags); | ||
221 | 224 | ||
222 | /* Releasing Buffers */ | 225 | /* Releasing Buffers */ |
223 | extern void xfs_buf_free(xfs_buf_t *); | 226 | extern void xfs_buf_free(xfs_buf_t *); |