From 6c1b92df814622cfca793657e0060335b39bd61e Mon Sep 17 00:00:00 2001 From: Andrew Stone Date: Thu, 25 Feb 2021 04:13:30 -0800 Subject: Fix deadlock in conn cleanup (#244) Calling through to request_free() from clean_req() causes deadlock since sshfs.lock is already held by the caller of clean_req(). --- sshfs.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/sshfs.c b/sshfs.c index 0a40950..32130e1 100644 --- a/sshfs.c +++ b/sshfs.c @@ -1401,9 +1401,11 @@ static int sftp_read(struct conn *conn, uint8_t *type, struct buffer *buf) static void request_free(struct request *req) { - pthread_mutex_lock(&sshfs.lock); + if (req->end_func) + req->end_func(req); + req->conn->req_count--; - pthread_mutex_unlock(&sshfs.lock); + buf_free(&req->reply); sem_destroy(&req->ready); g_free(req); @@ -1449,11 +1451,9 @@ static int clean_req(void *key, struct request *req, gpointer user_data) req->error = -EIO; if (req->want_reply) sem_post(&req->ready); - else { - if (req->end_func) - req->end_func(req); + else request_free(req); - } + return TRUE; } @@ -1515,12 +1515,9 @@ static int process_one_request(struct conn *conn) if (req->want_reply) sem_post(&req->ready); else { - if (req->end_func) { - pthread_mutex_lock(&sshfs.lock); - req->end_func(req); - pthread_mutex_unlock(&sshfs.lock); - } + pthread_mutex_lock(&sshfs.lock); request_free(req); + pthread_mutex_unlock(&sshfs.lock); } } else buf_free(&buf); @@ -1970,12 +1967,9 @@ static int sftp_request_wait(struct request *req, uint8_t type, } out: - if (req->end_func) { - pthread_mutex_lock(&sshfs.lock); - req->end_func(req); - pthread_mutex_unlock(&sshfs.lock); - } + pthread_mutex_lock(&sshfs.lock); request_free(req); + pthread_mutex_unlock(&sshfs.lock); return err; } -- cgit v1.2.3