Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
/* 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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
/* 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;
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
/* 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);
}
Esempio n. 13
0
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);
}