+struct lmv_obj *
+lmv_grab_obj(struct obd_device *obd, struct lustre_id *id)
+{
+ struct lmv_obj *obj;
+ ENTRY;
+
+ spin_lock(&obj_list_lock);
+ obj = __grab_obj(obd, id);
+ spin_unlock(&obj_list_lock);
+
+ RETURN(obj);
+}
+
+/* looks in objects list for an object that matches passed @id. If it is not
+ * found -- creates it using passed @mea and puts onto list. */
+static struct lmv_obj *
+__create_obj(struct obd_device *obd, struct lustre_id *id, struct mea *mea)
+{
+ struct lmv_obj *new, *obj;
+ ENTRY;
+
+ obj = lmv_grab_obj(obd, id);
+ if (obj)
+ RETURN(obj);
+
+ /* no such object yet, allocate and initialize it. */
+ new = lmv_alloc_obj(obd, id, mea);
+ if (!new)
+ RETURN(NULL);
+
+ /* check if someone create it already while we were dealing with
+ * allocating @obj. */
+ spin_lock(&obj_list_lock);
+ obj = __grab_obj(obd, id);
+ if (obj) {
+ /* someone created it already - put @obj and getting out. */
+ lmv_free_obj(new);
+ spin_unlock(&obj_list_lock);
+ RETURN(obj);
+ }
+
+ __add_obj(new);
+ __get_obj(new);
+
+ spin_unlock(&obj_list_lock);
+
+ CDEBUG(D_OTHER, "new obj in lmv cache: "DLID4"\n",
+ OLID4(id));
+
+ RETURN(new);
+
+}
+
+/* creates object from passed @id and @mea. If @mea is NULL, it will be
+ * obtained from correct MDT and used for constructing the object. */
+struct lmv_obj *
+lmv_create_obj(struct obd_export *exp, struct lustre_id *id, struct mea *mea)