[RHEL7,COMMIT] fs/fuse kio_pcs: fix map leaks in process_ireq_truncate()

Submitted by Konstantin Khorenko on Oct. 31, 2018, 1:02 p.m.

Details

Message ID 201810311302.w9VD2odo023457@finist-ce7.sw.ru
State New
Series "fs/fuse kio_pcs: fix map leaks in process_ireq_truncate()"
Headers show

Commit Message

Konstantin Khorenko Oct. 31, 2018, 1:02 p.m.
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.15
------>
commit 46b140d8e702cc39f22c9d9c180c2f556809fe89
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Wed Oct 31 16:02:50 2018 +0300

    fs/fuse kio_pcs: fix map leaks in process_ireq_truncate()
    
    In addition to finding maps, pcs_find_get_map() increases reference
    to map which returns. So after using the map we need to call pcs_map_put() at the end.
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    =====================
    Patchset description:
    
    FUSE KIO: Mapping truncate fixes
    
    https://jira.sw.ru/browse/PSBM-89539
---
 fs/fuse/kio/pcs/pcs_map.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c
index c4628b0a65a5..8579b5eb8bc9 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -2405,45 +2405,34 @@  void process_ireq_truncate(struct pcs_int_request *ireq)
 		return;
 	}
 	end = map_chunk_end(m);
-	if (end <= ireq->truncreq.offset) {
-		map_truncate_tail(&di->mapping, end);
-		ireq_complete(ireq);
-		return;
-	}
+	if (end <= ireq->truncreq.offset)
+		goto truncate_tail;
 
 	if (ireq->truncreq.phase == 0) {
-		if (valid_for_truncate(m, ireq)) {
-			map_truncate_tail(&di->mapping, end);
-			ireq_complete(ireq);
-			return;
-		}
+		if (valid_for_truncate(m, ireq))
+			goto truncate_tail;
 	} else {
 		/* We already had some valid map. Must get new one. */
-
-
 		spin_lock(&m->lock);
 		if ((m->state & (PCS_MAP_ERROR|PCS_MAP_RESOLVING|PCS_MAP_NEW|PCS_MAP_READABLE)) ==
 		    (PCS_MAP_NEW|PCS_MAP_READABLE)) {
 
 			spin_unlock(&m->lock);
 			FUSE_KLOG(cc_from_maps(m->maps)->fc, LOG_INFO, "map " MAP_FMT " unexpectedly converted to hole", MAP_ARGS(m));
-			map_truncate_tail(&di->mapping, end);
-			ireq_complete(ireq);
-			return;
+			goto truncate_tail;
 		}
 
 		if (m->state & PCS_MAP_RESOLVING) {
 			list_add_tail(&ireq->list, &m->queue);
 			spin_unlock(&m->lock);
+			pcs_map_put(m);
 			return;
 		}
 
 		if (!(m->state & (PCS_MAP_ERROR|PCS_MAP_NEW))) {
 			if (map_version_compare(&m->version, &ireq->truncreq.version) > 0) {
 				spin_unlock(&m->lock);
-				map_truncate_tail(&di->mapping, end);
-				ireq_complete(ireq);
-				return;
+				goto truncate_tail;
 			}
 
 			FUSE_KTRACE(ireq->cc->fc, "map " MAP_FMT " is not updated yet", MAP_ARGS(m));
@@ -2453,6 +2442,14 @@  void process_ireq_truncate(struct pcs_int_request *ireq)
 		spin_unlock(&m->lock);
 	}
 	pcs_map_queue_resolve(m, ireq, 1);
+	pcs_map_put(m);
+	return;
+
+truncate_tail:
+       map_truncate_tail(&di->mapping, end);
+       ireq_complete(ireq);
+       pcs_map_put(m);
+       return;
 }