From: Xiubo Li <xiubli@xxxxxxxxxx>
Just in case the session's refcount reach 0 and is releasing, and
if we get the session without checking it, we may encounter kernel
crash.
Rename get_session to ceph_get_mds_session and make it global.
Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx>
---
fs/ceph/caps.c | 4 ++--
fs/ceph/mds_client.c | 16 ++++++++--------
fs/ceph/mds_client.h | 9 ++-------
3 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 5c89a915409b..5a828298456a 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -812,7 +812,7 @@ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented, int mask)
&ci->vfs_inode, cap, ceph_cap_string(cap->issued));
if (mask >= 0) {
- s = get_session(cap->session);
+ s = ceph_get_mds_session(cap->session);
if (cap == ci->i_auth_cap)
r = revoking;
if (mask & (cap->issued & ~r))
@@ -907,7 +907,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch,
if (!__cap_is_valid(cap))
continue;
- s = get_session(cap->session);
+ s = ceph_get_mds_session(cap->session);
if ((cap->issued & mask) == mask) {
dout("__ceph_caps_issued_mask ino 0x%lx cap %p issued %s"
" (mask %s)\n", ci->vfs_inode.i_ino, cap,
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 99de89a3a0d3..619b08cba677 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -538,7 +538,7 @@ const char *ceph_session_state_name(int s)
}
}
-static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
+struct ceph_mds_session *ceph_get_mds_session(struct ceph_mds_session *s)
{
if (refcount_inc_not_zero(&s->s_ref)) {
dout("mdsc get_session %p %d -> %d\n", s,
@@ -571,7 +571,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
{
if (mds >= mdsc->max_sessions || !mdsc->sessions[mds])
return NULL;
- return get_session(mdsc->sessions[mds]);
+ return ceph_get_mds_session(mdsc->sessions[mds]);
}
static bool __have_session(struct ceph_mds_client *mdsc, int mds)
@@ -2004,7 +2004,7 @@ void ceph_flush_cap_releases(struct ceph_mds_client *mdsc,
if (mdsc->stopping)
return;
- get_session(session);
+ ceph_get_mds_session(session);
if (queue_work(mdsc->fsc->cap_wq,
&session->s_cap_release_work)) {
dout("cap release work queued\n");
@@ -2619,7 +2619,7 @@ static void __do_request(struct ceph_mds_client *mdsc,
goto finish;
}
}
- req->r_session = get_session(session);
+ req->r_session = ceph_get_mds_session(session);
dout("do_request mds%d session %p state %s\n", mds, session,
ceph_session_state_name(session->s_state));
@@ -3143,7 +3143,7 @@ static void handle_session(struct ceph_mds_session *session,
mutex_lock(&mdsc->mutex);
if (op == CEPH_SESSION_CLOSE) {
- get_session(session);
+ ceph_get_mds_session(session);
__unregister_session(mdsc, session);
}
/* FIXME: this ttl calculation is generous */
@@ -3818,7 +3818,7 @@ static void check_new_map(struct ceph_mds_client *mdsc,
if (i >= newmap->m_num_mds) {
/* force close session for stopped mds */
- get_session(s);
+ ceph_get_mds_session(s);
__unregister_session(mdsc, s);
__wake_requests(mdsc, &s->s_waiting);
mutex_unlock(&mdsc->mutex);
@@ -4460,7 +4460,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
mutex_lock(&mdsc->mutex);
for (i = 0; i < mdsc->max_sessions; i++) {
if (mdsc->sessions[i]) {
- session = get_session(mdsc->sessions[i]);
+ session = ceph_get_mds_session(mdsc->sessions[i]);
__unregister_session(mdsc, session);
mutex_unlock(&mdsc->mutex);
mutex_lock(&session->s_mutex);
@@ -4693,7 +4693,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con)
{
struct ceph_mds_session *s = con->private;
- if (get_session(s)) {
+ if (ceph_get_mds_session(s)) {
dout("mdsc con_get %p ok (%d)\n", s, refcount_read(&s->s_ref));
return con;
}
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 40676c2392cf..37e8798e7408 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -457,15 +457,10 @@ extern const char *ceph_mds_op_name(int op);
extern struct ceph_mds_session *
__ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
-static inline struct ceph_mds_session *
-ceph_get_mds_session(struct ceph_mds_session *s)
-{
- refcount_inc(&s->s_ref);
- return s;
-}
-
extern const char *ceph_session_state_name(int s);
+extern struct ceph_mds_session *
+ceph_get_mds_session(struct ceph_mds_session *s);
extern void ceph_put_mds_session(struct ceph_mds_session *s);
extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,