From: Patrick Donnelly Date: Tue, 13 Feb 2024 16:07:26 +0000 (-0500) Subject: mds: provide mechanism to authpin while freezing X-Git-Tag: v20.0.0~2328^2~36 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a9964a7ccc4394f923fb0f1c76eb8fa03fe8733d;p=ceph.git mds: provide mechanism to authpin while freezing When a subtree is freezing, it's no longer possible to acquire new authpins. This is a problem when a compound request like quiescing a subtree is trying to acquire authpins for each sub-op. This creates a situation where some quiesce sub-ops complete with authpins (thereby preventing the tree from becoming "frozen") and new sub-ops cannot acquire authpins (because the tree is "freezing"). To circumvent this, allow some authpin requests to proceed if FLAG_BYPASSFREEZING is set. Signed-off-by: Patrick Donnelly --- diff --git a/src/mds/CDentry.cc b/src/mds/CDentry.cc index 8694dfc72a2e6..9f5f1a49f55ec 100644 --- a/src/mds/CDentry.cc +++ b/src/mds/CDentry.cc @@ -368,10 +368,10 @@ int CDentry::get_num_dir_auth_pins() const return auth_pins; } -bool CDentry::can_auth_pin(int *err_ret) const +bool CDentry::can_auth_pin(int *err_ret, bool bypassfreezing) const { ceph_assert(dir); - return dir->can_auth_pin(err_ret); + return dir->can_auth_pin(err_ret, bypassfreezing); } void CDentry::auth_pin(void *by) diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 2566395d18561..837ce2b8818d8 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -222,7 +222,7 @@ public: void _put() override; // auth pins - bool can_auth_pin(int *err_ret=nullptr) const override; + bool can_auth_pin(int *err_ret=nullptr, bool bypassfreezing=false) const override; void auth_pin(void *by) override; void auth_unpin(void *by) override; void adjust_nested_auth_pins(int diradj, void *by); diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index a8aaf11c0512c..c65dee271fc8e 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -3445,16 +3445,25 @@ void CDir::adjust_freeze_after_rename(CDir *dir) mdcache->mds->queue_waiters(unfreeze_waiters); } -bool CDir::can_auth_pin(int *err_ret) const +bool CDir::can_auth_pin(int *err_ret, bool bypassfreezing) const { int err; if (!is_auth()) { err = ERR_NOT_AUTH; - } else if (is_freezing_dir() || is_frozen_dir()) { + } else if (is_freezing_dir()) { + if (bypassfreezing) { + dout(20) << "allowing authpin with freezing" << dendl; + err = 0; + } else { + err = ERR_FRAGMENTING_DIR; + } + } else if (is_frozen_dir()) { err = ERR_FRAGMENTING_DIR; } else { auto p = is_freezing_or_frozen_tree(); - if (p.first || p.second) { + if (p.first && !bypassfreezing) { + err = ERR_EXPORTING_TREE; + } else if (p.second) { err = ERR_EXPORTING_TREE; } else { err = 0; diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 7cc4dc7ffcf83..234da01b10c9b 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -526,7 +526,7 @@ public: void abort_import(); // -- auth pins -- - bool can_auth_pin(int *err_ret=nullptr) const override; + bool can_auth_pin(int *err_ret=nullptr, bool bypassfreezing=false) const override; int get_auth_pins() const { return auth_pins; } int get_dir_auth_pins() const { return dir_auth_pins; } void auth_pin(void *who) override; diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 7e9185ff5cc66..6d15908e54552 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -2929,11 +2929,18 @@ void CInode::clear_ambiguous_auth() } // auth_pins -bool CInode::can_auth_pin(int *err_ret) const { +bool CInode::can_auth_pin(int *err_ret, bool bypassfreezing) const { int err; if (!is_auth()) { err = ERR_NOT_AUTH; - } else if (is_freezing_inode() || is_frozen_inode() || is_frozen_auth_pin()) { + } else if (is_freezing_inode()) { + if (bypassfreezing) { + dout(20) << "allowing authpin with freezing" << dendl; + err = 0; + } else { + err = ERR_EXPORTING_INODE; + } + } else if (is_frozen_inode() || is_frozen_auth_pin()) { err = ERR_EXPORTING_INODE; } else { if (parent) diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 242288d5ec330..7d91becb97b9b 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -926,7 +926,7 @@ class CInode : public MDSCacheObject, public InodeStoreBase, public Counteris_ambiguous_auth = false; } -bool MDRequestImpl::can_auth_pin(MDSCacheObject *object) +bool MDRequestImpl::can_auth_pin(MDSCacheObject *object, bool bypassfreezing) { - return object->can_auth_pin() || + return object->can_auth_pin(nullptr, bypassfreezing) || (is_auth_pinned(object) && has_more() && more()->is_freeze_authpin && more()->rename_inode == object); diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h index ded6271f99ee3..fcb0b5a21ad8b 100644 --- a/src/mds/Mutation.h +++ b/src/mds/Mutation.h @@ -399,7 +399,7 @@ struct MDRequestImpl : public MutationImpl { bool freeze_auth_pin(CInode *inode); void unfreeze_auth_pin(bool clear_inode=false); void set_remote_frozen_auth_pin(CInode *inode); - bool can_auth_pin(MDSCacheObject *object); + bool can_auth_pin(MDSCacheObject *object, bool bypassfreezing=false); void drop_local_auth_pins(); void set_ambiguous_auth(CInode *inode); void clear_ambiguous_auth(); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index b27cd2bdbc244..5749bfa7f263d 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3149,9 +3149,13 @@ void Server::handle_peer_auth_pin(const MDRequestRef& mdr) list objects; CInode *auth_pin_freeze = NULL; bool nonblocking = mdr->peer_request->is_nonblocking(); + bool bypassfreezing = mdr->peer_request->is_bypassfreezing(); bool fail = false, wouldblock = false, readonly = false; ref_t reply; + dout(15) << " nonblocking=" << nonblocking + << " bypassfreezing=" << bypassfreezing << dendl; + if (mdcache->is_readonly()) { dout(10) << " read-only FS" << dendl; readonly = true; @@ -3183,7 +3187,7 @@ void Server::handle_peer_auth_pin(const MDRequestRef& mdr) } if (mdr->is_auth_pinned(obj)) continue; - if (!mdr->can_auth_pin(obj)) { + if (!mdr->can_auth_pin(obj, bypassfreezing)) { if (nonblocking) { dout(10) << " can't auth_pin (freezing?) " << *obj << " nonblocking" << dendl; fail = true; diff --git a/src/messages/MMDSPeerRequest.h b/src/messages/MMDSPeerRequest.h index 1799ab361a115..1a007364d4abb 100644 --- a/src/messages/MMDSPeerRequest.h +++ b/src/messages/MMDSPeerRequest.h @@ -106,6 +106,7 @@ public: static constexpr unsigned FLAG_INTERRUPTED = 1<<5; static constexpr unsigned FLAG_NOTIFYBLOCKING = 1<<6; static constexpr unsigned FLAG_REQBLOCKED = 1<<7; + static constexpr unsigned FLAG_BYPASSFREEZING = 1<<8; // for locking __u16 lock_type; // lock object type @@ -160,6 +161,8 @@ public: void clear_notify_blocking() const { flags &= ~FLAG_NOTIFYBLOCKING; } bool is_req_blocked() const { return (flags & FLAG_REQBLOCKED); } void mark_req_blocked() { flags |= FLAG_REQBLOCKED; } + bool is_bypassfreezing() const { return (flags & FLAG_BYPASSFREEZING); } + void mark_bypassfreezing() { flags |= FLAG_BYPASSFREEZING; } void set_lock_type(int t) { lock_type = t; } const ceph::buffer::list& get_lock_data() const { return inode_export; }