hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
--------------------------------
A reference count for dep_link is put twice when there is a contention as follows, which causes an assertion failure in cachefiles_put_object().
t1 | t2 --------------------------------- fscache_dequeue_object if (!list_empty(&object->dep_link)) fscache_enqueue_dependents spin_lock(&object->lock); list_del_init(&dep->dep_link); fscache_put_object(dep, fscache_obj_put_enq_dep); spin_unlock(&object->lock); spin_lock(&object->parent->lock); list_del_init(&object->dep_link); fscache_put_object(object, fscache_obj_put_dequeue); spin_unlock(&object->parent->lock);
fscache_put_object cachefiles_put_object ASSERTCMP(u, !=, -1) // Assertion Failure!
Avoid this problem by again checking whether object->dep_link is empty under lock protection.
Fixes: bfba3a3ac037 ("[Huawei] fscache: fix reference count leakage during abort init") Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/fscache/object.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 297b90eca985..11170f079d33 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -902,13 +902,16 @@ static void fscache_dequeue_object(struct fscache_object *object) { _enter("{OBJ%x}", object->debug_id);
+ if (list_empty(&object->dep_link)) + goto out; + + spin_lock(&object->parent->lock); if (!list_empty(&object->dep_link)) { - spin_lock(&object->parent->lock); list_del_init(&object->dep_link); fscache_put_object(object, fscache_obj_put_dequeue); - spin_unlock(&object->parent->lock); } - + spin_unlock(&object->parent->lock); +out: _leave(""); }