diff options
author | Dave Chinner <dchinner@redhat.com> | 2018-05-13 23:10:05 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-05-15 18:12:51 -0700 |
commit | 879de98ead5106ffd5486aa6c11a3fad141049d9 (patch) | |
tree | 9f1edecb6e305aacb9cef8b990c8cbb36bc72a37 /fs/xfs/xfs_buf.h | |
parent | 84d42ea6b6269aee7eb3d91a4425a08b8965fd4a (diff) | |
download | linux-stable-879de98ead5106ffd5486aa6c11a3fad141049d9.tar.gz linux-stable-879de98ead5106ffd5486aa6c11a3fad141049d9.tar.bz2 linux-stable-879de98ead5106ffd5486aa6c11a3fad141049d9.zip |
xfs: one-shot cached buffers
For the new growfs work, we want to ensure that we serialise
secondary superblock updates with other operations (e.g. scrub)
correctly, but we don't want to cache the buffers for long term
reuse. We need cached buffers for serialisation, however.
To solve this, introduce a "oneshot" buffer which will be marshalled
through the cache but then released once the last current reference
goes away. If the buffer is already cached, then we ignore the
"one-shot" behaviour and leave the buffer in the state it was prior
to the one-shot command being run. This means we don't perturb
either the working set or existing cached buffer state by a one-shot
operation.
Signed-Off-By: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_buf.h')
-rw-r--r-- | fs/xfs/xfs_buf.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 830e2f6c064a..f5f2b71c2fde 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -347,6 +347,18 @@ extern void xfs_buf_terminate(void); void xfs_buf_set_ref(struct xfs_buf *bp, int lru_ref); +/* + * If the buffer is already on the LRU, do nothing. Otherwise set the buffer + * up with a reference count of 0 so it will be tossed from the cache when + * released. + */ +static inline void xfs_buf_oneshot(struct xfs_buf *bp) +{ + if (!list_empty(&bp->b_lru) || atomic_read(&bp->b_lru_ref) > 1) + return; + atomic_set(&bp->b_lru_ref, 0); +} + static inline int xfs_buf_ispinned(struct xfs_buf *bp) { return atomic_read(&bp->b_pin_count); |