162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2000-2005 Silicon Graphics, Inc.
462306a36Sopenharmony_ci * All Rights Reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_BUF_H__
762306a36Sopenharmony_ci#define __XFS_BUF_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/list.h>
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/spinlock.h>
1262306a36Sopenharmony_ci#include <linux/mm.h>
1362306a36Sopenharmony_ci#include <linux/fs.h>
1462306a36Sopenharmony_ci#include <linux/dax.h>
1562306a36Sopenharmony_ci#include <linux/uio.h>
1662306a36Sopenharmony_ci#include <linux/list_lru.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciextern struct kmem_cache *xfs_buf_cache;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/*
2162306a36Sopenharmony_ci *	Base types
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_cistruct xfs_buf;
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define XFS_BUF_DADDR_NULL	((xfs_daddr_t) (-1LL))
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define XBF_READ	 (1u << 0) /* buffer intended for reading from device */
2862306a36Sopenharmony_ci#define XBF_WRITE	 (1u << 1) /* buffer intended for writing to device */
2962306a36Sopenharmony_ci#define XBF_READ_AHEAD	 (1u << 2) /* asynchronous read-ahead */
3062306a36Sopenharmony_ci#define XBF_NO_IOACCT	 (1u << 3) /* bypass I/O accounting (non-LRU bufs) */
3162306a36Sopenharmony_ci#define XBF_ASYNC	 (1u << 4) /* initiator will not wait for completion */
3262306a36Sopenharmony_ci#define XBF_DONE	 (1u << 5) /* all pages in the buffer uptodate */
3362306a36Sopenharmony_ci#define XBF_STALE	 (1u << 6) /* buffer has been staled, do not find it */
3462306a36Sopenharmony_ci#define XBF_WRITE_FAIL	 (1u << 7) /* async writes have failed on this buffer */
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* buffer type flags for write callbacks */
3762306a36Sopenharmony_ci#define _XBF_INODES	 (1u << 16)/* inode buffer */
3862306a36Sopenharmony_ci#define _XBF_DQUOTS	 (1u << 17)/* dquot buffer */
3962306a36Sopenharmony_ci#define _XBF_LOGRECOVERY (1u << 18)/* log recovery buffer */
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* flags used only internally */
4262306a36Sopenharmony_ci#define _XBF_PAGES	 (1u << 20)/* backed by refcounted pages */
4362306a36Sopenharmony_ci#define _XBF_KMEM	 (1u << 21)/* backed by heap memory */
4462306a36Sopenharmony_ci#define _XBF_DELWRI_Q	 (1u << 22)/* buffer on a delwri queue */
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* flags used only as arguments to access routines */
4762306a36Sopenharmony_ci/*
4862306a36Sopenharmony_ci * Online fsck is scanning the buffer cache for live buffers.  Do not warn
4962306a36Sopenharmony_ci * about length mismatches during lookups and do not return stale buffers.
5062306a36Sopenharmony_ci */
5162306a36Sopenharmony_ci#define XBF_LIVESCAN	 (1u << 28)
5262306a36Sopenharmony_ci#define XBF_INCORE	 (1u << 29)/* lookup only, return if found in cache */
5362306a36Sopenharmony_ci#define XBF_TRYLOCK	 (1u << 30)/* lock requested, but do not wait */
5462306a36Sopenharmony_ci#define XBF_UNMAPPED	 (1u << 31)/* do not map the buffer */
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_citypedef unsigned int xfs_buf_flags_t;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#define XFS_BUF_FLAGS \
6062306a36Sopenharmony_ci	{ XBF_READ,		"READ" }, \
6162306a36Sopenharmony_ci	{ XBF_WRITE,		"WRITE" }, \
6262306a36Sopenharmony_ci	{ XBF_READ_AHEAD,	"READ_AHEAD" }, \
6362306a36Sopenharmony_ci	{ XBF_NO_IOACCT,	"NO_IOACCT" }, \
6462306a36Sopenharmony_ci	{ XBF_ASYNC,		"ASYNC" }, \
6562306a36Sopenharmony_ci	{ XBF_DONE,		"DONE" }, \
6662306a36Sopenharmony_ci	{ XBF_STALE,		"STALE" }, \
6762306a36Sopenharmony_ci	{ XBF_WRITE_FAIL,	"WRITE_FAIL" }, \
6862306a36Sopenharmony_ci	{ _XBF_INODES,		"INODES" }, \
6962306a36Sopenharmony_ci	{ _XBF_DQUOTS,		"DQUOTS" }, \
7062306a36Sopenharmony_ci	{ _XBF_LOGRECOVERY,	"LOG_RECOVERY" }, \
7162306a36Sopenharmony_ci	{ _XBF_PAGES,		"PAGES" }, \
7262306a36Sopenharmony_ci	{ _XBF_KMEM,		"KMEM" }, \
7362306a36Sopenharmony_ci	{ _XBF_DELWRI_Q,	"DELWRI_Q" }, \
7462306a36Sopenharmony_ci	/* The following interface flags should never be set */ \
7562306a36Sopenharmony_ci	{ XBF_LIVESCAN,		"LIVESCAN" }, \
7662306a36Sopenharmony_ci	{ XBF_INCORE,		"INCORE" }, \
7762306a36Sopenharmony_ci	{ XBF_TRYLOCK,		"TRYLOCK" }, \
7862306a36Sopenharmony_ci	{ XBF_UNMAPPED,		"UNMAPPED" }
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * Internal state flags.
8262306a36Sopenharmony_ci */
8362306a36Sopenharmony_ci#define XFS_BSTATE_DISPOSE	 (1 << 0)	/* buffer being discarded */
8462306a36Sopenharmony_ci#define XFS_BSTATE_IN_FLIGHT	 (1 << 1)	/* I/O in flight */
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/*
8762306a36Sopenharmony_ci * The xfs_buftarg contains 2 notions of "sector size" -
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * 1) The metadata sector size, which is the minimum unit and
9062306a36Sopenharmony_ci *    alignment of IO which will be performed by metadata operations.
9162306a36Sopenharmony_ci * 2) The device logical sector size
9262306a36Sopenharmony_ci *
9362306a36Sopenharmony_ci * The first is specified at mkfs time, and is stored on-disk in the
9462306a36Sopenharmony_ci * superblock's sb_sectsize.
9562306a36Sopenharmony_ci *
9662306a36Sopenharmony_ci * The latter is derived from the underlying device, and controls direct IO
9762306a36Sopenharmony_ci * alignment constraints.
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_citypedef struct xfs_buftarg {
10062306a36Sopenharmony_ci	dev_t			bt_dev;
10162306a36Sopenharmony_ci	struct block_device	*bt_bdev;
10262306a36Sopenharmony_ci	struct dax_device	*bt_daxdev;
10362306a36Sopenharmony_ci	u64			bt_dax_part_off;
10462306a36Sopenharmony_ci	struct xfs_mount	*bt_mount;
10562306a36Sopenharmony_ci	unsigned int		bt_meta_sectorsize;
10662306a36Sopenharmony_ci	size_t			bt_meta_sectormask;
10762306a36Sopenharmony_ci	size_t			bt_logical_sectorsize;
10862306a36Sopenharmony_ci	size_t			bt_logical_sectormask;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	/* LRU control structures */
11162306a36Sopenharmony_ci	struct shrinker		bt_shrinker;
11262306a36Sopenharmony_ci	struct list_lru		bt_lru;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	struct percpu_counter	bt_io_count;
11562306a36Sopenharmony_ci	struct ratelimit_state	bt_ioerror_rl;
11662306a36Sopenharmony_ci} xfs_buftarg_t;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci#define XB_PAGES	2
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistruct xfs_buf_map {
12162306a36Sopenharmony_ci	xfs_daddr_t		bm_bn;	/* block number for I/O */
12262306a36Sopenharmony_ci	int			bm_len;	/* size of I/O */
12362306a36Sopenharmony_ci	unsigned int		bm_flags;
12462306a36Sopenharmony_ci};
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/*
12762306a36Sopenharmony_ci * Online fsck is scanning the buffer cache for live buffers.  Do not warn
12862306a36Sopenharmony_ci * about length mismatches during lookups and do not return stale buffers.
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_ci#define XBM_LIVESCAN		(1U << 0)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \
13362306a36Sopenharmony_ci	struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) };
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct xfs_buf_ops {
13662306a36Sopenharmony_ci	char *name;
13762306a36Sopenharmony_ci	union {
13862306a36Sopenharmony_ci		__be32 magic[2];	/* v4 and v5 on disk magic values */
13962306a36Sopenharmony_ci		__be16 magic16[2];	/* v4 and v5 on disk magic values */
14062306a36Sopenharmony_ci	};
14162306a36Sopenharmony_ci	void (*verify_read)(struct xfs_buf *);
14262306a36Sopenharmony_ci	void (*verify_write)(struct xfs_buf *);
14362306a36Sopenharmony_ci	xfs_failaddr_t (*verify_struct)(struct xfs_buf *bp);
14462306a36Sopenharmony_ci};
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cistruct xfs_buf {
14762306a36Sopenharmony_ci	/*
14862306a36Sopenharmony_ci	 * first cacheline holds all the fields needed for an uncontended cache
14962306a36Sopenharmony_ci	 * hit to be fully processed. The semaphore straddles the cacheline
15062306a36Sopenharmony_ci	 * boundary, but the counter and lock sits on the first cacheline,
15162306a36Sopenharmony_ci	 * which is the only bit that is touched if we hit the semaphore
15262306a36Sopenharmony_ci	 * fast-path on locking.
15362306a36Sopenharmony_ci	 */
15462306a36Sopenharmony_ci	struct rhash_head	b_rhash_head;	/* pag buffer hash node */
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	xfs_daddr_t		b_rhash_key;	/* buffer cache index */
15762306a36Sopenharmony_ci	int			b_length;	/* size of buffer in BBs */
15862306a36Sopenharmony_ci	atomic_t		b_hold;		/* reference count */
15962306a36Sopenharmony_ci	atomic_t		b_lru_ref;	/* lru reclaim ref count */
16062306a36Sopenharmony_ci	xfs_buf_flags_t		b_flags;	/* status flags */
16162306a36Sopenharmony_ci	struct semaphore	b_sema;		/* semaphore for lockables */
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	/*
16462306a36Sopenharmony_ci	 * concurrent access to b_lru and b_lru_flags are protected by
16562306a36Sopenharmony_ci	 * bt_lru_lock and not by b_sema
16662306a36Sopenharmony_ci	 */
16762306a36Sopenharmony_ci	struct list_head	b_lru;		/* lru list */
16862306a36Sopenharmony_ci	spinlock_t		b_lock;		/* internal state lock */
16962306a36Sopenharmony_ci	unsigned int		b_state;	/* internal state flags */
17062306a36Sopenharmony_ci	int			b_io_error;	/* internal IO error state */
17162306a36Sopenharmony_ci	wait_queue_head_t	b_waiters;	/* unpin waiters */
17262306a36Sopenharmony_ci	struct list_head	b_list;
17362306a36Sopenharmony_ci	struct xfs_perag	*b_pag;		/* contains rbtree root */
17462306a36Sopenharmony_ci	struct xfs_mount	*b_mount;
17562306a36Sopenharmony_ci	struct xfs_buftarg	*b_target;	/* buffer target (device) */
17662306a36Sopenharmony_ci	void			*b_addr;	/* virtual address of buffer */
17762306a36Sopenharmony_ci	struct work_struct	b_ioend_work;
17862306a36Sopenharmony_ci	struct completion	b_iowait;	/* queue for I/O waiters */
17962306a36Sopenharmony_ci	struct xfs_buf_log_item	*b_log_item;
18062306a36Sopenharmony_ci	struct list_head	b_li_list;	/* Log items list head */
18162306a36Sopenharmony_ci	struct xfs_trans	*b_transp;
18262306a36Sopenharmony_ci	struct page		**b_pages;	/* array of page pointers */
18362306a36Sopenharmony_ci	struct page		*b_page_array[XB_PAGES]; /* inline pages */
18462306a36Sopenharmony_ci	struct xfs_buf_map	*b_maps;	/* compound buffer map */
18562306a36Sopenharmony_ci	struct xfs_buf_map	__b_map;	/* inline compound buffer map */
18662306a36Sopenharmony_ci	int			b_map_count;
18762306a36Sopenharmony_ci	atomic_t		b_pin_count;	/* pin count */
18862306a36Sopenharmony_ci	atomic_t		b_io_remaining;	/* #outstanding I/O requests */
18962306a36Sopenharmony_ci	unsigned int		b_page_count;	/* size of page array */
19062306a36Sopenharmony_ci	unsigned int		b_offset;	/* page offset of b_addr,
19162306a36Sopenharmony_ci						   only for _XBF_KMEM buffers */
19262306a36Sopenharmony_ci	int			b_error;	/* error code on I/O */
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	/*
19562306a36Sopenharmony_ci	 * async write failure retry count. Initialised to zero on the first
19662306a36Sopenharmony_ci	 * failure, then when it exceeds the maximum configured without a
19762306a36Sopenharmony_ci	 * success the write is considered to be failed permanently and the
19862306a36Sopenharmony_ci	 * iodone handler will take appropriate action.
19962306a36Sopenharmony_ci	 *
20062306a36Sopenharmony_ci	 * For retry timeouts, we record the jiffie of the first failure. This
20162306a36Sopenharmony_ci	 * means that we can change the retry timeout for buffers already under
20262306a36Sopenharmony_ci	 * I/O and thus avoid getting stuck in a retry loop with a long timeout.
20362306a36Sopenharmony_ci	 *
20462306a36Sopenharmony_ci	 * last_error is used to ensure that we are getting repeated errors, not
20562306a36Sopenharmony_ci	 * different errors. e.g. a block device might change ENOSPC to EIO when
20662306a36Sopenharmony_ci	 * a failure timeout occurs, so we want to re-initialise the error
20762306a36Sopenharmony_ci	 * retry behaviour appropriately when that happens.
20862306a36Sopenharmony_ci	 */
20962306a36Sopenharmony_ci	int			b_retries;
21062306a36Sopenharmony_ci	unsigned long		b_first_retry_time; /* in jiffies */
21162306a36Sopenharmony_ci	int			b_last_error;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	const struct xfs_buf_ops	*b_ops;
21462306a36Sopenharmony_ci	struct rcu_head		b_rcu;
21562306a36Sopenharmony_ci};
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci/* Finding and Reading Buffers */
21862306a36Sopenharmony_ciint xfs_buf_get_map(struct xfs_buftarg *target, struct xfs_buf_map *map,
21962306a36Sopenharmony_ci		int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp);
22062306a36Sopenharmony_ciint xfs_buf_read_map(struct xfs_buftarg *target, struct xfs_buf_map *map,
22162306a36Sopenharmony_ci		int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp,
22262306a36Sopenharmony_ci		const struct xfs_buf_ops *ops, xfs_failaddr_t fa);
22362306a36Sopenharmony_civoid xfs_buf_readahead_map(struct xfs_buftarg *target,
22462306a36Sopenharmony_ci			       struct xfs_buf_map *map, int nmaps,
22562306a36Sopenharmony_ci			       const struct xfs_buf_ops *ops);
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_cistatic inline int
22862306a36Sopenharmony_cixfs_buf_incore(
22962306a36Sopenharmony_ci	struct xfs_buftarg	*target,
23062306a36Sopenharmony_ci	xfs_daddr_t		blkno,
23162306a36Sopenharmony_ci	size_t			numblks,
23262306a36Sopenharmony_ci	xfs_buf_flags_t		flags,
23362306a36Sopenharmony_ci	struct xfs_buf		**bpp)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	return xfs_buf_get_map(target, &map, 1, XBF_INCORE | flags, bpp);
23862306a36Sopenharmony_ci}
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic inline int
24162306a36Sopenharmony_cixfs_buf_get(
24262306a36Sopenharmony_ci	struct xfs_buftarg	*target,
24362306a36Sopenharmony_ci	xfs_daddr_t		blkno,
24462306a36Sopenharmony_ci	size_t			numblks,
24562306a36Sopenharmony_ci	struct xfs_buf		**bpp)
24662306a36Sopenharmony_ci{
24762306a36Sopenharmony_ci	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	return xfs_buf_get_map(target, &map, 1, 0, bpp);
25062306a36Sopenharmony_ci}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_cistatic inline int
25362306a36Sopenharmony_cixfs_buf_read(
25462306a36Sopenharmony_ci	struct xfs_buftarg	*target,
25562306a36Sopenharmony_ci	xfs_daddr_t		blkno,
25662306a36Sopenharmony_ci	size_t			numblks,
25762306a36Sopenharmony_ci	xfs_buf_flags_t		flags,
25862306a36Sopenharmony_ci	struct xfs_buf		**bpp,
25962306a36Sopenharmony_ci	const struct xfs_buf_ops *ops)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	return xfs_buf_read_map(target, &map, 1, flags, bpp, ops,
26462306a36Sopenharmony_ci			__builtin_return_address(0));
26562306a36Sopenharmony_ci}
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_cistatic inline void
26862306a36Sopenharmony_cixfs_buf_readahead(
26962306a36Sopenharmony_ci	struct xfs_buftarg	*target,
27062306a36Sopenharmony_ci	xfs_daddr_t		blkno,
27162306a36Sopenharmony_ci	size_t			numblks,
27262306a36Sopenharmony_ci	const struct xfs_buf_ops *ops)
27362306a36Sopenharmony_ci{
27462306a36Sopenharmony_ci	DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
27562306a36Sopenharmony_ci	return xfs_buf_readahead_map(target, &map, 1, ops);
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ciint xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks,
27962306a36Sopenharmony_ci		xfs_buf_flags_t flags, struct xfs_buf **bpp);
28062306a36Sopenharmony_ciint xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr,
28162306a36Sopenharmony_ci		size_t numblks, xfs_buf_flags_t flags, struct xfs_buf **bpp,
28262306a36Sopenharmony_ci		const struct xfs_buf_ops *ops);
28362306a36Sopenharmony_ciint _xfs_buf_read(struct xfs_buf *bp, xfs_buf_flags_t flags);
28462306a36Sopenharmony_civoid xfs_buf_hold(struct xfs_buf *bp);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci/* Releasing Buffers */
28762306a36Sopenharmony_ciextern void xfs_buf_rele(struct xfs_buf *);
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/* Locking and Unlocking Buffers */
29062306a36Sopenharmony_ciextern int xfs_buf_trylock(struct xfs_buf *);
29162306a36Sopenharmony_ciextern void xfs_buf_lock(struct xfs_buf *);
29262306a36Sopenharmony_ciextern void xfs_buf_unlock(struct xfs_buf *);
29362306a36Sopenharmony_ci#define xfs_buf_islocked(bp) \
29462306a36Sopenharmony_ci	((bp)->b_sema.count <= 0)
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistatic inline void xfs_buf_relse(struct xfs_buf *bp)
29762306a36Sopenharmony_ci{
29862306a36Sopenharmony_ci	xfs_buf_unlock(bp);
29962306a36Sopenharmony_ci	xfs_buf_rele(bp);
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/* Buffer Read and Write Routines */
30362306a36Sopenharmony_ciextern int xfs_bwrite(struct xfs_buf *bp);
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ciextern void __xfs_buf_ioerror(struct xfs_buf *bp, int error,
30662306a36Sopenharmony_ci		xfs_failaddr_t failaddr);
30762306a36Sopenharmony_ci#define xfs_buf_ioerror(bp, err) __xfs_buf_ioerror((bp), (err), __this_address)
30862306a36Sopenharmony_ciextern void xfs_buf_ioerror_alert(struct xfs_buf *bp, xfs_failaddr_t fa);
30962306a36Sopenharmony_civoid xfs_buf_ioend_fail(struct xfs_buf *);
31062306a36Sopenharmony_civoid xfs_buf_zero(struct xfs_buf *bp, size_t boff, size_t bsize);
31162306a36Sopenharmony_civoid __xfs_buf_mark_corrupt(struct xfs_buf *bp, xfs_failaddr_t fa);
31262306a36Sopenharmony_ci#define xfs_buf_mark_corrupt(bp) __xfs_buf_mark_corrupt((bp), __this_address)
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci/* Buffer Utility Routines */
31562306a36Sopenharmony_ciextern void *xfs_buf_offset(struct xfs_buf *, size_t);
31662306a36Sopenharmony_ciextern void xfs_buf_stale(struct xfs_buf *bp);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci/* Delayed Write Buffer Routines */
31962306a36Sopenharmony_ciextern void xfs_buf_delwri_cancel(struct list_head *);
32062306a36Sopenharmony_ciextern bool xfs_buf_delwri_queue(struct xfs_buf *, struct list_head *);
32162306a36Sopenharmony_ciextern int xfs_buf_delwri_submit(struct list_head *);
32262306a36Sopenharmony_ciextern int xfs_buf_delwri_submit_nowait(struct list_head *);
32362306a36Sopenharmony_ciextern int xfs_buf_delwri_pushbuf(struct xfs_buf *, struct list_head *);
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_cistatic inline xfs_daddr_t xfs_buf_daddr(struct xfs_buf *bp)
32662306a36Sopenharmony_ci{
32762306a36Sopenharmony_ci	return bp->b_maps[0].bm_bn;
32862306a36Sopenharmony_ci}
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_civoid xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci/*
33362306a36Sopenharmony_ci * If the buffer is already on the LRU, do nothing. Otherwise set the buffer
33462306a36Sopenharmony_ci * up with a reference count of 0 so it will be tossed from the cache when
33562306a36Sopenharmony_ci * released.
33662306a36Sopenharmony_ci */
33762306a36Sopenharmony_cistatic inline void xfs_buf_oneshot(struct xfs_buf *bp)
33862306a36Sopenharmony_ci{
33962306a36Sopenharmony_ci	if (!list_empty(&bp->b_lru) || atomic_read(&bp->b_lru_ref) > 1)
34062306a36Sopenharmony_ci		return;
34162306a36Sopenharmony_ci	atomic_set(&bp->b_lru_ref, 0);
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_cistatic inline int xfs_buf_ispinned(struct xfs_buf *bp)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	return atomic_read(&bp->b_pin_count);
34762306a36Sopenharmony_ci}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_cistatic inline int
35062306a36Sopenharmony_cixfs_buf_verify_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
35162306a36Sopenharmony_ci{
35262306a36Sopenharmony_ci	return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
35362306a36Sopenharmony_ci				cksum_offset);
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic inline void
35762306a36Sopenharmony_cixfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
35862306a36Sopenharmony_ci{
35962306a36Sopenharmony_ci	xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
36062306a36Sopenharmony_ci			 cksum_offset);
36162306a36Sopenharmony_ci}
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci/*
36462306a36Sopenharmony_ci *	Handling of buftargs.
36562306a36Sopenharmony_ci */
36662306a36Sopenharmony_cistruct xfs_buftarg *xfs_alloc_buftarg(struct xfs_mount *mp,
36762306a36Sopenharmony_ci		struct block_device *bdev);
36862306a36Sopenharmony_ciextern void xfs_free_buftarg(struct xfs_buftarg *);
36962306a36Sopenharmony_ciextern void xfs_buftarg_wait(struct xfs_buftarg *);
37062306a36Sopenharmony_ciextern void xfs_buftarg_drain(struct xfs_buftarg *);
37162306a36Sopenharmony_ciextern int xfs_setsize_buftarg(struct xfs_buftarg *, unsigned int);
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci#define xfs_getsize_buftarg(buftarg)	block_size((buftarg)->bt_bdev)
37462306a36Sopenharmony_ci#define xfs_readonly_buftarg(buftarg)	bdev_read_only((buftarg)->bt_bdev)
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ciint xfs_buf_reverify(struct xfs_buf *bp, const struct xfs_buf_ops *ops);
37762306a36Sopenharmony_cibool xfs_verify_magic(struct xfs_buf *bp, __be32 dmagic);
37862306a36Sopenharmony_cibool xfs_verify_magic16(struct xfs_buf *bp, __be16 dmagic);
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci#endif	/* __XFS_BUF_H__ */
381