From: Xiubo Li Date: Mon, 8 Jul 2024 07:53:28 +0000 (+0800) Subject: mds: avoid acquiring the wrlock twice for a single request X-Git-Tag: v20.0.0~314^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=276b81a55d391b52f9772fc76b86b845eb3854a6;p=ceph.git mds: avoid acquiring the wrlock twice for a single request In case the current request has lock cache attached and then the lock cache must have already acquired the wrlock of filelock. So currently the path_traverse() will acquire the wrlock twice and possibly caused deadlock by itself. Fixes: https://tracker.ceph.com/issues/65607 Signed-off-by: Xiubo Li Signed-off-by: Sunnatillo --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 3af0d8c6b1ec..cbe7c94bf099 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8515,8 +8515,11 @@ int MDCache::path_traverse(const MDRequestRef& mdr, MDSContextFactory& cf, lov.add_xlock(&dn->lock); } else { // force client to flush async dir operation if necessary - if (cur->filelock.is_cached()) + if (cur->filelock.is_cached() && + !(mdr->lock_cache && + static_cast(mdr->lock_cache)->is_wrlocked(&cur->filelock))) { lov.add_wrlock(&cur->filelock); + } lov.add_rdlock(&dn->lock); } if (!mds->locker->acquire_locks(mdr, lov)) { @@ -8635,8 +8638,11 @@ int MDCache::path_traverse(const MDRequestRef& mdr, MDSContextFactory& cf, lov.add_xlock(&dn->lock); } else { // force client to flush async dir operation if necessary - if (cur->filelock.is_cached()) + if (cur->filelock.is_cached() && + !(mdr->lock_cache && + static_cast(mdr->lock_cache)->is_wrlocked(&cur->filelock))) { lov.add_wrlock(&cur->filelock); + } lov.add_rdlock(&dn->lock); } if (!mds->locker->acquire_locks(mdr, lov)) { diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 9448e63749f1..b1e0d987194f 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -4041,6 +4041,7 @@ const char** MDSRankDispatcher::get_tracked_conf_keys() const "clog_to_syslog_level", \ "fsid", \ "host", \ + "mds_allow_async_dirops", \ "mds_alternate_name_max", \ "mds_bal_export_pin", \ "mds_bal_fragment_dirs", \ @@ -4116,8 +4117,7 @@ const char** MDSRankDispatcher::get_tracked_conf_keys() const "mds_session_cap_acquisition_throttle", \ "mds_session_max_caps_throttle_ratio", \ "mds_session_metadata_threshold", \ - "mds_symlink_recovery", \ - "mds_allow_async_dirops" + "mds_symlink_recovery" constexpr bool is_sorted = [] () constexpr { constexpr auto arr = std::to_array({KEYS});