From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751567AbbIKGh6 (ORCPT ); Fri, 11 Sep 2015 02:37:58 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:52937 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750992AbbIKGh4 (ORCPT ); Fri, 11 Sep 2015 02:37:56 -0400 X-AuditID: cbfee61b-f79d56d0000048c5-1b-55f276c39a8e From: Chao Yu To: Jaegeuk Kim Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH 1/7] f2fs: reorganize f2fs_map_blocks Date: Fri, 11 Sep 2015 14:37:13 +0800 Message-id: <00f101d0ec5c$63c14020$2b43c060$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-index: AdDsXAt3ncAMKp/JR3aqmgcblp578A== Content-language: zh-cn X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrNLMWRmVeSWpSXmKPExsVy+t9jQd3DZZ9CDXq7+SyerJ/FbHFpkbvF 5V1z2ByYPTat6mTz2L3gM5PH501yAcxRXDYpqTmZZalF+nYJXBm/GwQLdspXLD95mbGB8aJ4 FyMnh4SAicSXl1eYIWwxiQv31rN1MXJxCAnMYpT4N+8IlPOKUeLUi0ZWkCo2ARWJ5R3/mUBs ESD70KLL7CA2s4CHRGPHd7AaYQFTicM/DoLZLAKqEof6t4Ft4BWwlFjws4UNwhaU+DH5HgtE r5bE+p3HmSBseYnNa95CXaQgsePsa0aIXXoSlzcvhtolLrHxyC2WCYxAZyKMmoVk1Cwko2Yh aVnAyLKKUSK1ILmgOCk91ygvtVyvODG3uDQvXS85P3cTIziIn0nvYDy8y/0QowAHoxIPr4Xq p1Ah1sSy4srcQ4wSHMxKIrwGckAh3pTEyqrUovz4otKc1OJDjNIcLErivLIrn4UKCaQnlqRm p6YWpBbBZJk4OKUaGOt1y0xzKjur+T2sHq19FDz9nXc/Z3KvbInNqUVlS67KfRCZnrPzE+M/ zSfXTeWPxM7neMivsOjGZ417LTdNisWS3TiEk45+vXS0sej38nju+GD3eM8tBkdcBO+t+6af tqri7hmjG/cKZa7O3rwkU66mx3jTe99bNrPf+TgoXpxQW7+3PUF6sRJLcUaioRZzUXEiABeE WeJeAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In this patch, we try to reorganize f2fs_map_blocks to make block mapping flow more clear by using following structure: /* check status of mapping */ if (unmapped) { /* blkaddr == NULL_ADDR || blkaddr == NEW_ADDR */ if (create) { /* write path, handle dio write case here */ alloc_and_map; } else { /* * handle read cases from all call paths: * 1. generic read; * 2. dio read; * 3. fiemap; * 4. bmap */ } } /* map buffer_header */ Besides, this patch handles the missing case correctly for dio write: When we fail in __allocate_data_blocks, then in f2fs_map_blocks, we will not allocate blocks correctly for preallocated blocks, but returning with an unmapped buffer head, which will result in failure of dio write. Signed-off-by: Chao Yu --- fs/f2fs/data.c | 84 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a82abe9..a737ca5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -595,40 +595,36 @@ static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, err = 0; goto unlock_out; } - if (dn.data_blkaddr == NEW_ADDR) { - if (flag == F2FS_GET_BLOCK_BMAP) { - err = -ENOENT; - goto put_out; - } else if (flag == F2FS_GET_BLOCK_READ || - flag == F2FS_GET_BLOCK_DIO) { - goto put_out; + + if (dn.data_blkaddr == NEW_ADDR || dn.data_blkaddr == NULL_ADDR) { + if (create) { + err = __allocate_data_block(&dn); + if (err) + goto put_out; + allocated = true; + map->m_flags = F2FS_MAP_NEW; + } else { + if (flag != F2FS_GET_BLOCK_FIEMAP || + dn.data_blkaddr != NEW_ADDR) { + if (flag == F2FS_GET_BLOCK_BMAP) + err = -ENOENT; + goto put_out; + } + + /* + * preallocated unwritten block should be mapped + * for fiemap. + */ + if (dn.data_blkaddr == NEW_ADDR) + map->m_flags = F2FS_MAP_UNWRITTEN; } - /* - * if it is in fiemap call path (flag = F2FS_GET_BLOCK_FIEMAP), - * mark it as mapped and unwritten block. - */ } - if (dn.data_blkaddr != NULL_ADDR) { - map->m_flags = F2FS_MAP_MAPPED; - map->m_pblk = dn.data_blkaddr; - if (dn.data_blkaddr == NEW_ADDR) - map->m_flags |= F2FS_MAP_UNWRITTEN; - } else if (create) { - err = __allocate_data_block(&dn); - if (err) - goto put_out; - allocated = true; - map->m_flags = F2FS_MAP_NEW | F2FS_MAP_MAPPED; - map->m_pblk = dn.data_blkaddr; - } else { - if (flag == F2FS_GET_BLOCK_BMAP) - err = -ENOENT; - goto put_out; - } + map->m_flags |= F2FS_MAP_MAPPED; + map->m_pblk = dn.data_blkaddr; + map->m_len = 1; end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); - map->m_len = 1; dn.ofs_in_node++; pgofs++; @@ -647,23 +643,31 @@ get_next: goto unlock_out; } - if (dn.data_blkaddr == NEW_ADDR && - flag != F2FS_GET_BLOCK_FIEMAP) - goto put_out; - end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode)); } if (maxblocks > map->m_len) { block_t blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); - if (blkaddr == NULL_ADDR && create) { - err = __allocate_data_block(&dn); - if (err) - goto sync_out; - allocated = true; - map->m_flags |= F2FS_MAP_NEW; - blkaddr = dn.data_blkaddr; + + if (blkaddr == NEW_ADDR && blkaddr == NULL_ADDR) { + if (create) { + err = __allocate_data_block(&dn); + if (err) + goto sync_out; + allocated = true; + map->m_flags |= F2FS_MAP_NEW; + blkaddr = dn.data_blkaddr; + } else { + /* + * we only merge preallocated unwritten blocks + * for fiemap. + */ + if (flag != F2FS_GET_BLOCK_FIEMAP || + blkaddr != NEW_ADDR) + goto sync_out; + } } + /* Give more consecutive addresses for the readahead */ if ((map->m_pblk != NEW_ADDR && blkaddr == (map->m_pblk + ofs)) || -- 2.4.2