hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT
--------------------------------
Replacing wait_for_completion() with wait_for_completion_killable() in cachefiles_ondemand_send_req() allows us to kill processes that might trigger a hunk_task if the daemon is abnormal.
But now only CACHEFILES_OP_READ is killable, because OP_CLOSE and OP_OPEN is initiated from kworker context and the signal is prohibited in these kworker.
Note that when the req in xas changes, i.e. xas_load(&xas) != req, it means that a process will complete the current request soon, so wait again for the request to be completed.
Suggested-by: Hou Tao houtao1@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/cachefiles/ondemand.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 2cbe8a1b953f..4fb5cdfde51c 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -517,8 +517,24 @@ static int cachefiles_ondemand_send_req(struct cachefiles_object *object, xa_unlock(&cache->reqs);
wake_up_all(&cache->daemon_pollwq); - wait_for_completion(&req->done); - ret = req->error; +wait: + ret = wait_for_completion_killable(&req->done); + if (!ret) { + ret = req->error; + } else { + xa_lock(&cache->reqs); + if (radix_tree_lookup(&cache->reqs, id) == req) { + radix_tree_delete(&cache->reqs, id); + ret = -EINTR; + } + xa_unlock(&cache->reqs); + + /* Someone will complete it soon. */ + if (ret != -EINTR) { + cpu_relax(); + goto wait; + } + } cachefiles_req_put(req); return ret; out: