From patchwork Fri Jul 25 08:31:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Sterba X-Patchwork-Id: 4621731 Return-Path: X-Original-To: patchwork-ocfs2-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 65C639F23C for ; Fri, 25 Jul 2014 08:33:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B7E9A201F7 for ; Fri, 25 Jul 2014 08:33:00 +0000 (UTC) Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F478201F2 for ; Fri, 25 Jul 2014 08:32:59 +0000 (UTC) Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s6P8WI2R010474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 25 Jul 2014 08:32:19 GMT Received: from oss.oracle.com (oss-external.oracle.com [137.254.96.51]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s6P8WIRJ009414 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 25 Jul 2014 08:32:18 GMT Received: from localhost ([127.0.0.1] helo=oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1XAavK-0005Da-CS; Fri, 25 Jul 2014 01:32:18 -0700 Received: from acsinet22.oracle.com ([141.146.126.238]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1XAaul-0005CW-Sv for ocfs2-devel@oss.oracle.com; Fri, 25 Jul 2014 01:31:44 -0700 Received: from aserp1020.oracle.com (aserp1020.oracle.com [141.146.126.67]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s6P8Vhwk027093 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 25 Jul 2014 08:31:43 GMT Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by aserp1020.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s6P8VfhO026401 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Fri, 25 Jul 2014 08:31:42 GMT Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C15AEAC1F; Fri, 25 Jul 2014 08:31:40 +0000 (UTC) Received: by ds.suse.cz (Postfix, from userid 10065) id E86CADAAE1; Fri, 25 Jul 2014 10:31:39 +0200 (CEST) From: David Sterba To: linux-fsdevel@vger.kernel.org Date: Fri, 25 Jul 2014 10:31:39 +0200 Message-Id: X-Mailer: git-send-email 1.9.0 In-Reply-To: References: X-Flow-Control-Info: class=Pass-to-MM reputation=ipRisk-All ip=195.135.220.15 ct-class=T1 ct-vol1=0 ct-vol2=4 ct-vol3=3 ct-risk=42 ct-spam1=65 ct-spam2=7 ct-bulk=60 rcpts=1 size=10844 X-Sendmail-CM-Score: 0.00% X-Sendmail-CM-Analysis: v=2.1 cv=YrQ2GeoX c=1 sm=1 tr=0 a=uEuDQZVrWKuLCe7byFjfVg==:117 a=uEuDQZVrWKuLCe7byFjfVg==:17 a=YSJB0m9c9dIA:10 a=TSbVqHtbAAAA:8 a=OLL_FvSJAAAA:8 a=drOt6m5kAAAA:8 a=FOH2dFAWAAAA:8 a=JfrnYn6hAAAA:8 a=iox4zFpeAAAA:8 a=20KFwNOVAAAA:8 a=eJfxg xciAAAA:8 a=MgFa1VvhBWQ2fACebmAA:9 a=kR6rkKVVdFkCg2uy:21 a=NZIMYnqzJ1Kl2xAR:21 a=GBbsmUOCxiUA:10 a=npO87R0EFmwA:10 a=3Rfx1nUSh_UA:10 a=n9GBPR9yFnkA:10 a=jEp0ucaQiEUA:10 a=W39ifWXXhksA:10 X-Sendmail-CT-RefID: str=0001.0A090202.53D215EE.0347:SCFSTAT18040053, ss=1, re=-4.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-Sendmail-CT-Classification: not spam Cc: adilger@dilger.ca, linux-nilfs@vger.kernel.org, "Theodore Ts'o" , mfasheh@suse.com, david@fromorbit.com, David Sterba , xfs@oss.sgi.com, hch@infradead.org, Chris Mason , Ben Myers , linux-btrfs@vger.kernel.org, viro@zeniv.linux.org.uk, linux-ext4@vger.kernel.org, Steven Whitehouse , ocfs2-devel@oss.oracle.com Subject: [Ocfs2-devel] [PATCH 2/5] fiemap: add EXTENT_DATA_COMPRESSED flag X-BeenThere: ocfs2-devel@oss.oracle.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ocfs2-devel-bounces@oss.oracle.com Errors-To: ocfs2-devel-bounces@oss.oracle.com X-Source-IP: acsinet21.oracle.com [141.146.126.237] X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This flag was not accepted when fiemap was proposed [2] due to lack of in-kernel users. Btrfs has compression for a long time and we'd like to see that an extent is compressed in the output of 'filefrag' utility once it's taught about it. For that purpose, a reserved field from fiemap_extent is used to let the filesystem store along the physcial extent length when the flag is set. This keeps compatibility with applications that use FIEMAP. Extend arguments of fiemap_fill_next_extent and update all users. [1] http://article.gmane.org/gmane.comp.file-systems.ext4/8871 [2] http://thread.gmane.org/gmane.comp.file-systems.ext4/8870 [3] http://thread.gmane.org/gmane.linux.file-systems/77632 (v1) [4] http://www.spinics.net/lists/linux-fsdevel/msg69078.html (v2) Cc: Al Viro CC: Andreas Dilger CC: Chris Mason CC: Christoph Hellwig CC KONISHI Ryusuke CC: Mark Fasheh CC: Steven Whitehouse CC: "Theodore Ts'o" CC: Ben Myers Signed-off-by: David Sterba --- fs/btrfs/extent_io.c | 2 +- fs/ext4/extents.c | 3 ++- fs/ext4/inline.c | 2 +- fs/gfs2/inode.c | 2 +- fs/ioctl.c | 27 +++++++++++++++++++++------ fs/nilfs2/inode.c | 8 +++++--- fs/ocfs2/extent_map.c | 4 ++-- fs/xfs/xfs_iops.c | 2 +- include/linux/fs.h | 2 +- include/uapi/linux/fiemap.h | 8 +++++++- 10 files changed, 42 insertions(+), 18 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index a389820d158b..eec118bf77ae 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4357,7 +4357,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, end = 1; } ret = fiemap_fill_next_extent(fieinfo, em_start, disko, - em_len, flags); + em_len, em_len, flags); if (ret) goto out_free; } diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 4da228a0e6d0..0bdd173ac728 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2253,6 +2253,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode, (__u64)es.es_lblk << blksize_bits, (__u64)es.es_pblk << blksize_bits, (__u64)es.es_len << blksize_bits, + (__u64)es.es_len << blksize_bits, flags); if (err < 0) break; @@ -5125,7 +5126,7 @@ static int ext4_xattr_fiemap(struct inode *inode, if (physical) error = fiemap_fill_next_extent(fieinfo, 0, physical, - length, flags); + length, length, flags); return (error < 0 ? error : 0); } diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 645205d8ada6..3825ff9dc40d 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -1825,7 +1825,7 @@ int ext4_inline_data_fiemap(struct inode *inode, if (physical) error = fiemap_fill_next_extent(fieinfo, 0, physical, - length, flags); + length, length, flags); brelse(iloc.bh); out: up_read(&EXT4_I(inode)->xattr_sem); diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index e62e59477884..5b45cf4e5465 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1931,7 +1931,7 @@ static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, len = size - start; if (start < size) ret = fiemap_fill_next_extent(fieinfo, start, phys, - len, flags); + len, len, flags); if (ret == 1) ret = 0; } else { diff --git a/fs/ioctl.c b/fs/ioctl.c index 8ac3fad36192..24a9d912d1e6 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -70,20 +70,26 @@ static int ioctl_fibmap(struct file *filp, int __user *p) * @logical: Extent logical start offset, in bytes * @phys: Extent physical start offset, in bytes * @len: Extent length, in bytes + * @phys_len: Physical extent length in bytes * @flags: FIEMAP_EXTENT flags that describe this extent * * Called from file system ->fiemap callback. Will populate extent * info as passed in via arguments and copy to user memory. On * success, extent count on fieinfo is incremented. * + * Extents without any encoding must set the physical and logical length + * to the same value. Otherwise, set flags to FIEMAP_EXTENT_ENCODED + * and possibly specify encoding type. + * * Returns 0 on success, -errno on error, 1 if this was the last * extent that will fit in user array. */ #define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC) -#define SET_NO_UNMOUNTED_IO_FLAGS (FIEMAP_EXTENT_DATA_ENCRYPTED) +#define SET_NO_UNMOUNTED_IO_FLAGS (FIEMAP_EXTENT_DATA_ENCRYPTED | \ + FIEMAP_EXTENT_DATA_COMPRESSED) #define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE) int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical, - u64 phys, u64 len, u32 flags) + u64 phys, u64 len, u64 phys_len, u32 flags) { struct fiemap_extent extent; struct fiemap_extent __user *dest = fieinfo->fi_extents_start; @@ -110,6 +116,14 @@ int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical, extent.fe_length = len; extent.fe_flags = flags; + WARN_ONCE((flags & FIEMAP_EXTENT_DATA_COMPRESSED) + && !(flags & FIEMAP_EXTENT_ENCODED)); + WARN_ONCE(phys_len != len && !(flags & FIEMAP_EXTENT_DATA_COMPRESSED), + "physical length %llu != logical length %llu without = DATA_COMPRESSED\n", + phys_len, len); + + extent.fe_phys_length = phys_len; + dest += fieinfo->fi_extents_mapped; if (copy_to_user(dest, &extent, sizeof(extent))) return -EFAULT; @@ -318,10 +332,11 @@ int __generic_block_fiemap(struct inode *inode, flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST; ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, - flags); + size, flags); } else if (size) { ret = fiemap_fill_next_extent(fieinfo, logical, - phys, size, flags); + phys, size, + size, flags); size = 0; } @@ -347,7 +362,7 @@ int __generic_block_fiemap(struct inode *inode, if (start_blk > last_blk && !whole_file) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, - flags); + size, flags); break; } @@ -358,7 +373,7 @@ int __generic_block_fiemap(struct inode *inode, if (size) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, - flags); + size, flags); if (ret) break; } diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 6252b173a465..a74d3a0e670a 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -1017,7 +1017,8 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, if (size) { /* End of the current extent */ ret = fiemap_fill_next_extent( - fieinfo, logical, phys, size, flags); + fieinfo, logical, phys, size, size, + flags); if (ret) break; } @@ -1067,7 +1068,8 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, flags |= FIEMAP_EXTENT_LAST; ret = fiemap_fill_next_extent( - fieinfo, logical, phys, size, flags); + fieinfo, logical, phys, size, + size, flags); if (ret) break; size = 0; @@ -1083,7 +1085,7 @@ int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, /* Terminate the current extent */ ret = fiemap_fill_next_extent( fieinfo, logical, phys, size, - flags); + size, flags); if (ret || blkoff > end_blkoff) break; diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 767370b656ca..45c95aa2a00f 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -736,7 +736,7 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh, id2.i_data.id_data); ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count, - flags); + id_count, flags); if (ret < 0) return ret; } @@ -809,7 +809,7 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, virt_bytes = (u64)le32_to_cpu(rec.e_cpos) << osb->s_clustersize_bits; ret = fiemap_fill_next_extent(fieinfo, virt_bytes, phys_bytes, - len_bytes, fe_flags); + len_bytes, len_bytes, fe_flags); if (ret) break; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 205613a06068..eeef5381debb 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1030,7 +1030,7 @@ xfs_fiemap_format( fiemap_flags |= FIEMAP_EXTENT_LAST; error = fiemap_fill_next_extent(fieinfo, logical, physical, - length, fiemap_flags); + length, length, fiemap_flags); if (error > 0) { error = 0; *full = 1; /* user array now full */ diff --git a/include/linux/fs.h b/include/linux/fs.h index e11d60cc867b..609e1d72c3e0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1412,7 +1412,7 @@ struct fiemap_extent_info { fiemap_extent array */ }; int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical, - u64 phys, u64 len, u32 flags); + u64 phys, u64 len, u64 phys_len, u32 flags); int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); /* diff --git a/include/uapi/linux/fiemap.h b/include/uapi/linux/fiemap.h index 93abfcd9ac47..11b51887b94a 100644 --- a/include/uapi/linux/fiemap.h +++ b/include/uapi/linux/fiemap.h @@ -19,7 +19,9 @@ struct fiemap_extent { __u64 fe_physical; /* physical offset in bytes for the start * of the extent from the beginning of the disk */ __u64 fe_length; /* length in bytes for this extent */ - __u64 fe_reserved64[2]; + __u64 fe_phys_length; /* physical length in bytes, may be different from + * fe_length and sets additional extent flags */ + __u64 fe_reserved64; __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */ __u32 fe_reserved[3]; }; @@ -50,6 +52,10 @@ struct fiemap { * Sets EXTENT_UNKNOWN. */ #define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read * while fs is unmounted */ +#define FIEMAP_EXTENT_DATA_COMPRESSED 0x00000040 /* Data is compressed by fs. + * Sets EXTENT_ENCODED and + * the compressed size is + * stored in fe_phys_length */ #define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs. * Sets EXTENT_ENCODED */ #define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be