aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/tnc_commit.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index f50c3e5da263..d6fab1a9986c 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -89,6 +89,10 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
89 ubifs_assert(ubifs_zn_dirty(znode)); 89 ubifs_assert(ubifs_zn_dirty(znode));
90 ubifs_assert(ubifs_zn_cow(znode)); 90 ubifs_assert(ubifs_zn_cow(znode));
91 91
92 /*
93 * Note, unlike 'write_index()' we do not add memory barriers here
94 * because this function is called with @c->tnc_mutex locked.
95 */
92 __clear_bit(DIRTY_ZNODE, &znode->flags); 96 __clear_bit(DIRTY_ZNODE, &znode->flags);
93 __clear_bit(COW_ZNODE, &znode->flags); 97 __clear_bit(COW_ZNODE, &znode->flags);
94 98
@@ -903,6 +907,28 @@ static int write_index(struct ubifs_info *c)
903 clear_bit(COW_ZNODE, &znode->flags); 907 clear_bit(COW_ZNODE, &znode->flags);
904 smp_mb__after_clear_bit(); 908 smp_mb__after_clear_bit();
905 909
910 /*
911 * We have marked the znode as clean but have not updated the
912 * @c->clean_zn_cnt counter. If this znode becomes dirty again
913 * before 'free_obsolete_znodes()' is called, then
914 * @c->clean_zn_cnt will be decremented before it gets
915 * incremented (resulting in 2 decrements for the same znode).
916 * This means that @c->clean_zn_cnt may become negative for a
917 * while.
918 *
919 * Q: why we cannot increment @c->clean_zn_cnt?
920 * A: because we do not have the @c->tnc_mutex locked, and the
921 * following code would be racy and buggy:
922 *
923 * if (!ubifs_zn_obsolete(znode)) {
924 * atomic_long_inc(&c->clean_zn_cnt);
925 * atomic_long_inc(&ubifs_clean_zn_cnt);
926 * }
927 *
928 * Thus, we just delay the @c->clean_zn_cnt update until we
929 * have the mutex locked.
930 */
931
906 /* Do not access znode from this point on */ 932 /* Do not access znode from this point on */
907 933
908 /* Update buffer positions */ 934 /* Update buffer positions */