Patch "ext4: work around deleting a file with i_nlink == 0 safely" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    ext4: work around deleting a file with i_nlink == 0 safely

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     ext4-work-around-deleting-a-file-with-i_nlink-0-safe.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit f32ff790b2fa9807a541020c841beced452ab4b1
Author: Theodore Ts'o <tytso@xxxxxxx>
Date:   Mon Nov 11 22:18:13 2019 -0500

    ext4: work around deleting a file with i_nlink == 0 safely
    
    [ Upstream commit c7df4a1ecb8579838ec8c56b2bb6a6716e974f37 ]
    
    If the file system is corrupted such that a file's i_links_count is
    too small, then it's possible that when unlinking that file, i_nlink
    will already be zero.  Previously we were working around this kind of
    corruption by forcing i_nlink to one; but we were doing this before
    trying to delete the directory entry --- and if the file system is
    corrupted enough that ext4_delete_entry() fails, then we exit with
    i_nlink elevated, and this causes the orphan inode list handling to be
    FUBAR'ed, such that when we unmount the file system, the orphan inode
    list can get corrupted.
    
    A better way to fix this is to simply skip trying to call drop_nlink()
    if i_nlink is already zero, thus moving the check to the place where
    it makes the most sense.
    
    https://bugzilla.kernel.org/show_bug.cgi?id=205433
    
    Link: https://lore.kernel.org/r/20191112032903.8828-1-tytso@xxxxxxx
    Signed-off-by: Theodore Ts'o <tytso@xxxxxxx>
    Cc: stable@xxxxxxxxxx
    Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index aa08e129149d..712bf332e394 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3040,18 +3040,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 	if (IS_DIRSYNC(dir))
 		ext4_handle_sync(handle);
 
-	if (inode->i_nlink == 0) {
-		ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
-				   dentry->d_name.len, dentry->d_name.name);
-		set_nlink(inode, 1);
-	}
 	retval = ext4_delete_entry(handle, dir, de, bh);
 	if (retval)
 		goto end_unlink;
 	dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
 	ext4_update_dx_flag(dir);
 	ext4_mark_inode_dirty(handle, dir);
-	drop_nlink(inode);
+	if (inode->i_nlink == 0)
+		ext4_warning_inode(inode, "Deleting file '%.*s' with no links",
+				   dentry->d_name.len, dentry->d_name.name);
+	else
+		drop_nlink(inode);
 	if (!inode->i_nlink)
 		ext4_orphan_add(handle, inode);
 	inode->i_ctime = ext4_current_time(inode);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux