Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51042122 authored by Sage Weil's avatar Sage Weil
Browse files

ceph: fix endian conversions for ceph_pg



The endian conversions don't quite work with the old union ceph_pg.  Just
make it a regular struct, and make each field __le.  This is simpler and it
has the added bonus of actually working.

Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 63f2d211
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -99,7 +99,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
	u64 len = 1, olen;
	u64 tmp;
	struct ceph_object_layout ol;
	union ceph_pg pgid;
	struct ceph_pg pgid;

	/* copy and validate */
	if (copy_from_user(&dl, arg, sizeof(dl)))
@@ -121,7 +121,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
	ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout,
				osdc->osdmap);

	pgid.pg64 = le64_to_cpu(ol.ol_pgid);
	pgid = ol.ol_pgid;
	dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid);
	if (dl.osd >= 0) {
		struct ceph_entity_addr *a =
+4 −4
Original line number Diff line number Diff line
@@ -520,7 +520,7 @@ static int __map_osds(struct ceph_osd_client *osdc,
		      struct ceph_osd_request *req)
{
	struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
	union ceph_pg pgid;
	struct ceph_pg pgid;
	int o = -1;
	int err;
	struct ceph_osd *newosd = NULL;
@@ -530,7 +530,7 @@ static int __map_osds(struct ceph_osd_client *osdc,
				      &req->r_file_layout, osdc->osdmap);
	if (err)
		return err;
	pgid.pg64 = le64_to_cpu(reqhead->layout.ol_pgid);
	pgid = reqhead->layout.ol_pgid;
	o = ceph_calc_pg_primary(osdc->osdmap, pgid);

	if ((req->r_osd && req->r_osd->o_osd == o &&
@@ -538,8 +538,8 @@ static int __map_osds(struct ceph_osd_client *osdc,
	    (req->r_osd == NULL && o == -1))
		return 0;  /* no change */

	dout("map_osds tid %llu pgid %llx pool %d osd%d (was osd%d)\n",
	     req->r_tid, pgid.pg64, pgid.pg.pool, o,
	dout("map_osds tid %llu pgid %d.%x osd%d (was osd%d)\n",
	     req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
	     req->r_osd ? req->r_osd->o_osd : -1);

	if (req->r_osd) {
+61 −39
Original line number Diff line number Diff line
@@ -366,19 +366,33 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
/*
 * Insert a new pg_temp mapping
 */
static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
{
	u64 a = *(u64 *)&l;
	u64 b = *(u64 *)&r;

	if (a < b)
		return -1;
	if (a > b)
		return 1;
	return 0;
}

static int __insert_pg_mapping(struct ceph_pg_mapping *new,
			       struct rb_root *root)
{
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	struct ceph_pg_mapping *pg = NULL;
	int c;

	while (*p) {
		parent = *p;
		pg = rb_entry(parent, struct ceph_pg_mapping, node);
		if (new->pgid < pg->pgid)
		c = pgid_cmp(new->pgid, pg->pgid);
		if (c < 0)
			p = &(*p)->rb_left;
		else if (new->pgid > pg->pgid)
		else if (c > 0)
			p = &(*p)->rb_right;
		else
			return -EEXIST;
@@ -467,11 +481,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
	ceph_decode_32_safe(p, end, len, bad);
	for (i = 0; i < len; i++) {
		int n, j;
		u64 pgid;
		struct ceph_pg pgid;
		struct ceph_pg_mapping *pg;

		ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
		pgid = ceph_decode_64(p);
		ceph_decode_copy(p, &pgid, sizeof(pgid));
		n = ceph_decode_32(p);
		ceph_decode_need(p, end, n * sizeof(u32), bad);
		pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
@@ -487,7 +501,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
		err = __insert_pg_mapping(pg, &map->pg_temp);
		if (err)
			goto bad;
		dout(" added pg_temp %llx len %d\n", pgid, len);
		dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, len);
	}

	/* crush */
@@ -659,19 +673,20 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
	while (len--) {
		struct ceph_pg_mapping *pg;
		int j;
		u64 pgid;
		struct ceph_pg pgid;
		u32 pglen;
		ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
		pgid = ceph_decode_64(p);
		ceph_decode_copy(p, &pgid, sizeof(pgid));
		pglen = ceph_decode_32(p);

		/* remove any? */
		while (rbp && rb_entry(rbp, struct ceph_pg_mapping,
				       node)->pgid <= pgid) {
		while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
						node)->pgid, pgid) <= 0) {
			struct rb_node *cur = rbp;
			rbp = rb_next(rbp);
			dout(" removed pg_temp %llx\n",
			     rb_entry(cur, struct ceph_pg_mapping, node)->pgid);
			     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
					       node)->pgid);
			rb_erase(cur, &map->pg_temp);
		}

@@ -690,14 +705,16 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
			err = __insert_pg_mapping(pg, &map->pg_temp);
			if (err)
				goto bad;
			dout(" added pg_temp %llx len %d\n", pgid, pglen);
			dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
			     pglen);
		}
	}
	while (rbp) {
		struct rb_node *cur = rbp;
		rbp = rb_next(rbp);
		dout(" removed pg_temp %llx\n",
		     rb_entry(cur, struct ceph_pg_mapping, node)->pgid);
		     *(u64 *)&rb_entry(cur, struct ceph_pg_mapping,
				       node)->pgid);
		rb_erase(cur, &map->pg_temp);
	}

