• Richard Weinberger's avatar
    ubifs: Handle re-linking of inodes correctly while recovery · ed0d232d
    Richard Weinberger authored
    commit e58725d51fa8da9133f3f1c54170aa2e43056b91 upstream.
    
    UBIFS's recovery code strictly assumes that a deleted inode will never
    come back, therefore it removes all data which belongs to that inode
    as soon it faces an inode with link count 0 in the replay list.
    Before O_TMPFILE this assumption was perfectly fine. With O_TMPFILE
    it can lead to data loss upon a power-cut.
    
    Consider a journal with entries like:
    0: inode X (nlink = 0) /* O_TMPFILE was created */
    1: data for inode X /* Someone writes to the temp file */
    2: inode X (nlink = 0) /* inode was changed, xattr, chmod, … */
    3: inode X (nlink = 1) /* inode was re-linked via linkat() */
    
    Upon replay of entry #2 UBIFS will drop all data that belongs to inode X,
    this will lead to an empty file after mounting.
    
    As solution for this problem, scan the replay list for a re-link entry
    before dropping data.
    
    Fixes: 474b9370 ("ubifs: Implement O_TMPFILE")
    Cc: stable@vger.kernel.org # 4.9-4.18
    Cc: Russell Senior <russell@personaltelco.net>
    Cc: Rafał Miłecki <zajec5@gmail.com>
    Reported-by: 's avatarRussell Senior <russell@personaltelco.net>
    Reported-by: 's avatarRafał Miłecki <zajec5@gmail.com>
    Tested-by: 's avatarRafał Miłecki <rafal@milecki.pl>
    Signed-off-by: Richard Weinberger's avatarRichard Weinberger <richard@nod.at>
    [rmilecki: update ubifs_assert() calls to compile with 4.18 and older]
    Signed-off-by: 's avatarRafał Miłecki <rafal@milecki.pl>
    (cherry picked from commit e58725d51fa8da9133f3f1c54170aa2e43056b91)
    Signed-off-by: 's avatarSasha Levin <sashal@kernel.org>
    ed0d232d
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
budget.c Loading commit data...
commit.c Loading commit data...
compress.c Loading commit data...
crypto.c Loading commit data...
debug.c Loading commit data...
debug.h Loading commit data...
dir.c Loading commit data...
file.c Loading commit data...
find.c Loading commit data...
gc.c Loading commit data...
io.c Loading commit data...
ioctl.c Loading commit data...
journal.c Loading commit data...
key.h Loading commit data...
log.c Loading commit data...
lprops.c Loading commit data...
lpt.c Loading commit data...
lpt_commit.c Loading commit data...
master.c Loading commit data...
misc.c Loading commit data...
misc.h Loading commit data...
orphan.c Loading commit data...
recovery.c Loading commit data...
replay.c Loading commit data...
sb.c Loading commit data...
scan.c Loading commit data...
shrinker.c Loading commit data...
super.c Loading commit data...
tnc.c Loading commit data...
tnc_commit.c Loading commit data...
tnc_misc.c Loading commit data...
ubifs-media.h Loading commit data...
ubifs.h Loading commit data...
xattr.c Loading commit data...