* caller that everything is okay. Real connection will be performed later.
*/
static int lmv_connect(const struct lu_env *env,
- struct lustre_handle *conn, struct obd_device *obd,
+ struct obd_export **exp, struct obd_device *obd,
struct obd_uuid *cluuid, struct obd_connect_data *data,
void *localdata)
{
struct proc_dir_entry *lmv_proc_dir;
#endif
struct lmv_obd *lmv = &obd->u.lmv;
- struct obd_export *exp;
+ struct lustre_handle conn = { 0 };
int rc = 0;
ENTRY;
- rc = class_connect(conn, obd, cluuid);
- if (rc) {
- CERROR("class_connection() returned %d\n", rc);
- RETURN(rc);
- }
-
- exp = class_conn2export(conn);
-
/*
* We don't want to actually do the underlying connections more than
* once, so keep track.
*/
lmv->refcount++;
if (lmv->refcount > 1) {
- class_export_put(exp);
+ *exp = NULL;
RETURN(0);
}
- lmv->exp = exp;
+ rc = class_connect(&conn, obd, cluuid);
+ if (rc) {
+ CERROR("class_connection() returned %d\n", rc);
+ RETURN(rc);
+ }
+
+ *exp = class_conn2export(&conn);
+ class_export_get(*exp);
+
+ lmv->exp = *exp;
lmv->connected = 0;
lmv->cluuid = *cluuid;
struct obd_uuid *cluuid = &lmv->cluuid;
struct obd_connect_data *mdc_data = NULL;
struct obd_uuid lmv_mdc_uuid = { "LMV_MDC_UUID" };
- struct lustre_handle conn = {0, };
struct obd_device *mdc_obd;
struct obd_export *mdc_exp;
struct lu_fld_target target;
RETURN(-EINVAL);
}
- rc = obd_connect(NULL, &conn, mdc_obd, &lmv_mdc_uuid,
+ rc = obd_connect(NULL, &mdc_exp, mdc_obd, &lmv_mdc_uuid,
&lmv->conn_data, NULL);
if (rc) {
CERROR("target %s connect error %d\n", tgt->ltd_uuid.uuid, rc);
RETURN(rc);
}
- mdc_exp = class_conn2export(&conn);
-
/*
* Init fid sequence client for this mdc and add new fld target.
*/
{
struct obd_device *obddev = class_exp2obd(exp);
struct lmv_obd *lmv = &obddev->u.lmv;
- int i;
+ int i = 0;
int rc = 0;
int set = 0;
+ int count = lmv->desc.ld_tgt_count;
ENTRY;
- if (lmv->desc.ld_tgt_count == 0)
+ if (count == 0)
RETURN(-ENOTTY);
switch (cmd) {
memcpy(&index, data->ioc_inlbuf2, sizeof(__u32));
LASSERT(data->ioc_plen1 == sizeof(struct obd_statfs));
- if ((index >= lmv->desc.ld_tgt_count))
+ if ((index >= count))
RETURN(-ENODEV);
if (!lmv->tgts[index].ltd_active)
RETURN(-EFAULT);
break;
}
+ case OBD_IOC_QUOTACTL: {
+ struct if_quotactl *qctl = karg;
+ struct lmv_tgt_desc *tgt = NULL;
+ struct obd_quotactl *oqctl;
+
+ if (qctl->qc_valid == QC_MDTIDX) {
+ if (qctl->qc_idx < 0 || count <= qctl->qc_idx)
+ RETURN(-EINVAL);
+
+ tgt = &lmv->tgts[qctl->qc_idx];
+ if (!tgt->ltd_exp)
+ RETURN(-EINVAL);
+ } else if (qctl->qc_valid == QC_UUID) {
+ for (i = 0; i < count; i++) {
+ tgt = &lmv->tgts[i];
+ if (!obd_uuid_equals(&tgt->ltd_uuid,
+ &qctl->obd_uuid))
+ continue;
+
+ if (tgt->ltd_exp == NULL)
+ RETURN(-EINVAL);
+
+ break;
+ }
+ } else {
+ RETURN(-EINVAL);
+ }
+
+ if (i >= count)
+ RETURN(-EAGAIN);
+
+ LASSERT(tgt && tgt->ltd_exp);
+ OBD_ALLOC_PTR(oqctl);
+ if (!oqctl)
+ RETURN(-ENOMEM);
+
+ QCTL_COPY(oqctl, qctl);
+ rc = obd_quotactl(tgt->ltd_exp, oqctl);
+ if (rc == 0) {
+ QCTL_COPY(qctl, oqctl);
+ qctl->qc_valid = QC_MDTIDX;
+ qctl->obd_uuid = tgt->ltd_uuid;
+ }
+ OBD_FREE_PTR(oqctl);
+ break;
+ }
+ case OBD_IOC_CHANGELOG_CLEAR: {
+ struct ioc_changelog_clear *icc = karg;
+
+ if (icc->icc_mdtindex >= count)
+ RETURN(-ENODEV);
+
+ rc = obd_iocontrol(cmd, lmv->tgts[icc->icc_mdtindex].ltd_exp,
+ sizeof(*icc), icc, NULL);
+ break;
+ }
+
default : {
- for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+ for (i = 0; i < count; i++) {
int err;
if (lmv->tgts[i].ltd_exp == NULL)
err = obd_iocontrol(cmd, lmv->tgts[i].ltd_exp, len,
karg, uarg);
- if (err) {
+ if (err == -ENODATA && cmd == OBD_IOC_POLL_QUOTACHECK) {
+ RETURN(err);
+ } else if (err) {
if (lmv->tgts[i].ltd_active) {
CERROR("error: iocontrol MDC %s on MDT"
"idx %d cmd %x: err = %d\n",
rc = obd_fid_alloc(tgt->ltd_exp, fid, NULL);
if (rc > 0) {
LASSERT(fid_is_sane(fid));
-
- /*
- * Client switches to new sequence, setup FLD.
- */
- rc = fld_client_create(&lmv->lmv_fld, fid_seq(fid),
- mds, NULL);
- if (rc) {
- /*
- * Delete just allocated fid sequence in case
- * of fail back.
- */
- CERROR("Can't create fld entry, rc %d\n", rc);
- obd_fid_delete(tgt->ltd_exp, NULL);
- }
+ rc = 0;
}
EXIT;
else if (rc)
RETURN(rc);
- CDEBUG(D_INODE, "CREATE '%*s' on "DFID" -> mds #"LPU64"\n",
+ CDEBUG(D_INODE, "CREATE '%*s' on "DFID" -> mds #%x\n",
op_data->op_namelen, op_data->op_name, PFID(&op_data->op_fid1),
op_data->op_mds);
RETURN(rc);
}
- CDEBUG(D_INODE, "Forward to mds #"LPU64" ("DFID")\n",
+ CDEBUG(D_INODE, "Forward to mds #%x ("DFID")\n",
mds, PFID(&op_data->op_fid1));
op_data->op_fsuid = current->fsuid;
RETURN(rc);
}
-int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data)
+int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
+ __u32 *bits)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
int rc;
ENTRY;
- rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data);
+
+ rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data, bits);
RETURN(rc);
}
RETURN(rc);
}
+int lmv_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req,
+ const struct req_msg_field *field, struct obd_capa **oc)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ int rc;
+
+ ENTRY;
+ rc = md_unpack_capa(lmv->tgts[0].ltd_exp, req, field, oc);
+ RETURN(rc);
+}
+
int lmv_intent_getattr_async(struct obd_export *exp,
struct md_enqueue_info *minfo,
struct ldlm_enqueue_info *einfo)
.m_set_open_replay_data = lmv_set_open_replay_data,
.m_clear_open_replay_data = lmv_clear_open_replay_data,
.m_renew_capa = lmv_renew_capa,
+ .m_unpack_capa = lmv_unpack_capa,
.m_get_remote_perm = lmv_get_remote_perm,
.m_intent_getattr_async = lmv_intent_getattr_async,
.m_revalidate_lock = lmv_revalidate_lock
};
+static quota_interface_t *quota_interface;
+extern quota_interface_t lmv_quota_interface;
+
int __init lmv_init(void)
{
struct lprocfs_static_vars lvars;
}
lprocfs_lmv_init_vars(&lvars);
+
+ request_module("lquota");
+ quota_interface = PORTAL_SYMBOL_GET(lmv_quota_interface);
+ init_obd_quota_ops(quota_interface, &lmv_obd_ops);
+
rc = class_register_type(&lmv_obd_ops, &lmv_md_ops,
lvars.module_vars, LUSTRE_LMV_NAME, NULL);
- if (rc)
+ if (rc) {
+ if (quota_interface)
+ PORTAL_SYMBOL_PUT(lmv_quota_interface);
cfs_mem_cache_destroy(lmv_object_cache);
+ }
return rc;
}
#ifdef __KERNEL__
static void lmv_exit(void)
{
+ if (quota_interface)
+ PORTAL_SYMBOL_PUT(lmv_quota_interface);
+
class_unregister_type(LUSTRE_LMV_NAME);
LASSERTF(atomic_read(&lmv_object_count) == 0,