>From cb347219bc21622dee06491b689c711e452005ce Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Thu, 24 Feb 2011 11:56:43 -0800 Subject: [PATCH] ext2: Resolve i_nlink count corruption with heavy unlink and rename old_inode's i_nlink count can become corrupt in ext2_rename() because we do not grab it's i_mutex in vfs_rename_other(). Looking into this further it has been determined there is no good reason for changing old_inode's link counts at all. Instead we just mark the inode as dirty when we are done. CC: Al Viro CC: Jan Kara Signed-off-by: Josh Hunt --- fs/ext2/namei.c | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 2e1d834..adb9185 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -344,7 +344,6 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page); if (!new_de) goto out_dir; - inode_inc_link_count(old_inode); ext2_set_link(new_dir, new_de, new_page, old_inode, 1); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) @@ -356,12 +355,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, if (new_dir->i_nlink >= EXT2_LINK_MAX) goto out_dir; } - inode_inc_link_count(old_inode); err = ext2_add_link(new_dentry, old_inode); - if (err) { - inode_dec_link_count(old_inode); + if (err) goto out_dir; - } if (dir_de) inode_inc_link_count(new_dir); } @@ -369,12 +365,11 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, /* * Like most other Unix systems, set the ctime for inodes on a * rename. - * inode_dec_link_count() will mark the inode dirty. */ old_inode->i_ctime = CURRENT_TIME_SEC; + mark_inode_dirty(old_inode); ext2_delete_entry (old_de, old_page); - inode_dec_link_count(old_inode); if (dir_de) { if (old_dir != new_dir) -- 1.7.0.4