From: Xiubo Li Date: Fri, 19 Feb 2021 14:05:23 +0000 (+0800) Subject: client: wake up the front pos waiter X-Git-Tag: v15.2.13~8^2~10^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b8aebba5979d15a8b9a262fe5a698fc6ea3cbae7;p=ceph.git client: wake up the front pos waiter The old code was buggy, why it ran well without any problem is that the big client_lock will make sure that the read/write won't run in parallel, so it won't be any problem here. But when introducing inode lock to break the client_lock, which will allow the read/write to run parallelly, the pos waiters won't get any chance to be woke up. In unlock_fh_pos(), it will always wake up the frontest waiter. Fixes: https://tracker.ceph.com/issues/49379 Signed-off-by: Xiubo Li (cherry picked from commit 66bcb880abe56c08e04876e98d3d751e78f8fd2f) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 06254493ea502..837860d1f43c4 100755 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -9143,8 +9143,15 @@ void Client::lock_fh_pos(Fh *f) void Client::unlock_fh_pos(Fh *f) { + ceph_assert(ceph_mutex_is_locked_by_me(client_lock)); + ldout(cct, 10) << __func__ << " " << f << dendl; f->pos_locked = false; + if (!f->pos_waiters.empty()) { + // only wake up the oldest waiter + auto cond = f->pos_waiters.front(); + cond->notify_one(); + } } int Client::uninline_data(Inode *in, Context *onfinish)