From: Zizhi Wo wozizhi@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
--------------------------------
This patch modifies some functions, adds barriers in fscache/cachefiles to both wake and wait processes that may be problematic due to out-of-order memory.
Fixes: ef778e7ae67c ("FS-Cache: Provide proper invalidation") Fixes: da9803bc8812 ("FS-Cache: Add interface to check consistency of a cached object") Fixes: 94d30ae90a00 ("FS-Cache: Provide the ability to enable/disable cookies") Fixes: b73608d715eb ("fscache: add a waiting mechanism when duplicate cookies are detected") Signed-off-by: Zizhi Wo wozizhi@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/cachefiles/namei.c | 4 +--- fs/fscache/cookie.c | 16 +++++++--------- fs/fscache/page.c | 8 ++++---- 3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 93c511d1fff3..6eeef666c609 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -264,11 +264,9 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
write_lock(&cache->active_lock); rb_erase(&object->active_node, &cache->active_nodes); - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); + clear_and_wake_up_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); write_unlock(&cache->active_lock);
- wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); - /* This object can now be culled, so we need to let the daemon know * that there is something it can remove if it needs to. */ diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index c2b1637eaa03..ea1beed4df11 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c @@ -223,14 +223,14 @@ static int fscache_wait_on_cookie_collision(struct fscache_cookie *candidate) { int ret;
- ret = wait_on_bit_timeout(&candidate->flags, FSCACHE_COOKIE_ACQUIRE_PENDING, - TASK_INTERRUPTIBLE, 20 * HZ); + ret = wait_on_bit_timeout_acquire(&candidate->flags, FSCACHE_COOKIE_ACQUIRE_PENDING, + TASK_INTERRUPTIBLE, 20 * HZ); if (ret == -EINTR) return ret; if (fscache_is_acquire_pending(candidate)) { pr_notice("Potential cookie collision!"); - return wait_on_bit(&candidate->flags, FSCACHE_COOKIE_ACQUIRE_PENDING, - TASK_INTERRUPTIBLE); + return wait_on_bit_acquire(&candidate->flags, FSCACHE_COOKIE_ACQUIRE_PENDING, + TASK_INTERRUPTIBLE); } return 0; } @@ -445,8 +445,7 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie, }
out_unlock: - clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); - wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK); + clear_and_wake_up_bit(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); } EXPORT_SYMBOL(__fscache_enable_cookie);
@@ -725,7 +724,7 @@ void __fscache_wait_on_invalidate(struct fscache_cookie *cookie) { _enter("%p", cookie);
- wait_on_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING, + wait_on_bit_acquire(&cookie->flags, FSCACHE_COOKIE_INVALIDATING, TASK_UNINTERRUPTIBLE);
_leave(""); @@ -842,8 +841,7 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, }
out_unlock_enable: - clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); - wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK); + clear_and_wake_up_bit(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags); _leave(""); } EXPORT_SYMBOL(__fscache_disable_cookie); diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 3ff3799e42ef..95490d809b5e 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -383,8 +383,8 @@ int fscache_wait_for_operation_activation(struct fscache_object *object, _debug(">>> WT"); if (stat_op_waits) fscache_stat(stat_op_waits); - if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING, - TASK_INTERRUPTIBLE) != 0) { + if (wait_on_bit_acquire(&op->flags, FSCACHE_OP_WAITING, + TASK_INTERRUPTIBLE) != 0) { trace_fscache_op(object->cookie, op, fscache_op_signal); ret = fscache_cancel_op(op, false); if (ret == 0) @@ -392,8 +392,8 @@ int fscache_wait_for_operation_activation(struct fscache_object *object,
/* it's been removed from the pending queue by another party, * so we should get to run shortly */ - wait_on_bit(&op->flags, FSCACHE_OP_WAITING, - TASK_UNINTERRUPTIBLE); + wait_on_bit_acquire(&op->flags, FSCACHE_OP_WAITING, + TASK_UNINTERRUPTIBLE); } _debug("<<< GO");