-int lmv_lookup_slaves(struct obd_export *exp, struct ptlrpc_request **reqp)
-{
- struct obd_device *obd = exp->exp_obd;
- struct lmv_obd *lmv = &obd->u.lmv;
- struct mds_body *body = NULL;
- struct lustre_handle *lockh;
- struct ldlm_lock *lock;
- struct mds_body *body2;
- struct ll_uctxt uctxt;
- struct lmv_obj *obj;
- int i, rc = 0;
- ENTRY;
-
- LASSERT(reqp);
- LASSERT(*reqp);
-
- /* master is locked. we'd like to take locks on slaves and update
- * attributes to be returned from the slaves it's important that lookup
- * is called in two cases:
-
- * - for first time (dcache has no such a resolving yet).
- * - ->d_revalidate() returned false.
-
- * last case possible only if all the objs (master and all slaves aren't
- * valid */
-
- body = lustre_msg_buf((*reqp)->rq_repmsg, 1, sizeof(*body));
- LASSERT(body != NULL);
-
- obj = lmv_grab_obj(obd, &body->fid1);
- LASSERT(obj != NULL);
-
- CDEBUG(D_OTHER, "lookup slaves for %lu/%lu/%lu\n",
- (unsigned long)body->fid1.mds,
- (unsigned long)body->fid1.id,
- (unsigned long)body->fid1.generation);
-
- uctxt.gid1 = 0;
- uctxt.gid2 = 0;
-
- lmv_lock_obj(obj);
-
- for (i = 0; i < obj->objcount; i++) {
- struct ll_fid fid = obj->objs[i].fid;
- struct ptlrpc_request *req = NULL;
- struct lookup_intent it;
-
- if (fid_equal(&fid, &obj->fid))
- /* skip master obj */
- continue;
-
- CDEBUG(D_OTHER, "lookup slave %lu/%lu/%lu\n",
- (unsigned long)fid.mds, (unsigned long)fid.id,
- (unsigned long)fid.generation);
-
- /* is obj valid? */
- memset(&it, 0, sizeof(it));
- it.it_op = IT_GETATTR;
- rc = md_intent_lock(lmv->tgts[fid.mds].ltd_exp, &uctxt, &fid,
- NULL, 0, NULL, 0, &fid, &it, 0, &req,
- lmv_dirobj_blocking_ast);
-
- lockh = (struct lustre_handle *)&it.d.lustre.it_lock_handle;
- if (rc > 0) {
- /* nice, this slave is valid */
- LASSERT(req == NULL);
- CDEBUG(D_OTHER, "cached\n");
- goto release_lock;
- }
-
- if (rc < 0)
- /* error during revalidation */
- GOTO(cleanup, rc);
-
- /* rc == 0, this means we have no such a lock and can't think
- * obj is still valid. lookup it again */
- LASSERT(req == NULL);
- req = NULL;
-
- memset(&it, 0, sizeof(it));
- it.it_op = IT_GETATTR;
- rc = md_intent_lock(lmv->tgts[fid.mds].ltd_exp, &uctxt, &fid,
- NULL, 0, NULL, 0, NULL, &it, 0, &req,
- lmv_dirobj_blocking_ast);
-
- lockh = (struct lustre_handle *) &it.d.lustre.it_lock_handle;
- LASSERT(rc <= 0);
-
- if (rc < 0)
- /* error during lookup */
- GOTO(cleanup, rc);
-
- lock = ldlm_handle2lock(lockh);
- LASSERT(lock);
-
- lock->l_ast_data = lmv_get_obj(obj);
-
- body2 = lustre_msg_buf(req->rq_repmsg, 1, sizeof(*body2));
- LASSERT(body2);
-
- obj->objs[i].size = body2->size;
-
- CDEBUG(D_OTHER, "fresh: %lu\n",
- (unsigned long)obj->objs[i].size);
-
- LDLM_LOCK_PUT(lock);
-
- if (req)
- ptlrpc_req_finished(req);
-release_lock:
- lmv_update_body_from_obj(body, obj->objs + i);
-
- if (it.d.lustre.it_lock_mode)
- ldlm_lock_decref(lockh, it.d.lustre.it_lock_mode);
- }
-cleanup:
- lmv_unlock_obj(obj);
- lmv_put_obj(obj);
- RETURN(rc);
-}
-
-int lmv_intent_lookup(struct obd_export *exp, struct ll_uctxt *uctxt,
- struct ll_fid *pfid, const char *name, int len,
- void *lmm, int lmmsize, struct ll_fid *cfid,
- struct lookup_intent *it, int flags,
- struct ptlrpc_request **reqp,
- ldlm_blocking_callback cb_blocking)
-{
- struct obd_device *obd = exp->exp_obd;
- struct lmv_obd *lmv = &obd->u.lmv;
- struct mds_body *body = NULL;
- struct ll_fid rpfid = *pfid;
- struct lmv_obj *obj;
- struct mea *mea;
- int rc, mds, loop = 0;
- ENTRY;
-
- /* IT_LOOKUP is intended to produce name -> fid resolving (let's call
- * this lookup below) or to confirm requested resolving is still valid
- * (let's call this revalidation) cfid != NULL specifies revalidation */
-
- if (cfid) {
- /* this is revalidation: we have to check is LOOKUP lock still
- * valid for given fid. very important part is that we have to
- * choose right mds because namespace is per mds */
- rpfid = *pfid;
- obj = lmv_grab_obj(obd, pfid);
- if (obj) {
- mds = raw_name2idx(obj->objcount, (char *) name, len);
- rpfid = obj->objs[mds].fid;
- lmv_put_obj(obj);
- }
- mds = rpfid.mds;
-
- CDEBUG(D_OTHER, "revalidate lookup for %lu/%lu/%lu to %d MDS\n",
- (unsigned long)cfid->mds, (unsigned long)cfid->id,
- (unsigned long)cfid->generation, mds);
-
- rc = md_intent_lock(lmv->tgts[mds].ltd_exp, uctxt, pfid, name,
- len, lmm, lmmsize, cfid, it, flags,
- reqp, cb_blocking);
- RETURN(rc);
- }
-
- mds = pfid->mds;
-repeat:
- LASSERT(++loop <= 2);
- /* this is lookup. during lookup we have to update all the attributes,
- * because returned values will be put in struct inode */
-
- obj = lmv_grab_obj(obd, pfid);
- if (obj) {
- if (len) {
- /* directory is already splitted. calculate mds */
- mds = raw_name2idx(obj->objcount, (char *)name, len);
- rpfid = obj->objs[mds].fid;
- mds = rpfid.mds;
- }
- lmv_put_obj(obj);
- }
-
- rc = md_intent_lock(lmv->tgts[mds].ltd_exp, uctxt, &rpfid, name,
- len, lmm, lmmsize, NULL, it, flags, reqp,
- cb_blocking);
- if (rc > 0) {
- /* very interesting. it seems object is still valid but for some
- * reason llite calls lookup, not revalidate */
- CWARN("lookup for %lu/%lu/%lu and data should be uptodate\n",
- (unsigned long)rpfid.mds, (unsigned long)rpfid.id,
- (unsigned long)rpfid.generation);
- LASSERT(*reqp == NULL);
- RETURN(rc);
- }
-
- if (rc == 0 && *reqp == NULL) {
- /* once again, we're asked for lookup, not revalidate */
- CWARN("lookup for %lu/%lu/%lu and data should be uptodate\n",
- (unsigned long)rpfid.mds, (unsigned long)rpfid.id,
- (unsigned long)rpfid.generation);
- RETURN(rc);
- }
-