Received: by 2002:a25:86ce:0:0:0:0:0 with SMTP id y14csp645403ybm; Tue, 21 May 2019 00:44:49 -0700 (PDT) X-Google-Smtp-Source: APXvYqxEAkCY90DdxHmgs5Nk/xMPRC5cUQ5KIdUF/YBnSBJdqeapwsX2ezZHfU5x+YIo+brfHmwu X-Received: by 2002:a17:902:6948:: with SMTP id k8mr81592390plt.81.1558424689129; Tue, 21 May 2019 00:44:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558424689; cv=none; d=google.com; s=arc-20160816; b=iZQudvsV3m45IWM7mvcMKyzqa6qVb4OPRmZtjzsEe1B87UkHtot0sCyKagdhlskN4j tUTeaPQ3Y8tTkbEkfcNXWbBRGGjd1O+l+loKMoOnolVcJcKehr2+ylPsRxJWHLtFnO9p ejJtF3Q+QUT6m5cYCCFq1cgtoJYSUz5jAevIzevGvrYdMgiUl0/Lzc2eNFLjtN1DCRW/ 8NvIJm81d1e3eZdKe42oApBP0s28w9zU81U750bmgfWgE9pS8D4vXR0tWGAOHlOgubgY JlxUQoS8pJy5AhjYQCYFxh/x19CQYR47W4c9sAfSpY9w6klKHMp85J1zoAaXVc6C0QIk zrpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=2vDAF0YsNNrapmu7HYhf5SsgZ3M30cX732tAwhkfoNQ=; b=G04vFDtv/+/kYxlQTJnPNx7AsXAiX6T1ssAyeSSTmKeYDVs+y9G7rpSfihfZWP22iT Mp5pWRVmJM7sVcIl9mUjdZml4hmlX/hTAu4pUqRZBVuaMa9JMOQXNHjpxOEaGrshniUZ h7AxuQagKVcKKn8+kUwypznEKeK8Hu7Rra/r2tU84U/Q2EoLnrmQdaRUfvR547qtfoHF maSoEWL4OQcSskQduEyYXhZsmgC5zQMVCnm6s86BwQk19r6n1uS7p4zMERiZx05Rks4C GMRO02GVoYknGeKiHNH2/6AR9vgsnm8cwaeFhZsqbLtcOda2SBYOuLgBPNe/ghMX5TZ6 VAFg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i98si20628062plb.104.2019.05.21.00.44.34; Tue, 21 May 2019 00:44:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-ext4-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726316AbfEUHoI (ORCPT + 99 others); Tue, 21 May 2019 03:44:08 -0400 Received: from mx2.suse.de ([195.135.220.15]:37342 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726419AbfEUHoH (ORCPT ); Tue, 21 May 2019 03:44:07 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E2512AE1D; Tue, 21 May 2019 07:44:05 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id D20EB1E3C72; Tue, 21 May 2019 09:44:04 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , "Weiny, Ira" , Jan Kara Subject: [PATCH 3/3] ext4: Gracefully handle ext4_break_layouts() failure during truncate Date: Tue, 21 May 2019 09:43:58 +0200 Message-Id: <20190521074358.17186-4-jack@suse.cz> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190521074358.17186-1-jack@suse.cz> References: <20190521074358.17186-1-jack@suse.cz> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org ext4_break_layouts() may fail e.g. due to a signal being delivered. Thus we need to handle its failure gracefully and not by taking the filesystem down. Currently ext4_break_layouts() failure is rare but it may become more common once RDMA uses layout leases for handling long-term page pins for DAX mappings. To handle the failure we need to move ext4_break_layouts() earlier during setattr handling before we do hard to undo changes such as modifying inode size. To be able to do that we also have to move some other checks which are better done without holding i_mmap_sem earlier. Reported-by: "Weiny, Ira" Signed-off-by: Jan Kara --- fs/ext4/inode.c | 55 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c7f77c643008..979570b42e18 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5571,7 +5571,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (attr->ia_valid & ATTR_SIZE) { handle_t *handle; loff_t oldsize = inode->i_size; - int shrink = (attr->ia_size <= inode->i_size); + int shrink = (attr->ia_size < inode->i_size); if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); @@ -5585,18 +5585,35 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size) inode_inc_iversion(inode); - if (ext4_should_order_data(inode) && - (attr->ia_size < inode->i_size)) { - error = ext4_begin_ordered_truncate(inode, + if (shrink) { + if (ext4_should_order_data(inode)) { + error = ext4_begin_ordered_truncate(inode, attr->ia_size); - if (error) - goto err_out; + if (error) + goto err_out; + } + /* + * Blocks are going to be removed from the inode. Wait + * for dio in flight. + */ + inode_dio_wait(inode); + } else { + pagecache_isize_extended(inode, oldsize, inode->i_size); } + + down_write(&EXT4_I(inode)->i_mmap_sem); + + rc = ext4_break_layouts(inode); + if (rc) { + up_write(&EXT4_I(inode)->i_mmap_sem); + return rc; + } + if (attr->ia_size != inode->i_size) { handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); if (IS_ERR(handle)) { error = PTR_ERR(handle); - goto err_out; + goto out_mmap_sem; } if (ext4_handle_valid(handle) && shrink) { error = ext4_orphan_add(handle, inode); @@ -5627,29 +5644,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (error) { if (orphan && inode->i_nlink) ext4_orphan_del(NULL, inode); - goto err_out; + goto out_mmap_sem; } } - if (!shrink) { - pagecache_isize_extended(inode, oldsize, inode->i_size); - } else { - /* - * Blocks are going to be removed from the inode. Wait - * for dio in flight. - */ - inode_dio_wait(inode); - } - if (orphan && ext4_should_journal_data(inode)) - ext4_wait_for_tail_page_commit(inode); - down_write(&EXT4_I(inode)->i_mmap_sem); - - rc = ext4_break_layouts(inode); - if (rc) { - up_write(&EXT4_I(inode)->i_mmap_sem); - error = rc; - goto err_out; - } + if (shrink && ext4_should_journal_data(inode)) + ext4_wait_for_tail_page_commit(inode); /* * Truncate pagecache after we've waited for commit * in data=journal mode to make pages freeable. @@ -5660,6 +5660,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (rc) error = rc; } +out_mmap_sem: up_write(&EXT4_I(inode)->i_mmap_sem); } -- 2.16.4