From 7f11a2d372f3fdaa842ba49d19d5a6107fd2c43d Mon Sep 17 00:00:00 2001 From: deen Date: Wed, 22 Apr 2009 12:08:34 +0000 Subject: [PATCH] This patch implements separate function for handling OPEN requests from Lustre clients acting as NFS servers, named mdt_open_anon_by_fid(). It searches for existing object and, if succeed, takes an open lock on the object and its attributes. If a client didn't ask for the open lock, it releases it at the end. We must always take an open lock at the beginning in order to protect object's attributes. b=16715 i=oleg.drokin i=alexey.lyashkov --- lustre/mdt/mdt_handler.c | 11 ++++++-- lustre/mdt/mdt_open.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 3212962..59c0753 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -3358,7 +3358,6 @@ static int mdt_intent_reint(enum mdt_it_code opcode, } rep->lock_policy_res2 = clear_serious(rc); - lhc->mlh_reg_lh.cookie = 0ull; if (rc == -ENOTCONN || rc == -ENODEV || rc == -EOVERFLOW) { /**< if VBR failure then return error */ /* @@ -3367,6 +3366,7 @@ static int mdt_intent_reint(enum mdt_it_code opcode, * will detect this, then disconnect, reconnect the import * immediately, instead of impacting the following the rpc. */ + lhc->mlh_reg_lh.cookie = 0ull; RETURN(rc); } else { /* @@ -3377,7 +3377,14 @@ static int mdt_intent_reint(enum mdt_it_code opcode, * FIXME: when open lock is finished, that should be * checked here. */ - RETURN(ELDLM_LOCK_ABORTED); + if (lustre_handle_is_used(&lhc->mlh_reg_lh)) { + rep->lock_policy_res2 = 0; + rc = mdt_intent_lock_replace(info, lockp, NULL, lhc, flags); + RETURN(rc); + } else { + lhc->mlh_reg_lh.cookie = 0ull; + RETURN(ELDLM_LOCK_ABORTED); + } } } diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index cfa4961..e2bea57 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -809,6 +809,68 @@ static int mdt_open_by_fid(struct mdt_thread_info* info, RETURN(rc); } +static int mdt_open_anon_by_fid(struct mdt_thread_info* info, + struct ldlm_reply *rep, + struct mdt_lock_handle *lhc) +{ + __u32 flags = info->mti_spec.sp_cr_flags; + struct mdt_reint_record *rr = &info->mti_rr; + struct md_attr *ma = &info->mti_attr; + struct mdt_object *o; + int rc; + ldlm_mode_t lm; + ENTRY; + + o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2); + if (IS_ERR(o)) + RETURN(rc = PTR_ERR(o)); + + rc = mdt_object_exists(o); + if (rc == 0) { + mdt_set_disposition(info, rep, (DISP_LOOKUP_EXECD | + DISP_LOOKUP_NEG)); + GOTO(out, rc = -ENOENT); + } else if (rc < 0) { + CERROR("NFS remote open shouldn't happen.\n"); + GOTO(out, rc); + } + + mdt_set_disposition(info, rep, (DISP_IT_EXECD | + DISP_LOOKUP_EXECD | + DISP_LOOKUP_POS)); + + if (flags & FMODE_WRITE) + lm = LCK_CW; + else if (flags & MDS_FMODE_EXEC) + lm = LCK_PR; + else + lm = LCK_CR; + + mdt_lock_handle_init(lhc); + mdt_lock_reg_init(lhc, lm); + rc = mdt_object_lock(info, o, lhc, + MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN, + MDT_CROSS_LOCK); + if (rc) + GOTO(out, rc); + + rc = mo_attr_get(info->mti_env, mdt_object_child(o), ma); + if (rc) + GOTO(out, rc); + + if (flags & MDS_OPEN_LOCK) + mdt_set_disposition(info, rep, DISP_OPEN_LOCK); + rc = mdt_finish_open(info, NULL, o, flags, 0, rep); + + if (!(flags & MDS_OPEN_LOCK)) + mdt_object_unlock(info, o, lhc, 1); + + GOTO(out, rc); +out: + mdt_object_put(info->mti_env, o); + return rc; +} + int mdt_pin(struct mdt_thread_info* info) { ENTRY; @@ -937,6 +999,10 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) } CDEBUG(D_INFO, "Open replay did find object, continue as " "regular open\n"); + } else if (rr->rr_namelen == 0 && !info->mti_cross_ref) { + result = mdt_open_anon_by_fid(info, ldlm_rep, lhc); + if (result != -ENOENT) + GOTO(out, result); } if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK)) -- 1.8.3.1