+int ll_objects_destroy(struct ptlrpc_request *request, struct inode *dir)
+{
+ struct mdt_body *body;
+ struct lov_mds_md *eadata;
+ struct lov_stripe_md *lsm = NULL;
+ struct obd_trans_info oti = { 0 };
+ struct obdo *oa;
+ struct obd_capa *oc = NULL;
+ int rc;
+ ENTRY;
+
+ /* req is swabbed so this is safe */
+ body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
+ if (!(body->valid & OBD_MD_FLEASIZE))
+ RETURN(0);
+
+ if (body->eadatasize == 0) {
+ CERROR("OBD_MD_FLEASIZE set but eadatasize zero\n");
+ GOTO(out, rc = -EPROTO);
+ }
+
+ /* The MDS sent back the EA because we unlinked the last reference
+ * to this file. Use this EA to unlink the objects on the OST.
+ * It's opaque so we don't swab here; we leave it to obd_unpackmd() to
+ * check it is complete and sensible. */
+ eadata = req_capsule_server_sized_get(&request->rq_pill, &RMF_MDT_MD,
+ body->eadatasize);
+ LASSERT(eadata != NULL);
+
+ rc = obd_unpackmd(ll_i2dtexp(dir), &lsm, eadata, body->eadatasize);
+ if (rc < 0) {
+ CERROR("obd_unpackmd: %d\n", rc);
+ GOTO(out, rc);
+ }
+ LASSERT(rc >= sizeof(*lsm));
+
+ OBDO_ALLOC(oa);
+ if (oa == NULL)
+ GOTO(out_free_memmd, rc = -ENOMEM);
+
+ oa->o_id = lsm->lsm_object_id;
+ oa->o_seq = lsm->lsm_object_seq;
+ oa->o_mode = body->mode & S_IFMT;
+ oa->o_valid = OBD_MD_FLID | OBD_MD_FLTYPE | OBD_MD_FLGROUP;
+
+ if (body->valid & OBD_MD_FLCOOKIE) {
+ oa->o_valid |= OBD_MD_FLCOOKIE;
+ oti.oti_logcookies =
+ req_capsule_server_sized_get(&request->rq_pill,
+ &RMF_LOGCOOKIES,
+ sizeof(struct llog_cookie) *
+ lsm->lsm_stripe_count);
+ if (oti.oti_logcookies == NULL) {
+ oa->o_valid &= ~OBD_MD_FLCOOKIE;
+ body->valid &= ~OBD_MD_FLCOOKIE;
+ }
+ }
+
+ if (body->valid & OBD_MD_FLOSSCAPA) {
+ rc = md_unpack_capa(ll_i2mdexp(dir), request, &RMF_CAPA2, &oc);
+ if (rc)
+ GOTO(out_free_memmd, rc);
+ }
+
+ rc = obd_destroy(ll_i2dtexp(dir), oa, lsm, &oti, ll_i2mdexp(dir), oc);
+ capa_put(oc);
+ OBDO_FREE(oa);
+ if (rc)
+ CERROR("obd destroy objid "LPX64" error %d\n",
+ lsm->lsm_object_id, rc);
+ out_free_memmd:
+ obd_free_memmd(ll_i2dtexp(dir), &lsm);
+ out:
+ return rc;
+}
+
+/* ll_unlink_generic() doesn't update the inode with the new link count.
+ * Instead, ll_ddelete() and ll_d_iput() will update it based upon if there
+ * is any lock existing. They will recycle dentries and inodes based upon locks
+ * too. b=20433 */
+static int ll_unlink_generic(struct inode *dir, struct dentry *dparent,
+ struct dentry *dchild, struct qstr *name)