This is version 2 of the hole punching series I posted last week. The following things have changed -Hole punching doesn't change file size -Fixed the mode checks in ext4/btrfs/gfs2 so they do what they are supposed to I posted updates to xfstests and xfsprogs in order to test this new interface, and ran the test on xfs to make sure hole punching worked properly for xfs and I tested it on btrfs to make sure it failed properly. This series also adds support for doing hole punching to ocfs2, but I did not test this part of it, albiet it's an obvious fix so it should work fine. Thanks, Josef
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 2/6] XFS: handle hole punching via fallocate properly
This patch simply allows XFS to handle the hole punching flag in fallocate properly. I've tested this with a little program that does a bunch of random hole punching with FL_KEEP_SIZE and without it to make sure it does the right thing. Thanks, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/xfs/linux-2.6/xfs_iops.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 96107ef..63cc929 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -516,6 +516,7 @@ xfs_vn_fallocate( loff_t new_size = 0; xfs_flock64_t bf; xfs_inode_t *ip = XFS_I(inode); + int cmd = XFS_IOC_RESVSP; /* preallocation on directories not yet supported */ error = -ENODEV; @@ -528,8 +529,11 @@ xfs_vn_fallocate( xfs_ilock(ip, XFS_IOLOCK_EXCL); + if (mode & FALLOC_FL_PUNCH_HOLE) + cmd = XFS_IOC_UNRESVSP; + /* check the new inode size is valid before allocating */ - if (!(mode & FALLOC_FL_KEEP_SIZE) && + if (!(mode & (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) && offset + len > i_size_read(inode)) { new_size = offset + len; error = inode_newsize_ok(inode, new_size); @@ -537,8 +541,7 @@ xfs_vn_fallocate( goto out_unlock; } - error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, - 0, XFS_ATTR_NOLOCK); + error = -xfs_change_file_space(ip, cmd, &bf, 0, XFS_ATTR_NOLOCK); if (error) goto out_unlock; -- 1.6.6.1
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 3/6] Ocfs2: handle hole punching via fallocate properly
This patch just makes ocfs2 use its UNRESERVP ioctl when we get the hole punch flag in fallocate. I didn't test it, but it seems simple enough. Thanks, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/ocfs2/file.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 77b4c04..181ae52 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1992,6 +1992,7 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct ocfs2_space_resv sr; int change_size = 1; + int cmd = OCFS2_IOC_RESVSP64; if (!ocfs2_writes_unwritten_extents(osb)) return -EOPNOTSUPP; @@ -2002,12 +2003,17 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, if (mode & FALLOC_FL_KEEP_SIZE) change_size = 0; + if (mode & FALLOC_FL_PUNCH_HOLE) { + cmd = OCFS2_IOC_UNRESVSP64; + change_size = 0; + } + sr.l_whence = 0; sr.l_start = (s64)offset; sr.l_len = (s64)len; - return __ocfs2_change_file_space(NULL, inode, offset, - OCFS2_IOC_RESVSP64, &sr, change_size); + return __ocfs2_change_file_space(NULL, inode, offset, cmd, &sr, + change_size); } int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, -- 1.6.6.1
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 1/6] fs: add hole punching to fallocate
Hole punching has already been implemented by XFS and OCFS2, and has the potential to be implemented on both BTRFS and EXT4 so we need a generic way to get to this feature. The simplest way in my mind is to add FALLOC_FL_PUNCH_HOLE to fallocate() since it already looks like the normal fallocate() operation. I've tested this patch with XFS and BTRFS to make sure XFS did what it's supposed to do and that BTRFS failed like it was supposed to. Thank you, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/open.c | 2 +- include/linux/falloc.h | 1 + 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/fs/open.c b/fs/open.c index 4197b9e..ab8dedf 100644 --- a/fs/open.c +++ b/fs/open.c @@ -223,7 +223,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) return -EINVAL; /* Return error if mode is not supported */ - if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) + if (mode && (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))) return -EOPNOTSUPP; if (!(file->f_mode & FMODE_WRITE)) diff --git a/include/linux/falloc.h b/include/linux/falloc.h index 3c15510..851cba2 100644 --- a/include/linux/falloc.h +++ b/include/linux/falloc.h @@ -2,6 +2,7 @@ #define _FALLOC_H_ #define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */ +#define FALLOC_FL_PUNCH_HOLE 0X02 /* de-allocates range */ #ifdef __KERNEL__ -- 1.6.6.1
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 4/6] Ext4: fail if we try to use hole punch
Ext4 doesn't have the ability to punch holes yet, so make sure we return EOPNOTSUPP if we try to use hole punching through fallocate. This support can be added later. Thanks, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/ext4/extents.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0554c48..35bca73 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3622,6 +3622,10 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) struct ext4_map_blocks map; unsigned int credits, blkbits = inode->i_blkbits; + /* We only support the FALLOC_FL_KEEP_SIZE mode */ + if (mode && (mode != FALLOC_FL_KEEP_SIZE)) + return -EOPNOTSUPP; + /* * currently supporting (pre)allocate mode for extent-based * files _only_ -- 1.6.6.1
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 6/6] Gfs2: fail if we try to use hole punch
Gfs2 doesn't have the ability to punch holes yet, so make sure we return EOPNOTSUPP if we try to use hole punching through fallocate. This support can be added later. Thanks, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/gfs2/ops_inode.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 12cbea7..65cb5f6 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c @@ -1439,6 +1439,10 @@ static long gfs2_fallocate(struct inode *inode, int mode, loff_t offset, loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; next = (next + 1) << sdp->sd_sb.sb_bsize_shift; + /* We only support the FALLOC_FL_KEEP_SIZE mode */ + if (mode && (mode != FALLOC_FL_KEEP_SIZE)) + return -EOPNOTSUPP; + offset = (offset >> sdp->sd_sb.sb_bsize_shift) << sdp->sd_sb.sb_bsize_shift; -- 1.6.6.1
Josef Bacik
2010-Nov-15 17:14 UTC
[Ocfs2-devel] [PATCH 5/6] Btrfs: fail if we try to use hole punch
Btrfs doesn't have the ability to punch holes yet, so make sure we return EOPNOTSUPP if we try to use hole punching through fallocate. This support can be added later. Thanks, Signed-off-by: Josef Bacik <josef at redhat.com> --- fs/btrfs/inode.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 78877d7..6f08892 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6936,6 +6936,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, alloc_start = offset & ~mask; alloc_end = (offset + len + mask) & ~mask; + /* We only support the FALLOC_FL_KEEP_SIZE mode */ + if (mode && (mode != FALLOC_FL_KEEP_SIZE)) + return -EOPNOTSUPP; + /* * wait for ordered IO before we have any locks. We'll loop again * below with the locks held. -- 1.6.6.1
Jan Kara
2010-Nov-16 11:16 UTC
[Ocfs2-devel] [PATCH 1/6] fs: add hole punching to fallocate
On Mon 15-11-10 12:05:18, Josef Bacik wrote:> diff --git a/fs/open.c b/fs/open.c > index 4197b9e..ab8dedf 100644 > --- a/fs/open.c > +++ b/fs/open.c > @@ -223,7 +223,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) > return -EINVAL; > > /* Return error if mode is not supported */ > - if (mode && !(mode & FALLOC_FL_KEEP_SIZE)) > + if (mode && (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)))Why not just: if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) ?> diff --git a/include/linux/falloc.h b/include/linux/falloc.h > index 3c15510..851cba2 100644 > --- a/include/linux/falloc.h > +++ b/include/linux/falloc.h > @@ -2,6 +2,7 @@ > #define _FALLOC_H_ > > #define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */ > +#define FALLOC_FL_PUNCH_HOLE 0X02 /* de-allocates range */^ use lowercase 'x' please... Honza -- Jan Kara <jack at suse.cz> SUSE Labs, CR
Jan Kara
2010-Nov-16 11:50 UTC
[Ocfs2-devel] [PATCH 3/6] Ocfs2: handle hole punching via fallocate properly
On Mon 15-11-10 12:05:20, Josef Bacik wrote:> This patch just makes ocfs2 use its UNRESERVP ioctl when we get the hole punch > flag in fallocate. I didn't test it, but it seems simple enough. Thanks, > > Signed-off-by: Josef Bacik <josef at redhat.com>You might want to directly CC Joel Becker <Joel.Becker at oracle.com> who maintains OCFS2. Otherwise the patch looks OK so you can add Acked-by: Jan Kara <jack at suse.cz> for what it's worth ;). Honza> --- > fs/ocfs2/file.c | 10 ++++++++-- > 1 files changed, 8 insertions(+), 2 deletions(-) > > diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c > index 77b4c04..181ae52 100644 > --- a/fs/ocfs2/file.c > +++ b/fs/ocfs2/file.c > @@ -1992,6 +1992,7 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, > struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); > struct ocfs2_space_resv sr; > int change_size = 1; > + int cmd = OCFS2_IOC_RESVSP64; > > if (!ocfs2_writes_unwritten_extents(osb)) > return -EOPNOTSUPP; > @@ -2002,12 +2003,17 @@ static long ocfs2_fallocate(struct inode *inode, int mode, loff_t offset, > if (mode & FALLOC_FL_KEEP_SIZE) > change_size = 0; > > + if (mode & FALLOC_FL_PUNCH_HOLE) { > + cmd = OCFS2_IOC_UNRESVSP64; > + change_size = 0; > + } > + > sr.l_whence = 0; > sr.l_start = (s64)offset; > sr.l_len = (s64)len; > > - return __ocfs2_change_file_space(NULL, inode, offset, > - OCFS2_IOC_RESVSP64, &sr, change_size); > + return __ocfs2_change_file_space(NULL, inode, offset, cmd, &sr, > + change_size); > } > > int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, > -- > 1.6.6.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- Jan Kara <jack at suse.cz> SUSE Labs, CR
Jan Kara
2010-Nov-16 11:52 UTC
[Ocfs2-devel] [PATCH 4/6] Ext4: fail if we try to use hole punch
On Mon 15-11-10 12:05:21, Josef Bacik wrote:> Ext4 doesn't have the ability to punch holes yet, so make sure we return > EOPNOTSUPP if we try to use hole punching through fallocate. This support can > be added later. Thanks, > > Signed-off-by: Josef Bacik <josef at redhat.com>Acked-by: Jan Kara <jack at suse.cz> Honza> --- > fs/ext4/extents.c | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > > diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c > index 0554c48..35bca73 100644 > --- a/fs/ext4/extents.c > +++ b/fs/ext4/extents.c > @@ -3622,6 +3622,10 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) > struct ext4_map_blocks map; > unsigned int credits, blkbits = inode->i_blkbits; > > + /* We only support the FALLOC_FL_KEEP_SIZE mode */ > + if (mode && (mode != FALLOC_FL_KEEP_SIZE)) > + return -EOPNOTSUPP; > + > /* > * currently supporting (pre)allocate mode for extent-based > * files _only_ > -- > 1.6.6.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- Jan Kara <jack at suse.cz> SUSE Labs, CR