Skip to content

Commit

Permalink
ceph: fix deadlock or deadcode of misusing dget()
Browse files Browse the repository at this point in the history
The lock order is incorrect between denty and its parent, we should
always make sure that the parent get the lock first.

But since this deadcode is never used and the parent dir will always
be set from the callers, let's just remove it.

Link: https://lore.kernel.org/r/20231116081919.GZ1957730@ZenIV
Reported-by: Al Viro <[email protected]>
Signed-off-by: Xiubo Li <[email protected]>
Reviewed-by: Jeff Layton <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
  • Loading branch information
lxbsz authored and idryomov committed Jan 15, 2024
1 parent aaefabc commit b493ad7
Showing 1 changed file with 3 additions and 6 deletions.
9 changes: 3 additions & 6 deletions fs/ceph/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -4887,13 +4887,15 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry,
struct inode *dir,
int mds, int drop, int unless)
{
struct dentry *parent = NULL;
struct ceph_mds_request_release *rel = *p;
struct ceph_dentry_info *di = ceph_dentry(dentry);
struct ceph_client *cl;
int force = 0;
int ret;

/* This shouldn't happen */
BUG_ON(!dir);

/*
* force an record for the directory caps if we have a dentry lease.
* this is racy (can't take i_ceph_lock and d_lock together), but it
Expand All @@ -4903,14 +4905,9 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry,
spin_lock(&dentry->d_lock);
if (di->lease_session && di->lease_session->s_mds == mds)
force = 1;
if (!dir) {
parent = dget(dentry->d_parent);
dir = d_inode(parent);
}
spin_unlock(&dentry->d_lock);

ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force);
dput(parent);

cl = ceph_inode_to_client(dir);
spin_lock(&dentry->d_lock);
Expand Down

0 comments on commit b493ad7

Please sign in to comment.