From: Jeffle Xu jefflexu@linux.alibaba.com
anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
Reference: https://gitee.com/anolis/cloud-kernel/commit/a2ad84f77271
--------------------------------
ANBZ: #1666
object->fscache.parent->n_children will be decreased and then object->fscache.parent will be set to NULL in fscache_relinquish_cookie(). Thus it is reasonable that object->fscache.parent->n_children shall not be zero when object->fscache.parent is non-NULL.
While in on-demand mode, each anon_fd also holds one reference to the corresponding object. The anon_fd can be closed asynchronously with fscache_relinquish_cookie(), in which case the following race can be triggered.
user daemon erofs umount cookie state machine worker =========== ============ ============== close(anon_fd) umount fscache_relinquish_cookie cachefiles_ondemand_fd_release cachefiles_put_object fscache_drop_object # check object->fscache.parent # decrease object->parent->n_children # object->parent = NULL # check object->fscache.parent->n_children
To fix this, simply skip the ASSERT in cachefiles_put_object() in on-demand mode.
Signed-off-by: Jeffle Xu jefflexu@linux.alibaba.com Signed-off-by: Huang Jianan jnhuang@linux.alibaba.com Reviewed-by: Gao Xiang hsiangkao@linux.alibaba.com Reviewed-by: Jeffle Xu jefflexu@linux.alibaba.com Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/cachefiles/interface.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 99f50bc59b3c..80a241638452 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -339,8 +339,11 @@ static void cachefiles_put_object(struct fscache_object *_object, ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); #endif
- ASSERTIFCMP(object->fscache.parent, - object->fscache.parent->n_children, >, 0); + if (!cachefiles_in_ondemand_mode(container_of(object->fscache.cache, + struct cachefiles_cache, cache))) { + ASSERTIFCMP(object->fscache.parent, + object->fscache.parent->n_children, >, 0); + }
u = atomic_dec_return(&object->usage); trace_cachefiles_ref(object, _object->cookie,