ceph: don't return -ESTALE if there's still an open file
[ Upstream commit5.4-rM2-2.2.x-imx-squashed878dabb641
] Similarly to commit03f219041f
("ceph: check i_nlink while converting a file handle to dentry"), this fixes another corner case with name_to_handle_at/open_by_handle_at. The issue has been detected by xfstest generic/467, when doing: - name_to_handle_at("/cephfs/myfile") - open("/cephfs/myfile") - unlink("/cephfs/myfile") - sync; sync; - drop caches - open_by_handle_at() The call to open_by_handle_at should not fail because the file hasn't been deleted yet (only unlinked) and we do have a valid handle to it. -ESTALE shall be returned only if i_nlink is 0 *and* i_count is 1. This patch also makes sure we have LINK caps before checking i_nlink. Signed-off-by: Luis Henriques <lhenriques@suse.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Acked-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
parent
145565f722
commit
8074607871
|
@ -172,9 +172,16 @@ struct inode *ceph_lookup_inode(struct super_block *sb, u64 ino)
|
|||
static struct dentry *__fh_to_dentry(struct super_block *sb, u64 ino)
|
||||
{
|
||||
struct inode *inode = __lookup_inode(sb, ino);
|
||||
int err;
|
||||
|
||||
if (IS_ERR(inode))
|
||||
return ERR_CAST(inode);
|
||||
if (inode->i_nlink == 0) {
|
||||
/* We need LINK caps to reliably check i_nlink */
|
||||
err = ceph_do_getattr(inode, CEPH_CAP_LINK_SHARED, false);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
/* -ESTALE if inode as been unlinked and no file is open */
|
||||
if ((inode->i_nlink == 0) && (atomic_read(&inode->i_count) == 1)) {
|
||||
iput(inode);
|
||||
return ERR_PTR(-ESTALE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue