+static int lmv_cancel_unused(struct obd_export *exp,
+ const struct lu_fid *fid,
+ ldlm_policy_data_t *policy,
+ ldlm_mode_t mode, int flags, void *opaque)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ int rc = 0, err, i;
+ ENTRY;
+
+ LASSERT(fid != NULL);
+
+ for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+ if (!lmv->tgts[i].ltd_exp || !lmv->tgts[i].ltd_active)
+ continue;
+
+ err = md_cancel_unused(lmv->tgts[i].ltd_exp, fid,
+ policy, mode, flags, opaque);
+ if (!rc)
+ rc = err;
+ }
+ RETURN(rc);
+}
+
+int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+
+ ENTRY;
+ RETURN(md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data));
+}
+
+ldlm_mode_t lmv_lock_match(struct obd_export *exp, int flags,
+ const struct lu_fid *fid, ldlm_type_t type,
+ ldlm_policy_data_t *policy, ldlm_mode_t mode,
+ struct lustre_handle *lockh)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ ldlm_mode_t rc;
+ int i;
+ ENTRY;
+
+ CDEBUG(D_OTHER, "lock match for "DFID"\n", PFID(fid));
+
+ /* with CMD every object can have two locks in different namespaces:
+ * lookup lock in space of mds storing direntry and update/open lock in
+ * space of mds storing inode. Thus we check all targets, not only that
+ * one fid was created in. */
+ for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
+ rc = md_lock_match(lmv->tgts[i].ltd_exp, flags, fid,
+ type, policy, mode, lockh);
+ if (rc)
+ RETURN(rc);
+ }
+
+ RETURN(0);
+}
+
+int lmv_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req,
+ int offset, struct obd_export *dt_exp,
+ struct obd_export *md_exp, struct lustre_md *md)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ int rc;
+
+ ENTRY;
+ rc = md_get_lustre_md(lmv->tgts[0].ltd_exp, req, offset, dt_exp, md_exp,
+ md);
+ RETURN(rc);
+}
+
+int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+
+ ENTRY;
+ if (md->mea)
+ obd_free_memmd(exp, (struct lov_stripe_md**)&md->mea);
+ RETURN(md_free_lustre_md(lmv->tgts[0].ltd_exp, md));
+}
+
+int lmv_set_open_replay_data(struct obd_export *exp,
+ struct obd_client_handle *och,
+ struct ptlrpc_request *open_req)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct obd_export *tgt_exp;
+
+ ENTRY;
+
+ tgt_exp = lmv_find_export(lmv, &och->och_fid);
+ if (IS_ERR(tgt_exp))
+ RETURN(PTR_ERR(tgt_exp));
+
+ RETURN(md_set_open_replay_data(tgt_exp, och, open_req));
+}
+
+int lmv_clear_open_replay_data(struct obd_export *exp,
+ struct obd_client_handle *och)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct obd_export *tgt_exp;
+ ENTRY;
+
+ tgt_exp = lmv_find_export(lmv, &och->och_fid);
+ if (IS_ERR(tgt_exp))
+ RETURN(PTR_ERR(tgt_exp));
+
+ RETURN(md_clear_open_replay_data(tgt_exp, och));
+}
+
+static int lmv_get_remote_perm(struct obd_export *exp,
+ const struct lu_fid *fid,
+ struct obd_capa *oc,
+ struct ptlrpc_request **request)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct obd_export *tgt_exp;
+ int rc;
+
+ ENTRY;
+
+ rc = lmv_check_connect(obd);
+ if (rc)
+ RETURN(rc);
+
+ tgt_exp = lmv_find_export(lmv, fid);
+ if (IS_ERR(tgt_exp))
+ RETURN(PTR_ERR(tgt_exp));
+
+ rc = md_get_remote_perm(tgt_exp, fid, oc, request);
+
+ RETURN(rc);
+}
+
+static int lmv_renew_capa(struct obd_export *exp, struct obd_capa *oc,
+ renew_capa_cb_t cb)