diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-06 20:15:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-06 20:15:15 -0400 |
commit | 1cc9629402b1eba0d4e21b2cc43eec9bd737f9bd (patch) | |
tree | 6bd52203d0d071acd3311d5093b4aa61c313faad /fs | |
parent | 8b8ce8810b092cef35e15af6577ad569f6145c0a (diff) | |
parent | 153a10939ea6e42e9c0115b0645060d0d7bb4697 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: fix crush device 'out' threshold to 1.0, not 0.1
ceph: fix caps usage accounting for import (non-reserved) case
ceph: only release clean, unused caps with mds requests
ceph: fix crush CHOOSE_LEAF when type is already a leaf
ceph: fix crush recursion
ceph: fix caps debugfs entry
ceph: delay umount until all mds requests drop inode+dentry refs
ceph: handle splice_dentry/d_materialize_unique error in readdir_prepopulate
ceph: fix crush map update decoding
ceph: fix message memory leak, uninitialized variable
ceph: fix map handler error path
ceph: some endianity fixes
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/auth_x.c | 2 | ||||
-rw-r--r-- | fs/ceph/caps.c | 21 | ||||
-rw-r--r-- | fs/ceph/crush/mapper.c | 41 | ||||
-rw-r--r-- | fs/ceph/debugfs.c | 2 | ||||
-rw-r--r-- | fs/ceph/inode.c | 19 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 6 | ||||
-rw-r--r-- | fs/ceph/messenger.c | 4 | ||||
-rw-r--r-- | fs/ceph/mon_client.c | 3 | ||||
-rw-r--r-- | fs/ceph/osd_client.c | 3 | ||||
-rw-r--r-- | fs/ceph/osdmap.c | 1 |
10 files changed, 69 insertions, 33 deletions
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 83d4d2785ffe..3fe49042d8ad 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c | |||
@@ -493,7 +493,7 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, | |||
493 | return -EAGAIN; | 493 | return -EAGAIN; |
494 | } | 494 | } |
495 | 495 | ||
496 | op = le32_to_cpu(head->op); | 496 | op = le16_to_cpu(head->op); |
497 | result = le32_to_cpu(head->result); | 497 | result = le32_to_cpu(head->result); |
498 | dout("handle_reply op %d result %d\n", op, result); | 498 | dout("handle_reply op %d result %d\n", op, result); |
499 | switch (op) { | 499 | switch (op) { |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 619b61655ee5..74144d6389f0 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -244,8 +244,14 @@ static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx) | |||
244 | struct ceph_cap *cap = NULL; | 244 | struct ceph_cap *cap = NULL; |
245 | 245 | ||
246 | /* temporary, until we do something about cap import/export */ | 246 | /* temporary, until we do something about cap import/export */ |
247 | if (!ctx) | 247 | if (!ctx) { |
248 | return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); | 248 | cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); |
249 | if (cap) { | ||
250 | caps_use_count++; | ||
251 | caps_total_count++; | ||
252 | } | ||
253 | return cap; | ||
254 | } | ||
249 | 255 | ||
250 | spin_lock(&caps_list_lock); | 256 | spin_lock(&caps_list_lock); |
251 | dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", | 257 | dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", |
@@ -2886,18 +2892,19 @@ int ceph_encode_inode_release(void **p, struct inode *inode, | |||
2886 | struct ceph_inode_info *ci = ceph_inode(inode); | 2892 | struct ceph_inode_info *ci = ceph_inode(inode); |
2887 | struct ceph_cap *cap; | 2893 | struct ceph_cap *cap; |
2888 | struct ceph_mds_request_release *rel = *p; | 2894 | struct ceph_mds_request_release *rel = *p; |
2895 | int used, dirty; | ||
2889 | int ret = 0; | 2896 | int ret = 0; |
2890 | int used = 0; | ||
2891 | 2897 | ||
2892 | spin_lock(&inode->i_lock); | 2898 | spin_lock(&inode->i_lock); |
2893 | used = __ceph_caps_used(ci); | 2899 | used = __ceph_caps_used(ci); |
2900 | dirty = __ceph_caps_dirty(ci); | ||
2894 | 2901 | ||
2895 | dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode, | 2902 | dout("encode_inode_release %p mds%d used|dirty %s drop %s unless %s\n", |
2896 | mds, ceph_cap_string(used), ceph_cap_string(drop), | 2903 | inode, mds, ceph_cap_string(used|dirty), ceph_cap_string(drop), |
2897 | ceph_cap_string(unless)); | 2904 | ceph_cap_string(unless)); |
2898 | 2905 | ||
2899 | /* only drop unused caps */ | 2906 | /* only drop unused, clean caps */ |
2900 | drop &= ~used; | 2907 | drop &= ~(used | dirty); |
2901 | 2908 | ||
2902 | cap = __get_cap_for_mds(ci, mds); | 2909 | cap = __get_cap_for_mds(ci, mds); |
2903 | if (cap && __cap_is_valid(cap)) { | 2910 | if (cap && __cap_is_valid(cap)) { |
diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index 9ba54efb6543..a4eec133258e 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c | |||
@@ -238,7 +238,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket, | |||
238 | 238 | ||
239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) | 239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) |
240 | { | 240 | { |
241 | dprintk("choose %d x=%d r=%d\n", in->id, x, r); | 241 | dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r); |
242 | switch (in->alg) { | 242 | switch (in->alg) { |
243 | case CRUSH_BUCKET_UNIFORM: | 243 | case CRUSH_BUCKET_UNIFORM: |
244 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, | 244 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, |
@@ -264,7 +264,7 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r) | |||
264 | */ | 264 | */ |
265 | static int is_out(struct crush_map *map, __u32 *weight, int item, int x) | 265 | static int is_out(struct crush_map *map, __u32 *weight, int item, int x) |
266 | { | 266 | { |
267 | if (weight[item] >= 0x1000) | 267 | if (weight[item] >= 0x10000) |
268 | return 0; | 268 | return 0; |
269 | if (weight[item] == 0) | 269 | if (weight[item] == 0) |
270 | return 1; | 270 | return 1; |
@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map, | |||
305 | int itemtype; | 305 | int itemtype; |
306 | int collide, reject; | 306 | int collide, reject; |
307 | const int orig_tries = 5; /* attempts before we fall back to search */ | 307 | const int orig_tries = 5; /* attempts before we fall back to search */ |
308 | dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos); | 308 | |
309 | dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d\n", recurse_to_leaf ? "_LEAF" : "", | ||
310 | bucket->id, x, outpos, numrep); | ||
309 | 311 | ||
310 | for (rep = outpos; rep < numrep; rep++) { | 312 | for (rep = outpos; rep < numrep; rep++) { |
311 | /* keep trying until we get a non-out, non-colliding item */ | 313 | /* keep trying until we get a non-out, non-colliding item */ |
@@ -366,6 +368,7 @@ static int crush_choose(struct crush_map *map, | |||
366 | BUG_ON(item >= 0 || | 368 | BUG_ON(item >= 0 || |
367 | (-1-item) >= map->max_buckets); | 369 | (-1-item) >= map->max_buckets); |
368 | in = map->buckets[-1-item]; | 370 | in = map->buckets[-1-item]; |
371 | retry_bucket = 1; | ||
369 | continue; | 372 | continue; |
370 | } | 373 | } |
371 | 374 | ||
@@ -377,15 +380,25 @@ static int crush_choose(struct crush_map *map, | |||
377 | } | 380 | } |
378 | } | 381 | } |
379 | 382 | ||
380 | if (recurse_to_leaf && | 383 | reject = 0; |
381 | item < 0 && | 384 | if (recurse_to_leaf) { |
382 | crush_choose(map, map->buckets[-1-item], | 385 | if (item < 0) { |
383 | weight, | 386 | if (crush_choose(map, |
384 | x, outpos+1, 0, | 387 | map->buckets[-1-item], |
385 | out2, outpos, | 388 | weight, |
386 | firstn, 0, NULL) <= outpos) { | 389 | x, outpos+1, 0, |
387 | reject = 1; | 390 | out2, outpos, |
388 | } else { | 391 | firstn, 0, |
392 | NULL) <= outpos) | ||
393 | /* didn't get leaf */ | ||
394 | reject = 1; | ||
395 | } else { | ||
396 | /* we already have a leaf! */ | ||
397 | out2[outpos] = item; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | if (!reject) { | ||
389 | /* out? */ | 402 | /* out? */ |
390 | if (itemtype == 0) | 403 | if (itemtype == 0) |
391 | reject = is_out(map, weight, | 404 | reject = is_out(map, weight, |
@@ -424,12 +437,12 @@ reject: | |||
424 | continue; | 437 | continue; |
425 | } | 438 | } |
426 | 439 | ||
427 | dprintk("choose got %d\n", item); | 440 | dprintk("CHOOSE got %d\n", item); |
428 | out[outpos] = item; | 441 | out[outpos] = item; |
429 | outpos++; | 442 | outpos++; |
430 | } | 443 | } |
431 | 444 | ||
432 | dprintk("choose returns %d\n", outpos); | 445 | dprintk("CHOOSE returns %d\n", outpos); |
433 | return outpos; | 446 | return outpos; |
434 | } | 447 | } |
435 | 448 | ||
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 3be33fb066cc..f2f5332ddbba 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -261,7 +261,7 @@ static int osdc_show(struct seq_file *s, void *pp) | |||
261 | 261 | ||
262 | static int caps_show(struct seq_file *s, void *p) | 262 | static int caps_show(struct seq_file *s, void *p) |
263 | { | 263 | { |
264 | struct ceph_client *client = p; | 264 | struct ceph_client *client = s->private; |
265 | int total, avail, used, reserved, min; | 265 | int total, avail, used, reserved, min; |
266 | 266 | ||
267 | ceph_reservation_status(client, &total, &avail, &used, &reserved, &min); | 267 | ceph_reservation_status(client, &total, &avail, &used, &reserved, &min); |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index ab47f46ca282..8f9b9fe8ef9f 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -854,8 +854,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
854 | d_drop(dn); | 854 | d_drop(dn); |
855 | realdn = d_materialise_unique(dn, in); | 855 | realdn = d_materialise_unique(dn, in); |
856 | if (IS_ERR(realdn)) { | 856 | if (IS_ERR(realdn)) { |
857 | pr_err("splice_dentry error %p inode %p ino %llx.%llx\n", | 857 | pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", |
858 | dn, in, ceph_vinop(in)); | 858 | PTR_ERR(realdn), dn, in, ceph_vinop(in)); |
859 | if (prehash) | 859 | if (prehash) |
860 | *prehash = false; /* don't rehash on error */ | 860 | *prehash = false; /* don't rehash on error */ |
861 | dn = realdn; /* note realdn contains the error */ | 861 | dn = realdn; /* note realdn contains the error */ |
@@ -1234,18 +1234,23 @@ retry_lookup: | |||
1234 | goto out; | 1234 | goto out; |
1235 | } | 1235 | } |
1236 | dn = splice_dentry(dn, in, NULL); | 1236 | dn = splice_dentry(dn, in, NULL); |
1237 | if (IS_ERR(dn)) | ||
1238 | dn = NULL; | ||
1237 | } | 1239 | } |
1238 | 1240 | ||
1239 | if (fill_inode(in, &rinfo->dir_in[i], NULL, session, | 1241 | if (fill_inode(in, &rinfo->dir_in[i], NULL, session, |
1240 | req->r_request_started, -1, | 1242 | req->r_request_started, -1, |
1241 | &req->r_caps_reservation) < 0) { | 1243 | &req->r_caps_reservation) < 0) { |
1242 | pr_err("fill_inode badness on %p\n", in); | 1244 | pr_err("fill_inode badness on %p\n", in); |
1243 | dput(dn); | 1245 | goto next_item; |
1244 | continue; | ||
1245 | } | 1246 | } |
1246 | update_dentry_lease(dn, rinfo->dir_dlease[i], | 1247 | if (dn) |
1247 | req->r_session, req->r_request_started); | 1248 | update_dentry_lease(dn, rinfo->dir_dlease[i], |
1248 | dput(dn); | 1249 | req->r_session, |
1250 | req->r_request_started); | ||
1251 | next_item: | ||
1252 | if (dn) | ||
1253 | dput(dn); | ||
1249 | } | 1254 | } |
1250 | req->r_did_prepopulate = true; | 1255 | req->r_did_prepopulate = true; |
1251 | 1256 | ||
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 1766947fc07a..3ab79f6c4ce8 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2783,6 +2783,12 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) | |||
2783 | drop_leases(mdsc); | 2783 | drop_leases(mdsc); |
2784 | ceph_flush_dirty_caps(mdsc); | 2784 | ceph_flush_dirty_caps(mdsc); |
2785 | wait_requests(mdsc); | 2785 | wait_requests(mdsc); |
2786 | |||
2787 | /* | ||
2788 | * wait for reply handlers to drop their request refs and | ||
2789 | * their inode/dcache refs | ||
2790 | */ | ||
2791 | ceph_msgr_flush(); | ||
2786 | } | 2792 | } |
2787 | 2793 | ||
2788 | /* | 2794 | /* |
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 64b8b1f7863d..9ad43a310a41 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -657,7 +657,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr, | |||
657 | dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, | 657 | dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, |
658 | con->connect_seq, global_seq, proto); | 658 | con->connect_seq, global_seq, proto); |
659 | 659 | ||
660 | con->out_connect.features = CEPH_FEATURE_SUPPORTED_CLIENT; | 660 | con->out_connect.features = cpu_to_le64(CEPH_FEATURE_SUPPORTED_CLIENT); |
661 | con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); | 661 | con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); |
662 | con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); | 662 | con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); |
663 | con->out_connect.global_seq = cpu_to_le32(global_seq); | 663 | con->out_connect.global_seq = cpu_to_le32(global_seq); |
@@ -1396,10 +1396,12 @@ static int read_partial_message(struct ceph_connection *con) | |||
1396 | if (!con->in_msg) { | 1396 | if (!con->in_msg) { |
1397 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, | 1397 | dout("got hdr type %d front %d data %d\n", con->in_hdr.type, |
1398 | con->in_hdr.front_len, con->in_hdr.data_len); | 1398 | con->in_hdr.front_len, con->in_hdr.data_len); |
1399 | skip = 0; | ||
1399 | con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip); | 1400 | con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip); |
1400 | if (skip) { | 1401 | if (skip) { |
1401 | /* skip this message */ | 1402 | /* skip this message */ |
1402 | dout("alloc_msg said skip message\n"); | 1403 | dout("alloc_msg said skip message\n"); |
1404 | BUG_ON(con->in_msg); | ||
1403 | con->in_base_pos = -front_len - middle_len - data_len - | 1405 | con->in_base_pos = -front_len - middle_len - data_len - |
1404 | sizeof(m->footer); | 1406 | sizeof(m->footer); |
1405 | con->in_tag = CEPH_MSGR_TAG_READY; | 1407 | con->in_tag = CEPH_MSGR_TAG_READY; |
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 07a539906e67..cc115eafae11 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c | |||
@@ -725,7 +725,8 @@ static void handle_auth_reply(struct ceph_mon_client *monc, | |||
725 | dout("authenticated, starting session\n"); | 725 | dout("authenticated, starting session\n"); |
726 | 726 | ||
727 | monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; | 727 | monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; |
728 | monc->client->msgr->inst.name.num = monc->auth->global_id; | 728 | monc->client->msgr->inst.name.num = |
729 | cpu_to_le64(monc->auth->global_id); | ||
729 | 730 | ||
730 | __send_subscribe(monc); | 731 | __send_subscribe(monc); |
731 | __resend_generic_request(monc); | 732 | __resend_generic_request(monc); |
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d25b4add85b4..92b7251a53f1 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
@@ -1344,7 +1344,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) | |||
1344 | int type = le16_to_cpu(msg->hdr.type); | 1344 | int type = le16_to_cpu(msg->hdr.type); |
1345 | 1345 | ||
1346 | if (!osd) | 1346 | if (!osd) |
1347 | return; | 1347 | goto out; |
1348 | osdc = osd->o_osdc; | 1348 | osdc = osd->o_osdc; |
1349 | 1349 | ||
1350 | switch (type) { | 1350 | switch (type) { |
@@ -1359,6 +1359,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) | |||
1359 | pr_err("received unknown message type %d %s\n", type, | 1359 | pr_err("received unknown message type %d %s\n", type, |
1360 | ceph_msg_type_name(type)); | 1360 | ceph_msg_type_name(type)); |
1361 | } | 1361 | } |
1362 | out: | ||
1362 | ceph_msg_put(msg); | 1363 | ceph_msg_put(msg); |
1363 | } | 1364 | } |
1364 | 1365 | ||
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index ddc656fb5c05..50ce64ebd330 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
@@ -707,6 +707,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
707 | newcrush = crush_decode(*p, min(*p+len, end)); | 707 | newcrush = crush_decode(*p, min(*p+len, end)); |
708 | if (IS_ERR(newcrush)) | 708 | if (IS_ERR(newcrush)) |
709 | return ERR_CAST(newcrush); | 709 | return ERR_CAST(newcrush); |
710 | *p += len; | ||
710 | } | 711 | } |
711 | 712 | ||
712 | /* new flags? */ | 713 | /* new flags? */ |