]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: set the correct WRLOCK flag always in wrlock_force() 57085/head
authorXiubo Li <xiubli@redhat.com>
Thu, 25 Apr 2024 04:06:25 +0000 (12:06 +0800)
committerXiubo Li <xiubli@redhat.com>
Wed, 8 May 2024 01:12:37 +0000 (09:12 +0800)
The wrlock is not like the xlock, which needs to be acquired in
the CInode's auth always, and it is based on the CDir's auths instead.

When a remote_wrlock is acquired and the local MDS will add a lock
item and marks it as REMOTE_WRLOCK. And later when the local MDS try
to force wrlock in the emplace_lock() will just return the existing
lock item without updating the WRLOCK flag. So when cleaning the
requests later it will just release the remote locks and then removes
lock items directly, which will miss releasing the local wrlock
reference.

Fixes: https://tracker.ceph.com/issues/65630
Signed-off-by: Xiubo Li <xiubli@redhat.com>
src/mds/Locker.cc

index 294683c0717fcff87411a94cf1e1f68a97a40af0..1386fd067911b6bf3d47412096b2971befdc8193 100644 (file)
@@ -1832,7 +1832,8 @@ void Locker::wrlock_force(SimpleLock *lock, MutationRef& mut)
   dout(7) << "wrlock_force  on " << *lock
          << " on " << *lock->get_parent() << dendl;  
   lock->get_wrlock(true);
-  mut->emplace_lock(lock, MutationImpl::LockOp::WRLOCK);
+  auto it = mut->emplace_lock(lock, MutationImpl::LockOp::WRLOCK);
+  it->flags |= MutationImpl::LockOp::WRLOCK; // may already remote_wrlocked
 }
 
 bool Locker::wrlock_try(SimpleLock *lock, const MutationRef& mut, client_t client)
@@ -2054,7 +2055,8 @@ bool Locker::xlock_start(SimpleLock *lock, const MDRequestRef& mut)
            in && in->issued_caps_need_gather(lock))) { // xlocker does not hold shared cap
        lock->set_state(LOCK_XLOCK);
        lock->get_xlock(mut, client);
-       mut->emplace_lock(lock, MutationImpl::LockOp::XLOCK);
+       auto it = mut->emplace_lock(lock, MutationImpl::LockOp::XLOCK);
+       ceph_assert(it->is_xlock());
        mut->finish_locking(lock);
        return true;
       }
@@ -5138,7 +5140,8 @@ void Locker::scatter_writebehind(ScatterLock *lock)
 
   // forcefully take a wrlock
   lock->get_wrlock(true);
-  mut->emplace_lock(lock, MutationImpl::LockOp::WRLOCK);
+  auto it = mut->emplace_lock(lock, MutationImpl::LockOp::WRLOCK);
+  ceph_assert(it->is_wrlock());
 
   in->pre_cow_old_inode();  // avoid cow mayhem
 
@@ -5529,7 +5532,8 @@ bool Locker::local_xlock_start(LocalLockC *lock, const MDRequestRef& mut)
   }
 
   lock->get_xlock(mut, mut->get_client());
-  mut->emplace_lock(lock, MutationImpl::LockOp::XLOCK);
+  auto it = mut->emplace_lock(lock, MutationImpl::LockOp::XLOCK);
+  ceph_assert(it->is_xlock());
   return true;
 }