From 993858982eda2c7a7179b6c67c2d425df8e692f8 Mon Sep 17 00:00:00 2001 From: wang di Date: Sun, 12 Apr 2015 22:30:10 -0700 Subject: [PATCH] LU-6458 mdd: try linkEA first in mdd_parent_fid 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 Change-Id: Ia54a2d36b6ab640c533c0fb864431db062646299 Reviewed-on: http://review.whamcloud.com/14444 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/mdd/mdd_dir.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index b472596..fe07480 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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); } /* -- 1.8.3.1