[RHEL7,COMMIT] fs/fuse kio: retry allocation PCS_IREQ_FLUSH request

Submitted by Konstantin Khorenko on Dec. 4, 2018, 1:17 p.m.

Details

Message ID 201812041317.wB4DHA46002751@finist-ce7.sw.ru
State New
Series "Fuse KIO: fix fsync/flush loss"
Headers show

Commit Message

Konstantin Khorenko Dec. 4, 2018, 1:17 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.20.2.vz7.73.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.20.2.vz7.73.17
------>
commit 7910b45be0d03ba8e3b48238bded18704c64732d
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Tue Dec 4 16:17:09 2018 +0300

    fs/fuse kio: retry allocation PCS_IREQ_FLUSH request
    
    If cslist has changed during request allocation, that is no reason not to run
    PCS_IREQ_FLUSH. In the case when cslist has changed let's re-allocate the
    request with new cslist and try it again to fix possible loss of fsync/flush
    request.
    
    https://pmc.acronis.com/browse/VSTOR-18475
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_map.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 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 1e700dff2043..817c7d6a9379 100644
--- a/fs/fuse/kio/pcs/pcs_map.c
+++ b/fs/fuse/kio/pcs/pcs_map.c
@@ -2983,6 +2983,7 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m,
 	struct pcs_int_request *sreq;
 	struct pcs_msg * msg;
 
+retry:
 	spin_lock(&m->lock);
 	if (!valid_for_flush(m, timer_sync)) {
 		spin_unlock(&m->lock);
@@ -2998,7 +2999,6 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m,
 
 	cslist = m->cs_list;
 	cslist_get(cslist);
-	/* TODO: Need to grab reference to de? */
 	de = pcs_dentry_from_map(m);
 	spin_unlock(&m->lock);
 
@@ -3014,7 +3014,13 @@  static int prepare_map_flush_ireq(struct pcs_map_entry *m,
 	/* All resources allocated, we need to recheck maps state again */
 	spin_lock(&m->lock);
 	cslist_put(cslist);
-	if (!valid_for_flush(m, timer_sync) || m->cs_list != cslist) {
+	if (unlikely(m->cs_list != cslist)) {
+		spin_unlock(&m->lock);
+		pcs_free_msg(msg);
+		ireq_destroy(sreq);
+		goto retry;
+	}
+	if (!valid_for_flush(m, timer_sync)) {
 		spin_unlock(&m->lock);
 		pcs_free_msg(msg);
 		ireq_destroy(sreq);