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 */ |
