From a0b959c53d10bf3f0fd6b22de46397d0c7e5f667 Mon Sep 17 00:00:00 2001 From: Li Xi Date: Wed, 8 Oct 2014 20:27:22 +0800 Subject: [PATCH] LU-3727 nfs: Fix ll_get_parent() LBUG caused by permission When ll_get_parent() is trying to get the attributes of parent directory, EACCES will be returned if NFS daemon user does not have the execute permission of the child directory. This patch fixes the problem by skipping permission check for ll_get_parent(). Signed-off-by: Li Xi Change-Id: Id922d170c89519b755f69a2818d6ed53f8cc7ad9 Reviewed-on: http://review.whamcloud.com/7327 Reviewed-by: Bobi Jam Tested-by: Jenkins Reviewed-by: Lai Siyao Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/md_object.h | 3 ++- lustre/mdd/mdd_dir.c | 3 ++- lustre/mdt/mdt_handler.c | 65 +++++++++++++++++++++------------------------- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 12c224c..99998e2 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -161,7 +161,8 @@ struct md_op_spec { /** don't create lov objects or llog cookie - this replay */ unsigned int no_create:1, sp_cr_lookup:1, /* do lookup sanity check or not. */ - sp_rm_entry:1; /* only remove name entry */ + sp_rm_entry:1, /* only remove name entry */ + sp_permitted:1; /* do not check permission */ /** Current lock mode for parent dir where create is performing. */ mdl_mode_t sp_cr_mode; diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 9744718..5d4fbf3 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -119,7 +119,8 @@ int mdd_lookup(const struct lu_env *env, if (rc != 0) RETURN(rc); - rc = __mdd_lookup(env, pobj, pattr, lname, fid, MAY_EXEC); + rc = __mdd_lookup(env, pobj, pattr, lname, fid, + (spec != NULL && spec->sp_permitted) ? 0 : MAY_EXEC); RETURN(rc); } diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 619fa79..79ca02b 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -1309,43 +1309,32 @@ out: } static int mdt_raw_lookup(struct mdt_thread_info *info, - struct mdt_object *parent, - const struct lu_name *lname, - struct ldlm_reply *ldlm_rep) + struct mdt_object *parent, + const struct lu_name *lname, + struct ldlm_reply *ldlm_rep) { - struct md_object *next = mdt_object_child(info->mti_object); - const struct mdt_body *reqbody = info->mti_body; - struct lu_fid *child_fid = &info->mti_tmp_fid1; - struct mdt_body *repbody; - int rc; - ENTRY; - - if (reqbody->mbo_valid != OBD_MD_FLID) - RETURN(0); + struct lu_fid *child_fid = &info->mti_tmp_fid1; + int rc; + ENTRY; - LASSERT(!info->mti_cross_ref); + LASSERT(!info->mti_cross_ref); - /* Only got the fid of this obj by name */ - fid_zero(child_fid); - rc = mdo_lookup(info->mti_env, next, lname, child_fid, - &info->mti_spec); -#if 0 - /* XXX is raw_lookup possible as intent operation? */ - if (rc != 0) { - if (rc == -ENOENT) - mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_NEG); - RETURN(rc); - } else - mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_POS); + /* Only got the fid of this obj by name */ + fid_zero(child_fid); + rc = mdo_lookup(info->mti_env, mdt_object_child(info->mti_object), + lname, child_fid, &info->mti_spec); + if (rc == 0) { + struct mdt_body *repbody; - repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); -#endif - if (rc == 0) { - repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); + repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); repbody->mbo_fid1 = *child_fid; repbody->mbo_valid = OBD_MD_FLID; - } - RETURN(1); + mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_POS); + } else if (rc == -ENOENT) { + mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_NEG); + } + + RETURN(rc); } /* @@ -1467,10 +1456,15 @@ static int mdt_getattr_name_lock(struct mdt_thread_info *info, } if (lu_name_is_valid(lname)) { - rc = mdt_raw_lookup(info, parent, lname, ldlm_rep); - if (rc != 0) { - if (rc > 0) - rc = 0; + /* Always allow to lookup ".." */ + if (unlikely(lname->ln_namelen == 2 && + lname->ln_name[0] == '.' && + lname->ln_name[1] == '.')) + info->mti_spec.sp_permitted = 1; + + if (info->mti_body->mbo_valid == OBD_MD_FLID) { + rc = mdt_raw_lookup(info, parent, lname, ldlm_rep); + RETURN(rc); } @@ -2875,6 +2869,7 @@ void mdt_thread_info_init(struct ptlrpc_request *req, info->mti_spec.no_create = 0; info->mti_spec.sp_rm_entry = 0; + info->mti_spec.sp_permitted = 0; info->mti_spec.u.sp_ea.eadata = NULL; info->mti_spec.u.sp_ea.eadatalen = 0; -- 1.8.3.1