]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: check for snapshots on parent snaprealms
authorPatrick Donnelly <pdonnell@ibm.com>
Mon, 14 Apr 2025 18:02:01 +0000 (14:02 -0400)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 28 Apr 2025 19:36:29 +0000 (15:36 -0400)
The code was incorrectly only looking at snapshots in the current snaprealm.

Fixes: https://tracker.ceph.com/issues/70912
Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
(cherry picked from commit b8fd8e79ae757619b7d6011134dc2ed2ce17d8e4)

src/mds/Server.cc
src/mds/Server.h

index 874b8c45d1d0ac562ddc05dedb7219b089470427..576ee3d5cabb79d3d0fb22aa26fbbebe0b467d90 100644 (file)
@@ -6497,11 +6497,7 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
     if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
       return;
 
-    if (_dir_is_nonempty(mdr, cur)) {
-      respond_to_request(mdr, -ENOTEMPTY);
-      return;
-    }
-    if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+    if (_dir_is_nonempty(mdr, cur) || _dir_has_snaps(mdr, cur)) {
       respond_to_request(mdr, -ENOTEMPTY);
       return;
     }
@@ -6529,11 +6525,7 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
     if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
       return;
 
-    if (_dir_is_nonempty(mdr, cur)) {
-      respond_to_request(mdr, -ENOTEMPTY);
-      return;
-    }
-    if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+    if (_dir_is_nonempty(mdr, cur) || _dir_has_snaps(mdr, cur)) {
       respond_to_request(mdr, -ENOTEMPTY);
       return;
     }
@@ -6566,11 +6558,7 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
     if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
       return;
 
-    if (_dir_is_nonempty(mdr, cur)) {
-      respond_to_request(mdr, -ENOTEMPTY);
-      return;
-    }
-    if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+    if (_dir_is_nonempty(mdr, cur) || _dir_has_snaps(mdr, cur)) {
       respond_to_request(mdr, -ENOTEMPTY);
       return;
     }
@@ -6594,11 +6582,7 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
     if (!xlock_policylock(mdr, cur, false, false, std::move(lov)))
       return;
 
-    if (_dir_is_nonempty(mdr, cur)) {
-      respond_to_request(mdr, -ENOTEMPTY);
-      return;
-    }
-    if (cur->snaprealm && cur->snaprealm->srnode.snaps.size()) {
+    if (_dir_is_nonempty(mdr, cur) || _dir_has_snaps(mdr, cur)) {
       respond_to_request(mdr, -ENOTEMPTY);
       return;
     }
@@ -8902,6 +8886,16 @@ bool Server::_dir_is_nonempty_unlocked(const MDRequestRef& mdr, CInode *in)
   return false;
 }
 
+bool Server::_dir_has_snaps(const MDRequestRef& mdr, CInode *diri)
+{
+  dout(10) << __func__ << ": " << *diri << dendl;
+  ceph_assert(diri->is_auth());
+  ceph_assert(diri->snaplock.can_read(mdr->get_client()));
+
+  SnapRealm *realm = diri->find_snaprealm();
+  return !realm->get_snaps().empty();
+}
+
 bool Server::_dir_is_nonempty(const MDRequestRef& mdr, CInode *in)
 {
   dout(10) << "dir_is_nonempty " << *in << dendl;
index e7aca9e18e1606bf9cf10ae51ba9d5f36bbe52d4..730da85c36c4c9fcc94ae84409a59af997b656ec 100644 (file)
@@ -279,6 +279,7 @@ public:
   void handle_client_unlink(const MDRequestRef& mdr);
   bool _dir_is_nonempty_unlocked(const MDRequestRef& mdr, CInode *rmdiri);
   bool _dir_is_nonempty(const MDRequestRef& mdr, CInode *rmdiri);
+  bool _dir_has_snaps(const MDRequestRef& mdr, CInode *diri);
   void _unlink_local(const MDRequestRef& mdr, CDentry *dn, CDentry *straydn);
   void _unlink_local_finish(const MDRequestRef& mdr,
                            CDentry *dn, CDentry *straydn,