mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
ubifs: Fix adding orphan entry twice for the same inode
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 = 1
ubifs_delete_orphan
orphan_delete
if (orph->cmt)
orph->del = 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: 32fe905c17 ("ubifs: Fix O_TMPFILE corner case in ubifs_link()")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218672
Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
This commit is contained in:
parent
6376d7503b
commit
7efc34b53b
|
|
@ -136,6 +136,7 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
|
|||
|
||||
if (orph->cmt) {
|
||||
orph->del = 1;
|
||||
rb_erase(&orph->rb, &c->orph_tree);
|
||||
orph->dnext = c->orph_dnext;
|
||||
c->orph_dnext = orph;
|
||||
dbg_gen("delete later ino %lu", (unsigned long)orph->inum);
|
||||
|
|
@ -461,7 +462,6 @@ static void erase_deleted(struct ubifs_info *c)
|
|||
dnext = 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 -= 1;
|
||||
dbg_gen("deleting orphan ino %lu", (unsigned long)orphan->inum);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user