aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-08-07 13:57:12 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-08-07 13:57:12 -0400
commit2ba090d521c5e09f32316c179d25bb6f699d3568 (patch)
tree1171512eca076f1e10fea00dcf8e07766486c1a4 /fs/xfs/libxfs
parenta0e336ba3e3d1c7ec0f738a2e2e203434c00b08e (diff)
xfs: use WRITE_ONCE to update if_seq
This adds ordering of the updates and makes sure we always see the if_seq update before the extent tree is modified. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/libxfs')
-rw-r--r--fs/xfs/libxfs/xfs_iext_tree.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c
index 8a7aea041ee1..771dd072015d 100644
--- a/fs/xfs/libxfs/xfs_iext_tree.c
+++ b/fs/xfs/libxfs/xfs_iext_tree.c
@@ -14,6 +14,7 @@
14#include "xfs_inode_fork.h" 14#include "xfs_inode_fork.h"
15#include "xfs_trans_resv.h" 15#include "xfs_trans_resv.h"
16#include "xfs_mount.h" 16#include "xfs_mount.h"
17#include "xfs_bmap.h"
17#include "xfs_trace.h" 18#include "xfs_trace.h"
18 19
19/* 20/*
@@ -612,6 +613,19 @@ xfs_iext_realloc_root(
612 cur->leaf = new; 613 cur->leaf = new;
613} 614}
614 615
616/*
617 * Increment the sequence counter if we are on a COW fork. This allows
618 * the writeback code to skip looking for a COW extent if the COW fork
619 * hasn't changed. We use WRITE_ONCE here to ensure the update to the
620 * sequence counter is seen before the modifications to the extent
621 * tree itself take effect.
622 */
623static inline void xfs_iext_inc_seq(struct xfs_ifork *ifp, int state)
624{
625 if (state & BMAP_COWFORK)
626 WRITE_ONCE(ifp->if_seq, READ_ONCE(ifp->if_seq) + 1);
627}
628
615void 629void
616xfs_iext_insert( 630xfs_iext_insert(
617 struct xfs_inode *ip, 631 struct xfs_inode *ip,
@@ -624,7 +638,7 @@ xfs_iext_insert(
624 struct xfs_iext_leaf *new = NULL; 638 struct xfs_iext_leaf *new = NULL;
625 int nr_entries, i; 639 int nr_entries, i;
626 640
627 ifp->if_seq++; 641 xfs_iext_inc_seq(ifp, state);
628 642
629 if (ifp->if_height == 0) 643 if (ifp->if_height == 0)
630 xfs_iext_alloc_root(ifp, cur); 644 xfs_iext_alloc_root(ifp, cur);
@@ -866,7 +880,7 @@ xfs_iext_remove(
866 ASSERT(ifp->if_u1.if_root != NULL); 880 ASSERT(ifp->if_u1.if_root != NULL);
867 ASSERT(xfs_iext_valid(ifp, cur)); 881 ASSERT(xfs_iext_valid(ifp, cur));
868 882
869 ifp->if_seq++; 883 xfs_iext_inc_seq(ifp, state);
870 884
871 nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1; 885 nr_entries = xfs_iext_leaf_nr_entries(ifp, leaf, cur->pos) - 1;
872 for (i = cur->pos; i < nr_entries; i++) 886 for (i = cur->pos; i < nr_entries; i++)
@@ -974,7 +988,7 @@ xfs_iext_update_extent(
974{ 988{
975 struct xfs_ifork *ifp = xfs_iext_state_to_fork(ip, state); 989 struct xfs_ifork *ifp = xfs_iext_state_to_fork(ip, state);
976 990
977 ifp->if_seq++; 991 xfs_iext_inc_seq(ifp, state);
978 992
979 if (cur->pos == 0) { 993 if (cur->pos == 0) {
980 struct xfs_bmbt_irec old; 994 struct xfs_bmbt_irec old;