+int lmv_enqueue_slaves(struct obd_export *exp, int locktype,
+ struct lookup_intent *it, int lockmode,
+ struct mdc_op_data *data, struct lustre_handle *lockh,
+ void *lmm, int lmmsize, ldlm_completion_callback cb_completion,
+ ldlm_blocking_callback cb_blocking, void *cb_data)
+{
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct mea *mea = data->mea1;
+ struct mdc_op_data data2;
+ int i, rc, mds;
+ ENTRY;
+
+ LASSERT(mea != NULL);
+ for (i = 0; i < mea->mea_count; i++) {
+ memset(&data2, 0, sizeof(data2));
+ data2.fid1 = mea->mea_fids[i];
+ mds = data2.fid1.mds;
+
+ if (lmv->tgts[mds].ltd_exp == NULL)
+ continue;
+
+ rc = md_enqueue(lmv->tgts[mds].ltd_exp, locktype, it, lockmode,
+ &data2, lockh + i, lmm, lmmsize, cb_completion,
+ cb_blocking, cb_data);
+
+ CDEBUG(D_OTHER, "take lock on slave %lu/%lu/%lu -> %d/%d\n",
+ (unsigned long)mea->mea_fids[i].mds,
+ (unsigned long)mea->mea_fids[i].id,
+ (unsigned long)mea->mea_fids[i].generation,
+ rc, it->d.lustre.it_status);
+ if (rc)
+ GOTO(cleanup, rc);
+ if (it->d.lustre.it_data) {
+ struct ptlrpc_request *req;
+ req = (struct ptlrpc_request *) it->d.lustre.it_data;
+ ptlrpc_req_finished(req);
+ }
+
+ if (it->d.lustre.it_status)
+ GOTO(cleanup, rc = it->d.lustre.it_status);
+ }
+ RETURN(0);
+
+cleanup:
+ /* drop all taken locks */
+ while (--i >= 0) {
+ if (lockh[i].cookie)
+ ldlm_lock_decref(lockh + i, lockmode);
+ lockh[i].cookie = 0;
+ }
+ RETURN(rc);
+}
+