]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid journaling overhead for ceph.dir.subvolume for no-op case 41996/head
authorPatrick Donnelly <pdonnell@redhat.com>
Fri, 18 Jun 2021 16:27:54 +0000 (09:27 -0700)
committerPatrick Donnelly <pdonnell@redhat.com>
Wed, 23 Jun 2021 20:56:02 +0000 (13:56 -0700)
In preparation for acquiring the xlock on the directory inode, the MDS
must journal a few events before continuing on with the setvxattr. This
can cause significant delays in the volumes ceph-mgr module which needs
to regularly enable this vxattr from multiple code paths. We could cache
in that module whether the vxattr is set but it's also pretty easy to
adjust the MDS to acquire a rdlock on the directory to check if the
subvolume flag is already set. That is much lighter weight and the lock
is generally readily available.

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

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

index 4b2ea17114a97085ccdbd65158bbc2a264189060..536f6e806f519d6677ded7eda9c0ebf214c43ad4 100644 (file)
@@ -304,6 +304,7 @@ struct MDRequestImpl : public MutationImpl {
     bool is_ambiguous_auth = false;
     bool is_remote_frozen_authpin = false;
     bool is_inode_exporter = false;
+    bool rdonly_checks = false;
 
     map<client_t, pair<Session*, uint64_t> > imported_session_map;
     map<CInode*, map<client_t,Capability::Export> > cap_imports;
index e4b9c28e3fe1eddf1086c486635cadf800b9e4bb..35c9005b19477acda81aa75353c15b09c7eb23fa 100644 (file)
@@ -5637,9 +5637,36 @@ void Server::handle_set_vxattr(MDRequestRef& mdr, CInode *cur)
       return;
     }
 
-    if (!xlock_policylock(mdr, cur, false, true))
-      return;
+    /* Verify it's not already a subvolume with lighter weight
+     * rdlock.
+     */
+    if (!mdr->more()->rdonly_checks) {
+      if (!(mdr->locking_state & MutationImpl::ALL_LOCKED)) {
+        MutationImpl::LockOpVec lov;
+        lov.add_rdlock(&cur->snaplock);
+        if (!mds->locker->acquire_locks(mdr, lov))
+          return;
+        mdr->locking_state |= MutationImpl::ALL_LOCKED;
+      }
+      SnapRealm *realm = cur->find_snaprealm();
+      const auto srnode = cur->get_projected_srnode();
+      if (val == (srnode && srnode->is_subvolume())) {
+        dout(20) << "already marked subvolume" << dendl;
+        respond_to_request(mdr, 0);
+        return;
+      }
+      mdr->more()->rdonly_checks = true;
+    }
+
+    if ((mdr->locking_state & MutationImpl::ALL_LOCKED) && !mdr->is_xlocked(&cur->snaplock)) {
+      /* drop the rdlock and acquire xlocks */
+      dout(20) << "dropping rdlocks" << dendl;
+      mds->locker->drop_locks(mdr.get());
+      if (!xlock_policylock(mdr, cur, false, true))
+        return;
+    }
 
+    /* repeat rdonly checks in case changed between rdlock -> xlock */
     SnapRealm *realm = cur->find_snaprealm();
     if (val) {
       inodeno_t subvol_ino = realm->get_subvolume_ino();