]> 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>
Wed, 16 Apr 2025 14:47:15 +0000 (10:47 -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>
src/mds/Server.cc
src/mds/Server.h

index e78b43a82ffe30e10f3277d3b17a77af844add2f..8885931ee6eb29313129e75533fb67e888831ac9 100644 (file)
@@ -6595,11 +6595,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;
     }
@@ -6627,11 +6623,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;
     }
@@ -6664,11 +6656,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;
     }
@@ -6692,11 +6680,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;
     }
@@ -9225,6 +9209,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 460618a319c70f8303016b6fea918e800b5d0359..b8b78b2dff62c904111f9291ec14b9ee878dd333 100644 (file)
@@ -302,6 +302,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,