aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-07-06 20:15:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-07-06 20:15:15 -0400
commit1cc9629402b1eba0d4e21b2cc43eec9bd737f9bd (patch)
tree6bd52203d0d071acd3311d5093b4aa61c313faad /fs
parent8b8ce8810b092cef35e15af6577ad569f6145c0a (diff)
parent153a10939ea6e42e9c0115b0645060d0d7bb4697 (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.c2
-rw-r--r--fs/ceph/caps.c21
-rw-r--r--fs/ceph/crush/mapper.c41
-rw-r--r--fs/ceph/debugfs.c2
-rw-r--r--fs/ceph/inode.c19
-rw-r--r--fs/ceph/mds_client.c6
-rw-r--r--fs/ceph/messenger.c4
-rw-r--r--fs/ceph/mon_client.c3
-rw-r--r--fs/ceph/osd_client.c3
-rw-r--r--fs/ceph/osdmap.c1
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
239static int crush_bucket_choose(struct crush_bucket *in, int x, int r) 239static 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 */
265static int is_out(struct crush_map *map, __u32 *weight, int item, int x) 265static 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
262static int caps_show(struct seq_file *s, void *p) 262static 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);
1251next_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 }
1362out:
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? */