From 3f8a028ede974bfa2eb3b55df44be600b4d09198 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 1 Mar 2020 12:34:10 -0500 Subject: [PATCH] libxfs: introduce libxfs_buf_read_uncached Introduce an uncached read function so that userspace can handle them in the same way as the kernel. This also eliminates the need for some of the libxfs_purgebuf calls (and two trips into the cache code). Refactor the get/read uncached buffer functions to hide the details of uncached buffer-ism in rdwr.c. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Eric Sandeen --- libxfs/libxfs_api_defs.h | 2 ++ libxfs/libxfs_io.h | 22 +++---------- libxfs/rdwr.c | 67 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h index df267c98a..1149e301f 100644 --- a/libxfs/libxfs_api_defs.h +++ b/libxfs/libxfs_api_defs.h @@ -45,7 +45,9 @@ #define xfs_btree_init_block libxfs_btree_init_block #define xfs_buf_delwri_submit libxfs_buf_delwri_submit #define xfs_buf_get libxfs_buf_get +#define xfs_buf_get_uncached libxfs_buf_get_uncached #define xfs_buf_read libxfs_buf_read +#define xfs_buf_read_uncached libxfs_buf_read_uncached #define xfs_buf_relse libxfs_buf_relse #define xfs_bunmapi libxfs_bunmapi #define xfs_bwrite libxfs_bwrite diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h index d96b5318e..21afc99c1 100644 --- a/libxfs/libxfs_io.h +++ b/libxfs/libxfs_io.h @@ -255,23 +255,11 @@ xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t len) return 0; } -/* - * Allocate an uncached buffer that points nowhere. The refcount will be 1, - * and the cache node hash list will be empty to indicate that it's uncached. - */ -static inline struct xfs_buf * -xfs_buf_get_uncached(struct xfs_buftarg *targ, size_t bblen, int flags) -{ - struct xfs_buf *bp; - - bp = libxfs_getbufr(targ, XFS_BUF_DADDR_NULL, bblen); - if (!bp) - return NULL; - - INIT_LIST_HEAD(&bp->b_node.cn_hash); - bp->b_node.cn_count = 1; - return bp; -} +struct xfs_buf *libxfs_buf_get_uncached(struct xfs_buftarg *targ, size_t bblen, + int flags); +int libxfs_buf_read_uncached(struct xfs_buftarg *targ, xfs_daddr_t daddr, + size_t bblen, int flags, struct xfs_buf **bpp, + const struct xfs_buf_ops *ops); /* Push a single buffer on a delwri queue. */ static inline void diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 2c67edded..3b4702664 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1073,6 +1073,73 @@ libxfs_readbuf_map(struct xfs_buftarg *btp, struct xfs_buf_map *map, int nmaps, return bp; } +/* Allocate a raw uncached buffer. */ +static inline struct xfs_buf * +libxfs_getbufr_uncached( + struct xfs_buftarg *targ, + xfs_daddr_t daddr, + size_t bblen) +{ + struct xfs_buf *bp; + + bp = libxfs_getbufr(targ, daddr, bblen); + if (!bp) + return NULL; + + INIT_LIST_HEAD(&bp->b_node.cn_hash); + bp->b_node.cn_count = 1; + return bp; +} + +/* + * Allocate an uncached buffer that points nowhere. The refcount will be 1, + * and the cache node hash list will be empty to indicate that it's uncached. + */ +struct xfs_buf * +libxfs_buf_get_uncached( + struct xfs_buftarg *targ, + size_t bblen, + int flags) +{ + return libxfs_getbufr_uncached(targ, XFS_BUF_DADDR_NULL, bblen); +} + +/* + * Allocate and read an uncached buffer. The refcount will be 1, and the cache + * node hash list will be empty to indicate that it's uncached. + */ +int +libxfs_buf_read_uncached( + struct xfs_buftarg *targ, + xfs_daddr_t daddr, + size_t bblen, + int flags, + struct xfs_buf **bpp, + const struct xfs_buf_ops *ops) +{ + struct xfs_buf *bp; + int error; + + *bpp = NULL; + bp = libxfs_getbufr_uncached(targ, daddr, bblen); + if (!bp) + return -ENOMEM; + + error = libxfs_readbufr(targ, daddr, bp, bblen, flags); + if (error) + goto err; + + error = libxfs_readbuf_verify(bp, ops); + if (error) + goto err; + + *bpp = bp; + return 0; +err: + libxfs_buf_relse(bp); + return error; +} + static int __write_buf(int fd, void *buf, int len, off64_t offset, int flags) { -- 2.47.3