diff options
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r-- | fs/ceph/mds_client.c | 68 |
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 | */ | ||
3027 | bool 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); |