[3/3] fs/fuse kio: retry allocation PCS_IREQ_FLUSH request

Submitted by Pavel Butsykin on Dec. 3, 2018, 1:02 p.m.

Details

Message ID 20181203130210.32011-4-pbutsykin@virtuozzo.com
State New
Series "Fuse KIO: fix fsync/flush loss"
Headers show

Commit Message

Pavel Butsykin Dec. 3, 2018, 1:02 p.m.
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.

Signed-off-by: Pavel Butsykin <pbutsykin@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);