Whamcloud - gitweb
LU-12090 utils: lfs rmfid
[fs/lustre-release.git] / lustre / lmv / lmv_obd.c
index 4cd844f..73fece5 100644 (file)
@@ -2981,6 +2981,96 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
         RETURN(-EINVAL);
 }
 
+static int lmv_rmfid(struct obd_export *exp, struct fid_array *fa,
+                    int *__rcs, struct ptlrpc_request_set *_set)
+{
+       struct obd_device *obddev = class_exp2obd(exp);
+       struct ptlrpc_request_set *set = _set;
+       struct lmv_obd *lmv = &obddev->u.lmv;
+       int tgt_count = lmv->desc.ld_tgt_count;
+       struct fid_array *fat, **fas = NULL;
+       int i, rc, **rcs = NULL;
+
+       if (!set) {
+               set = ptlrpc_prep_set();
+               if (!set)
+                       RETURN(-ENOMEM);
+       }
+
+       /* split FIDs by targets */
+       OBD_ALLOC(fas, sizeof(fas) * tgt_count);
+       if (fas == NULL)
+               GOTO(out, rc = -ENOMEM);
+       OBD_ALLOC(rcs, sizeof(int *) * tgt_count);
+       if (rcs == NULL)
+               GOTO(out_fas, rc = -ENOMEM);
+
+       for (i = 0; i < fa->fa_nr; i++) {
+               unsigned int idx;
+
+               rc = lmv_fld_lookup(lmv, &fa->fa_fids[i], &idx);
+               if (rc) {
+                       CDEBUG(D_OTHER, "can't lookup "DFID": rc = %d\n",
+                              PFID(&fa->fa_fids[i]), rc);
+                       continue;
+               }
+               LASSERT(idx < tgt_count);
+               if (!fas[idx])
+                       OBD_ALLOC(fas[idx], offsetof(struct fid_array,
+                                 fa_fids[fa->fa_nr]));
+               if (!fas[idx])
+                       GOTO(out, rc = -ENOMEM);
+               if (!rcs[idx])
+                       OBD_ALLOC(rcs[idx], sizeof(int) * fa->fa_nr);
+               if (!rcs[idx])
+                       GOTO(out, rc = -ENOMEM);
+
+               fat = fas[idx];
+               fat->fa_fids[fat->fa_nr++] = fa->fa_fids[i];
+       }
+
+       for (i = 0; i < tgt_count; i++) {
+               fat = fas[i];
+               if (!fat || fat->fa_nr == 0)
+                       continue;
+               rc = md_rmfid(lmv->tgts[i]->ltd_exp, fat, rcs[i], set);
+       }
+
+       rc = ptlrpc_set_wait(NULL, set);
+       if (rc == 0) {
+               int j = 0;
+               for (i = 0; i < tgt_count; i++) {
+                       fat = fas[i];
+                       if (!fat || fat->fa_nr == 0)
+                               continue;
+                       /* copy FIDs back */
+                       memcpy(fa->fa_fids + j, fat->fa_fids,
+                              fat->fa_nr * sizeof(struct lu_fid));
+                       /* copy rcs back */
+                       memcpy(__rcs + j, rcs[i], fat->fa_nr * sizeof(**rcs));
+                       j += fat->fa_nr;
+               }
+       }
+       if (set != _set)
+               ptlrpc_set_destroy(set);
+
+out:
+       for (i = 0; i < tgt_count; i++) {
+               if (fas && fas[i])
+                       OBD_FREE(fas[i], offsetof(struct fid_array,
+                                               fa_fids[fa->fa_nr]));
+               if (rcs && rcs[i])
+                       OBD_FREE(rcs[i], sizeof(int) * fa->fa_nr);
+       }
+       if (rcs)
+               OBD_FREE(rcs, sizeof(int *) * tgt_count);
+out_fas:
+       if (fas)
+               OBD_FREE(fas, sizeof(fas) * tgt_count);
+
+       RETURN(rc);
+}
+
 /**
  * Asynchronously set by key a value associated with a LMV device.
  *
@@ -3587,6 +3677,7 @@ struct md_ops lmv_md_ops = {
        .m_revalidate_lock      = lmv_revalidate_lock,
        .m_get_fid_from_lsm     = lmv_get_fid_from_lsm,
        .m_unpackmd             = lmv_unpackmd,
+       .m_rmfid                = lmv_rmfid,
 };
 
 static int __init lmv_init(void)