aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mds_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r--fs/ceph/mds_client.c68
1 files changed, 35 insertions, 33 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a75ddbf9fe37..397a47b696ce 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2208,7 +2208,7 @@ static void handle_session(struct ceph_mds_session *session,
2208 pr_info("mds%d reconnect denied\n", session->s_mds); 2208 pr_info("mds%d reconnect denied\n", session->s_mds);
2209 remove_session_caps(session); 2209 remove_session_caps(session);
2210 wake = 1; /* for good measure */ 2210 wake = 1; /* for good measure */
2211 complete_all(&mdsc->session_close_waiters); 2211 wake_up_all(&mdsc->session_close_wq);
2212 kick_requests(mdsc, mds); 2212 kick_requests(mdsc, mds);
2213 break; 2213 break;
2214 2214
@@ -2876,7 +2876,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
2876 return -ENOMEM; 2876 return -ENOMEM;
2877 2877
2878 init_completion(&mdsc->safe_umount_waiters); 2878 init_completion(&mdsc->safe_umount_waiters);
2879 init_completion(&mdsc->session_close_waiters); 2879 init_waitqueue_head(&mdsc->session_close_wq);
2880 INIT_LIST_HEAD(&mdsc->waiting_for_map); 2880 INIT_LIST_HEAD(&mdsc->waiting_for_map);
2881 mdsc->sessions = NULL; 2881 mdsc->sessions = NULL;
2882 mdsc->max_sessions = 0; 2882 mdsc->max_sessions = 0;
@@ -3021,6 +3021,23 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc)
3021 wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); 3021 wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush));
3022} 3022}
3023 3023
3024/*
3025 * true if all sessions are closed, or we force unmount
3026 */
3027bool done_closing_sessions(struct ceph_mds_client *mdsc)
3028{
3029 int i, n = 0;
3030
3031 if (mdsc->client->mount_state == CEPH_MOUNT_SHUTDOWN)
3032 return true;
3033
3034 mutex_lock(&mdsc->mutex);
3035 for (i = 0; i < mdsc->max_sessions; i++)
3036 if (mdsc->sessions[i])
3037 n++;
3038 mutex_unlock(&mdsc->mutex);
3039 return n == 0;
3040}
3024 3041
3025/* 3042/*
3026 * called after sb is ro. 3043 * called after sb is ro.
@@ -3029,45 +3046,32 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
3029{ 3046{
3030 struct ceph_mds_session *session; 3047 struct ceph_mds_session *session;
3031 int i; 3048 int i;
3032 int n;
3033 struct ceph_client *client = mdsc->client; 3049 struct ceph_client *client = mdsc->client;
3034 unsigned long started, timeout = client->mount_args->mount_timeout * HZ; 3050 unsigned long timeout = client->mount_args->mount_timeout * HZ;
3035 3051
3036 dout("close_sessions\n"); 3052 dout("close_sessions\n");
3037 3053
3038 mutex_lock(&mdsc->mutex);
3039
3040 /* close sessions */ 3054 /* close sessions */
3041 started = jiffies; 3055 mutex_lock(&mdsc->mutex);
3042 while (time_before(jiffies, started + timeout)) { 3056 for (i = 0; i < mdsc->max_sessions; i++) {
3043 dout("closing sessions\n"); 3057 session = __ceph_lookup_mds_session(mdsc, i);
3044 n = 0; 3058 if (!session)
3045 for (i = 0; i < mdsc->max_sessions; i++) { 3059 continue;
3046 session = __ceph_lookup_mds_session(mdsc, i);
3047 if (!session)
3048 continue;
3049 mutex_unlock(&mdsc->mutex);
3050 mutex_lock(&session->s_mutex);
3051 __close_session(mdsc, session);
3052 mutex_unlock(&session->s_mutex);
3053 ceph_put_mds_session(session);
3054 mutex_lock(&mdsc->mutex);
3055 n++;
3056 }
3057 if (n == 0)
3058 break;
3059
3060 if (client->mount_state == CEPH_MOUNT_SHUTDOWN)
3061 break;
3062
3063 dout("waiting for sessions to close\n");
3064 mutex_unlock(&mdsc->mutex); 3060 mutex_unlock(&mdsc->mutex);
3065 wait_for_completion_timeout(&mdsc->session_close_waiters, 3061 mutex_lock(&session->s_mutex);
3066 timeout); 3062 __close_session(mdsc, session);
3063 mutex_unlock(&session->s_mutex);
3064 ceph_put_mds_session(session);
3067 mutex_lock(&mdsc->mutex); 3065 mutex_lock(&mdsc->mutex);
3068 } 3066 }
3067 mutex_unlock(&mdsc->mutex);
3068
3069 dout("waiting for sessions to close\n");
3070 wait_event_timeout(mdsc->session_close_wq, done_closing_sessions(mdsc),
3071 timeout);
3069 3072
3070 /* tear down remaining sessions */ 3073 /* tear down remaining sessions */
3074 mutex_lock(&mdsc->mutex);
3071 for (i = 0; i < mdsc->max_sessions; i++) { 3075 for (i = 0; i < mdsc->max_sessions; i++) {
3072 if (mdsc->sessions[i]) { 3076 if (mdsc->sessions[i]) {
3073 session = get_session(mdsc->sessions[i]); 3077 session = get_session(mdsc->sessions[i]);
@@ -3080,9 +3084,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
3080 mutex_lock(&mdsc->mutex); 3084 mutex_lock(&mdsc->mutex);
3081 } 3085 }
3082 } 3086 }
3083
3084 WARN_ON(!list_empty(&mdsc->cap_delay_list)); 3087 WARN_ON(!list_empty(&mdsc->cap_delay_list));
3085
3086 mutex_unlock(&mdsc->mutex); 3088 mutex_unlock(&mdsc->mutex);
3087 3089
3088 ceph_cleanup_empty_realms(mdsc); 3090 ceph_cleanup_empty_realms(mdsc);