diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ubifs/tnc_commit.c | 26 |
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 */ |