summaryrefslogtreecommitdiff
path: root/fs/ubifs
diff options
context:
space:
mode:
authorGuochun Mao <guochun.mao@mediatek.com>2021-03-16 11:52:14 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-05-11 15:47:33 +0300
commit50b0c0c3385d80ee23173dc1d9fd82803ed45aac (patch)
treec0491bd60cadfe3c2f2940058faa72c272a6f71f /fs/ubifs
parent5a876a46d7b7fc112d7cb2bff460612d7f0ed4b5 (diff)
downloadlinux-50b0c0c3385d80ee23173dc1d9fd82803ed45aac.tar.xz
ubifs: Only check replay with inode type to judge if inode linked
commit 3e903315790baf4a966436e7f32e9c97864570ac upstream. Conside the following case, it just write a big file into flash, when complete writing, delete the file, and then power off promptly. Next time power on, we'll get a replay list like: ... LEB 1105:211344 len 4144 deletion 0 sqnum 428783 key type 1 inode 80 LEB 15:233544 len 160 deletion 1 sqnum 428785 key type 0 inode 80 LEB 1105:215488 len 4144 deletion 0 sqnum 428787 key type 1 inode 80 ... In the replay list, data nodes' deletion are 0, and the inode node's deletion is 1. In current logic, the file's dentry will be removed, but inode and the flash space it occupied will be reserved. User will see that much free space been disappeared. We only need to check the deletion value of the following inode type node of the replay entry. Fixes: e58725d51fa8 ("ubifs: Handle re-linking of inodes correctly while recovery") Cc: stable@vger.kernel.org Signed-off-by: Guochun Mao <guochun.mao@mediatek.com> Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/replay.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 9a151a1f5e26..1c6fc99fca30 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -223,7 +223,8 @@ static bool inode_still_linked(struct ubifs_info *c, struct replay_entry *rino)
*/
list_for_each_entry_reverse(r, &c->replay_list, list) {
ubifs_assert(c, r->sqnum >= rino->sqnum);
- if (key_inum(c, &r->key) == key_inum(c, &rino->key))
+ if (key_inum(c, &r->key) == key_inum(c, &rino->key) &&
+ key_type(c, &r->key) == UBIFS_INO_KEY)
return r->deletion == 0;
}