Commit ca1b3ab2 authored by Baokun Li's avatar Baokun Li
Browse files

fscache: fix assertion failure in cachefiles_put_object()

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: default avatarBaokun Li <libaokun1@huawei.com>
parent bfe51376
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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)) {
	if (list_empty(&object->dep_link))
		goto out;

	spin_lock(&object->parent->lock);
	if (!list_empty(&object->dep_link)) {
		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("");
}