]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid journaling overhead for ceph.dir.subvolume for no-op case 41995/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:54:49 +0000 (13:54 -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 1c5b95371882ea2909ac99bac07f0e13a8a93692..6d4073aafb3e1e1a444116d6ba2446a18f94f6f9 100644 (file)
@@ -308,6 +308,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;
 
     std::map<client_t, std::pair<Session*, uint64_t> > imported_session_map;
     std::map<CInode*, std::map<client_t,Capability::Export> > cap_imports;
index 8f3831cb02b1672bb6fbe265446b2630699dbead..22750c2fb75238e2632afd6bea849614e5383055 100644 (file)
@@ -5673,9 +5673,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();