/* * Callback function invoked by the OSP layer when the connection to the master * has been set up. * * \param data - is a pointer to the qsd_instance * * \retval - 0 on success, appropriate error on failure */ static int qsd_conn_callback(void *data) { struct qsd_instance *qsd = (struct qsd_instance *)data; int type; ENTRY; /* qsd_exp should now be valid */ LASSERT(qsd->qsd_exp); qsd->qsd_ns = class_exp2obd(qsd->qsd_exp)->obd_namespace; write_lock(&qsd->qsd_lock); /* notify that qsd_exp is now valid */ qsd->qsd_exp_valid = true; write_unlock(&qsd->qsd_lock); /* Now that the connection to master is setup, we can initiate the * reintegration procedure for quota types which are enabled. * It is worth noting that, if the qsd_instance hasn't been started * already, then we can only complete the first two steps of the * reintegration procedure (i.e. global lock enqueue and slave * index transfer) since the space usage reconciliation (i.e. * step 3) will have to wait for qsd_start() to be called */ for (type = USRQUOTA; type < MAXQUOTAS; type++) { struct qsd_qtype_info *qqi = qsd->qsd_type_array[type]; wake_up(&qqi->qqi_reint_thread.t_ctl_waitq); } RETURN(0); }
int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, struct lov_stripe_md *lsm) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; return lov_obd_packmd(lov, lmmp, lsm); }
int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) { CFS_LIST_HEAD(cancels); struct obd_device *obd = class_exp2obd(exp); struct ptlrpc_request *req = *request; int count = 0, rc; ENTRY; LASSERT(req == NULL); if ((op_data->op_flags & MF_MDC_CANCEL_FID1) && (fid_is_sane(&op_data->op_fid1)) && !OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET)) count = mdc_resource_get_unused(exp, &op_data->op_fid1, &cancels, LCK_EX, MDS_INODELOCK_UPDATE); if ((op_data->op_flags & MF_MDC_CANCEL_FID3) && (fid_is_sane(&op_data->op_fid3)) && !OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET)) count += mdc_resource_get_unused(exp, &op_data->op_fid3, &cancels, LCK_EX, MDS_INODELOCK_FULL); req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_REINT_UNLINK); if (req == NULL) { ldlm_lock_list_put(&cancels, l_bl_ast, count); RETURN(-ENOMEM); } mdc_set_capa_size(req, &RMF_CAPA1, op_data->op_capa1); req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, op_data->op_namelen + 1); rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count); if (rc) { ptlrpc_request_free(req); RETURN(rc); } mdc_unlink_pack(req, op_data); req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, obd->u.cli.cl_max_mds_easize); req_capsule_set_size(&req->rq_pill, &RMF_LOGCOOKIES, RCL_SERVER, obd->u.cli.cl_max_mds_cookiesize); ptlrpc_request_set_replen(req); *request = req; rc = mdc_reint(req, obd->u.cli.cl_rpc_lock, LUSTRE_IMP_FULL); if (rc == -ERESTARTSYS) rc = 0; RETURN(rc); }
/* Unpack LOV object metadata from disk storage. It is packed in LE byte * order and is opaque to the networking layer. */ int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, struct lov_mds_md *lmm, int lmm_bytes) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; int rc = 0, lsm_size; __u16 stripe_count; __u32 magic; __u32 pattern; ENTRY; /* If passed an MDS struct use values from there, otherwise defaults */ if (lmm) { rc = lov_verify_lmm(lmm, lmm_bytes, &stripe_count); if (rc) RETURN(rc); magic = le32_to_cpu(lmm->lmm_magic); pattern = le32_to_cpu(lmm->lmm_pattern); } else { magic = LOV_MAGIC; stripe_count = lov_get_stripecnt(lov, magic, 0); pattern = LOV_PATTERN_RAID0; } /* If we aren't passed an lsmp struct, we just want the size */ if (!lsmp) { /* XXX LOV STACKING call into osc for sizes */ LBUG(); RETURN(lov_stripe_md_size(stripe_count)); } /* If we are passed an allocated struct but nothing to unpack, free */ if (*lsmp && !lmm) { lov_free_memmd(lsmp); RETURN(0); } lsm_size = lov_alloc_memmd(lsmp, stripe_count, pattern, magic); if (lsm_size < 0) RETURN(lsm_size); /* If we are passed a pointer but nothing to unpack, we only alloc */ if (!lmm) RETURN(lsm_size); LASSERT(lsm_op_find(magic) != NULL); rc = lsm_op_find(magic)->lsm_unpackmd(lov, *lsmp, lmm); if (rc) { lov_free_memmd(lsmp); RETURN(rc); } RETURN(lsm_size); }
int lov_quota_adjust_qunit(struct obd_export *exp, struct quota_adjust_qunit *oqaq, struct lustre_quota_ctxt *qctxt, struct ptlrpc_request_set *rqset) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; int i, err, rc = 0; unsigned no_set = 0; ENTRY; if (!QAQ_IS_ADJBLK(oqaq)) { CERROR("bad qaq_flags %x for lov obd.\n", oqaq->qaq_flags); RETURN(-EFAULT); } if (rqset == NULL) { rqset = ptlrpc_prep_set(); if (!rqset) RETURN(-ENOMEM); no_set = 1; } obd_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) { CDEBUG(D_HA, "ost %d is inactive\n", i); continue; } err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq, NULL, rqset); if (err) { if (lov->lov_tgts[i]->ltd_active && !rc) rc = err; continue; } } err = ptlrpc_set_wait(rqset); if (!rc) rc = err; /* Destroy the set if none was provided by the caller */ if (no_set) ptlrpc_set_destroy(rqset); obd_putref(obd); RETURN(rc); }
int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) { LIST_HEAD(cancels); struct obd_device *obd = class_exp2obd(exp); struct ptlrpc_request *req = *request; int count = 0, rc; LASSERT(!req); if ((op_data->op_flags & MF_MDC_CANCEL_FID1) && (fid_is_sane(&op_data->op_fid1))) count = mdc_resource_get_unused(exp, &op_data->op_fid1, &cancels, LCK_EX, MDS_INODELOCK_UPDATE); if ((op_data->op_flags & MF_MDC_CANCEL_FID3) && (fid_is_sane(&op_data->op_fid3))) count += mdc_resource_get_unused(exp, &op_data->op_fid3, &cancels, LCK_EX, MDS_INODELOCK_FULL); req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_REINT_UNLINK); if (!req) { ldlm_lock_list_put(&cancels, l_bl_ast, count); return -ENOMEM; } req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, op_data->op_namelen + 1); rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count); if (rc) { ptlrpc_request_free(req); return rc; } mdc_unlink_pack(req, op_data); req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, obd->u.cli.cl_default_mds_easize); ptlrpc_request_set_replen(req); *request = req; rc = mdc_reint(req, LUSTRE_IMP_FULL); if (rc == -ERESTARTSYS) rc = 0; return rc; }
int lov_quota_check(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; int i, rc = 0; ENTRY; obd_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { if (!lov->lov_tgts[i]) continue; if (!lov->lov_tgts[i]->ltd_active) { CERROR("lov idx %d inactive\n", i); rc = -EIO; goto out; } } for (i = 0; i < lov->desc.ld_tgt_count; i++) { int err; if (!lov->lov_tgts[i]) continue; err = obd_quotacheck(lov->lov_tgts[i]->ltd_exp, oqctl); if (err && !rc) rc = err; } out: obd_putref(obd); RETURN(rc); }
int lmv_quota_check(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl) { struct obd_device *obd = class_exp2obd(exp); struct lmv_obd *lmv = &obd->u.lmv; struct lmv_tgt_desc *tgt; int i, rc = 0; ENTRY; for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgt++) { int err; if (!tgt->ltd_active) { CERROR("lmv idx %d inactive\n", i); RETURN(-EIO); } err = obd_quotacheck(tgt->ltd_exp, oqctl); if (err && !rc) rc = err; } RETURN(rc); }
static int __lov_setstripe(struct obd_export *exp, int max_lmm_size, struct lov_stripe_md **lsmp, struct lov_user_md *lump) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; char buffer[sizeof(struct lov_user_md_v3)]; struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)&buffer[0]; struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&buffer[0]; int lmm_magic; __u16 stripe_count; int rc; int cplen = 0; rc = lov_lum_swab_if_needed(lumv3, &lmm_magic, lump); if (rc) return rc; /* in the rest of the tests, as *lumv1 and lumv3 have the same * fields, we use lumv1 to avoid code duplication */ if (lumv1->lmm_pattern == 0) { lumv1->lmm_pattern = lov->desc.ld_pattern ? lov->desc.ld_pattern : LOV_PATTERN_RAID0; } if (lov_pattern(lumv1->lmm_pattern) != LOV_PATTERN_RAID0) { CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n", lumv1->lmm_pattern); return -EINVAL; } /* 64kB is the largest common page size we see (ia64), and matches the * check in lfs */ if (lumv1->lmm_stripe_size & (LOV_MIN_STRIPE_SIZE - 1)) { CDEBUG(D_IOCTL, "stripe size %u not multiple of %u, fixing\n", lumv1->lmm_stripe_size, LOV_MIN_STRIPE_SIZE); lumv1->lmm_stripe_size = LOV_MIN_STRIPE_SIZE; } if ((lumv1->lmm_stripe_offset >= lov->desc.ld_tgt_count) && (lumv1->lmm_stripe_offset != (typeof(lumv1->lmm_stripe_offset))(-1))) { CDEBUG(D_IOCTL, "stripe offset %u > number of OSTs %u\n", lumv1->lmm_stripe_offset, lov->desc.ld_tgt_count); return -EINVAL; } stripe_count = lov_get_stripecnt(lov, lmm_magic, lumv1->lmm_stripe_count); if (max_lmm_size) { int max_stripes = (max_lmm_size - lov_mds_md_size(0, lmm_magic)) / sizeof(struct lov_ost_data_v1); if (unlikely(max_stripes < stripe_count)) { CDEBUG(D_IOCTL, "stripe count reset from %d to %d\n", stripe_count, max_stripes); stripe_count = max_stripes; } } if (lmm_magic == LOV_USER_MAGIC_V3) { struct pool_desc *pool; /* In the function below, .hs_keycmp resolves to * pool_hashkey_keycmp() */ /* coverity[overrun-buffer-val] */ pool = lov_find_pool(lov, lumv3->lmm_pool_name); if (pool != NULL) { if (lumv3->lmm_stripe_offset != (typeof(lumv3->lmm_stripe_offset))(-1)) { rc = lov_check_index_in_pool( lumv3->lmm_stripe_offset, pool); if (rc < 0) { lov_pool_putref(pool); return -EINVAL; } } if (stripe_count > pool_tgt_count(pool)) stripe_count = pool_tgt_count(pool); lov_pool_putref(pool); } } if (lumv1->lmm_pattern & LOV_PATTERN_F_RELEASED) stripe_count = 0; rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic); if (rc >= 0) { (*lsmp)->lsm_oinfo[0]->loi_ost_idx = lumv1->lmm_stripe_offset; (*lsmp)->lsm_stripe_size = lumv1->lmm_stripe_size; if (lmm_magic == LOV_USER_MAGIC_V3) { cplen = strlcpy((*lsmp)->lsm_pool_name, lumv3->lmm_pool_name, sizeof((*lsmp)->lsm_pool_name)); if (cplen >= sizeof((*lsmp)->lsm_pool_name)) rc = -E2BIG; } rc = 0; } return rc; }
/* Pack LOV object metadata for disk storage. It is packed in LE byte * order and is opaque to the networking layer. * * XXX In the future, this will be enhanced to get the EA size from the * underlying OSC device(s) to get their EA sizes so we can stack * LOVs properly. For now lov_mds_md_size() just assumes one obd_id * per stripe. */ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, struct lov_stripe_md *lsm) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; struct lov_mds_md_v1 *lmmv1; struct lov_mds_md_v3 *lmmv3; __u16 stripe_count; struct lov_ost_data_v1 *lmm_objects; int lmm_size, lmm_magic; int i; int cplen = 0; if (lsm) { lmm_magic = lsm->lsm_magic; } else { if (lmmp && *lmmp) lmm_magic = le32_to_cpu((*lmmp)->lmm_magic); else /* lsm == NULL and lmmp == NULL */ lmm_magic = LOV_MAGIC; } if ((lmm_magic != LOV_MAGIC_V1) && (lmm_magic != LOV_MAGIC_V3)) { CERROR("bad mem LOV MAGIC: 0x%08X != 0x%08X nor 0x%08X\n", lmm_magic, LOV_MAGIC_V1, LOV_MAGIC_V3); return -EINVAL; } if (lsm) { /* If we are just sizing the EA, limit the stripe count * to the actual number of OSTs in this filesystem. */ if (!lmmp) { stripe_count = lov_get_stripecnt(lov, lmm_magic, lsm->lsm_stripe_count); lsm->lsm_stripe_count = stripe_count; } else if (!lsm_is_released(lsm)) { stripe_count = lsm->lsm_stripe_count; } else { stripe_count = 0; } } else { /* No need to allocate more than maximum supported stripes. * Anyway, this is pretty inaccurate since ld_tgt_count now * represents max index and we should rely on the actual number * of OSTs instead */ stripe_count = lov_mds_md_max_stripe_count( lov->lov_ocd.ocd_max_easize, lmm_magic); if (stripe_count > lov->desc.ld_tgt_count) stripe_count = lov->desc.ld_tgt_count; } /* XXX LOV STACKING call into osc for sizes */ lmm_size = lov_mds_md_size(stripe_count, lmm_magic); if (!lmmp) return lmm_size; if (*lmmp && !lsm) { stripe_count = le16_to_cpu((*lmmp)->lmm_stripe_count); lmm_size = lov_mds_md_size(stripe_count, lmm_magic); OBD_FREE_LARGE(*lmmp, lmm_size); *lmmp = NULL; return 0; } if (!*lmmp) { OBD_ALLOC_LARGE(*lmmp, lmm_size); if (!*lmmp) return -ENOMEM; } CDEBUG(D_INFO, "lov_packmd: LOV_MAGIC 0x%08X, lmm_size = %d \n", lmm_magic, lmm_size); lmmv1 = *lmmp; lmmv3 = (struct lov_mds_md_v3 *)*lmmp; if (lmm_magic == LOV_MAGIC_V3) lmmv3->lmm_magic = cpu_to_le32(LOV_MAGIC_V3); else lmmv1->lmm_magic = cpu_to_le32(LOV_MAGIC_V1); if (!lsm) return lmm_size; /* lmmv1 and lmmv3 point to the same struct and have the * same first fields */ lmm_oi_cpu_to_le(&lmmv1->lmm_oi, &lsm->lsm_oi); lmmv1->lmm_stripe_size = cpu_to_le32(lsm->lsm_stripe_size); lmmv1->lmm_stripe_count = cpu_to_le16(stripe_count); lmmv1->lmm_pattern = cpu_to_le32(lsm->lsm_pattern); lmmv1->lmm_layout_gen = cpu_to_le16(lsm->lsm_layout_gen); if (lsm->lsm_magic == LOV_MAGIC_V3) { cplen = strlcpy(lmmv3->lmm_pool_name, lsm->lsm_pool_name, sizeof(lmmv3->lmm_pool_name)); if (cplen >= sizeof(lmmv3->lmm_pool_name)) return -E2BIG; lmm_objects = lmmv3->lmm_objects; } else { lmm_objects = lmmv1->lmm_objects; } for (i = 0; i < stripe_count; i++) { struct lov_oinfo *loi = lsm->lsm_oinfo[i]; /* XXX LOV STACKING call down to osc_packmd() to do packing */ LASSERTF(ostid_id(&loi->loi_oi) != 0, "lmm_oi "DOSTID " stripe %u/%u idx %u\n", POSTID(&lmmv1->lmm_oi), i, stripe_count, loi->loi_ost_idx); ostid_cpu_to_le(&loi->loi_oi, &lmm_objects[i].l_ost_oi); lmm_objects[i].l_ost_gen = cpu_to_le32(loi->loi_ost_gen); lmm_objects[i].l_ost_idx = cpu_to_le32(loi->loi_ost_idx); } return lmm_size; }
static int __lov_setstripe(struct obd_export *exp, int max_lmm_size, struct lov_stripe_md **lsmp, struct lov_user_md *lump) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; char buffer[sizeof(struct lov_user_md_v3)]; struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)&buffer[0]; struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&buffer[0]; int lmm_magic; int stripe_count; int rc; ENTRY; if (cfs_copy_from_user(lumv3, lump, sizeof(struct lov_user_md_v1))) RETURN(-EFAULT); lmm_magic = lumv1->lmm_magic; if (lmm_magic == __swab32(LOV_USER_MAGIC_V1)) { lustre_swab_lov_user_md_v1(lumv1); lmm_magic = LOV_USER_MAGIC_V1; } else if (lmm_magic == LOV_USER_MAGIC_V3) { if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3))) RETURN(-EFAULT); } else if (lmm_magic == __swab32(LOV_USER_MAGIC_V3)) { if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3))) RETURN(-EFAULT); lustre_swab_lov_user_md_v3(lumv3); lmm_magic = LOV_USER_MAGIC_V3; } else if (lmm_magic != LOV_USER_MAGIC_V1) { CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n", lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3); RETURN(-EINVAL); } /* in the rest of the tests, as *lumv1 and lumv3 have the same * fields, we use lumv1 to avoid code duplication */ if (lumv1->lmm_pattern == 0) { lumv1->lmm_pattern = lov->desc.ld_pattern ? lov->desc.ld_pattern : LOV_PATTERN_RAID0; } if (lumv1->lmm_pattern != LOV_PATTERN_RAID0) { CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n", lumv1->lmm_pattern); RETURN(-EINVAL); } /* 64kB is the largest common page size we see (ia64), and matches the * check in lfs */ if (lumv1->lmm_stripe_size & (LOV_MIN_STRIPE_SIZE - 1)) { CDEBUG(D_IOCTL, "stripe size %u not multiple of %u, fixing\n", lumv1->lmm_stripe_size, LOV_MIN_STRIPE_SIZE); lumv1->lmm_stripe_size = LOV_MIN_STRIPE_SIZE; } if ((lumv1->lmm_stripe_offset >= lov->desc.ld_tgt_count) && (lumv1->lmm_stripe_offset != (typeof(lumv1->lmm_stripe_offset))(-1))) { CDEBUG(D_IOCTL, "stripe offset %u > number of OSTs %u\n", lumv1->lmm_stripe_offset, lov->desc.ld_tgt_count); RETURN(-EINVAL); } stripe_count = lov_get_stripecnt(lov, lumv1->lmm_stripe_count); if (max_lmm_size) { int max_stripes = (max_lmm_size - lov_mds_md_size(0, lmm_magic)) / sizeof(struct lov_ost_data_v1); if (unlikely(max_stripes < stripe_count)) { CDEBUG(D_IOCTL, "stripe count reset from %d to %d\n", stripe_count, max_stripes); stripe_count = max_stripes; } } if (lmm_magic == LOV_USER_MAGIC_V3) { struct pool_desc *pool; pool = lov_find_pool(lov, lumv3->lmm_pool_name); if (pool != NULL) { if (lumv3->lmm_stripe_offset != (typeof(lumv3->lmm_stripe_offset))(-1)) { rc = lov_check_index_in_pool( lumv3->lmm_stripe_offset, pool); if (rc < 0) { lov_pool_putref(pool); RETURN(-EINVAL); } } if (stripe_count > pool_tgt_count(pool)) stripe_count = pool_tgt_count(pool); lov_pool_putref(pool); } } rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic); if (rc >= 0) { (*lsmp)->lsm_oinfo[0]->loi_ost_idx = lumv1->lmm_stripe_offset; (*lsmp)->lsm_stripe_size = lumv1->lmm_stripe_size; if (lmm_magic == LOV_USER_MAGIC_V3) strncpy((*lsmp)->lsm_pool_name, lumv3->lmm_pool_name, LOV_MAXPOOLNAME); rc = 0; } RETURN(rc); }
/* Pack LOV object metadata for disk storage. It is packed in LE byte * order and is opaque to the networking layer. * * XXX In the future, this will be enhanced to get the EA size from the * underlying OSC device(s) to get their EA sizes so we can stack * LOVs properly. For now lov_mds_md_size() just assumes one obd_id * per stripe. */ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, struct lov_stripe_md *lsm) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; struct lov_mds_md_v1 *lmmv1; struct lov_mds_md_v3 *lmmv3; int stripe_count; struct lov_ost_data_v1 *lmm_objects; int lmm_size, lmm_magic; int i; ENTRY; if (lsm) { lmm_magic = lsm->lsm_magic; /* If we are just sizing the EA, limit the stripe count * to the actual number of OSTs in this filesystem. */ if (!lmmp) { stripe_count = lov_get_stripecnt(lov, lsm->lsm_stripe_count); lsm->lsm_stripe_count = stripe_count; } else { stripe_count = lsm->lsm_stripe_count; } } else { /* No needs to allocated more than LOV_MAX_STRIPE_COUNT. * Anyway, this is pretty inaccurate since ld_tgt_count now * represents max index and we should rely on the actual number * of OSTs instead */ stripe_count = min((__u32)LOV_MAX_STRIPE_COUNT, lov->desc.ld_tgt_count); if (lmmp && *lmmp) lmm_magic = le32_to_cpu((*lmmp)->lmm_magic); else /* lsm == NULL and lmmp == NULL */ lmm_magic = LOV_MAGIC; } if ((lmm_magic != LOV_MAGIC_V1) && (lmm_magic != LOV_MAGIC_V3)) { CERROR("bad mem LOV MAGIC: 0x%08X != 0x%08X nor 0x%08X\n", lmm_magic, LOV_MAGIC_V1, LOV_MAGIC_V3); RETURN(-EINVAL); } /* XXX LOV STACKING call into osc for sizes */ lmm_size = lov_mds_md_size(stripe_count, lmm_magic); if (!lmmp) RETURN(lmm_size); if (*lmmp && !lsm) { stripe_count = le32_to_cpu((*lmmp)->lmm_stripe_count); lmm_size = lov_mds_md_size(stripe_count, lmm_magic); OBD_FREE(*lmmp, lmm_size); *lmmp = NULL; RETURN(0); } if (!*lmmp) { OBD_ALLOC(*lmmp, lmm_size); if (!*lmmp) RETURN(-ENOMEM); } CDEBUG(D_INFO, "lov_packmd: LOV_MAGIC 0x%08X, lmm_size = %d \n", lmm_magic, lmm_size); lmmv1 = *lmmp; lmmv3 = (struct lov_mds_md_v3 *)*lmmp; if (lmm_magic == LOV_MAGIC_V3) lmmv3->lmm_magic = cpu_to_le32(LOV_MAGIC_V3); else lmmv1->lmm_magic = cpu_to_le32(LOV_MAGIC_V1); if (!lsm) RETURN(lmm_size); /* lmmv1 and lmmv3 point to the same struct and have the * same first fields */ lmmv1->lmm_object_id = cpu_to_le64(lsm->lsm_object_id); lmmv1->lmm_object_seq = cpu_to_le64(lsm->lsm_object_seq); lmmv1->lmm_stripe_size = cpu_to_le32(lsm->lsm_stripe_size); lmmv1->lmm_stripe_count = cpu_to_le32(stripe_count); lmmv1->lmm_pattern = cpu_to_le32(lsm->lsm_pattern); if (lsm->lsm_magic == LOV_MAGIC_V3) { strncpy(lmmv3->lmm_pool_name, lsm->lsm_pool_name, LOV_MAXPOOLNAME); lmm_objects = lmmv3->lmm_objects; } else { lmm_objects = lmmv1->lmm_objects; } for (i = 0; i < stripe_count; i++) { struct lov_oinfo *loi = lsm->lsm_oinfo[i]; /* XXX LOV STACKING call down to osc_packmd() to do packing */ LASSERTF(loi->loi_id, "lmm_oid "LPU64" stripe %u/%u idx %u\n", lmmv1->lmm_object_id, i, stripe_count, loi->loi_ost_idx); lmm_objects[i].l_object_id = cpu_to_le64(loi->loi_id); lmm_objects[i].l_object_seq = cpu_to_le64(loi->loi_seq); lmm_objects[i].l_ost_gen = cpu_to_le32(loi->loi_ost_gen); lmm_objects[i].l_ost_idx = cpu_to_le32(loi->loi_ost_idx); } RETURN(lmm_size); }
int mdc_unlink(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) { struct list_head cancels = LIST_HEAD_INIT(cancels); struct obd_device *obd = class_exp2obd(exp); struct ptlrpc_request *req = *request; int count = 0, rc; ENTRY; LASSERT(req == NULL); if ((op_data->op_flags & MF_MDC_CANCEL_FID1) && (fid_is_sane(&op_data->op_fid1))) count = mdc_resource_get_unused(exp, &op_data->op_fid1, &cancels, LCK_EX, MDS_INODELOCK_UPDATE); if ((op_data->op_flags & MF_MDC_CANCEL_FID3) && (fid_is_sane(&op_data->op_fid3))) /* don't cancel DoM lock which may cause data flush */ count += mdc_resource_get_unused(exp, &op_data->op_fid3, &cancels, LCK_EX, MDS_INODELOCK_ELC); req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_REINT_UNLINK); if (req == NULL) { ldlm_lock_list_put(&cancels, l_bl_ast, count); RETURN(-ENOMEM); } req_capsule_set_size(&req->rq_pill, &RMF_NAME, RCL_CLIENT, op_data->op_namelen + 1); /* get SELinux policy info if any */ rc = sptlrpc_get_sepol(req); if (rc < 0) { ptlrpc_request_free(req); RETURN(rc); } req_capsule_set_size(&req->rq_pill, &RMF_SELINUX_POL, RCL_CLIENT, strlen(req->rq_sepol) ? strlen(req->rq_sepol) + 1 : 0); rc = mdc_prep_elc_req(exp, req, MDS_REINT, &cancels, count); if (rc) { ptlrpc_request_free(req); RETURN(rc); } mdc_unlink_pack(req, op_data); req_capsule_set_size(&req->rq_pill, &RMF_MDT_MD, RCL_SERVER, obd->u.cli.cl_default_mds_easize); ptlrpc_request_set_replen(req); *request = req; rc = mdc_reint(req, LUSTRE_IMP_FULL); if (rc == -ERESTARTSYS) rc = 0; RETURN(rc); }