diff options
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r-- | fs/ocfs2/namei.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f4d609be9400..3683643f3f0e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -664,6 +664,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
666 | sigset_t oldset; | 666 | sigset_t oldset; |
667 | u64 old_de_ino; | ||
667 | 668 | ||
668 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, | 669 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, |
669 | old_dentry->d_name.len, old_dentry->d_name.name, | 670 | old_dentry->d_name.len, old_dentry->d_name.name, |
@@ -686,6 +687,22 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
686 | goto out; | 687 | goto out; |
687 | } | 688 | } |
688 | 689 | ||
690 | err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | ||
691 | old_dentry->d_name.len, &old_de_ino); | ||
692 | if (err) { | ||
693 | err = -ENOENT; | ||
694 | goto out; | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * Check whether another node removed the source inode while we | ||
699 | * were in the vfs. | ||
700 | */ | ||
701 | if (old_de_ino != OCFS2_I(inode)->ip_blkno) { | ||
702 | err = -ENOENT; | ||
703 | goto out; | ||
704 | } | ||
705 | |||
689 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 706 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
690 | dentry->d_name.len); | 707 | dentry->d_name.len); |
691 | if (err) | 708 | if (err) |