summary refs log tree commit diff
path: root/fs
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2019-07-12 15:57:52 +0200
committerAndreas Gruenbacher <agruenba@redhat.com>2019-08-09 17:00:50 +0100
commit72d36d0529c6d9ee8b950c819508b1e344d8cc4f (patch)
treeab590c9a5ab67fd8b5869f98fa822c1ec8c053ff /fs
parent34aad20bc3fff3ce4e3fa8cb1d0265a1df5cded5 (diff)
downloadlinux-72d36d0529c6d9ee8b950c819508b1e344d8cc4f.tar.gz
gfs2: Add support for IOMAP_ZERO
Add support for the IOMAP_ZERO iomap operation so that iomap_zero_range will
work as expected.  In the IOMAP_ZERO case, the caller of iomap_zero_range is
responsible for taking an exclusive glock on the inode, so we need no
additional locking in gfs2_iomap_begin.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/bmap.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 907b79483050..8431c14c3ee1 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1168,7 +1168,7 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
 	if (ret)
 		goto out_unlock;
 
-	switch(flags & IOMAP_WRITE) {
+	switch(flags & (IOMAP_WRITE | IOMAP_ZERO)) {
 	case IOMAP_WRITE:
 		if (flags & IOMAP_DIRECT) {
 			/*
@@ -1180,6 +1180,10 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
 			goto out_unlock;
 		}
 		break;
+	case IOMAP_ZERO:
+		if (iomap->type == IOMAP_HOLE)
+			goto out_unlock;
+		break;
 	default:
 		goto out_unlock;
 	}
@@ -1201,11 +1205,15 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_sbd *sdp = GFS2_SB(inode);
 
-	switch (flags & IOMAP_WRITE) {
+	switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
 	case IOMAP_WRITE:
 		if (flags & IOMAP_DIRECT)
 			return 0;
 		break;
+	case IOMAP_ZERO:
+		 if (iomap->type == IOMAP_HOLE)
+			 return 0;
+		 break;
 	default:
 		 return 0;
 	}