From nobody Sun Feb 8 18:18:31 2026 Received: from szxga07-in.huawei.com (szxga07-in.huawei.com [45.249.212.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA02513D269 for ; Wed, 10 Apr 2024 07:46:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.35 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735185; cv=none; b=bVlVtHLZywqU02HWHuPGbcI9BWkvCBSEinBd24rlxcSDlpMAXFstC7nJU4PzNn6YMhwzHR8o/EaItcmloikqxbv4zWaQ3TY9aKxGvW1yUbi0SaMSvfuBKH2yu+8+AbIFD7ag2IjJI1rZD+BubaqXLSUUo/0Lzev8Tp0mTC1iPNc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735185; c=relaxed/simple; bh=wTq3HYhinE4OWJZe3eZJodnF0j/EUVlXkR3PNU1l3dE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U9GbV2x2JuTsVKK6acMVbdUrrh3Cuipz3HZPlJd5CrozKfmg5iE75sUBVGyV90WdPdc+kv80p9uZK65UEEBSllj7p+jhL2TC+rEMQasTFC8RLAUCaLTDzrqiW836pRMUXbFDMpSj2X2wYyuFJG2g3FhQovcI0SLXgrGTDQhWm/8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4VDvvj2SvQz1RC5R; Wed, 10 Apr 2024 15:43:29 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id 72E8818001A; Wed, 10 Apr 2024 15:46:21 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:18 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 1/9] ubifs: Fix unattached xattr inode if powercut happens after deleting Date: Wed, 10 Apr 2024 15:37:43 +0800 Message-ID: <20240410073751.2522830-2-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" When powercut happens after deleting file, the xattr inode could be alone existing in TNC but its' xattr entry cannot be found in TNC. File inode and xattr inode are added into orphan list after deleting file, file inode's nlink is 0 but xattr inode's nlink is not 0 (PS: zero nlink xattr inode is written on disk in evicting process by ubifs_jnl_write_inode). So, following process could happen: 1. touch file 2. setxattr(file) 3. unlink file // inode(nlink=3D0), xattr inode(nlink=3D1) are added into orphan list 4. commit // write inode inum and xattr inum into orphan area 5. powercut 6. mount do_kill_orphans // inode(nlink=3D0) is deleted from TNC by ubifs_tnc_remove_range, // xattr entry is deleted too. // xattr inode(nlink=3D1) is not deleted from TNC Finally we could see following error while debugging UBIFS: UBIFS error (ubi0:0 pid 1093): dbg_check_filesystem [ubifs]: inode 66 nlink is 1, but calculated nlink is 0 UBIFS (ubi0:0): dump of the inode 66 sitting in LEB 12:2128 node_type 0 (inode node) group_type 1 (in node group) len 197 key (66, inode) size 37 nlink 1 flags 0x20 xattr_cnt 0 xattr_size 0 xattr_names 0 data len 37 Fix it by removing entire inode with it's xattrs while replaying orphan, just replace function ubifs_tnc_remove_range by ubifs_tnc_remove_ino. Fixes: ee1438ce5dc4 ("ubifs: Check link count of inodes when killing orphan= s.") Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D218661 Signed-off-by: Zhihao Cheng --- fs/ubifs/orphan.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 4909321d84cf..ddeb125e6930 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -691,12 +691,12 @@ static int do_kill_orphans(struct ubifs_info *c, stru= ct ubifs_scan_leb *sleb, =20 n =3D (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3; for (i =3D 0; i < n; i++) { - union ubifs_key key1, key2; + union ubifs_key key; =20 inum =3D le64_to_cpu(orph->inos[i]); =20 - ino_key_init(c, &key1, inum); - err =3D ubifs_tnc_lookup(c, &key1, ino); + ino_key_init(c, &key, inum); + err =3D ubifs_tnc_lookup(c, &key, ino); if (err && err !=3D -ENOENT) goto out_free; =20 @@ -708,10 +708,7 @@ static int do_kill_orphans(struct ubifs_info *c, struc= t ubifs_scan_leb *sleb, dbg_rcvry("deleting orphaned inode %lu", (unsigned long)inum); =20 - lowest_ino_key(c, &key1, inum); - highest_ino_key(c, &key2, inum); - - err =3D ubifs_tnc_remove_range(c, &key1, &key2); + err =3D ubifs_tnc_remove_ino(c, inum); if (err) goto out_ro; } --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C2F513D280 for ; Wed, 10 Apr 2024 07:46:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.191 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735186; cv=none; b=N5u1B5QfX4DWvLzAHkn2l6JZgAhiQ5xP2hOsJr7go1Hb9AUezWGcJ0Y6QEYnHzWWBZW7wKeQ5NpsShh93pWBTMY3cqQ0j5PzzLn4aFjj6Dg77txWxEf5yBQjFMo5ClFCkmCrD0QIFH/eso+UFGJweuXIXDu0UXM6OEjyPV60FMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735186; c=relaxed/simple; bh=kIFjLrt9m+zZNmywWL62UMLqVssCxPvAgJDMfY+QUeQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=UY/GwEpQCfkUhsOc3mDAyRpQfi3crJ6gU1HavEMgJkx06MzeMBhEZMtBYgdkuh7K9EFDr/xL2KLr2ayFgTH4qQTvaRr15sd9Lxb0ontiTByQS8wCUOCZSRg3vS0B+4s/L1P3J6A4oGSEuvn+bOAKldwbVMmqTtvOBxjBgb5mqaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.191 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4VDvy74PJPz1GGhr; Wed, 10 Apr 2024 15:45:35 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id 81DAA180064; Wed, 10 Apr 2024 15:46:21 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:19 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 2/9] ubifs: Don't add xattr inode into orphan area Date: Wed, 10 Apr 2024 15:37:44 +0800 Message-ID: <20240410073751.2522830-3-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" Now, the entire inode with its' xattrs are removed while replaying orphan nodes. There is no need to add xattr inodes into orphan area, which is based on the fact that xattr entries won't be cleared from disk before deleting xattr inodes, in another words, current logic can make sure that xattr inode be deleted in any cases even UBIFS not record xattr inode into orphan area. Let's looking for possible paths that could clear xattr entries from disk but leave the xattr inode on TNC: 1. unlink/tmpfile -> ubifs_jnl_update: inode(nlink=3D0) is written into bud LEB and added into orphan list, then: a. powercut: ubifs_tnc_remove_ino(xattr entry/inode can be found from TNC and being deleted) is invoked in replaying journal. b. commit + powercut: inode is written into orphan area, and ubifs_tnc_remove_ino is invoked in replaying orphan nodes. c. evicting + powercut: xattr inode(nlink=3D0) is written on disk, xattr is removed from TNC, gc could clear xattr entries from disk. ubifs_tnc_remove_ino will apply on inode and xattr inode in replaying journal, so lost xattr entries will make no influence. d. evicting + commit + powercut: xattr inode/entry are removed from index tree(on disk) by ubifs_jnl_write_inode, xattr inode is cleared from orphan area by ubifs_jnl_write_inode + commit. e. commit + evicting + powercut: inode is written into orphan area, then equivalent to c. 2. remove xattr -> ubifs_jnl_delete_xattr: xattr entry(inum=3D0) and xattr inode(nlink=3D0) is written into bud LEB, xattr entry/inode are removed from TNC, then: a. powercut: gc could clear xattr entries from disk, which won't affect deleting xattr entry from TNC. ubifs_tnc_remove_ino will apply on xattr inode in replaying journal, ubifs_tnc_remove_nm will apply on xattr entry in replaying journal. b. commit + powercut: xattr entry/inode are removed from index tree (on disk). Tracking xattr inode in orphan list is imported by commit 988bec41318f3f ("ubifs: orphan: Handle xattrs like files"), it aims to fix the similar problem described in commit 7959cf3a7506d4a ("ubifs: journal: Handle xattrs like files"). Actually, the problem only exist in journal case but not the orphan case. So, we can remove the orphan tracking for xattr inodes. Signed-off-by: Zhihao Cheng --- fs/ubifs/orphan.c | 85 ++++++++--------------------------------------- fs/ubifs/ubifs.h | 3 -- 2 files changed, 14 insertions(+), 74 deletions(-) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index ddeb125e6930..88fbf331ad8c 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -42,24 +42,30 @@ =20 static int dbg_check_orphans(struct ubifs_info *c); =20 -static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum, - struct ubifs_orphan *parent_orphan) +/** + * ubifs_add_orphan - add an orphan. + * @c: UBIFS file-system description object + * @inum: orphan inode number + * + * Add an orphan. This function is called when an inodes link count drops = to + * zero. + */ +int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) { struct ubifs_orphan *orphan, *o; struct rb_node **p, *parent =3D NULL; =20 orphan =3D kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS); if (!orphan) - return ERR_PTR(-ENOMEM); + return -ENOMEM; orphan->inum =3D inum; orphan->new =3D 1; - INIT_LIST_HEAD(&orphan->child_list); =20 spin_lock(&c->orphan_lock); if (c->tot_orphans >=3D c->max_orphans) { spin_unlock(&c->orphan_lock); kfree(orphan); - return ERR_PTR(-ENFILE); + return -ENFILE; } p =3D &c->orph_tree.rb_node; while (*p) { @@ -73,7 +79,7 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info = *c, ino_t inum, ubifs_err(c, "orphaned twice"); spin_unlock(&c->orphan_lock); kfree(orphan); - return ERR_PTR(-EINVAL); + return -EINVAL; } } c->tot_orphans +=3D 1; @@ -83,14 +89,9 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info= *c, ino_t inum, list_add_tail(&orphan->list, &c->orph_list); list_add_tail(&orphan->new_list, &c->orph_new); =20 - if (parent_orphan) { - list_add_tail(&orphan->child_list, - &parent_orphan->child_list); - } - spin_unlock(&c->orphan_lock); dbg_gen("ino %lu", (unsigned long)inum); - return orphan; + return 0; } =20 static struct ubifs_orphan *lookup_orphan(struct ubifs_info *c, ino_t inum) @@ -144,59 +145,6 @@ static void orphan_delete(struct ubifs_info *c, struct= ubifs_orphan *orph) __orphan_drop(c, orph); } =20 -/** - * ubifs_add_orphan - add an orphan. - * @c: UBIFS file-system description object - * @inum: orphan inode number - * - * Add an orphan. This function is called when an inodes link count drops = to - * zero. - */ -int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) -{ - int err =3D 0; - ino_t xattr_inum; - union ubifs_key key; - struct ubifs_dent_node *xent, *pxent =3D NULL; - struct fscrypt_name nm =3D {0}; - struct ubifs_orphan *xattr_orphan; - struct ubifs_orphan *orphan; - - orphan =3D orphan_add(c, inum, NULL); - if (IS_ERR(orphan)) - return PTR_ERR(orphan); - - lowest_xent_key(c, &key, inum); - while (1) { - xent =3D ubifs_tnc_next_ent(c, &key, &nm); - if (IS_ERR(xent)) { - err =3D PTR_ERR(xent); - if (err =3D=3D -ENOENT) - break; - kfree(pxent); - return err; - } - - fname_name(&nm) =3D xent->name; - fname_len(&nm) =3D le16_to_cpu(xent->nlen); - xattr_inum =3D le64_to_cpu(xent->inum); - - xattr_orphan =3D orphan_add(c, xattr_inum, orphan); - if (IS_ERR(xattr_orphan)) { - kfree(pxent); - kfree(xent); - return PTR_ERR(xattr_orphan); - } - - kfree(pxent); - pxent =3D xent; - key_read(c, &xent->key, &key); - } - kfree(pxent); - - return 0; -} - /** * ubifs_delete_orphan - delete an orphan. * @c: UBIFS file-system description object @@ -206,7 +154,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) */ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) { - struct ubifs_orphan *orph, *child_orph, *tmp_o; + struct ubifs_orphan *orph; =20 spin_lock(&c->orphan_lock); =20 @@ -219,11 +167,6 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t i= num) return; } =20 - list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list= ) { - list_del(&child_orph->child_list); - orphan_delete(c, child_orph); - } -=09 orphan_delete(c, orph); =20 spin_unlock(&c->orphan_lock); diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 7a7c62104f2b..3651a87e64b2 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -923,8 +923,6 @@ struct ubifs_budget_req { * @rb: rb-tree node of rb-tree of orphans sorted by inode number * @list: list head of list of orphans in order added * @new_list: list head of list of orphans added since the last commit - * @child_list: list of xattr children if this orphan hosts xattrs, list h= ead - * if this orphan is a xattr, not used otherwise. * @cnext: next orphan to commit * @dnext: next orphan to delete * @inum: inode number @@ -936,7 +934,6 @@ struct ubifs_orphan { struct rb_node rb; struct list_head list; struct list_head new_list; - struct list_head child_list; struct ubifs_orphan *cnext; struct ubifs_orphan *dnext; ino_t inum; --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A43713A405 for ; Wed, 10 Apr 2024 07:46:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.190 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735186; cv=none; b=tnzJSKrWIGtjdoSX1mefDwpAFxVXzWKSNBO+syFAyG0AnDjOmWwe26M0yITPr7nm451fwzkt9G8IoCPGOYDpk33h8h8aA7jRnVdKzk4IOoz1eReleELi8mPFd91F8ZRuP65DE209ZelkmueW9SSajKTb3xJFveeGRbaZPImxfOM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735186; c=relaxed/simple; bh=INjSlanK9XfjHFkoiXnaNur5yuaYf8vOZO36/sJ9GnA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=M0j7Mjd15s4pNaJR6X37NbtSpZ9NLpsWMvFWKSLe0dpCnG6HHR4/sDjsV17jMya4alEg4oNCPHaHHTs4Adbp8Ame+GEzy9Z5K0g/JnB5qPOyT5eDwjBRuuIqk8flN2W2LYu8R93DBddCnr6g1MjVMoHKute9M869gBfrT8W/9mQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.190 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4VDvvj5jXgz29dP9; Wed, 10 Apr 2024 15:43:29 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id 90AFA18001A; Wed, 10 Apr 2024 15:46:21 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:19 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 3/9] Revert "ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path" Date: Wed, 10 Apr 2024 15:37:45 +0800 Message-ID: <20240410073751.2522830-4-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" This reverts commit 6379b44cdcd67f5f5d986b73953e99700591edfa. Commit 1e022216dcd2 ("ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path") is applied again in commit 6379b44cdcd6 ("ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path"), which changed ubifs_mknod (It won't become a real problem). Just revert it. Signed-off-by: Zhihao Cheng --- fs/ubifs/dir.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index eac0fef801f1..551148de66cd 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1133,8 +1133,6 @@ static int ubifs_mknod(struct mnt_idmap *idmap, struc= t inode *dir, dir_ui->ui_size =3D dir->i_size; mutex_unlock(&dir_ui->ui_mutex); out_inode: - /* Free inode->i_link before inode is marked as bad. */ - fscrypt_free_inode(inode); make_bad_inode(inode); iput(inode); out_fname: --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga06-in.huawei.com (szxga06-in.huawei.com [45.249.212.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F6E513D2A2 for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735188; cv=none; b=YKeQq4ejzKSrc9s2r6IPg+7d2lTDlu4uX5Eo4JUBmnkOVtP2jEbfOGCDgHVUMCJC5HPNgDaGjfzzM9Je6ww2AwYFfMg8grL8rBnOrMKKNbXWWgURdO77mTv3daz8XDI7H8KUlN3AOe1T+ZnKNtmvk43UszrnkolqO70d/A9APKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735188; c=relaxed/simple; bh=eVjgfv6c6w9mMdyjEREivPKWmBPpimfOyfdSSj4rIqU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YIn+LA8zJbz14tMmWVjEyYcV5fJ3jrGkKBLFD+MEWs//n7S5QFUvHzw8BBA8z1OL6fEdDMLDLQcJ1JiQAfFYOkzp8IF4DKzQzDDVRnNVHNP8xdZOiP59JV/9rGBaLYC7Ov7AWfmM5whZv+GskANfmcZrMKSuzrjMEBCX6tu4TUs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4VDvy11JTjz21kfM; Wed, 10 Apr 2024 15:45:29 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id 89DDF18001A; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:20 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 4/9] ubifs: Remove insert_dead_orphan from replaying orphan process Date: Wed, 10 Apr 2024 15:37:46 +0800 Message-ID: <20240410073751.2522830-5-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" UBIFS will do commit at the end of mounting process(rw mode), dead orphans(added by insert_dead_orphan in replaying orphan) are deleted by ubifs_orphan_end_commit(). The only reason why dead orphans are added into orphan list is that old orpans may be lost when powercut happens in ubifs_orphan_end_commit(): ubifs_orphan_end_commit // TNC(updated by orphans) is not written yet if (c->cmt_orphans !=3D 0) commit_orphans consolidate // traverse orphan list write_orph_nodes // rewrite all orphans by ubifs_leb_change // If dead orphans are not in list, they will be lost when powercut // happens, then TNC won't be updated by old orphans in next mounting. Luckily, the condition 'c->cmt_orphans !=3D 0' will never be true in mounting process, there can't be new orphans added into orphan list before mounting returned, but commit will be done at the end of mounting. Signed-off-by: Zhihao Cheng --- fs/ubifs/orphan.c | 49 ----------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 88fbf331ad8c..6e843e8fc3db 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -513,51 +513,6 @@ int ubifs_clear_orphans(struct ubifs_info *c) return 0; } =20 -/** - * insert_dead_orphan - insert an orphan. - * @c: UBIFS file-system description object - * @inum: orphan inode number - * - * This function is a helper to the 'do_kill_orphans()' function. The orph= an - * must be kept until the next commit, so it is added to the rb-tree and t= he - * deletion list. - */ -static int insert_dead_orphan(struct ubifs_info *c, ino_t inum) -{ - struct ubifs_orphan *orphan, *o; - struct rb_node **p, *parent =3D NULL; - - orphan =3D kzalloc(sizeof(struct ubifs_orphan), GFP_KERNEL); - if (!orphan) - return -ENOMEM; - orphan->inum =3D inum; - - p =3D &c->orph_tree.rb_node; - while (*p) { - parent =3D *p; - o =3D rb_entry(parent, struct ubifs_orphan, rb); - if (inum < o->inum) - p =3D &(*p)->rb_left; - else if (inum > o->inum) - p =3D &(*p)->rb_right; - else { - /* Already added - no problem */ - kfree(orphan); - return 0; - } - } - c->tot_orphans +=3D 1; - rb_link_node(&orphan->rb, parent, p); - rb_insert_color(&orphan->rb, &c->orph_tree); - list_add_tail(&orphan->list, &c->orph_list); - orphan->del =3D 1; - orphan->dnext =3D c->orph_dnext; - c->orph_dnext =3D orphan; - dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum, - c->new_orphans, c->tot_orphans); - return 0; -} - /** * do_kill_orphans - remove orphan inodes from the index. * @c: UBIFS file-system description object @@ -655,10 +610,6 @@ static int do_kill_orphans(struct ubifs_info *c, struc= t ubifs_scan_leb *sleb, if (err) goto out_ro; } - - err =3D insert_dead_orphan(c, inum); - if (err) - goto out_free; } =20 *last_cmt_no =3D cmt_no; --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5979413D29B for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.190 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; cv=none; b=VGWrEJEXx0k3O2aee7BI1oqTU2buN+l1wDhHrtzlhq2b1O9Wd8F+iKrFbFUxtmg7KS1q8bDW6iFLswlaZWJwJOSrglmZEbAGyphtuF+6NsMU27+DLYObsEzFnwKMKMKYYHMbZao5EhSATt3+BsEFVLNaP3p/FUy/u+cvbY34Hqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; c=relaxed/simple; bh=9H9RAnJRufVKhGP+qju09AIocKKgwC7G55YIhfd+DRY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ChUc+ujAEG7WApapNiwSBQ1oTdlLky2EHeee/VdDwHJFwOeTsRw3jYz32lFWDXAKEUdaZXJfprRTdHZNL1+qf9XhO1pujUQUc+i/8x/E5QJEnhB6Dm4WvMeu2O058ObJdiWlgBAbrLbrM3Nq4GHNpBghJnmgH0nXjT+Anro4vwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.190 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4VDvvm5zVGz29khB; Wed, 10 Apr 2024 15:43:32 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id 99225180064; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:20 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 5/9] ubifs: Fix adding orphan entry twice for the same inode Date: Wed, 10 Apr 2024 15:37:47 +0800 Message-ID: <20240410073751.2522830-6-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" The tmpfile could be added into orphan list twice, first time is creation, the second time is removing after it is linked. The orphan entry could be added twice for tmpfile if following sequence is satisfied: ubifs_tmpfile ubifs_jnl_update ubifs_add_orphan // first time to add orphan entry P1 P2 ubifs_link do_commit ubifs_orphan_start_commit orphan->cmt =3D 1 ubifs_delete_orphan orphan_delete if (orph->cmt) orph->del =3D 1; // orphan entry is not deleted from tree return ubifs_unlink ubifs_jnl_update ubifs_add_orphan orphan_add // found old orphan entry, second time to add orphan entry ubifs_err(c, "orphaned twice") return -EINVAL // unlink failed! ubifs_orphan_end_commit erase_deleted // delete old orphan entry rb_erase(&orphan->rb, &c->orph_tree) Fix it by removing orphan entry from orphan tree in advance, rather than remove it from orphan tree in committing process. Fixes: 32fe905c17f0 ("ubifs: Fix O_TMPFILE corner case in ubifs_link()") Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D218672 Signed-off-by: Zhihao Cheng --- fs/ubifs/orphan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 6e843e8fc3db..37d206097112 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -136,6 +136,7 @@ static void orphan_delete(struct ubifs_info *c, struct = ubifs_orphan *orph) =20 if (orph->cmt) { orph->del =3D 1; + rb_erase(&orph->rb, &c->orph_tree); orph->dnext =3D c->orph_dnext; c->orph_dnext =3D orph; dbg_gen("delete later ino %lu", (unsigned long)orph->inum); @@ -461,7 +462,6 @@ static void erase_deleted(struct ubifs_info *c) dnext =3D orphan->dnext; ubifs_assert(c, !orphan->new); ubifs_assert(c, orphan->del); - rb_erase(&orphan->rb, &c->orph_tree); list_del(&orphan->list); c->tot_orphans -=3D 1; dbg_gen("deleting orphan ino %lu", (unsigned long)orphan->inum); --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5975B13D299 for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.190 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735188; cv=none; b=m0dJaSoCZmq+IBqhlRzAkCLQe5f/xyR0uzd38R2igCVqBz3VceSIk8sTu9hr4mrVSmCikFLsFs+fBvvWwee42XOq39omkfuwVNOZXTSZpq0muzDuQCj5XAnQ026YrbdKw4i6cmdHkOTf76aNHpfvkh1myF0G4eI49NOt9YjL59Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735188; c=relaxed/simple; bh=6enRpkCtRRhSMRNuro77x5hwv78gHH59C5x6cX07ujA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pWYYScdF0/ll7luBjMkwko1Gsf0nM0l8Ybje3yH08c4s/EdoaYcINgLTcsmRuz41xedM4gplP++2GV8qUk/yPHc1GNouBAiZIe7RZV9BUsoqxKUZ0/bFN5ATt8qSCTWNtoaHiHFaTFQ7ML5kWprbg7PP9fHQcpJFQSEAcO947nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.190 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4VDvvm6Jn4z29lMv; Wed, 10 Apr 2024 15:43:32 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id A876218001A; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:21 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 6/9] ubifs: Move ui->data initialization after initializing security Date: Wed, 10 Apr 2024 15:37:48 +0800 Message-ID: <20240410073751.2522830-7-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" Host inode and its' xattr will be written on disk after initializing security when creating symlink or dev, then the host inode and its dentry will be written again in ubifs_jnl_update. There is no need to write inode data in the security initialization pass, just move the ui->data initialization after initializing security. Signed-off-by: Zhihao Cheng --- fs/ubifs/dir.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 551148de66cd..848988f2b7dc 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1102,16 +1102,18 @@ static int ubifs_mknod(struct mnt_idmap *idmap, str= uct inode *dir, goto out_fname; } =20 + err =3D ubifs_init_security(dir, inode, &dentry->d_name); + if (err) { + kfree(dev); + goto out_inode; + } + init_special_inode(inode, inode->i_mode, rdev); inode->i_size =3D ubifs_inode(inode)->ui_size =3D devlen; ui =3D ubifs_inode(inode); ui->data =3D dev; ui->data_len =3D devlen; =20 - err =3D ubifs_init_security(dir, inode, &dentry->d_name); - if (err) - goto out_inode; - mutex_lock(&dir_ui->ui_mutex); dir->i_size +=3D sz_change; dir_ui->ui_size =3D dir->i_size; @@ -1184,6 +1186,10 @@ static int ubifs_symlink(struct mnt_idmap *idmap, st= ruct inode *dir, goto out_fname; } =20 + err =3D ubifs_init_security(dir, inode, &dentry->d_name); + if (err) + goto out_inode; + ui =3D ubifs_inode(inode); ui->data =3D kmalloc(disk_link.len, GFP_NOFS); if (!ui->data) { @@ -1209,10 +1215,6 @@ static int ubifs_symlink(struct mnt_idmap *idmap, st= ruct inode *dir, ui->data_len =3D disk_link.len - 1; inode->i_size =3D ubifs_inode(inode)->ui_size =3D disk_link.len - 1; =20 - err =3D ubifs_init_security(dir, inode, &dentry->d_name); - if (err) - goto out_inode; - mutex_lock(&dir_ui->ui_mutex); dir->i_size +=3D sz_change; dir_ui->ui_size =3D dir->i_size; --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga06-in.huawei.com (szxga06-in.huawei.com [45.249.212.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEBAD13D2AE for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; cv=none; b=UTZZuYr9AGdjCv791myB8KERrjv7Erx8Z5UF/gbJPLbEBuZk33miwfRUfi+QzYG2VaFfYHbl7X3h0Fte3gq2iKQnDZJDFLhDx8SOhkJ74mxsBD2kS0Fg6rwFYJrd/NMR+5pV7v5997fDdR6NMO7cYG86L2TKStM7PF61xAIRck4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; c=relaxed/simple; bh=54Bb4DcMPFl0NRDzOR8HV3jHx8WEO18mgMVk0qwy8U8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=drGphEkLBjuHmvI98CNcN4VFMoli3dw1a2rz7DiyjLQLuCPCBrIsRWFNPypOUXanqx70I37ziuRUDGECYFQHRuR8NXT0mZ+1qXjY6yRMDCyKRvuRU7xjwrzAr7HsXivxQ2x9Me3N6vYEjQBzsifpRw109RshZeTCdPcvv6e2npQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4VDvy12drVz21kfQ; Wed, 10 Apr 2024 15:45:29 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id B88D7180064; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:21 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 7/9] ubifs: Fix space leak when powercut happens in linking tmpfile Date: Wed, 10 Apr 2024 15:37:49 +0800 Message-ID: <20240410073751.2522830-8-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" There is a potential space leak problem when powercut happens in linking tmpfile, in which case, inode node (with nlink=3D0) and its' data nodes can be found from tnc (on flash), but there are no dentries related to the inode, so the file is invisible but takes free space. Detailed process is shown as: ubifs_tmpfile ubifs_jnl_update // Add bud A into log area ubifs_add_orphan // Add inode into orphan list P1 P2 ubifs_link ubifs_delete_orphan // Delete inode from orphan list, then inode won't // be written into orphan area, there is no chance // to delete inode by replaying orphan. commit // bud A won't be replayed in next mounting >> powercut << ubifs_jnl_update // Link inode to dentry The root cause is that orphan entry deletion and journal writing(for link) are interrupted by commit, which makes the two operations are not atomic. Fix it by doing ubifs_delete_orphan under the protection of c->commit_sem within ubifs_jnl_update. This is also a preparation to support all creating new files by orphan inode. v1 is https://lore.kernel.org/linux-mtd/20200701093227.674945-1-chengzhihao= 1@huawei.com/ Fixes: 32fe905c17f0 ("ubifs: Fix O_TMPFILE corner case in ubifs_link()") Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D208405 Signed-off-by: Zhihao Cheng --- fs/ubifs/dir.c | 22 ++++++++-------------- fs/ubifs/journal.c | 6 +++++- fs/ubifs/ubifs.h | 2 +- fs/ubifs/xattr.c | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 848988f2b7dc..fe16443243ab 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -325,7 +325,7 @@ static int ubifs_create(struct mnt_idmap *idmap, struct= inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); @@ -479,7 +479,7 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struc= t inode *dir, mutex_unlock(&ui->ui_mutex); =20 lock_2_inodes(dir, inode); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0); if (err) goto out_cancel; unlock_2_inodes(dir, inode); @@ -760,10 +760,6 @@ static int ubifs_link(struct dentry *old_dentry, struc= t inode *dir, =20 lock_2_inodes(dir, inode); =20 - /* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */ - if (inode->i_nlink =3D=3D 0) - ubifs_delete_orphan(c, inode->i_ino); - inc_nlink(inode); ihold(inode); inode_set_ctime_current(inode); @@ -771,7 +767,7 @@ static int ubifs_link(struct dentry *old_dentry, struct= inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, inode->i_nlink =3D=3D = 1); if (err) goto out_cancel; unlock_2_inodes(dir, inode); @@ -785,8 +781,6 @@ static int ubifs_link(struct dentry *old_dentry, struct= inode *dir, dir->i_size -=3D sz_change; dir_ui->ui_size =3D dir->i_size; drop_nlink(inode); - if (inode->i_nlink =3D=3D 0) - ubifs_add_orphan(c, inode->i_ino); unlock_2_inodes(dir, inode); ubifs_release_budget(c, &req); iput(inode); @@ -846,7 +840,7 @@ static int ubifs_unlink(struct inode *dir, struct dentr= y *dentry) dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0); if (err) goto out_cancel; unlock_2_inodes(dir, inode); @@ -950,7 +944,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry= *dentry) dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0); if (err) goto out_cancel; unlock_2_inodes(dir, inode); @@ -1025,7 +1019,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struc= t inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); if (err) { ubifs_err(c, "cannot create directory, error %d", err); goto out_cancel; @@ -1119,7 +1113,7 @@ static int ubifs_mknod(struct mnt_idmap *idmap, struc= t inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); @@ -1220,7 +1214,7 @@ static int ubifs_symlink(struct mnt_idmap *idmap, str= uct inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index f997a85bcdce..3178020ea3c1 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -643,6 +643,7 @@ static void set_dent_cookie(struct ubifs_info *c, struc= t ubifs_dent_node *dent) * @inode: inode to update * @deletion: indicates a directory entry deletion i.e unlink or rmdir * @xent: non-zero if the directory entry is an extended attribute entry + * @delete_orphan: indicates an orphan entry deletion for @inode * * This function updates an inode by writing a directory entry (or extended * attribute entry), the inode itself, and the parent directory inode (or = the @@ -664,7 +665,7 @@ static void set_dent_cookie(struct ubifs_info *c, struc= t ubifs_dent_node *dent) */ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, const struct fscrypt_name *nm, const struct inode *inode, - int deletion, int xent) + int deletion, int xent, int delete_orphan) { int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added =3D 0; int aligned_dlen, aligned_ilen, sync =3D IS_DIRSYNC(dir); @@ -806,6 +807,9 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct= inode *dir, if (err) goto out_ro; =20 + if (delete_orphan) + ubifs_delete_orphan(c, inode->i_ino); + finish_reservation(c); spin_lock(&ui->ui_lock); ui->synced_i_size =3D ui->ui_size; diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 3651a87e64b2..14d28c5456f4 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1800,7 +1800,7 @@ int ubifs_consolidate_log(struct ubifs_info *c); /* journal.c */ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, const struct fscrypt_name *nm, const struct inode *inode, - int deletion, int xent); + int deletion, int xent, int delete_orphan); int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, const union ubifs_key *key, const void *buf, int len); int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode); diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 0847db521984..f734588b224a 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -149,7 +149,7 @@ static int create_xattr(struct ubifs_info *c, struct in= ode *host, if (strcmp(fname_name(nm), UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) =3D=3D 0) host_ui->flags |=3D UBIFS_CRYPT_FL; =20 - err =3D ubifs_jnl_update(c, host, nm, inode, 0, 1); + err =3D ubifs_jnl_update(c, host, nm, inode, 0, 1, 0); if (err) goto out_cancel; ubifs_set_inode_flags(host); --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga07-in.huawei.com (szxga07-in.huawei.com [45.249.212.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1451C13D27E for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.35 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; cv=none; b=HlU1bFapsGHoPKZaSyEEIeQh9PaAh7PR6XKIiCkDjwihTH8DJJZ3B9dlkDLISs2xVQcG9KyNQCr/lvweFZBFKJrVh87LQ9fm90cigd4peaAwv6xuqXEwUsYqwGgdDSuVbfctWDZ7oXdlUK3B2rXg5DMsFHc13tBa8//POa44+Sw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; c=relaxed/simple; bh=CIF8fMtmNhLMxKJKOIAt7wipMYrDrHqmLF5RHllO3Lc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VC8V9/8aTxFbpEy5oSKBEcOONjdswgtrSMM4iiG+shWySXPcpZn1r2Wt/8QKEFvTI0ft0BQd8Tp9YxSACkP1VXIvm+xD41YXoWn6Ygxx4q0O5pLUhFTnognt1LJ6da54x8WEWDxzkFsMUUhiPzLQ0mu47yAh5FY/Y89QrxnbgBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.35 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga07-in.huawei.com (SkyGuard) with ESMTP id 4VDvvm4zTJz1RC8Q; Wed, 10 Apr 2024 15:43:32 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id C804218001A; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:22 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 8/9] ubifs: Fix unattached inode when powercut happens in creating Date: Wed, 10 Apr 2024 15:37:50 +0800 Message-ID: <20240410073751.2522830-9-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" For selinux or encryption scenarios, UBIFS could become inconsistent while creating new files in powercut case. Encryption/selinux related xattrs will be created before creating file dentry, which makes creation process is not atomic, details are shown as: Encryption case: ubifs_create ubifs_new_inode fscrypt_set_context ubifs_xattr_set create_xattr ubifs_jnl_update // Disk: xentry xinode inode(LAST_OF_NODE_GROUP) >> power cut << ubifs_jnl_update // Disk: dentry inode parent_inode(LAST_OF_NODE_GROUP) Selinux case: ubifs_create ubifs_new_inode ubifs_init_security security_inode_init_security ubifs_xattr_set create_xattr ubifs_jnl_update // Disk: xentry xinode inode(LAST_OF_NODE_GROUP) >> power cut << ubifs_jnl_update // Disk: dentry inode parent_inode(LAST_OF_NODE_GROUP) Above process will make chk_fs failed in next mounting: UBIFS error (ubi0:0 pid 7995): dbg_check_filesystem [ubifs]: inode 66 nlink is 1, but calculated nlink is 0 Fix it by allocating orphan inode for each non-xattr file creation, then removing orphan list in journal writing process, which ensures that both xattr and dentry be effective in atomic when powercut happens. Fixes: d7f0b70d30ff ("UBIFS: Add security.* XATTR support for the UBIFS") Fixes: d475a507457b ("ubifs: Add skeleton for fscrypto") Link: https://bugzilla.kernel.org/show_bug.cgi?id=3D218309 Suggested-by: Zhang Yi Signed-off-by: Zhihao Cheng --- fs/ubifs/dir.c | 59 +++++++++++++++++++++++++++++++--------------- fs/ubifs/journal.c | 14 +++++++---- fs/ubifs/ubifs.h | 4 ++-- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index fe16443243ab..c77ea57fe696 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -71,8 +71,13 @@ static int inherit_flags(const struct inode *dir, umode_= t mode) * @is_xattr: whether the inode is xattr inode * * This function finds an unused inode number, allocates new inode and - * initializes it. Returns new inode in case of success and an error code = in - * case of failure. + * initializes it. Non-xattr new inode may be written with xattrs(selinux/ + * encryption) before writing dentry, which could cause inconsistent probl= em + * when powercut happens between two operations. To deal with it, non-xattr + * new inode is initialized with zero-nlink and added into orphan list, ca= ller + * should make sure that inode is relinked later, and make sure that orphan + * removing and journal writing into an committing atomic operation. Retur= ns + * new inode in case of success and an error code in case of failure. */ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, umode_t mode, bool is_xattr) @@ -163,9 +168,25 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, st= ruct inode *dir, ui->creat_sqnum =3D ++c->max_sqnum; spin_unlock(&c->cnt_lock); =20 + if (!is_xattr) { + set_nlink(inode, 0); + err =3D ubifs_add_orphan(c, inode->i_ino); + if (err) { + ubifs_err(c, "ubifs_add_orphan failed: %i", err); + goto out_iput; + } + down_read(&c->commit_sem); + ui->del_cmtno =3D c->cmt_no; + up_read(&c->commit_sem); + } + if (encrypted) { err =3D fscrypt_set_context(inode, NULL); if (err) { + if (!is_xattr) { + set_nlink(inode, 1); + ubifs_delete_orphan(c, inode->i_ino); + } ubifs_err(c, "fscrypt_set_context failed: %i", err); goto out_iput; } @@ -320,12 +341,13 @@ static int ubifs_create(struct mnt_idmap *idmap, stru= ct inode *dir, if (err) goto out_inode; =20 + set_nlink(inode, 1); mutex_lock(&dir_ui->ui_mutex); dir->i_size +=3D sz_change; dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); @@ -340,8 +362,8 @@ static int ubifs_create(struct mnt_idmap *idmap, struct= inode *dir, dir->i_size -=3D sz_change; dir_ui->ui_size =3D dir->i_size; mutex_unlock(&dir_ui->ui_mutex); + set_nlink(inode, 0); out_inode: - make_bad_inode(inode); iput(inode); out_fname: fscrypt_free_filename(&nm); @@ -386,7 +408,6 @@ static struct inode *create_whiteout(struct inode *dir,= struct dentry *dentry) return inode; =20 out_inode: - make_bad_inode(inode); iput(inode); out_free: ubifs_err(c, "cannot create whiteout file, error %d", err); @@ -470,6 +491,7 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struc= t inode *dir, if (err) goto out_inode; =20 + set_nlink(inode, 1); mutex_lock(&ui->ui_mutex); insert_inode_hash(inode); d_tmpfile(file, inode); @@ -479,7 +501,7 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struc= t inode *dir, mutex_unlock(&ui->ui_mutex); =20 lock_2_inodes(dir, inode); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 1); if (err) goto out_cancel; unlock_2_inodes(dir, inode); @@ -492,7 +514,6 @@ static int ubifs_tmpfile(struct mnt_idmap *idmap, struc= t inode *dir, out_cancel: unlock_2_inodes(dir, inode); out_inode: - make_bad_inode(inode); if (!instantiated) iput(inode); out_budg: @@ -1011,6 +1032,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struc= t inode *dir, if (err) goto out_inode; =20 + set_nlink(inode, 1); mutex_lock(&dir_ui->ui_mutex); insert_inode_hash(inode); inc_nlink(inode); @@ -1019,7 +1041,7 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struc= t inode *dir, dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1); if (err) { ubifs_err(c, "cannot create directory, error %d", err); goto out_cancel; @@ -1036,8 +1058,8 @@ static int ubifs_mkdir(struct mnt_idmap *idmap, struc= t inode *dir, dir_ui->ui_size =3D dir->i_size; drop_nlink(dir); mutex_unlock(&dir_ui->ui_mutex); + set_nlink(inode, 0); out_inode: - make_bad_inode(inode); iput(inode); out_fname: fscrypt_free_filename(&nm); @@ -1107,13 +1129,14 @@ static int ubifs_mknod(struct mnt_idmap *idmap, str= uct inode *dir, ui =3D ubifs_inode(inode); ui->data =3D dev; ui->data_len =3D devlen; + set_nlink(inode, 1); =20 mutex_lock(&dir_ui->ui_mutex); dir->i_size +=3D sz_change; dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); @@ -1128,8 +1151,8 @@ static int ubifs_mknod(struct mnt_idmap *idmap, struc= t inode *dir, dir->i_size -=3D sz_change; dir_ui->ui_size =3D dir->i_size; mutex_unlock(&dir_ui->ui_mutex); + set_nlink(inode, 0); out_inode: - make_bad_inode(inode); iput(inode); out_fname: fscrypt_free_filename(&nm); @@ -1208,13 +1231,14 @@ static int ubifs_symlink(struct mnt_idmap *idmap, s= truct inode *dir, */ ui->data_len =3D disk_link.len - 1; inode->i_size =3D ubifs_inode(inode)->ui_size =3D disk_link.len - 1; + set_nlink(inode, 1); =20 mutex_lock(&dir_ui->ui_mutex); dir->i_size +=3D sz_change; dir_ui->ui_size =3D dir->i_size; inode_set_mtime_to_ts(dir, inode_set_ctime_to_ts(dir, inode_get_ctime(inode))); - err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 0); + err =3D ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1); if (err) goto out_cancel; mutex_unlock(&dir_ui->ui_mutex); @@ -1228,10 +1252,10 @@ static int ubifs_symlink(struct mnt_idmap *idmap, s= truct inode *dir, dir->i_size -=3D sz_change; dir_ui->ui_size =3D dir->i_size; mutex_unlock(&dir_ui->ui_mutex); + set_nlink(inode, 0); out_inode: /* Free inode->i_link before inode is marked as bad. */ fscrypt_free_inode(inode); - make_bad_inode(inode); iput(inode); out_fname: fscrypt_free_filename(&nm); @@ -1399,14 +1423,10 @@ static int do_rename(struct inode *old_dir, struct = dentry *old_dentry, */ err =3D ubifs_budget_space(c, &wht_req); if (err) { - /* - * Whiteout inode can not be written on flash by - * ubifs_jnl_write_inode(), because it's neither - * dirty nor zero-nlink. - */ iput(whiteout); goto out_release; } + set_nlink(whiteout, 1); =20 /* Add the old_dentry size to the old_dir size. */ old_sz -=3D CALC_DENT_SIZE(fname_len(&old_nm)); @@ -1485,7 +1505,7 @@ static int do_rename(struct inode *old_dir, struct de= ntry *old_dentry, } =20 err =3D ubifs_jnl_rename(c, old_dir, old_inode, &old_nm, new_dir, - new_inode, &new_nm, whiteout, sync); + new_inode, &new_nm, whiteout, sync, !!whiteout); if (err) goto out_cancel; =20 @@ -1538,6 +1558,7 @@ static int do_rename(struct inode *old_dir, struct de= ntry *old_dentry, unlock_4_inodes(old_dir, new_dir, new_inode, whiteout); if (whiteout) { ubifs_release_budget(c, &wht_req); + set_nlink(whiteout, 0); iput(whiteout); } out_release: diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 3178020ea3c1..4a35f9e8f668 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c @@ -643,7 +643,7 @@ static void set_dent_cookie(struct ubifs_info *c, struc= t ubifs_dent_node *dent) * @inode: inode to update * @deletion: indicates a directory entry deletion i.e unlink or rmdir * @xent: non-zero if the directory entry is an extended attribute entry - * @delete_orphan: indicates an orphan entry deletion for @inode + * @in_orphan: indicates whether the @inode is in orphan list * * This function updates an inode by writing a directory entry (or extended * attribute entry), the inode itself, and the parent directory inode (or = the @@ -665,7 +665,7 @@ static void set_dent_cookie(struct ubifs_info *c, struc= t ubifs_dent_node *dent) */ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, const struct fscrypt_name *nm, const struct inode *inode, - int deletion, int xent, int delete_orphan) + int deletion, int xent, int in_orphan) { int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added =3D 0; int aligned_dlen, aligned_ilen, sync =3D IS_DIRSYNC(dir); @@ -751,7 +751,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct= inode *dir, if (err) goto out_release; =20 - if (last_reference) { + if (last_reference && !in_orphan) { err =3D ubifs_add_orphan(c, inode->i_ino); if (err) { release_head(c, BASEHD); @@ -807,7 +807,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct= inode *dir, if (err) goto out_ro; =20 - if (delete_orphan) + if (in_orphan && inode->i_nlink) ubifs_delete_orphan(c, inode->i_ino); =20 finish_reservation(c); @@ -1340,6 +1340,7 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const str= uct inode *fst_dir, * @new_nm: new name of the new directory entry * @whiteout: whiteout inode * @sync: non-zero if the write-buffer has to be synchronized + * @delete_orphan: indicates an orphan entry deletion for @whiteout * * This function implements the re-name operation which may involve writin= g up * to 4 inodes(new inode, whiteout inode, old and new parent directory ino= des) @@ -1352,7 +1353,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const stru= ct inode *old_dir, const struct inode *new_dir, const struct inode *new_inode, const struct fscrypt_name *new_nm, - const struct inode *whiteout, int sync) + const struct inode *whiteout, int sync, int delete_orphan) { void *p; union ubifs_key key; @@ -1569,6 +1570,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const stru= ct inode *old_dir, goto out_ro; } =20 + if (delete_orphan) + ubifs_delete_orphan(c, whiteout->i_ino); + finish_reservation(c); if (new_inode) { mark_inode_clean(c, new_ui); diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 14d28c5456f4..12216a159227 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1800,7 +1800,7 @@ int ubifs_consolidate_log(struct ubifs_info *c); /* journal.c */ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, const struct fscrypt_name *nm, const struct inode *inode, - int deletion, int xent, int delete_orphan); + int deletion, int xent, int in_orphan); int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, const union ubifs_key *key, const void *buf, int len); int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode); @@ -1817,7 +1817,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const stru= ct inode *old_dir, const struct inode *new_dir, const struct inode *new_inode, const struct fscrypt_name *new_nm, - const struct inode *whiteout, int sync); + const struct inode *whiteout, int sync, int delete_orphan); int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, loff_t old_size, loff_t new_size); int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, --=20 2.39.2 From nobody Sun Feb 8 18:18:31 2026 Received: from szxga06-in.huawei.com (szxga06-in.huawei.com [45.249.212.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEB1A13D2AA for ; Wed, 10 Apr 2024 07:46:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; cv=none; b=LXtDdko8sBmwR7K7Zqq+Vp5P/0I7fY5fRI+rqjlq+qpgjE84Ilz5iCu0F7h9nlXxEhjCkQYoYwTYIPZ2/uGYWz5mLZGbM9k9i+qqhmls0lMuSu7+JHXUopsO4/7R1qs/+GdvgofpjUUbYHKpGtaetmufZE80jaZoeJD33Ez6/a4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712735189; c=relaxed/simple; bh=G4+x/gzMfAHDc0HnV9EsKR+APIrtrrMs/uq4LgHmv8M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RxwpWo6LYktVAqhBRM2yN0/yYQYVe8N7efonh11p9vM8o3lUYSNiKlNWd4ukR2qvcgWKC+2VuV3qMKLqSH1UYnhPLTnWgbDuYteEYfUZw7gOq1XMovltxL4EbnpArzt/shMTXGnlrwLr8uBzVNMSetxwn158BfXgkJOGa0vy9lo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.163]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4VDvy13XFZz21kfS; Wed, 10 Apr 2024 15:45:29 +0800 (CST) Received: from kwepemm600013.china.huawei.com (unknown [7.193.23.68]) by mail.maildlp.com (Postfix) with ESMTPS id D729F180063; Wed, 10 Apr 2024 15:46:24 +0800 (CST) Received: from huawei.com (10.175.104.67) by kwepemm600013.china.huawei.com (7.193.23.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Wed, 10 Apr 2024 15:46:22 +0800 From: Zhihao Cheng To: CC: , , Subject: [PATCH 9/9] ubifs: dbg_orphan_check: Fix missed key type checking Date: Wed, 10 Apr 2024 15:37:51 +0800 Message-ID: <20240410073751.2522830-10-chengzhihao1@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240410073751.2522830-1-chengzhihao1@huawei.com> References: <20240410073751.2522830-1-chengzhihao1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To kwepemm600013.china.huawei.com (7.193.23.68) Content-Type: text/plain; charset="utf-8" When selinux/encryption is enabled, xattr entry node is added into TNC before host inode when creating new file. So it is possible to find xattr entry without host inode from TNC. Orphan debug checking is called by ubifs_orphan_end_commit(), at that time, the commit semaphore is already unlock, so the new creation won't be blocked. Fixes: d7f0b70d30ff ("UBIFS: Add security.* XATTR support for the UBIFS") Fixes: d475a507457b ("ubifs: Add skeleton for fscrypto") Signed-off-by: Zhihao Cheng --- fs/ubifs/orphan.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 37d206097112..fb957d963ba6 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -816,8 +816,12 @@ static int dbg_orphan_check(struct ubifs_info *c, stru= ct ubifs_zbranch *zbr, =20 inum =3D key_inum(c, &zbr->key); if (inum !=3D ci->last_ino) { - /* Lowest node type is the inode node, so it comes first */ - if (key_type(c, &zbr->key) !=3D UBIFS_INO_KEY) + /* + * Lowest node type is the inode node or xattr entry(when + * selinux/encryption is enabled), so it comes first + */ + if (key_type(c, &zbr->key) !=3D UBIFS_INO_KEY && + key_type(c, &zbr->key) !=3D UBIFS_XENT_KEY) ubifs_err(c, "found orphan node ino %lu, type %d", (unsigned long)inum, key_type(c, &zbr->key)); ci->last_ino =3D inum; --=20 2.39.2