@@ -782,16 +799,19 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
			    struct ceph_osdmap *osdmap)
{
	unsigned num, num_mask;
	union ceph_pg pgid;
	struct ceph_pg pgid;
	s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred);
	int poolid = le32_to_cpu(fl->fl_pg_pool);
	struct ceph_pg_pool_info *pool;
	unsigned ps;

	if (poolid >= osdmap->num_pools)
		return -EIO;
	pool = &osdmap->pg_pool[poolid];

	pool = &osdmap->pg_pool[poolid];
	ps = ceph_full_name_hash(oid, strlen(oid));
	if (preferred >= 0) {
		ps += preferred;
		num = le32_to_cpu(pool->v.lpg_num);
		num_mask = pool->lpg_num_mask;
	} else {
@@ -799,22 +819,17 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
		num_mask = pool->pg_num_mask;
	}

	pgid.pg64 = 0;   /* start with it zeroed out */
	pgid.pg.ps = ceph_full_name_hash(oid, strlen(oid));
	pgid.pg.preferred = preferred;
	if (preferred >= 0)
		pgid.pg.ps += preferred;
	pgid.pg.pool = le32_to_cpu(fl->fl_pg_pool);
	pgid.ps = cpu_to_le16(ps);
	pgid.preferred = cpu_to_le16(preferred);
	pgid.pool = fl->fl_pg_pool;
	if (preferred >= 0)
		dout("calc_object_layout '%s' pgid %d.%xp%d (%llx)\n", oid,
		     pgid.pg.pool, pgid.pg.ps, (int)preferred, pgid.pg64);
		dout("calc_object_layout '%s' pgid %d.%xp%d\n", oid, poolid, ps,
		     (int)preferred);
	else
		dout("calc_object_layout '%s' pgid %d.%x (%llx)\n", oid,
		     pgid.pg.pool, pgid.pg.ps, pgid.pg64);
		dout("calc_object_layout '%s' pgid %d.%x\n", oid, poolid, ps);

	ol->ol_pgid = cpu_to_le64(pgid.pg64);
	ol->ol_pgid = pgid;
	ol->ol_stripe_unit = fl->fl_object_stripe_unit;

	return 0;
}

@@ -822,21 +837,24 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
 * Calculate raw osd vector for the given pgid.  Return pointer to osd
 * array, or NULL on failure.
 */
