diff options
| -rw-r--r-- | fs/ceph/mds_client.c | 68 | ||||
| -rw-r--r-- | fs/ceph/mds_client.h | 3 |
2 files changed, 37 insertions, 34 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); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index ab7e89f5e344..c98267ce6d2a 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
| @@ -234,7 +234,8 @@ struct ceph_mds_client { | |||
| 234 | struct mutex mutex; /* all nested structures */ | 234 | struct mutex mutex; /* all nested structures */ |
| 235 | 235 | ||
| 236 | struct ceph_mdsmap *mdsmap; | 236 | struct ceph_mdsmap *mdsmap; |
| 237 | struct completion safe_umount_waiters, session_close_waiters; | 237 | struct completion safe_umount_waiters; |
| 238 | wait_queue_head_t session_close_wq; | ||
| 238 | struct list_head waiting_for_map; | 239 | struct list_head waiting_for_map; |
| 239 | 240 | ||
| 240 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ | 241 | struct ceph_mds_session **sessions; /* NULL for mds if no session */ |
