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

Konstantin Khorenko khorenko at virtuozzo.com
Tue Nov 13 13:57:21 MSK 2018


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 at 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 at virtuozzo.com>
    Acked-by: Alexey Kuznetsov <kuznet at 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(-)

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_ */



More information about the Devel mailing list