static int *calc_pg_raw(struct ceph_osdmap *osdmap, union ceph_pg pgid,
static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
			int *osds, int *num)
{
	struct rb_node *n = osdmap->pg_temp.rb_node;
	struct ceph_pg_mapping *pg;
	struct ceph_pg_pool_info *pool;
	int ruleno;
	unsigned pps; /* placement ps */
	unsigned poolid, ps, pps;
	int preferred;
	int c;

	/* pg_temp? */
	while (n) {
		pg = rb_entry(n, struct ceph_pg_mapping, node);
		if (pgid.pg64 < pg->pgid)
		c = pgid_cmp(pgid, pg->pgid);
		if (c < 0)
			n = n->rb_left;
		else if (pgid.pg64 > pg->pgid)
		else if (c > 0)
			n = n->rb_right;
		else {
			*num = pg->len;
@@ -845,36 +863,40 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, union ceph_pg pgid,
	}

	/* crush */
	if (pgid.pg.pool >= osdmap->num_pools)
	poolid = le32_to_cpu(pgid.pool);
	ps = le16_to_cpu(pgid.ps);
	preferred = (s16)le16_to_cpu(pgid.preferred);

	if (poolid >= osdmap->num_pools)
		return NULL;
	pool = &osdmap->pg_pool[pgid.pg.pool];
	pool = &osdmap->pg_pool[poolid];
	ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
				 pool->v.type, pool->v.size);
	if (ruleno < 0) {
		pr_err("no crush rule pool %d type %d size %d\n",
		       pgid.pg.pool, pool->v.type, pool->v.size);
		       poolid, pool->v.type, pool->v.size);
		return NULL;
	}

	if (pgid.pg.preferred >= 0)
		pps = ceph_stable_mod(pgid.pg.ps,
	if (preferred >= 0)
		pps = ceph_stable_mod(ps,
				      le32_to_cpu(pool->v.lpgp_num),
				      pool->lpgp_num_mask);
	else
		pps = ceph_stable_mod(pgid.pg.ps,
		pps = ceph_stable_mod(ps,
				      le32_to_cpu(pool->v.pgp_num),
				      pool->pgp_num_mask);
	pps += pgid.pg.pool;
	pps += poolid;
	*num = crush_do_rule(osdmap->crush, ruleno, pps, osds,
			     min_t(int, pool->v.size, *num),
			     pgid.pg.preferred, osdmap->osd_weight);
			     preferred, osdmap->osd_weight);
	return osds;
}

/*
 * Return primary osd for given pgid, or -1 if none.
 */
int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid)
int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
{
	int rawosds[10], *osds;
	int i, num = ARRAY_SIZE(rawosds);
+3 −2
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ struct ceph_pg_pool_info {

struct ceph_pg_mapping {
	struct rb_node node;
	u64 pgid;
	struct ceph_pg pgid;
	int len;
	int osds[];
};
@@ -118,6 +118,7 @@ extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
				   const char *oid,
				   struct ceph_file_layout *fl,
				   struct ceph_osdmap *osdmap);
extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid);
extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
				struct ceph_pg pgid);

#endif
+5 −8
Original line number Diff line number Diff line
@@ -55,13 +55,10 @@ struct ceph_timespec {
 * placement group.
 * we encode this into one __le64.
 */
union ceph_pg {
	__u64 pg64;
	struct {
		__s16 preferred; /* preferred primary osd */
		__u16 ps;        /* placement seed */
		__u32 pool;      /* object pool */
	} __attribute__ ((packed)) pg;
struct ceph_pg {
	__le16 preferred; /* preferred primary osd */
	__le16 ps;        /* placement seed */
	__le32 pool;      /* object pool */
} __attribute__ ((packed));

/*
@@ -117,7 +114,7 @@ static inline int ceph_stable_mod(int x, int b, int bmask)
 * object layout - how a given object should be stored.
 */
struct ceph_object_layout {
	__le64 ol_pgid;           /* raw pg, with _full_ ps precision. */
	struct ceph_pg ol_pgid;   /* raw pg, with _full_ ps precision. */
	__le32 ol_stripe_unit;    /* for per-object parity, if any */
} __attribute__ ((packed));