Return-Path: Received: from mailout4.samsung.com ([203.254.224.34]:43531 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751075AbcAKG2a (ORCPT ); Mon, 11 Jan 2016 01:28:30 -0500 Received: from epcpsbgm1new.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O0R015BXZB4I570@mailout4.samsung.com> for linux-fsdevel@vger.kernel.org; Mon, 11 Jan 2016 15:28:29 +0900 (KST) Received: from lifan ([109.123.105.144]) by mmp1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O0R00KGOZALVDC0@mmp1.samsung.com> for linux-fsdevel@vger.kernel.org; Mon, 11 Jan 2016 15:28:29 +0900 (KST) From: Fan Li To: linux-fsdevel@vger.kernel.org Subject: [PATCH 2/3] fs: round len up before get mapping Date: Mon, 11 Jan 2016 14:27:55 +0800 Message-id: <001401d14c39$478ffa80$d6afef80$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=windows-1252 Content-transfer-encoding: 7bit Content-language: en-us Sender: linux-fsdevel-owner@vger.kernel.org List-ID: When len is less than one block, it will be extended to one block. If start + len exceeds the boundary of the original block because of the extension, one needless block will be returned. And this patch only tries to map blocks within range instead of mapping as many contiguous blocks as possible at once. That's because comparing to extent-based files, find mapping for indirect-based files could be time-consuming, especially after we found the last extent we need, we don't care how long the next extent, and should return right after find a mapped block or EOF. Signed-off-by: Fan Li --- fs/ioctl.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index 13a3e96..5d54377 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -276,23 +276,21 @@ int __generic_block_fiemap(struct inode *inode, len = isize - start; } - /* - * Some filesystems can't deal with being asked to map less than - * blocksize, so make sure our len is at least block length. - */ - if (logical_to_blk(inode, len) == 0) - len = blk_to_logical(inode, 1); - start_blk = logical_to_blk(inode, start); last_blk = logical_to_blk(inode, start + len - 1); do { + memset(&map_bh, 0, sizeof(struct buffer_head)); /* - * we set b_size to the total size we want so it will map as - * many contiguous blocks as possible at once + * Some filesystems would round down b_size to align + * with block size, if len isn't aligned already, the last + * block may not be returned. Let's round it up first. */ - memset(&map_bh, 0, sizeof(struct buffer_head)); - map_bh.b_size = len; + if (last_blk > start_blk) + map_bh.b_size = blk_to_logical(inode, + last_blk - start_blk + 1); + else + map_bh.b_size = blk_to_logical(inode, 1); ret = get_block(inode, start_blk, &map_bh, 0); if (ret) -- 1.7.9.5