diff options
Diffstat (limited to 'fs/ceph/mds_client.c')
-rw-r--r-- | fs/ceph/mds_client.c | 129 |
1 files changed, 81 insertions, 48 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index fad95f8f2608..3142b15940c2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1,17 +1,21 @@ | |||
1 | #include "ceph_debug.h" | 1 | #include <linux/ceph/ceph_debug.h> |
2 | 2 | ||
3 | #include <linux/fs.h> | ||
3 | #include <linux/wait.h> | 4 | #include <linux/wait.h> |
4 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
5 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/debugfs.h> | ||
8 | #include <linux/seq_file.h> | ||
6 | #include <linux/smp_lock.h> | 9 | #include <linux/smp_lock.h> |
7 | 10 | ||
8 | #include "mds_client.h" | ||
9 | #include "mon_client.h" | ||
10 | #include "super.h" | 11 | #include "super.h" |
11 | #include "messenger.h" | 12 | #include "mds_client.h" |
12 | #include "decode.h" | 13 | |
13 | #include "auth.h" | 14 | #include <linux/ceph/messenger.h> |
14 | #include "pagelist.h" | 15 | #include <linux/ceph/decode.h> |
16 | #include <linux/ceph/pagelist.h> | ||
17 | #include <linux/ceph/auth.h> | ||
18 | #include <linux/ceph/debugfs.h> | ||
15 | 19 | ||
16 | /* | 20 | /* |
17 | * A cluster of MDS (metadata server) daemons is responsible for | 21 | * A cluster of MDS (metadata server) daemons is responsible for |
@@ -286,8 +290,9 @@ void ceph_put_mds_session(struct ceph_mds_session *s) | |||
286 | atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); | 290 | atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); |
287 | if (atomic_dec_and_test(&s->s_ref)) { | 291 | if (atomic_dec_and_test(&s->s_ref)) { |
288 | if (s->s_authorizer) | 292 | if (s->s_authorizer) |
289 | s->s_mdsc->client->monc.auth->ops->destroy_authorizer( | 293 | s->s_mdsc->fsc->client->monc.auth->ops->destroy_authorizer( |
290 | s->s_mdsc->client->monc.auth, s->s_authorizer); | 294 | s->s_mdsc->fsc->client->monc.auth, |
295 | s->s_authorizer); | ||
291 | kfree(s); | 296 | kfree(s); |
292 | } | 297 | } |
293 | } | 298 | } |
@@ -344,7 +349,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, | |||
344 | s->s_seq = 0; | 349 | s->s_seq = 0; |
345 | mutex_init(&s->s_mutex); | 350 | mutex_init(&s->s_mutex); |
346 | 351 | ||
347 | ceph_con_init(mdsc->client->msgr, &s->s_con); | 352 | ceph_con_init(mdsc->fsc->client->msgr, &s->s_con); |
348 | s->s_con.private = s; | 353 | s->s_con.private = s; |
349 | s->s_con.ops = &mds_con_ops; | 354 | s->s_con.ops = &mds_con_ops; |
350 | s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; | 355 | s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; |
@@ -599,7 +604,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc, | |||
599 | } else if (req->r_dentry) { | 604 | } else if (req->r_dentry) { |
600 | struct inode *dir = req->r_dentry->d_parent->d_inode; | 605 | struct inode *dir = req->r_dentry->d_parent->d_inode; |
601 | 606 | ||
602 | if (dir->i_sb != mdsc->client->sb) { | 607 | if (dir->i_sb != mdsc->fsc->sb) { |
603 | /* not this fs! */ | 608 | /* not this fs! */ |
604 | inode = req->r_dentry->d_inode; | 609 | inode = req->r_dentry->d_inode; |
605 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { | 610 | } else if (ceph_snap(dir) != CEPH_NOSNAP) { |
@@ -884,7 +889,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
884 | __ceph_remove_cap(cap); | 889 | __ceph_remove_cap(cap); |
885 | if (!__ceph_is_any_real_caps(ci)) { | 890 | if (!__ceph_is_any_real_caps(ci)) { |
886 | struct ceph_mds_client *mdsc = | 891 | struct ceph_mds_client *mdsc = |
887 | &ceph_sb_to_client(inode->i_sb)->mdsc; | 892 | ceph_sb_to_client(inode->i_sb)->mdsc; |
888 | 893 | ||
889 | spin_lock(&mdsc->cap_dirty_lock); | 894 | spin_lock(&mdsc->cap_dirty_lock); |
890 | if (!list_empty(&ci->i_dirty_item)) { | 895 | if (!list_empty(&ci->i_dirty_item)) { |
@@ -1146,7 +1151,7 @@ int ceph_add_cap_releases(struct ceph_mds_client *mdsc, | |||
1146 | struct ceph_msg *msg, *partial = NULL; | 1151 | struct ceph_msg *msg, *partial = NULL; |
1147 | struct ceph_mds_cap_release *head; | 1152 | struct ceph_mds_cap_release *head; |
1148 | int err = -ENOMEM; | 1153 | int err = -ENOMEM; |
1149 | int extra = mdsc->client->mount_args->cap_release_safety; | 1154 | int extra = mdsc->fsc->mount_options->cap_release_safety; |
1150 | int num; | 1155 | int num; |
1151 | 1156 | ||
1152 | dout("add_cap_releases %p mds%d extra %d\n", session, session->s_mds, | 1157 | dout("add_cap_releases %p mds%d extra %d\n", session, session->s_mds, |
@@ -2085,7 +2090,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2085 | 2090 | ||
2086 | /* insert trace into our cache */ | 2091 | /* insert trace into our cache */ |
2087 | mutex_lock(&req->r_fill_mutex); | 2092 | mutex_lock(&req->r_fill_mutex); |
2088 | err = ceph_fill_trace(mdsc->client->sb, req, req->r_session); | 2093 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); |
2089 | if (err == 0) { | 2094 | if (err == 0) { |
2090 | if (result == 0 && rinfo->dir_nr) | 2095 | if (result == 0 && rinfo->dir_nr) |
2091 | ceph_readdir_prepopulate(req, req->r_session); | 2096 | ceph_readdir_prepopulate(req, req->r_session); |
@@ -2361,19 +2366,35 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2361 | 2366 | ||
2362 | if (recon_state->flock) { | 2367 | if (recon_state->flock) { |
2363 | int num_fcntl_locks, num_flock_locks; | 2368 | int num_fcntl_locks, num_flock_locks; |
2364 | 2369 | struct ceph_pagelist_cursor trunc_point; | |
2365 | lock_kernel(); | 2370 | |
2366 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); | 2371 | ceph_pagelist_set_cursor(pagelist, &trunc_point); |
2367 | rec.v2.flock_len = (2*sizeof(u32) + | 2372 | do { |
2368 | (num_fcntl_locks+num_flock_locks) * | 2373 | lock_flocks(); |
2369 | sizeof(struct ceph_filelock)); | 2374 | ceph_count_locks(inode, &num_fcntl_locks, |
2370 | 2375 | &num_flock_locks); | |
2371 | err = ceph_pagelist_append(pagelist, &rec, reclen); | 2376 | rec.v2.flock_len = (2*sizeof(u32) + |
2372 | if (!err) | 2377 | (num_fcntl_locks+num_flock_locks) * |
2373 | err = ceph_encode_locks(inode, pagelist, | 2378 | sizeof(struct ceph_filelock)); |
2374 | num_fcntl_locks, | 2379 | unlock_flocks(); |
2375 | num_flock_locks); | 2380 | |
2376 | unlock_kernel(); | 2381 | /* pre-alloc pagelist */ |
2382 | ceph_pagelist_truncate(pagelist, &trunc_point); | ||
2383 | err = ceph_pagelist_append(pagelist, &rec, reclen); | ||
2384 | if (!err) | ||
2385 | err = ceph_pagelist_reserve(pagelist, | ||
2386 | rec.v2.flock_len); | ||
2387 | |||
2388 | /* encode locks */ | ||
2389 | if (!err) { | ||
2390 | lock_flocks(); | ||
2391 | err = ceph_encode_locks(inode, | ||
2392 | pagelist, | ||
2393 | num_fcntl_locks, | ||
2394 | num_flock_locks); | ||
2395 | unlock_flocks(); | ||
2396 | } | ||
2397 | } while (err == -ENOSPC); | ||
2377 | } else { | 2398 | } else { |
2378 | err = ceph_pagelist_append(pagelist, &rec, reclen); | 2399 | err = ceph_pagelist_append(pagelist, &rec, reclen); |
2379 | } | 2400 | } |
@@ -2613,7 +2634,7 @@ static void handle_lease(struct ceph_mds_client *mdsc, | |||
2613 | struct ceph_mds_session *session, | 2634 | struct ceph_mds_session *session, |
2614 | struct ceph_msg *msg) | 2635 | struct ceph_msg *msg) |
2615 | { | 2636 | { |
2616 | struct super_block *sb = mdsc->client->sb; | 2637 | struct super_block *sb = mdsc->fsc->sb; |
2617 | struct inode *inode; | 2638 | struct inode *inode; |
2618 | struct ceph_inode_info *ci; | 2639 | struct ceph_inode_info *ci; |
2619 | struct dentry *parent, *dentry; | 2640 | struct dentry *parent, *dentry; |
@@ -2891,10 +2912,16 @@ static void delayed_work(struct work_struct *work) | |||
2891 | schedule_delayed(mdsc); | 2912 | schedule_delayed(mdsc); |
2892 | } | 2913 | } |
2893 | 2914 | ||
2915 | int ceph_mdsc_init(struct ceph_fs_client *fsc) | ||
2894 | 2916 | ||
2895 | int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | ||
2896 | { | 2917 | { |
2897 | mdsc->client = client; | 2918 | struct ceph_mds_client *mdsc; |
2919 | |||
2920 | mdsc = kzalloc(sizeof(struct ceph_mds_client), GFP_NOFS); | ||
2921 | if (!mdsc) | ||
2922 | return -ENOMEM; | ||
2923 | mdsc->fsc = fsc; | ||
2924 | fsc->mdsc = mdsc; | ||
2898 | mutex_init(&mdsc->mutex); | 2925 | mutex_init(&mdsc->mutex); |
2899 | mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); | 2926 | mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); |
2900 | if (mdsc->mdsmap == NULL) | 2927 | if (mdsc->mdsmap == NULL) |
@@ -2927,7 +2954,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | |||
2927 | INIT_LIST_HEAD(&mdsc->dentry_lru); | 2954 | INIT_LIST_HEAD(&mdsc->dentry_lru); |
2928 | 2955 | ||
2929 | ceph_caps_init(mdsc); | 2956 | ceph_caps_init(mdsc); |
2930 | ceph_adjust_min_caps(mdsc, client->min_caps); | 2957 | ceph_adjust_min_caps(mdsc, fsc->min_caps); |
2931 | 2958 | ||
2932 | return 0; | 2959 | return 0; |
2933 | } | 2960 | } |
@@ -2939,7 +2966,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) | |||
2939 | static void wait_requests(struct ceph_mds_client *mdsc) | 2966 | static void wait_requests(struct ceph_mds_client *mdsc) |
2940 | { | 2967 | { |
2941 | struct ceph_mds_request *req; | 2968 | struct ceph_mds_request *req; |
2942 | struct ceph_client *client = mdsc->client; | 2969 | struct ceph_fs_client *fsc = mdsc->fsc; |
2943 | 2970 | ||
2944 | mutex_lock(&mdsc->mutex); | 2971 | mutex_lock(&mdsc->mutex); |
2945 | if (__get_oldest_req(mdsc)) { | 2972 | if (__get_oldest_req(mdsc)) { |
@@ -2947,7 +2974,7 @@ static void wait_requests(struct ceph_mds_client *mdsc) | |||
2947 | 2974 | ||
2948 | dout("wait_requests waiting for requests\n"); | 2975 | dout("wait_requests waiting for requests\n"); |
2949 | wait_for_completion_timeout(&mdsc->safe_umount_waiters, | 2976 | wait_for_completion_timeout(&mdsc->safe_umount_waiters, |
2950 | client->mount_args->mount_timeout * HZ); | 2977 | fsc->client->options->mount_timeout * HZ); |
2951 | 2978 | ||
2952 | /* tear down remaining requests */ | 2979 | /* tear down remaining requests */ |
2953 | mutex_lock(&mdsc->mutex); | 2980 | mutex_lock(&mdsc->mutex); |
@@ -3030,7 +3057,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) | |||
3030 | { | 3057 | { |
3031 | u64 want_tid, want_flush; | 3058 | u64 want_tid, want_flush; |
3032 | 3059 | ||
3033 | if (mdsc->client->mount_state == CEPH_MOUNT_SHUTDOWN) | 3060 | if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN) |
3034 | return; | 3061 | return; |
3035 | 3062 | ||
3036 | dout("sync\n"); | 3063 | dout("sync\n"); |
@@ -3053,7 +3080,7 @@ bool done_closing_sessions(struct ceph_mds_client *mdsc) | |||
3053 | { | 3080 | { |
3054 | int i, n = 0; | 3081 | int i, n = 0; |
3055 | 3082 | ||
3056 | if (mdsc->client->mount_state == CEPH_MOUNT_SHUTDOWN) | 3083 | if (mdsc->fsc->mount_state == CEPH_MOUNT_SHUTDOWN) |
3057 | return true; | 3084 | return true; |
3058 | 3085 | ||
3059 | mutex_lock(&mdsc->mutex); | 3086 | mutex_lock(&mdsc->mutex); |
@@ -3071,8 +3098,8 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3071 | { | 3098 | { |
3072 | struct ceph_mds_session *session; | 3099 | struct ceph_mds_session *session; |
3073 | int i; | 3100 | int i; |
3074 | struct ceph_client *client = mdsc->client; | 3101 | struct ceph_fs_client *fsc = mdsc->fsc; |
3075 | unsigned long timeout = client->mount_args->mount_timeout * HZ; | 3102 | unsigned long timeout = fsc->client->options->mount_timeout * HZ; |
3076 | 3103 | ||
3077 | dout("close_sessions\n"); | 3104 | dout("close_sessions\n"); |
3078 | 3105 | ||
@@ -3119,7 +3146,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) | |||
3119 | dout("stopped\n"); | 3146 | dout("stopped\n"); |
3120 | } | 3147 | } |
3121 | 3148 | ||
3122 | void ceph_mdsc_stop(struct ceph_mds_client *mdsc) | 3149 | static void ceph_mdsc_stop(struct ceph_mds_client *mdsc) |
3123 | { | 3150 | { |
3124 | dout("stop\n"); | 3151 | dout("stop\n"); |
3125 | cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */ | 3152 | cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */ |
@@ -3129,6 +3156,15 @@ void ceph_mdsc_stop(struct ceph_mds_client *mdsc) | |||
3129 | ceph_caps_finalize(mdsc); | 3156 | ceph_caps_finalize(mdsc); |
3130 | } | 3157 | } |
3131 | 3158 | ||
3159 | void ceph_mdsc_destroy(struct ceph_fs_client *fsc) | ||
3160 | { | ||
3161 | struct ceph_mds_client *mdsc = fsc->mdsc; | ||
3162 | |||
3163 | ceph_mdsc_stop(mdsc); | ||
3164 | fsc->mdsc = NULL; | ||
3165 | kfree(mdsc); | ||
3166 | } | ||
3167 | |||
3132 | 3168 | ||
3133 | /* | 3169 | /* |
3134 | * handle mds map update. | 3170 | * handle mds map update. |
@@ -3145,14 +3181,14 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) | |||
3145 | 3181 | ||
3146 | ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); | 3182 | ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); |
3147 | ceph_decode_copy(&p, &fsid, sizeof(fsid)); | 3183 | ceph_decode_copy(&p, &fsid, sizeof(fsid)); |
3148 | if (ceph_check_fsid(mdsc->client, &fsid) < 0) | 3184 | if (ceph_check_fsid(mdsc->fsc->client, &fsid) < 0) |
3149 | return; | 3185 | return; |
3150 | epoch = ceph_decode_32(&p); | 3186 | epoch = ceph_decode_32(&p); |
3151 | maplen = ceph_decode_32(&p); | 3187 | maplen = ceph_decode_32(&p); |
3152 | dout("handle_map epoch %u len %d\n", epoch, (int)maplen); | 3188 | dout("handle_map epoch %u len %d\n", epoch, (int)maplen); |
3153 | 3189 | ||
3154 | /* do we need it? */ | 3190 | /* do we need it? */ |
3155 | ceph_monc_got_mdsmap(&mdsc->client->monc, epoch); | 3191 | ceph_monc_got_mdsmap(&mdsc->fsc->client->monc, epoch); |
3156 | mutex_lock(&mdsc->mutex); | 3192 | mutex_lock(&mdsc->mutex); |
3157 | if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) { | 3193 | if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) { |
3158 | dout("handle_map epoch %u <= our %u\n", | 3194 | dout("handle_map epoch %u <= our %u\n", |
@@ -3176,7 +3212,7 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) | |||
3176 | } else { | 3212 | } else { |
3177 | mdsc->mdsmap = newmap; /* first mds map */ | 3213 | mdsc->mdsmap = newmap; /* first mds map */ |
3178 | } | 3214 | } |
3179 | mdsc->client->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size; | 3215 | mdsc->fsc->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size; |
3180 | 3216 | ||
3181 | __wake_requests(mdsc, &mdsc->waiting_for_map); | 3217 | __wake_requests(mdsc, &mdsc->waiting_for_map); |
3182 | 3218 | ||
@@ -3277,7 +3313,7 @@ static int get_authorizer(struct ceph_connection *con, | |||
3277 | { | 3313 | { |
3278 | struct ceph_mds_session *s = con->private; | 3314 | struct ceph_mds_session *s = con->private; |
3279 | struct ceph_mds_client *mdsc = s->s_mdsc; | 3315 | struct ceph_mds_client *mdsc = s->s_mdsc; |
3280 | struct ceph_auth_client *ac = mdsc->client->monc.auth; | 3316 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
3281 | int ret = 0; | 3317 | int ret = 0; |
3282 | 3318 | ||
3283 | if (force_new && s->s_authorizer) { | 3319 | if (force_new && s->s_authorizer) { |
@@ -3311,7 +3347,7 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) | |||
3311 | { | 3347 | { |
3312 | struct ceph_mds_session *s = con->private; | 3348 | struct ceph_mds_session *s = con->private; |
3313 | struct ceph_mds_client *mdsc = s->s_mdsc; | 3349 | struct ceph_mds_client *mdsc = s->s_mdsc; |
3314 | struct ceph_auth_client *ac = mdsc->client->monc.auth; | 3350 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
3315 | 3351 | ||
3316 | return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len); | 3352 | return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len); |
3317 | } | 3353 | } |
@@ -3320,12 +3356,12 @@ static int invalidate_authorizer(struct ceph_connection *con) | |||
3320 | { | 3356 | { |
3321 | struct ceph_mds_session *s = con->private; | 3357 | struct ceph_mds_session *s = con->private; |
3322 | struct ceph_mds_client *mdsc = s->s_mdsc; | 3358 | struct ceph_mds_client *mdsc = s->s_mdsc; |
3323 | struct ceph_auth_client *ac = mdsc->client->monc.auth; | 3359 | struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth; |
3324 | 3360 | ||
3325 | if (ac->ops->invalidate_authorizer) | 3361 | if (ac->ops->invalidate_authorizer) |
3326 | ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); | 3362 | ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); |
3327 | 3363 | ||
3328 | return ceph_monc_validate_auth(&mdsc->client->monc); | 3364 | return ceph_monc_validate_auth(&mdsc->fsc->client->monc); |
3329 | } | 3365 | } |
3330 | 3366 | ||
3331 | static const struct ceph_connection_operations mds_con_ops = { | 3367 | static const struct ceph_connection_operations mds_con_ops = { |
@@ -3338,7 +3374,4 @@ static const struct ceph_connection_operations mds_con_ops = { | |||
3338 | .peer_reset = peer_reset, | 3374 | .peer_reset = peer_reset, |
3339 | }; | 3375 | }; |
3340 | 3376 | ||
3341 | |||
3342 | |||
3343 | |||
3344 | /* eof */ | 3377 | /* eof */ |