Skip to content

Commit

Permalink
ceph: don't take s_mutex or snap_rwsem in ceph_check_caps
Browse files Browse the repository at this point in the history
These locks appear to be completely unnecessary. Almost all of this
function is done under the inode->i_ceph_lock, aside from the actual
sending of the message. Don't take either lock in this function.

Signed-off-by: Jeff Layton <[email protected]>
Reviewed-by: Luis Henriques <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
  • Loading branch information
jtlayton authored and idryomov committed Jun 28, 2021
1 parent 52d60f8 commit 6a92b08
Showing 1 changed file with 11 additions and 61 deletions.
72 changes: 11 additions & 61 deletions fs/ceph/caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1912,22 +1912,20 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
struct ceph_cap *cap;
u64 flush_tid, oldest_flush_tid;
int file_wanted, used, cap_used;
int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */
int issued, implemented, want, retain, revoking, flushing = 0;
int mds = -1; /* keep track of how far we've gone through i_caps list
to avoid an infinite loop on retry */
struct rb_node *p;
bool queue_invalidate = false;
bool tried_invalidate = false;

if (session)
ceph_get_mds_session(session);

spin_lock(&ci->i_ceph_lock);
if (ci->i_ceph_flags & CEPH_I_FLUSH)
flags |= CHECK_CAPS_FLUSH;

goto retry_locked;
retry:
spin_lock(&ci->i_ceph_lock);
retry_locked:
/* Caps wanted by virtue of active open files. */
file_wanted = __ceph_caps_file_wanted(ci);

Expand Down Expand Up @@ -2007,7 +2005,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
ci->i_rdcache_revoking = ci->i_rdcache_gen;
}
tried_invalidate = true;
goto retry_locked;
goto retry;
}

for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
Expand All @@ -2021,8 +2019,6 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap))
continue;

/* NOTE: no side-effects allowed, until we take s_mutex */

/*
* If we have an auth cap, we don't need to consider any
* overlapping caps as used.
Expand Down Expand Up @@ -2085,37 +2081,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
continue; /* nope, all good */

ack:
if (session && session != cap->session) {
dout("oops, wrong session %p mutex\n", session);
mutex_unlock(&session->s_mutex);
session = NULL;
}
if (!session) {
session = cap->session;
if (mutex_trylock(&session->s_mutex) == 0) {
dout("inverting session/ino locks on %p\n",
session);
session = ceph_get_mds_session(session);
spin_unlock(&ci->i_ceph_lock);
if (took_snap_rwsem) {
up_read(&mdsc->snap_rwsem);
took_snap_rwsem = 0;
}
if (session) {
mutex_lock(&session->s_mutex);
ceph_put_mds_session(session);
} else {
/*
* Because we take the reference while
* holding the i_ceph_lock, it should
* never be NULL. Throw a warning if it
* ever is.
*/
WARN_ON_ONCE(true);
}
goto retry;
}
}
ceph_put_mds_session(session);
session = ceph_get_mds_session(cap->session);

/* kick flushing and flush snaps before sending normal
* cap message */
Expand All @@ -2127,20 +2094,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS)
__ceph_flush_snaps(ci, session);

goto retry_locked;
}

/* take snap_rwsem after session mutex */
if (!took_snap_rwsem) {
if (down_read_trylock(&mdsc->snap_rwsem) == 0) {
dout("inverting snap/in locks on %p\n",
inode);
spin_unlock(&ci->i_ceph_lock);
down_read(&mdsc->snap_rwsem);
took_snap_rwsem = 1;
goto retry;
}
took_snap_rwsem = 1;
goto retry;
}

if (cap == ci->i_auth_cap && ci->i_dirty_caps) {
Expand All @@ -2162,9 +2116,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,

__prep_cap(&arg, cap, CEPH_CAP_OP_UPDATE, mflags, cap_used,
want, retain, flushing, flush_tid, oldest_flush_tid);
spin_unlock(&ci->i_ceph_lock);

spin_unlock(&ci->i_ceph_lock);
__send_cap(&arg, ci);
spin_lock(&ci->i_ceph_lock);

goto retry; /* retake i_ceph_lock and restart our cap scan. */
}
Expand All @@ -2179,13 +2134,9 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,

spin_unlock(&ci->i_ceph_lock);

ceph_put_mds_session(session);
if (queue_invalidate)
ceph_queue_invalidate(inode);

if (session)
mutex_unlock(&session->s_mutex);
if (took_snap_rwsem)
up_read(&mdsc->snap_rwsem);
}

/*
Expand Down Expand Up @@ -3550,13 +3501,12 @@ static void handle_cap_grant(struct inode *inode,
if (wake)
wake_up_all(&ci->i_cap_wq);

mutex_unlock(&session->s_mutex);
if (check_caps == 1)
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL,
session);
else if (check_caps == 2)
ceph_check_caps(ci, CHECK_CAPS_NOINVAL, session);
else
mutex_unlock(&session->s_mutex);
}

/*
Expand Down

0 comments on commit 6a92b08

Please sign in to comment.