* request accordingly. shorten extent as necessary if it crosses an
* object boundary.
*/
-static int calc_layout(struct ceph_osd_client *osdc,
- struct ceph_vino vino, struct ceph_file_layout *layout,
- u64 off, u64 *plen,
- struct ceph_osd_request *req)
+static void calc_layout(struct ceph_osd_client *osdc,
+ struct ceph_vino vino, struct ceph_file_layout *layout,
+ u64 off, u64 *plen,
+ struct ceph_osd_request *req)
{
struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
struct ceph_osd_op *op = (void *)(reqhead + 1);
u64 orig_len = *plen;
u64 objoff, objlen; /* extent in object */
- int err;
/* object extent? */
reqhead->oid.ino = cpu_to_le64(vino.ino);
op->length = cpu_to_le64(objlen);
req->r_num_pages = calc_pages_for(off, *plen);
- /* pgid? */
- err = ceph_calc_object_layout(&reqhead->layout, &reqhead->oid, layout,
- osdc->osdmap);
-
- dout(10, "calc_layout %llx.%08x %llu~%llu pgid %llx (%d pages)\n",
+ dout(10, "calc_layout %llx.%08x %llu~%llu (%d pages)\n",
le64_to_cpu(reqhead->oid.ino), le32_to_cpu(reqhead->oid.bno),
- objoff, objlen, le64_to_cpu(reqhead->layout.ol_pgid),
- req->r_num_pages);
- return err;
+ objoff, objlen, req->r_num_pages);
}
int do_trunc = truncate_seq && (off + *plen > truncate_size);
int num_op = 1 + do_sync + do_trunc;
size_t msg_size = sizeof(*head) + num_op*sizeof(*op);
- int i, err;
+ int i;
u64 prevofs;
/* we may overallocate here, if our write extent is shortened below */
req->r_request = msg;
req->r_snapc = ceph_get_snap_context(snapc);
- /* calculate max write size, pgid */
- err = calc_layout(osdc, vino, layout, off, plen, req);
- if (err < 0) {
- ceph_msg_put(msg);
- kfree(req);
- return ERR_PTR(err);
- }
- req->r_pgid.pg64 = le64_to_cpu(head->layout.ol_pgid);
+ /* calculate max write size */
+ calc_layout(osdc, vino, layout, off, plen, req);
+ req->r_file_layout = *layout; /* keep a copy */
if (flags & CEPH_OSD_FLAG_MODIFY) {
req->r_request->hdr.data_off = cpu_to_le16(off);
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_pool_info *pool;
int ruleno;
unsigned pps; /* placement ps */
int osds[10], osd = -1;
int i, num;
- struct ceph_pg_pool_info *pool;
+ int err;
- if (req->r_pgid.pg.pool >= osdc->osdmap->num_pools)
+ err = ceph_calc_object_layout(&reqhead->layout, &reqhead->oid,
+ &req->r_file_layout, osdc->osdmap);
+ if (err)
+ return err;
+ pgid.pg64 = le64_to_cpu(reqhead->layout.ol_pgid);
+ if (pgid.pg.pool >= osdc->osdmap->num_pools)
return -1;
- pool = &osdc->osdmap->pg_pool[req->r_pgid.pg.pool];
+ pool = &osdc->osdmap->pg_pool[pgid.pg.pool];
ruleno = crush_find_rule(osdc->osdmap->crush, pool->v.crush_ruleset,
pool->v.type, pool->v.size);
if (ruleno < 0) {
derr(0, "map_osds no crush rule for pool %d type %d size %d\n",
- req->r_pgid.pg.pool, pool->v.type, pool->v.size);
+ pgid.pg.pool, pool->v.type, pool->v.size);
return -1;
}
- if (req->r_pgid.pg.preferred >= 0)
- pps = ceph_stable_mod(req->r_pgid.pg.ps,
+ if (pgid.pg.preferred >= 0)
+ pps = ceph_stable_mod(pgid.pg.ps,
le32_to_cpu(pool->v.lpgp_num),
pool->lpgp_num_mask);
else
- pps = ceph_stable_mod(req->r_pgid.pg.ps,
+ pps = ceph_stable_mod(pgid.pg.ps,
le32_to_cpu(pool->v.pgp_num),
pool->pgp_num_mask);
num = crush_do_rule(osdc->osdmap->crush, ruleno, pps, osds,
min_t(int, pool->v.size, ARRAY_SIZE(osds)),
- req->r_pgid.pg.preferred, osdc->osdmap->osd_weight);
+ pgid.pg.preferred, osdc->osdmap->osd_weight);
/* primary is first up osd */
for (i = 0; i < num; i++)
osd = osds[i];
break;
}
- dout(20, "map_osds tid %llu osd%d (was osd%d)\n", req->r_tid, osd,
- req->r_last_osd);
+ dout(20, "map_osds tid %llu pgid %llx pool %d osd%d (was osd%d)\n",
+ req->r_tid, pgid.pg64, pgid.pg.pool, osd, req->r_last_osd);
if (req->r_last_osd == osd &&
(osd < 0 || ceph_entity_addr_equal(&osdc->osdmap->osd_addr[osd],
&req->r_last_osd_addr)))