Discussion:
[Devel] [PATCH RHEL7 COMMIT] fs/fuse kio_pcs: fix map leaks in process_ireq_truncate()
Konstantin Khorenko
2018-10-31 13:02:52 UTC
Permalink
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 <***@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 <***@virtuozzo.com>
Reviewed-by: Kirill Tkhai <***@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(-)

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;
}

Loading...