Commit 1cc96294 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 8b8ce881 153a1093
...@@ -493,7 +493,7 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, ...@@ -493,7 +493,7 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
return -EAGAIN; return -EAGAIN;
} }
op = le32_to_cpu(head->op); op = le16_to_cpu(head->op);
result = le32_to_cpu(head->result); result = le32_to_cpu(head->result);
dout("handle_reply op %d result %d\n", op, result); dout("handle_reply op %d result %d\n", op, result);
switch (op) { switch (op) {
......
...@@ -244,8 +244,14 @@ static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx) ...@@ -244,8 +244,14 @@ static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx)
struct ceph_cap *cap = NULL; struct ceph_cap *cap = NULL;
/* temporary, until we do something about cap import/export */ /* temporary, until we do something about cap import/export */
if (!ctx) if (!ctx) {
return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
if (cap) {
caps_use_count++;
caps_total_count++;
}
return cap;
}
spin_lock(&caps_list_lock); spin_lock(&caps_list_lock);
dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", 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,18 +2892,19 @@ int ceph_encode_inode_release(void **p, struct inode *inode,
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_cap *cap; struct ceph_cap *cap;
struct ceph_mds_request_release *rel = *p; struct ceph_mds_request_release *rel = *p;
int used, dirty;
int ret = 0; int ret = 0;
int used = 0;
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
used = __ceph_caps_used(ci); used = __ceph_caps_used(ci);
dirty = __ceph_caps_dirty(ci);
dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode, dout("encode_inode_release %p mds%d used|dirty %s drop %s unless %s\n",
mds, ceph_cap_string(used), ceph_cap_string(drop), inode, mds, ceph_cap_string(used|dirty), ceph_cap_string(drop),
ceph_cap_string(unless)); ceph_cap_string(unless));
/* only drop unused caps */ /* only drop unused, clean caps */
drop &= ~used; drop &= ~(used | dirty);
cap = __get_cap_for_mds(ci, mds); cap = __get_cap_for_mds(ci, mds);
if (cap && __cap_is_valid(cap)) { if (cap && __cap_is_valid(cap)) {
......
...@@ -238,7 +238,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket, ...@@ -238,7 +238,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket,
static int crush_bucket_choose(struct crush_bucket *in, int x, int r) static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
{ {
dprintk("choose %d x=%d r=%d\n", in->id, x, r); dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r);
switch (in->alg) { switch (in->alg) {
case CRUSH_BUCKET_UNIFORM: case CRUSH_BUCKET_UNIFORM:
return bucket_uniform_choose((struct crush_bucket_uniform *)in, 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,7 +264,7 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
*/ */
static int is_out(struct crush_map *map, __u32 *weight, int item, int x) static int is_out(struct crush_map *map, __u32 *weight, int item, int x)
{ {
if (weight[item] >= 0x1000) if (weight[item] >= 0x10000)
return 0; return 0;
if (weight[item] == 0) if (weight[item] == 0)
return 1; return 1;
...@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map, ...@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map,
int itemtype; int itemtype;
int collide, reject; int collide, reject;
const int orig_tries = 5; /* attempts before we fall back to search */ const int orig_tries = 5; /* attempts before we fall back to search */
dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos);
dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d\n", recurse_to_leaf ? "_LEAF" : "",
bucket->id, x, outpos, numrep);
for (rep = outpos; rep < numrep; rep++) { for (rep = outpos; rep < numrep; rep++) {
/* keep trying until we get a non-out, non-colliding item */ /* keep trying until we get a non-out, non-colliding item */
...@@ -366,6 +368,7 @@ static int crush_choose(struct crush_map *map, ...@@ -366,6 +368,7 @@ static int crush_choose(struct crush_map *map,
BUG_ON(item >= 0 || BUG_ON(item >= 0 ||
(-1-item) >= map->max_buckets); (-1-item) >= map->max_buckets);
in = map->buckets[-1-item]; in = map->buckets[-1-item];
retry_bucket = 1;
continue; continue;
} }
...@@ -377,15 +380,25 @@ static int crush_choose(struct crush_map *map, ...@@ -377,15 +380,25 @@ static int crush_choose(struct crush_map *map,
} }
} }
if (recurse_to_leaf && reject = 0;
item < 0 && if (recurse_to_leaf) {
crush_choose(map, map->buckets[-1-item], if (item < 0) {
if (crush_choose(map,
map->buckets[-1-item],
weight, weight,
x, outpos+1, 0, x, outpos+1, 0,
out2, outpos, out2, outpos,
firstn, 0, NULL) <= outpos) { firstn, 0,
NULL) <= outpos)
/* didn't get leaf */
reject = 1; reject = 1;
} else { } else {
/* we already have a leaf! */
out2[outpos] = item;
}
}
if (!reject) {
/* out? */ /* out? */
if (itemtype == 0) if (itemtype == 0)
reject = is_out(map, weight, reject = is_out(map, weight,
...@@ -424,12 +437,12 @@ static int crush_choose(struct crush_map *map, ...@@ -424,12 +437,12 @@ static int crush_choose(struct crush_map *map,
continue; continue;
} }
dprintk("choose got %d\n", item); dprintk("CHOOSE got %d\n", item);
out[outpos] = item; out[outpos] = item;
outpos++; outpos++;
} }
dprintk("choose returns %d\n", outpos); dprintk("CHOOSE returns %d\n", outpos);
return outpos; return outpos;
} }
......
...@@ -261,7 +261,7 @@ static int osdc_show(struct seq_file *s, void *pp) ...@@ -261,7 +261,7 @@ static int osdc_show(struct seq_file *s, void *pp)
static int caps_show(struct seq_file *s, void *p) static int caps_show(struct seq_file *s, void *p)
{ {
struct ceph_client *client = p; struct ceph_client *client = s->private;
int total, avail, used, reserved, min; int total, avail, used, reserved, min;
ceph_reservation_status(client, &total, &avail, &used, &reserved, &min); ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
......
...@@ -854,8 +854,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, ...@@ -854,8 +854,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
d_drop(dn); d_drop(dn);
realdn = d_materialise_unique(dn, in); realdn = d_materialise_unique(dn, in);
if (IS_ERR(realdn)) { if (IS_ERR(realdn)) {
pr_err("splice_dentry error %p inode %p ino %llx.%llx\n", pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
dn, in, ceph_vinop(in)); PTR_ERR(realdn), dn, in, ceph_vinop(in));
if (prehash) if (prehash)
*prehash = false; /* don't rehash on error */ *prehash = false; /* don't rehash on error */
dn = realdn; /* note realdn contains the error */ dn = realdn; /* note realdn contains the error */
...@@ -1234,17 +1234,22 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, ...@@ -1234,17 +1234,22 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
goto out; goto out;
} }
dn = splice_dentry(dn, in, NULL); dn = splice_dentry(dn, in, NULL);
if (IS_ERR(dn))
dn = NULL;
} }
if (fill_inode(in, &rinfo->dir_in[i], NULL, session, if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
req->r_request_started, -1, req->r_request_started, -1,
&req->r_caps_reservation) < 0) { &req->r_caps_reservation) < 0) {
pr_err("fill_inode badness on %p\n", in); pr_err("fill_inode badness on %p\n", in);
dput(dn); goto next_item;
continue;
} }
if (dn)
update_dentry_lease(dn, rinfo->dir_dlease[i], update_dentry_lease(dn, rinfo->dir_dlease[i],
req->r_session, req->r_request_started); req->r_session,
req->r_request_started);
next_item:
if (dn)
dput(dn); dput(dn);
} }
req->r_did_prepopulate = true; req->r_did_prepopulate = true;
......
...@@ -2783,6 +2783,12 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) ...@@ -2783,6 +2783,12 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
drop_leases(mdsc); drop_leases(mdsc);
ceph_flush_dirty_caps(mdsc); ceph_flush_dirty_caps(mdsc);
wait_requests(mdsc); wait_requests(mdsc);
/*
* wait for reply handlers to drop their request refs and
* their inode/dcache refs
*/
ceph_msgr_flush();
} }
/* /*
......
...@@ -657,7 +657,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr, ...@@ -657,7 +657,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr,
dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
con->connect_seq, global_seq, proto); con->connect_seq, global_seq, proto);
con->out_connect.features = CEPH_FEATURE_SUPPORTED_CLIENT; con->out_connect.features = cpu_to_le64(CEPH_FEATURE_SUPPORTED_CLIENT);
con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
con->out_connect.global_seq = cpu_to_le32(global_seq); con->out_connect.global_seq = cpu_to_le32(global_seq);
...@@ -1396,10 +1396,12 @@ static int read_partial_message(struct ceph_connection *con) ...@@ -1396,10 +1396,12 @@ static int read_partial_message(struct ceph_connection *con)
if (!con->in_msg) { if (!con->in_msg) {
dout("got hdr type %d front %d data %d\n", con->in_hdr.type, dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
con->in_hdr.front_len, con->in_hdr.data_len); con->in_hdr.front_len, con->in_hdr.data_len);
skip = 0;
con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip); con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
if (skip) { if (skip) {
/* skip this message */ /* skip this message */
dout("alloc_msg said skip message\n"); dout("alloc_msg said skip message\n");
BUG_ON(con->in_msg);
con->in_base_pos = -front_len - middle_len - data_len - con->in_base_pos = -front_len - middle_len - data_len -
sizeof(m->footer); sizeof(m->footer);
con->in_tag = CEPH_MSGR_TAG_READY; con->in_tag = CEPH_MSGR_TAG_READY;
......
...@@ -725,7 +725,8 @@ static void handle_auth_reply(struct ceph_mon_client *monc, ...@@ -725,7 +725,8 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
dout("authenticated, starting session\n"); dout("authenticated, starting session\n");
monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
monc->client->msgr->inst.name.num = monc->auth->global_id; monc->client->msgr->inst.name.num =
cpu_to_le64(monc->auth->global_id);
__send_subscribe(monc); __send_subscribe(monc);
__resend_generic_request(monc); __resend_generic_request(monc);
......
...@@ -1344,7 +1344,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) ...@@ -1344,7 +1344,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
int type = le16_to_cpu(msg->hdr.type); int type = le16_to_cpu(msg->hdr.type);
if (!osd) if (!osd)
return; goto out;
osdc = osd->o_osdc; osdc = osd->o_osdc;
switch (type) { switch (type) {
...@@ -1359,6 +1359,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) ...@@ -1359,6 +1359,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
pr_err("received unknown message type %d %s\n", type, pr_err("received unknown message type %d %s\n", type,
ceph_msg_type_name(type)); ceph_msg_type_name(type));
} }
out:
ceph_msg_put(msg); ceph_msg_put(msg);
} }
......
...@@ -707,6 +707,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ...@@ -707,6 +707,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
newcrush = crush_decode(*p, min(*p+len, end)); newcrush = crush_decode(*p, min(*p+len, end));
if (IS_ERR(newcrush)) if (IS_ERR(newcrush))
return ERR_CAST(newcrush); return ERR_CAST(newcrush);
*p += len;
} }
/* new flags? */ /* new flags? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment