From patchwork Wed Dec 5 09:17:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlos Maiolino X-Patchwork-Id: 10713417 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 41A121057 for ; Wed, 5 Dec 2018 09:18:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32CAC2BE54 for ; Wed, 5 Dec 2018 09:18:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 271D92CD12; Wed, 5 Dec 2018 09:18:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1B0C2BE54 for ; Wed, 5 Dec 2018 09:18:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727349AbeLEJSL (ORCPT ); Wed, 5 Dec 2018 04:18:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54206 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727347AbeLEJSK (ORCPT ); Wed, 5 Dec 2018 04:18:10 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0F911315486E; Wed, 5 Dec 2018 09:18:10 +0000 (UTC) Received: from hades.usersys.redhat.com (unknown [10.43.17.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id D7D235D967; Wed, 5 Dec 2018 09:18:08 +0000 (UTC) From: Carlos Maiolino To: linux-fsdevel@vger.kernel.org Cc: hch@lst.de, adilger@dilger.ca, sandeen@redhat.com, david@fromorbit.com Subject: [PATCH 09/10 V2] Use FIEMAP for FIBMAP calls Date: Wed, 5 Dec 2018 10:17:27 +0100 Message-Id: <20181205091728.29903-10-cmaiolino@redhat.com> In-Reply-To: <20181205091728.29903-1-cmaiolino@redhat.com> References: <20181205091728.29903-1-cmaiolino@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Wed, 05 Dec 2018 09:18:10 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Enables the usage of FIEMAP ioctl infrastructure to handle FIBMAP calls. From now on, ->bmap() methods can start to be removed from filesystems which already provides ->fiemap(). This adds a new helper - bmap_fiemap() - which is used to fill in the fiemap request, call into the underlying filesystem and check the flags set in the extent requested. Add a new fiemap fill extent callback to handl the in-kernel only fiemap_extent structure used for FIBMAP. V2: - Now based on the updated fiemap_extent_info, - move the fiemap call itself to a new helper Signed-off-by: Carlos Maiolino --- fs/inode.c | 42 ++++++++++++++++++++++++++++++++++++++++-- fs/ioctl.c | 32 ++++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index db681d310465..f07cc183ddbd 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1578,6 +1578,40 @@ void iput(struct inode *inode) } EXPORT_SYMBOL(iput); +static int bmap_fiemap(struct inode *inode, sector_t *block) +{ + struct fiemap_extent_info fieinfo = { 0, }; + struct fiemap_extent fextent; + u64 start = *block << inode->i_blkbits; + int error = -EINVAL; + + fextent.fe_logical = 0; + fextent.fe_physical = 0; + fieinfo.fi_extents_max = 1; + fieinfo.fi_extents_mapped = 0; + fieinfo.fi_extents_start = &fextent; + fieinfo.fi_start = start; + fieinfo.fi_len = 1 << inode->i_blkbits; + fieinfo.fi_flags = 0; + fieinfo.fi_cb = fiemap_fill_kernel_extent; + + error = inode->i_op->fiemap(inode, &fieinfo); + + if (error) + return error; + + if (fieinfo.fi_flags & (FIEMAP_EXTENT_UNKNOWN | + FIEMAP_EXTENT_ENCODED | + FIEMAP_EXTENT_DATA_INLINE | + FIEMAP_EXTENT_UNWRITTEN)) + return -EINVAL; + + *block = (fextent.fe_physical + + (start - fextent.fe_logical)) >> inode->i_blkbits; + + return error; +} + /** * bmap - find a block number in a file * @inode: inode owning the block number being requested @@ -1594,10 +1628,14 @@ EXPORT_SYMBOL(iput); */ int bmap(struct inode *inode, sector_t *block) { - if (!inode->i_mapping->a_ops->bmap) + if (inode->i_op->fiemap) + return bmap_fiemap(inode, block); + else if (inode->i_mapping->a_ops->bmap) + *block = inode->i_mapping->a_ops->bmap(inode->i_mapping, + *block); + else return -EINVAL; - *block = inode->i_mapping->a_ops->bmap(inode->i_mapping, *block); return 0; } EXPORT_SYMBOL(bmap); diff --git a/fs/ioctl.c b/fs/ioctl.c index 6086978fe01e..bfa59df332bf 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -116,6 +116,38 @@ int fiemap_fill_user_extent(struct fiemap_extent_info *fieinfo, u64 logical, return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; } +int fiemap_fill_kernel_extent(struct fiemap_extent_info *fieinfo, u64 logical, + u64 phys, u64 len, u32 flags) +{ + struct fiemap_extent *extent = fieinfo->fi_extents_start; + + /* only count the extents */ + if (fieinfo->fi_extents_max == 0) { + fieinfo->fi_extents_mapped++; + return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; + } + + if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max) + return 1; + + if (flags & SET_UNKNOWN_FLAGS) + flags |= FIEMAP_EXTENT_UNKNOWN; + if (flags & SET_NO_UNMOUNTED_IO_FLAGS) + flags |= FIEMAP_EXTENT_ENCODED; + if (flags & SET_NOT_ALIGNED_FLAGS) + flags |= FIEMAP_EXTENT_NOT_ALIGNED; + + extent->fe_logical = logical; + extent->fe_physical = phys; + extent->fe_length = len; + extent->fe_flags = flags; + + fieinfo->fi_extents_mapped++; + + if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max) + return 1; + return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; +} /** * fiemap_fill_next_extent - Fiemap helper function * @fieinfo: Fiemap context passed into ->fiemap diff --git a/include/linux/fs.h b/include/linux/fs.h index 7a434979201c..28bb523d532a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1711,6 +1711,8 @@ struct fiemap_extent_info { fiemap_fill_cb fi_cb; }; +int fiemap_fill_kernel_extent(struct fiemap_extent_info *info, u64 logical, + u64 phys, u64 len, u32 flags); int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical, u64 phys, u64 len, u32 flags); int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);