-static int mdd_path2fid(const struct lu_env *env, struct mdd_device *mdd,
- const char *path, struct lu_fid *fid)
-{
- struct lu_buf *buf;
- struct lu_fid *f = &mdd_env_info(env)->mti_fid;
- struct mdd_object *obj;
- struct lu_name *lname = &mdd_env_info(env)->mti_name;
- char *name;
- int rc = 0;
- ENTRY;
-
- /* temp buffer for path element */
- buf = mdd_buf_alloc(env, PATH_MAX);
- if (buf->lb_buf == NULL)
- RETURN(-ENOMEM);
-
- lname->ln_name = name = buf->lb_buf;
- lname->ln_namelen = 0;
- *f = mdd->mdd_root_fid;
-
- while(1) {
- while (*path == '/')
- path++;
- if (*path == '\0')
- break;
- while (*path != '/' && *path != '\0') {
- *name = *path;
- path++;
- name++;
- lname->ln_namelen++;
- }
-
- *name = '\0';
- /* find obj corresponding to fid */
- obj = mdd_object_find(env, mdd, f);
- if (obj == NULL)
- GOTO(out, rc = -EREMOTE);
- if (IS_ERR(obj))
- GOTO(out, rc = -PTR_ERR(obj));
- /* get child fid from parent and name */
- rc = mdd_lookup(env, &obj->mod_obj, lname, f, NULL);
- mdd_object_put(env, obj);
- if (rc)
- break;
-
- name = buf->lb_buf;
- lname->ln_namelen = 0;
- }
-
- if (!rc)
- *fid = *f;
-out:
- RETURN(rc);
-}
-
-/** The maximum depth that fid2path() will search.
- * This is limited only because we want to store the fids for
- * historical path lookup purposes.
- */
-#define MAX_PATH_DEPTH 100
-
-/** mdd_path() lookup structure. */
-struct path_lookup_info {
- __u64 pli_recno; /**< history point */
- __u64 pli_currec; /**< current record */
- struct lu_fid pli_fid;
- struct lu_fid pli_fids[MAX_PATH_DEPTH]; /**< path, in fids */
- struct mdd_object *pli_mdd_obj;
- char *pli_path; /**< full path */
- int pli_pathlen;
- int pli_linkno; /**< which hardlink to follow */
- int pli_fidcount; /**< number of \a pli_fids */
-};
-
-static int mdd_path_current(const struct lu_env *env,
- struct path_lookup_info *pli)
-{
- struct mdd_device *mdd = mdo2mdd(&pli->pli_mdd_obj->mod_obj);
- struct mdd_object *mdd_obj;
- struct lu_buf *buf = NULL;
- struct link_ea_header *leh;
- struct link_ea_entry *lee;
- struct lu_name *tmpname = &mdd_env_info(env)->mti_name;
- struct lu_fid *tmpfid = &mdd_env_info(env)->mti_fid;
- char *ptr;
- int reclen;
- int rc;
- ENTRY;
-
- ptr = pli->pli_path + pli->pli_pathlen - 1;
- *ptr = 0;
- --ptr;
- pli->pli_fidcount = 0;
- pli->pli_fids[0] = *(struct lu_fid *)mdd_object_fid(pli->pli_mdd_obj);
-
- while (!mdd_is_root(mdd, &pli->pli_fids[pli->pli_fidcount])) {
- mdd_obj = mdd_object_find(env, mdd,
- &pli->pli_fids[pli->pli_fidcount]);
- if (mdd_obj == NULL)
- GOTO(out, rc = -EREMOTE);
- if (IS_ERR(mdd_obj))
- GOTO(out, rc = -PTR_ERR(mdd_obj));
- rc = lu_object_exists(&mdd_obj->mod_obj.mo_lu);
- if (rc <= 0) {
- mdd_object_put(env, mdd_obj);
- if (rc == -1)
- rc = -EREMOTE;
- else if (rc == 0)
- /* Do I need to error out here? */
- rc = -ENOENT;
- GOTO(out, rc);
- }
-
- /* Get parent fid and object name */
- mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
- buf = mdd_links_get(env, mdd_obj);
- mdd_read_unlock(env, mdd_obj);
- mdd_object_put(env, mdd_obj);
- if (IS_ERR(buf))
- GOTO(out, rc = PTR_ERR(buf));
-
- leh = buf->lb_buf;
- lee = (struct link_ea_entry *)(leh + 1); /* link #0 */
- mdd_lee_unpack(lee, &reclen, tmpname, tmpfid);
-
- /* If set, use link #linkno for path lookup, otherwise use
- link #0. Only do this for the final path element. */
- if ((pli->pli_fidcount == 0) &&
- (pli->pli_linkno < leh->leh_reccount)) {
- int count;
- for (count = 0; count < pli->pli_linkno; count++) {
- lee = (struct link_ea_entry *)
- ((char *)lee + reclen);
- mdd_lee_unpack(lee, &reclen, tmpname, tmpfid);
- }
- if (pli->pli_linkno < leh->leh_reccount - 1)
- /* indicate to user there are more links */
- pli->pli_linkno++;
- }
-
- /* Pack the name in the end of the buffer */
- ptr -= tmpname->ln_namelen;
- if (ptr - 1 <= pli->pli_path)
- GOTO(out, rc = -EOVERFLOW);
- strncpy(ptr, tmpname->ln_name, tmpname->ln_namelen);
- *(--ptr) = '/';
-
- /* Store the parent fid for historic lookup */
- if (++pli->pli_fidcount >= MAX_PATH_DEPTH)
- GOTO(out, rc = -EOVERFLOW);
- pli->pli_fids[pli->pli_fidcount] = *tmpfid;
- }
-
- /* Verify that our path hasn't changed since we started the lookup.
- Record the current index, and verify the path resolves to the
- same fid. If it does, then the path is correct as of this index. */
- cfs_spin_lock(&mdd->mdd_cl.mc_lock);
- pli->pli_currec = mdd->mdd_cl.mc_index;
- cfs_spin_unlock(&mdd->mdd_cl.mc_lock);
- rc = mdd_path2fid(env, mdd, ptr, &pli->pli_fid);
- if (rc) {
- CDEBUG(D_INFO, "mdd_path2fid(%s) failed %d\n", ptr, rc);
- GOTO (out, rc = -EAGAIN);
- }
- if (!lu_fid_eq(&pli->pli_fids[0], &pli->pli_fid)) {
- CDEBUG(D_INFO, "mdd_path2fid(%s) found another FID o="DFID
- " n="DFID"\n", ptr, PFID(&pli->pli_fids[0]),
- PFID(&pli->pli_fid));
- GOTO(out, rc = -EAGAIN);
- }
-
- memmove(pli->pli_path, ptr, pli->pli_path + pli->pli_pathlen - ptr);
-
- EXIT;
-out:
- if (buf && !IS_ERR(buf) && buf->lb_vmalloc)
- /* if we vmalloced a large buffer drop it */
- mdd_buf_put(buf);
-
- return rc;
-}
-
-static int mdd_path_historic(const struct lu_env *env,
- struct path_lookup_info *pli)
-{
- return 0;
-}
-