Whamcloud - gitweb
LU-6458 mdd: try linkEA first in mdd_parent_fid 44/14444/2
authorwang di <di.wang@intel.com>
Mon, 13 Apr 2015 05:30:10 +0000 (22:30 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 5 Jun 2015 01:53:39 +0000 (01:53 +0000)
It should try to get parent FID from linkEA first, if that
fails, then do lookup dotdot. Two benefits

1. read EA is likely cheaper than lookup.

2. for striped directory, lookup might cause load sub stripes,
which is only necessary for certain operation (like unlink),
and for other cases, we should avoid it, because it will pin
the sub_stripe object with the master objet in the memory, i.e.
sub stripe object will only be freed when the master object
is freed, see lod_object_free()->lod_object_free_striping().

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: Ia54a2d36b6ab640c533c0fb864431db062646299
Reviewed-on: http://review.whamcloud.com/14444
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdd/mdd_dir.c

index b472596..fe07480 100644 (file)
@@ -123,12 +123,57 @@ int mdd_lookup(const struct lu_env *env,
         RETURN(rc);
 }
 
+/**
+ * Get parent FID of the directory
+ *
+ * Read parent FID from linkEA, if that fails, then do lookup
+ * dotdot to get the parent FID.
+ *
+ * \param[in] env      execution environment
+ * \param[in] obj      object from which to find the parent FID
+ * \param[in] attr     attribute of the object
+ * \param[out] fid     fid to get the parent FID
+ *
+ * \retval             0 if getting the parent FID succeeds.
+ * \retval             negative errno if getting the parent FID fails.
+ **/
 static inline int mdd_parent_fid(const struct lu_env *env,
                                 struct mdd_object *obj,
                                 const struct lu_attr *attr,
                                 struct lu_fid *fid)
 {
-       return __mdd_lookup(env, &obj->mod_obj, attr, &lname_dotdot, fid, 0);
+       struct mdd_thread_info  *info = mdd_env_info(env);
+       struct linkea_data      ldata = { NULL };
+       struct lu_buf           *buf = &info->mti_link_buf;
+       struct lu_name          lname;
+       int                     rc = 0;
+
+       ENTRY;
+
+       LASSERT(S_ISDIR(mdd_object_type(obj)));
+
+       buf = lu_buf_check_and_alloc(buf, PATH_MAX);
+       if (buf->lb_buf == NULL)
+               GOTO(lookup, rc = 0);
+
+       ldata.ld_buf = buf;
+       rc = mdd_links_read(env, obj, &ldata);
+       if (rc != 0)
+               GOTO(lookup, rc);
+
+       LASSERT(ldata.ld_leh != NULL);
+       /* Directory should only have 1 parent */
+       if (ldata.ld_leh->leh_reccount > 1)
+               GOTO(lookup, rc);
+
+       ldata.ld_lee = (struct link_ea_entry *)(ldata.ld_leh + 1);
+
+       linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen, &lname, fid);
+       if (likely(fid_is_sane(fid)))
+               RETURN(0);
+lookup:
+       rc =  __mdd_lookup(env, &obj->mod_obj, attr, &lname_dotdot, fid, 0);
+       RETURN(rc);
 }
 
 /*