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,
return -EAGAIN;
}
op = le32_to_cpu(head->op);
op = le16_to_cpu(head->op);
result = le32_to_cpu(head->result);
dout("handle_reply op %d result %d\n", op, result);
switch (op) {
......
......@@ -244,8 +244,14 @@ static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx)
struct ceph_cap *cap = NULL;
/* temporary, until we do something about cap import/export */
if (!ctx)
return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
if (!ctx) {
cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
if (cap) {
caps_use_count++;
caps_total_count++;
}
return cap;
}
spin_lock(&caps_list_lock);
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,
struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_cap *cap;
struct ceph_mds_request_release *rel = *p;
int used, dirty;
int ret = 0;
int used = 0;
spin_lock(&inode->i_lock);
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,
mds, ceph_cap_string(used), ceph_cap_string(drop),
dout("encode_inode_release %p mds%d used|dirty %s drop %s unless %s\n",
inode, mds, ceph_cap_string(used|dirty), ceph_cap_string(drop),
ceph_cap_string(unless));
/* only drop unused caps */
drop &= ~used;
/* only drop unused, clean caps */
drop &= ~(used | dirty);
cap = __get_cap_for_mds(ci, mds);
if (cap && __cap_is_valid(cap)) {
......
......@@ -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)
{
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) {
case CRUSH_BUCKET_UNIFORM:
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)
*/
static int is_out(struct crush_map *map, __u32 *weight, int item, int x)
{
if (weight[item] >= 0x1000)
if (weight[item] >= 0x10000)
return 0;
if (weight[item] == 0)
return 1;
......@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map,
int itemtype;
int collide, reject;
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++) {
/* keep trying until we get a non-out, non-colliding item */
......@@ -366,6 +368,7 @@ static int crush_choose(struct crush_map *map,
BUG_ON(item >= 0 ||
(-1-item) >= map->max_buckets);
in = map->buckets[-1-item];
retry_bucket = 1;
continue;
}
......@@ -377,15 +380,25 @@ static int crush_choose(struct crush_map *map,
}
}
if (recurse_to_leaf &&
item < 0 &&
crush_choose(map, map->buckets[-1-item],
weight,
x, outpos+1, 0,
out2, outpos,
firstn, 0, NULL) <= outpos) {
reject = 1;
} else {
reject = 0;
if (recurse_to_leaf) {
if (item < 0) {
if (crush_choose(map,
map->buckets[-1-item],
weight,
x, outpos+1, 0,
out2, outpos,
firstn, 0,
NULL) <= outpos)
/* didn't get leaf */
reject = 1;
} else {
/* we already have a leaf! */
out2[outpos] = item;
}
}
if (!reject) {
/* out? */
if (itemtype == 0)
reject = is_out(map, weight,
......@@ -424,12 +437,12 @@ static int crush_choose(struct crush_map *map,
continue;
}
dprintk("choose got %d\n", item);
dprintk("CHOOSE got %d\n", item);
out[outpos] = item;
outpos++;
}
dprintk("choose returns %d\n", outpos);
dprintk("CHOOSE returns %d\n", outpos);
return outpos;
}
......
......@@ -261,7 +261,7 @@ static int osdc_show(struct seq_file *s, void *pp)
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;
ceph_reservation_status(client, &total, &avail, &used, &reserved, &min);
......
......@@ -854,8 +854,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
d_drop(dn);
realdn = d_materialise_unique(dn, in);
if (IS_ERR(realdn)) {
pr_err("splice_dentry error %p inode %p ino %llx.%llx\n",
dn, in, ceph_vinop(in));
pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
PTR_ERR(realdn), dn, in, ceph_vinop(in));
if (prehash)
*prehash = false; /* don't rehash on error */
dn = realdn; /* note realdn contains the error */
......@@ -1234,18 +1234,23 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
goto out;
}
dn = splice_dentry(dn, in, NULL);
if (IS_ERR(dn))
dn = NULL;
}
if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
req->r_request_started, -1,
&req->r_caps_reservation) < 0) {
pr_err("fill_inode badness on %p\n", in);
dput(dn);
continue;
goto next_item;
}
update_dentry_lease(dn, rinfo->dir_dlease[i],
req->r_session, req->r_request_started);
dput(dn);
if (dn)
update_dentry_lease(dn, rinfo->dir_dlease[i],
req->r_session,
req->r_request_started);
next_item:
if (dn)
dput(dn);
}
req->r_did_prepopulate = true;
......
......@@ -2783,6 +2783,12 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc)
drop_leases(mdsc);
ceph_flush_dirty_caps(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,
dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
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.connect_seq = cpu_to_le32(con->connect_seq);
con->out_connect.global_seq = cpu_to_le32(global_seq);
......@@ -1396,10 +1396,12 @@ static int read_partial_message(struct ceph_connection *con)
if (!con->in_msg) {
dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
con->in_hdr.front_len, con->in_hdr.data_len);
skip = 0;
con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
if (skip) {
/* skip this message */
dout("alloc_msg said skip message\n");
BUG_ON(con->in_msg);
con->in_base_pos = -front_len - middle_len - data_len -
sizeof(m->footer);
con->in_tag = CEPH_MSGR_TAG_READY;
......
......@@ -725,7 +725,8 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
dout("authenticated, starting session\n");
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);
__resend_generic_request(monc);
......
......@@ -1344,7 +1344,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
int type = le16_to_cpu(msg->hdr.type);
if (!osd)
return;
goto out;
osdc = osd->o_osdc;
switch (type) {
......@@ -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,
ceph_msg_type_name(type));
}
out:
ceph_msg_put(msg);
}
......
......@@ -707,6 +707,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
newcrush = crush_decode(*p, min(*p+len, end));
if (IS_ERR(newcrush))
return ERR_CAST(newcrush);
*p += len;
}
/* 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