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
This commit is contained in:
commit
1cc9629402
10 changed files with 69 additions and 33 deletions
|
@ -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? */
|
||||
|
|
Loading…
Add table
Reference in a new issue