From patchwork Tue Oct 24 12:46:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Chen X-Patchwork-Id: 10024213 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7FDC46035E for ; Tue, 24 Oct 2017 12:50:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F48D288D0 for ; Tue, 24 Oct 2017 12:50:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 53311288F1; Tue, 24 Oct 2017 12:50:20 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 695A7288D0 for ; Tue, 24 Oct 2017 12:50:19 +0000 (UTC) Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id v9OCnh8F022480 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 24 Oct 2017 12:49:43 GMT Received: from oss.oracle.com (oss-old-reserved.oracle.com [137.254.22.2]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v9OCnMdX030069 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 24 Oct 2017 12:49:23 GMT Received: from localhost ([127.0.0.1] helo=lb-oss.oracle.com) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1e6ye2-0000l7-Nd; Tue, 24 Oct 2017 05:49:22 -0700 Received: from userv0022.oracle.com ([156.151.31.74]) by oss.oracle.com with esmtp (Exim 4.63) (envelope-from ) id 1e6ydy-0000ku-9z for ocfs2-devel@oss.oracle.com; Tue, 24 Oct 2017 05:49:19 -0700 Received: from userp2030.oracle.com (userp2030.oracle.com [156.151.31.89]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id v9OCnHoW029865 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 24 Oct 2017 12:49:18 GMT Received: from pps.filterd (userp2030.oracle.com [127.0.0.1]) by userp2030.oracle.com (8.16.0.21/8.16.0.21) with SMTP id v9OCjKk4008187 for ; Tue, 24 Oct 2017 12:49:17 GMT Authentication-Results: oracle.com; spf=pass smtp.mailfrom=alex.chen@huawei.com Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) by userp2030.oracle.com with ESMTP id 2dt2rrvws4-1 for ; Tue, 24 Oct 2017 12:49:16 +0000 Received: from 172.30.72.60 (EHLO DGGEMS405-HUB.china.huawei.com) ([172.30.72.60]) by dggrg05-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DJW18536; Tue, 24 Oct 2017 20:47:35 +0800 (CST) Received: from [127.0.0.1] (10.177.26.59) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.361.1; Tue, 24 Oct 2017 20:46:29 +0800 Message-ID: <59EF3614.6050008@huawei.com> Date: Tue, 24 Oct 2017 20:46:12 +0800 From: alex chen User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 MIME-Version: 1.0 To: Andrew Morton X-Originating-IP: [10.177.26.59] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A0B0203.59EF3669.001F, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 7b18110e8b0829955ea913371eed512d X-CLX-Shades: MLX X-CLX-Response: 1TFkXGx8cEQpMehcbHxwRCllNF2dmchEKWUkXGnEaEBp3BhsZHHEYGBAadwY YGgYaEQpZXhdobmYRCklGF0VYS0lGT3VaWEVOX0leQ0VEHhEKQ04XfVNpS21wcEFSXmdwXU4SRm BdfRlfc2BvUltlWhoHTnARClhcFx8EGgQbGxMHG0gaThhOS08FGxoEGxoaBB4SBBsQGx4aHxoRC l5ZF3hgZF5EEQpNXBceEhIRCkxaF2lCTXkRCkVZF2hrEQpDWhceHwQYHhMEGBsYBBsTGxEKQl4X GxEKREkXGxoRCkJGF2xCWGl8QkZweRofEQpCXBcaEQpCRRdiEn1iEmJrHEVrfREKQk4XbEJIWVM aTWV4eB0RCkJMF2kBARhuGVsYUkd6EQpCbBdrHEJDTnpIHF56QBEKQkAXZXMZElMefRN4UxkRCk JYF2J9b3kBTxgZcHB7EQpaWBcbEQpwZxdvYRxZZ1IfehJsGBAZGhEKcGgXZh19QUJ+YmB5Y2AQG RoRCnBoF20dfwFzHV9LQk5nEBkaEQpwaBdvHk5JbhpBfm1uSBAZGhEKcGgXYU5YWHt+X2leTEEQ GRoRCnBoF2VIYllHT1J4f0IcEBkaEQpwbBdmQU5kU0tZcmB6HRAaEQptfhcaEQpYTRdLESA= X-PDR: PASS X-ServerName: szxga05-in.huawei.com X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 ip4:45.249.212.32 ip4:45.249.212.35 ip4:119.145.14.93 ip4:58.251.152.93 ip4:194.213.3.17 ip4:206.16.17.72 ip4:45.249.212.255 ip4:45.249.212.187/29 ip4:45.249.212.191 ~all X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8693 signatures=668600 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=156 malwarescore=0 suspectscore=8 phishscore=0 bulkscore=0 spamscore=0 clxscore=156 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1710240180 Cc: Zhen Ren , "ocfs2-devel@oss.oracle.com" Subject: [Ocfs2-devel] [PATCH v3] ocfs2: the ip_alloc_sem should be taken in ocfs2_get_block() 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: , Sender: ocfs2-devel-bounces@oss.oracle.com Errors-To: ocfs2-devel-bounces@oss.oracle.com X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Virus-Scanned: ClamAV using ClamSMTP The ip_alloc_sem should be taken in ocfs2_get_block() when reading file in DIRECT mode to prevent concurrent access to extent tree with ocfs2_dio_end_io_write(), which may cause BUGON in the following situation: read file 'A' end_io of writing file 'A' vfs_read __vfs_read ocfs2_file_read_iter generic_file_read_iter ocfs2_direct_IO __blockdev_direct_IO do_blockdev_direct_IO do_direct_IO get_more_blocks ocfs2_get_block ocfs2_extent_map_get_blocks ocfs2_get_clusters ocfs2_get_clusters_nocache() ocfs2_search_extent_list return the index of record which contains the v_cluster, that is v_cluster > rec[i]->e_cpos. ocfs2_dio_end_io ocfs2_dio_end_io_write down_write(&oi->ip_alloc_sem); ocfs2_mark_extent_written ocfs2_change_extent_flag ocfs2_split_extent ... --> modify the rec[i]->e_cpos, resulting in v_cluster < rec[i]->e_cpos. BUG_ON(v_cluster < le32_to_cpu(rec->e_cpos)) Fixes: c15471f79506 ("ocfs2: fix sparse file & data ordering issue in direct io") Signed-off-by: Alex Chen Reviewed-by: Jun Piao Acked-by: Changwei Ge Reviewed-by: Joseph Qi Reviewed-by: Gang He --- fs/ocfs2/aops.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 88a31e9..d151632 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -134,6 +134,19 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, return err; } +static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create) +{ + int ret = 0; + struct ocfs2_inode_info *oi = OCFS2_I(inode); + + down_read(&oi->ip_alloc_sem); + ret = ocfs2_get_block(inode, iblock, bh_result, create); + up_read(&oi->ip_alloc_sem); + + return ret; +} + int ocfs2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { @@ -2128,7 +2141,7 @@ static void ocfs2_dio_free_write_ctx(struct inode *inode, * called like this: dio->get_blocks(dio->inode, fs_startblk, * fs_count, map_bh, dio->rw == WRITE); */ -static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock, +static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); @@ -2154,12 +2167,9 @@ static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock, * while file size will be changed. */ if (pos + total_len <= i_size_read(inode)) { - down_read(&oi->ip_alloc_sem); - /* This is the fast path for re-write. */ - ret = ocfs2_get_block(inode, iblock, bh_result, create); - - up_read(&oi->ip_alloc_sem); + /* This is the fast path for re-write. */ + ret = ocfs2_lock_get_block(inode, iblock, bh_result, create); if (buffer_mapped(bh_result) && !buffer_new(bh_result) && ret == 0) @@ -2424,9 +2434,9 @@ static ssize_t ocfs2_direct_IO(struct kiocb *iocb, struct iov_iter *iter) return 0; if (iov_iter_rw(iter) == READ) - get_block = ocfs2_get_block; + get_block = ocfs2_lock_get_block; else - get_block = ocfs2_dio_get_block; + get_block = ocfs2_dio_wr_get_block; return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter, get_block,