[RHEL7,COMMIT] fs/fuse kio_pcs: invalidation maps in setattr kio

Submitted by Konstantin Khorenko on Nov. 13, 2018, 10:57 a.m.

Details

Message ID 201811131057.wADAvIia018449@finist-ce7.sw.ru
State New
Series "fs/fuse kio_pcs: invalidation maps in setattr kio"
Headers show

Commit Message

Konstantin Khorenko Nov. 13, 2018, 10:57 a.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.3
------>
commit f4bd502c809b24d28a88dccbde92475684219b1d
Author: Pavel Butsykin <pbutsykin@virtuozzo.com>
Date:   Tue Nov 13 13:57:17 2018 +0300

    fs/fuse kio_pcs: invalidation maps in setattr kio
    
    Currently shrink doesn't work correctly, it's not enough just to drop unused
    maps in shrink operation, moreover it's even wrong to drop the last one map.
    Since the proper truncate is made in user-client, all we need to do in the
    kernel is to drop no longer used maps and set STALE_MAP error to the last map,
    what exactly makes kernel pcs_mapping_truncate().
    
    This patch removes pcs_map_invalidate_tail() at shrink and instead adds
    pcs_mapping_truncate() in kpcs_setattr_end(), that will allow us to keep
    maps in sync in any setattr's.
    
    https://pmc.acronis.com/browse/VSTOR-16863
    
    Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet@virtuozzo.com>
---
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c | 13 ++++++-------
 fs/fuse/kio/pcs/pcs_map.h          |  7 -------
 2 files changed, 6 insertions(+), 14 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 1e493a8b3d39..d1d3f7f4a256 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -763,7 +763,6 @@  static void fuse_size_grow_work(struct work_struct *w)
 		di->size.required = 0;
 	spin_unlock(&di->lock);
 
-	pcs_mapping_truncate(di, old_size);
 	pcs_cc_requeue(di->cluster, &pending_reqs);
 }
 
@@ -988,6 +987,7 @@  static void kpcs_setattr_end(struct fuse_conn *fc, struct fuse_req *req)
 	struct fuse_setattr_in *inarg = (void*) req->in.args[0].value;
 	struct fuse_attr_out *outarg = (void*) req->out.args[0].value;
 	struct pcs_dentry_info *di = pcs_inode_from_fuse(fi);
+	u64 old_size;
 
 	BUG_ON(req->in.h.opcode != FUSE_SETATTR);
 	TRACE("update size: ino:%lu old_sz:%lld new:%lld\n",
@@ -997,10 +997,13 @@  static void kpcs_setattr_end(struct fuse_conn *fc, struct fuse_req *req)
 		goto fail;
 
 	spin_lock(&di->lock);
+	old_size = di->fileinfo.attr.size;
 	di->fileinfo.attr.size = outarg->attr.size;
 	spin_unlock(&di->lock);
 
-	if (outarg->attr.size != inarg->size) {
+	if (outarg->attr.size == inarg->size)
+		pcs_mapping_truncate(di, old_size);
+	else {
 		pr_err("kio: failed to set requested size: %llu %llu\n",
 			outarg->attr.size, inarg->size);
 		req->out.h.error = -EIO;
@@ -1066,11 +1069,7 @@  static void pcs_kio_setattr_handle(struct fuse_inode *fi, struct fuse_req *req)
 		BUG_ON(!mutex_is_locked(&req->io_inode->i_mutex));
 		/* wait for aio reads in flight */
 		inode_dio_wait(req->io_inode);
-		/*
-		 * Writebackcache was flushed already so it is safe to
-		 * drop pcs_mapping
-		 */
-		pcs_map_invalidate_tail(&di->mapping, inarg->size);
+
 		req->end = _pcs_shrink_end;
 	} else
 		req->end = _pcs_grow_end;
diff --git a/fs/fuse/kio/pcs/pcs_map.h b/fs/fuse/kio/pcs/pcs_map.h
index 14ae78af8e27..93cc04199845 100644
--- a/fs/fuse/kio/pcs/pcs_map.h
+++ b/fs/fuse/kio/pcs/pcs_map.h
@@ -263,11 +263,4 @@  static inline struct pcs_map_entry *pcs_map_get(struct pcs_map_entry *m)
 
 	return m;
 }
-
-static inline void pcs_map_invalidate_tail(struct pcs_mapping * mapping, u64 offset)
-{
-	unsigned long index = offset >> mapping->chunk_size_bits;
-
-	map_truncate_tail(mapping, index << mapping->chunk_size_bits);
-}
 #endif /* _PCS_MAP_H_ */