[Devel] [PATCH RHEL7 COMMIT] fuse kio: Fix rpc socket leak on rpc_abort()
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Oct 16 18:09:44 MSK 2018
The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.9
------>
commit f76c48f2552666a564ab4ae72b6673040b14c7e4
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Tue Oct 16 18:09:43 2018 +0300
fuse kio: Fix rpc socket leak on rpc_abort()
There is no a place we have paired fput() for fget()
from process_pcs_csconn_reply(), and it looks like
it is leaked. Also, there is no a place, we free sio.
Fix that.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
=====================
Patchset description:
Order pcs_rpc and pcs_sockio destruction and close leaked socket
https://pmc.acronis.com/browse/VSTOR-15305
Ploop can asynchronously unmap regions by sending IOCB_CMD_UNMAP_ITER, but this
command isn't quite correctly interpreted in Fuse. Moreover, in Fast-path mode,
fallocate(FALLOC_FL_PUNCH_HOLE|FALLOC_FL_ZERO_RANGE) falls to fuse user daemon
and it can lead to data corruption.
Let's fix it.
Kirill Tkhai (9):
fuse kio: Use __maybe_unused
fuse kio: Use sio eof instead of parent to determ abort
fuse kio: Reorder callback assignment
fuse kio: Add pcs_cleanup_wq
fuse kio: Destroy rpc in work func
fuse kio: Introduce pcs_sk_kick_queue()
fuse kio: Dereference sk_user_data under rcu
fuse kio: Fix rpc socket leak on rpc_abort()
fuse kio: Hold pcs_rpc counter till sio may be freed
---
fs/fuse/kio/pcs/pcs_rpc.c | 2 ++
fs/fuse/kio/pcs/pcs_sock_io.c | 12 +++++++-----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c
index 9035b504121b..7571523fe271 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.c
+++ b/fs/fuse/kio/pcs/pcs_rpc.c
@@ -208,6 +208,8 @@ void rpc_abort(struct pcs_rpc * ep, int fatal, int error)
sio->eof = NULL;
pcs_sock_error(sio, error);
+ if (ioconn->destruct)
+ ioconn->destruct(ioconn);
}
if (ep->state == PCS_RPC_UNCONN) {
diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c
index bcf4bf6745a8..68829daaa00e 100644
--- a/fs/fuse/kio/pcs/pcs_sock_io.c
+++ b/fs/fuse/kio/pcs/pcs_sock_io.c
@@ -4,6 +4,7 @@
#include <linux/kthread.h>
#include <linux/types.h>
#include <linux/highmem.h>
+#include <linux/file.h>
#include "pcs_types.h"
#include "pcs_sock_io.h"
@@ -43,11 +44,8 @@ void sio_push(struct pcs_sockio * sio)
static void pcs_restore_sockets(struct pcs_ioconn *ioconn);
void pcs_ioconn_unregister(struct pcs_ioconn *ioconn)
{
- if (!test_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags)) {
+ if (!test_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags))
set_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags);
- pcs_restore_sockets(ioconn);
- }
-
}
void pcs_ioconn_close(struct pcs_ioconn *ioconn)
@@ -500,7 +498,11 @@ void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn)
BUG_ON(!list_empty(&sio->write_queue));
BUG_ON(sio->write_queue_len);
- pcs_ioconn_close(ioconn);
+ if (ioconn->socket) {
+ pcs_restore_sockets(ioconn);
+ fput(ioconn->socket->file);
+ ioconn->socket = NULL;
+ }
/* Wait pending socket callbacks, e.g., sk_data_ready() */
call_rcu(&sio->rcu, sio_destroy_rcu);
More information about the Devel
mailing list