[Devel] [PATCH RHEL7 COMMIT] fuse kio: Handle fuse_map_resolve() failure in pcs_map_queue_resolve()

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jun 8 19:08:29 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-693.21.1.vz7.50.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.21.1.vz7.50.7
------>
commit ac54fb5aaae87e781843b73843028db662f2965c
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Fri Jun 8 19:08:29 2018 +0300

    fuse kio: Handle fuse_map_resolve() failure in pcs_map_queue_resolve()
    
    fuse_map_resolve() may fail, and the requests attached to the map
    must be completed. Otherwise, writers waiting for inode::i_dio_count
    will never end.
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_map.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_map.c b/fs/fuse/kio/pcs/pcs_map.c
index 0229aa37bccc..f48d8e30a61e 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -1162,16 +1162,15 @@ void pcs_map_complete(struct pcs_map_entry *m, struct pcs_ioc_getmap *omap)
 /* Atomically schedule map resolve and push ireq to wait completion */
 static void pcs_map_queue_resolve(struct pcs_map_entry * m, struct pcs_int_request *ireq, int direction)
 {
+	LIST_HEAD(l);
+	int ret;
 
 	DTRACE("enter m: " MAP_FMT ", ireq:%p dir:%d \n", MAP_ARGS(m), ireq,   direction);
 
 	spin_lock(&m->lock);
 	/* This should not happen unless aio_dio/fsync vs truncate race */
 	if (m->state & PCS_MAP_DEAD) {
-		struct list_head l;
-
 		spin_unlock(&m->lock);
-		INIT_LIST_HEAD(&l);
 		list_add(&ireq->list, &l);
 		pcs_ireq_queue_fail(&l, PCS_ERR_NET_ABORT);
 		return;
@@ -1195,7 +1194,16 @@ static void pcs_map_queue_resolve(struct pcs_map_entry * m, struct pcs_int_reque
 	spin_unlock(&m->lock);
 	/// TODO: THINK!!!!
 	/// May be it is reasonable to schedule fuse_map_resolve from work_queue?
-	fuse_map_resolve(m, direction);
+	ret = fuse_map_resolve(m, direction);
+	if (ret) {
+		TRACE("map error: %d for " MAP_FMT "\n", ret, MAP_ARGS(m));
+		spin_lock(&m->lock);
+		pcs_map_truncate(m, &l);
+		map_del_lru(m);
+		spin_unlock(&m->lock);
+		pcs_ireq_queue_fail(&l, PCS_ERR_NOMEM);
+		pcs_map_put(m);
+	}
 }
 
 /* If version on m is not already advanced, we must notify MDS about the error.


More information about the Devel mailing list