Skip to content

Commit bd04b91

Browse files
lxbszidryomov
authored andcommitted
ceph: fail the open_by_handle_at() if the dentry is being unlinked
When unlinking a file the kclient will send a unlink request to MDS by holding the dentry reference, and then the MDS will return 2 replies, which are unsafe reply and a deferred safe reply. After the unsafe reply received the kernel will return and succeed the unlink request to user space apps. Only when the safe reply received the dentry's reference will be released. Or the dentry will only be unhashed from dcache. But when the open_by_handle_at() begins to open the unlinked files it will succeed. The inode->i_count couldn't be used to check whether the inode is opened or not. Link: https://tracker.ceph.com/issues/56524 Signed-off-by: Xiubo Li <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Reviewed-by: Luís Henriques <[email protected]> Tested-by: Luís Henriques <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent b4b924c commit bd04b91

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

fs/ceph/export.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ struct inode *ceph_lookup_inode(struct super_block *sb, u64 ino)
181181
static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
182182
{
183183
struct inode *inode = __lookup_inode(sb, ino);
184+
struct ceph_inode_info *ci = ceph_inode(inode);
184185
int err;
185186

186187
if (IS_ERR(inode))
@@ -192,7 +193,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
192193
return ERR_PTR(err);
193194
}
194195
/* -ESTALE if inode as been unlinked and no file is open */
195-
if ((inode->i_nlink == 0) && (atomic_read(&inode->i_count) == 1)) {
196+
if ((inode->i_nlink == 0) && !__ceph_is_file_opened(ci)) {
196197
iput(inode);
197198
return ERR_PTR(-ESTALE);
198199
}

0 commit comments

Comments
 (0)