+#define md_op_data_fid(op_data, fl) \
+ (fl == MF_MDC_CANCEL_FID1 ? &op_data->op_fid1 : \
+ fl == MF_MDC_CANCEL_FID2 ? &op_data->op_fid2 : \
+ fl == MF_MDC_CANCEL_FID3 ? &op_data->op_fid3 : \
+ fl == MF_MDC_CANCEL_FID4 ? &op_data->op_fid4 : \
+ NULL)
+
+/* @tgt_exp is the export the metadata request is sent.
+ * @fid_exp is the export the cancel should be sent for the current fid.
+ * if @fid_exp is NULL, the export is found for the current fid.
+ * @op_data keeps the current fid, which is pointed through @flag.
+ * @mode, @bits -- lock match parameters. */
+static int lmv_early_cancel(struct lmv_obd *lmv, struct obd_export *tgt_exp,
+ struct obd_export *fid_exp,
+ struct md_op_data *op_data,
+ ldlm_mode_t mode, int bits, int flag)
+{
+ struct lu_fid *fid = md_op_data_fid(op_data, flag);
+ ldlm_policy_data_t policy = {{0}};
+ int rc = 0;
+ ENTRY;
+
+ if (!fid_is_sane(fid))
+ RETURN(0);
+
+ if (fid_exp == NULL)
+ fid_exp = lmv_find_export(lmv, fid);
+
+ if (tgt_exp == fid_exp) {
+ /* The export is the same as on the target server, cancel
+ * will be sent along with the main metadata operation. */
+ op_data->op_flags |= flag;
+ RETURN(0);
+ }
+
+ policy.l_inodebits.bits = bits;
+ rc = md_cancel_unused(fid_exp, fid, &policy, mode, LDLM_FL_ASYNC, NULL);
+ RETURN(rc);
+}
+
+#ifdef EARLY_CANCEL_FOR_STRIPED_DIR_IS_READY
+/* Check if the fid in @op_data pointed to by flag is of the same export(s)
+ * as @tgt_exp. Early cancels will be sent later by mdc code, otherwise, call
+ * md_cancel_unused for child export(s). */
+static int lmv_early_cancel_stripes(struct obd_export *exp,
+ struct obd_export *tgt_exp,
+ struct md_op_data *op_data,
+ ldlm_mode_t mode, int bits, int flag)
+{
+ struct lu_fid *fid = md_op_data_fid(op_data, flag);
+ struct obd_device *obd = exp->exp_obd;
+ struct lmv_obd *lmv = &obd->u.lmv;
+ struct obd_export *st_exp;
+ struct lmv_obj *obj;
+ int rc = 0;
+ ENTRY;
+
+ if (!fid_is_sane(fid))
+ RETURN(0);
+
+ obj = lmv_obj_grab(obd, fid);
+ if (obj) {
+ ldlm_policy_data_t policy = {{0}};
+ struct lu_fid *st_fid;
+ int i;
+
+ policy.l_inodebits.bits = bits;
+ for (i = 0; i < obj->lo_objcount; i++) {
+ st_exp = lmv_get_export(lmv, obj->lo_inodes[i].li_mds);
+ st_fid = &obj->lo_inodes[i].li_fid;
+ if (tgt_exp != st_exp) {
+ rc = md_cancel_unused(st_exp, st_fid, &policy,
+ mode, 0, NULL);
+ if (rc)
+ break;
+ } else {
+ /* Some export matches to @tgt_exp, do cancel
+ * for its fid in mdc */
+ *fid = *st_fid;
+ op_data->op_flags |= flag;
+ }
+ }
+ lmv_obj_put(obj);
+ } else {
+ rc = lmv_early_cancel(lmv, tgt_exp, NULL, op_data,
+ mode, bits, flag);
+ }
+ RETURN(rc);
+}
+#endif
+