From 48d9e119238fd0c54ff8b6a53f7bfed9d5750a24 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Tue, 9 Sep 2014 21:38:35 -0400 Subject: [PATCH] LU-5530 mdt: Properly match open lock and unlock It seems that when request resend with a corresponding lock match is in play (thanks to large striping + llnl patch for the client to send small requests only), after all the suffering and fixing coming from LU-2827, here is another casualty in in open/lease locking. mdt_reint_open() and mdt_open_by_fid_lock() might match the lock on resend and not call mdt_object_open_lock(), yet call mdt_object_open_unlock() before exit. Since mdt_object_open_lock/unlock also plays with a semaphore, hilarity ensues usually most visible as a rw_sem lockup in mdt_object_open_lock. This patch adds tracking whenever we actually called mdt_object_open_lock or not and only calls mdt_object_open_unlock if we did. Change-Id: I73c529229acec98cac4ad73f7b487e759ad9a763 Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/11841 Tested-by: Jenkins Reviewed-by: Jinshan Xiong Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Faccini Bruno --- lustre/mdt/mdt_open.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 50a8e61..4aacc8c 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1440,6 +1440,7 @@ int mdt_open_by_fid_lock(struct mdt_thread_info *info, struct ldlm_reply *rep, struct mdt_object *parent= NULL; struct mdt_object *o; int rc; + int object_locked = 0; __u64 ibits = 0; ENTRY; @@ -1494,6 +1495,7 @@ int mdt_open_by_fid_lock(struct mdt_thread_info *info, struct ldlm_reply *rep, GOTO(out, rc); } else if (rc > 0) { rc = mdt_object_open_lock(info, o, lhc, &ibits); + object_locked = 1; if (rc) GOTO(out_unlock, rc); } @@ -1520,7 +1522,8 @@ int mdt_open_by_fid_lock(struct mdt_thread_info *info, struct ldlm_reply *rep, GOTO(out_unlock, rc); out_unlock: - mdt_object_open_unlock(info, o, lhc, ibits, rc); + if (object_locked) + mdt_object_open_unlock(info, o, lhc, ibits, rc); out: mdt_object_put(env, o); out_parent_put: @@ -1599,6 +1602,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) struct mdt_reint_record *rr = &info->mti_rr; int result, rc; int created = 0; + int object_locked = 0; __u32 msg_flags; ENTRY; @@ -1849,6 +1853,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) /* get openlock if this isn't replay and client requested it */ if (!req_is_replay(req)) { rc = mdt_object_open_lock(info, child, lhc, &ibits); + object_locked = 1; if (rc != 0) GOTO(out_child_unlock, result = rc); else if (create_flags & MDS_OPEN_LOCK) @@ -1889,7 +1894,8 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) } EXIT; out_child_unlock: - mdt_object_open_unlock(info, child, lhc, ibits, result); + if (object_locked) + mdt_object_open_unlock(info, child, lhc, ibits, result); out_child: mdt_object_put(info->mti_env, child); out_parent: -- 1.8.3.1