Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp14361972pxu; Mon, 4 Jan 2021 22:28:02 -0800 (PST) X-Google-Smtp-Source: ABdhPJwsRIe7YRkp32shi9scLDSvTdWl2JqTcCWbCBADPU8mPn2vi6fPEHNEi2oLo2MDxEsbENRH X-Received: by 2002:a17:906:f1c8:: with SMTP id gx8mr70430710ejb.524.1609828082066; Mon, 04 Jan 2021 22:28:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609828082; cv=none; d=google.com; s=arc-20160816; b=vh44JyuAqOf72Kvd26tJDwX+ZnL3xpYMunGtCDbfrgmwI2EOKRoCrJ5RzTylgLgTOz RwWIUhtLxKj8IJEVAHuNii9CQGptlqDYyMZlQoKhbLH/6jiCvE/WPY78Dq8FNyv5DC0W XGtW8OcyWRRSboBtc8xHVZ4NlyC5z0Nd032Mu21mgR1IHN1yHA8StT1BaPFJAJBCgWVk JEGvRG6uXVsX5EjanqB67dO8wV5QPaHlhuEwRaJ6Mr9vgZ0K6c6MUgHdflRxtNB+xbdE B/jy2GuVc3U5GjsCSEEl7OJI4YA7JOg36KI3xkNoft4elQ4hfoBS8dqR0eB6zBxZfQhZ uqnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=zyZeYn5ejeHStU48Aedn2Tyl41MSC7+207YDzCiCFX0=; b=ZIX6WNvo0T6aXF1ti5W4NHqv78CG9AFKScJ2ZKE6OxZYH4RFSHoa1HfuK0BNPI4+wv wxgv6p/MmwaXbDi/FplsH2aPPq0a7oBEskLyt4oNiIMIewpdcveqmZAhdk9dSJ6QVvmF pt7/R85FWYnPdPtWXXrIalDYszMxD+dGYuwYyJYgf/7Lfwg/24gYd3gYZrpxFzf1fpDj o3VpvQF6ziuBEYjFnFddhgWoSfaXuBwXRY0dv74Nrv/u8DYLv2N333CdDLiL8wOhJa3Q Oh3BbBkGutX7efSQDVIx46Ip42Xd241M46/5173s9Hm3k2nWzcDngVR0clPwgCUv1IEH DGTA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id i7si29324330ejx.34.2021.01.04.22.27.34; Mon, 04 Jan 2021 22:28:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725710AbhAEG1R (ORCPT + 99 others); Tue, 5 Jan 2021 01:27:17 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:10545 "EHLO szxga05-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725298AbhAEG1R (ORCPT ); Tue, 5 Jan 2021 01:27:17 -0500 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.60]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4D92YK1yY0zMFb8; Tue, 5 Jan 2021 14:25:25 +0800 (CST) Received: from code-website.localdomain (10.175.127.227) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.498.0; Tue, 5 Jan 2021 14:26:25 +0800 From: yangerkun To: , , , CC: , , , , Subject: [PATCH v3] ext4: fix bug for rename with RENAME_WHITEOUT Date: Tue, 5 Jan 2021 14:28:57 +0800 Message-ID: <20210105062857.3566-1-yangerkun@huawei.com> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.127.227] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org We got a "deleted inode referenced" warning cross our fsstress test. The bug can be reproduced easily with following steps: cd /dev/shm mkdir test/ fallocate -l 128M img mkfs.ext4 -b 1024 img mount img test/ dd if=/dev/zero of=test/foo bs=1M count=128 mkdir test/dir/ && cd test/dir/ for ((i=0;i<1000;i++)); do touch file$i; done # consume all block cd ~ && renameat2(AT_FDCWD, /dev/shm/test/dir/file1, AT_FDCWD, /dev/shm/test/dir/dst_file, RENAME_WHITEOUT) # ext4_add_entry in ext4_rename will return ENOSPC!! cd /dev/shm/ && umount test/ && mount img test/ && ls -li test/dir/file1 We will get the output: "ls: cannot access 'test/dir/file1': Structure needs cleaning" and the dmesg show: "EXT4-fs error (device loop0): ext4_lookup:1626: inode #2049: comm ls: deleted inode referenced: 139" ext4_rename will create a special inode for whiteout and use this 'ino' to replace the source file's dir entry 'ino'. Once error happens latter(the error above was the ENOSPC return from ext4_add_entry in ext4_rename since all space has been consumed), the cleanup do drop the nlink for whiteout, but forget to restore 'ino' with source file. This will trigger the bug describle as above. Signed-off-by: yangerkun --- fs/ext4/namei.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index b17a082b7db1..90f7ebeb69c8 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3593,9 +3593,6 @@ static int ext4_setent(handle_t *handle, struct ext4_renament *ent, return retval2; } } - brelse(ent->bh); - ent->bh = NULL; - return retval; } @@ -3794,6 +3791,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, } } + old_file_type = old.de->file_type; if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) ext4_handle_sync(handle); @@ -3821,7 +3819,6 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, force_reread = (new.dir->i_ino == old.dir->i_ino && ext4_test_inode_flag(new.dir, EXT4_INODE_INLINE_DATA)); - old_file_type = old.de->file_type; if (whiteout) { /* * Do this before adding a new entry, so the old entry is sure @@ -3919,15 +3916,19 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, retval = 0; end_rename: - brelse(old.dir_bh); - brelse(old.bh); - brelse(new.bh); if (whiteout) { - if (retval) + if (retval) { + ext4_setent(handle, &old, + old.inode->i_ino, old_file_type); drop_nlink(whiteout); + } unlock_new_inode(whiteout); iput(whiteout); + } + brelse(old.dir_bh); + brelse(old.bh); + brelse(new.bh); if (handle) ext4_journal_stop(handle); return retval; -- 2.25.4