]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: implement look_for_lock, for fcntl F_GETLK-style things
authorGreg Farnum <gregf@hq.newdream.net>
Thu, 29 Apr 2010 23:00:10 +0000 (16:00 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Mon, 2 Aug 2010 17:39:55 +0000 (10:39 -0700)
src/mds/Server.cc
src/mds/mdstypes.h

index f6f10d2f48d3b0e7a1ffeb2b2f6ccb94bc61f7b5..32a136e37025f075f1802ef1504a82126fe156a2 100644 (file)
@@ -2660,7 +2660,7 @@ void Server::handle_client_file_readlock(MDRequest *mdr)
            << ", dropping request!" << dendl;
     return;
   }
-  lock_state->add_lock(checking_lock, false, false);
+  lock_state->look_for_lock(checking_lock);
 
   bufferlist lock_bl;
   ::encode(lock_state, lock_bl);
index 8f29b1c559666a9e5e7a898ce8e37fd24874c758..112d5f0b6e450bcdc54597f4639bae7e2007c479 100644 (file)
@@ -385,6 +385,28 @@ struct ceph_lock_state_t {
     return false;
   }
 
+  void look_for_lock(ceph_filelock& testing_lock) {
+    list<ceph_filelock*> overlapping_locks, self_overlapping_locks;
+    if (get_overlapping_locks(testing_lock, overlapping_locks)) {
+      split_by_owner(testing_lock, overlapping_locks, self_overlapping_locks);
+    }
+    if (!overlapping_locks.empty()) { //somebody else owns overlapping lock
+      if (CEPH_LOCK_EXCL == testing_lock.type) { //any lock blocks it
+       testing_lock = *(*overlapping_locks.begin());
+      } else {
+       ceph_filelock *blocking_lock;
+       if ((blocking_lock = contains_exclusive_lock(overlapping_locks))) {
+         testing_lock = *blocking_lock;
+       } else { //nothing blocking!
+         testing_lock.type = CEPH_LOCK_UNLOCK;
+       }
+      }
+      return;
+    }
+    //if we get here, only our own locks block
+    testing_lock.type = CEPH_LOCK_UNLOCK;
+  }
+
   /*
    * Remove lock(s) described in old_lock. This may involve splitting a
    * previous lock or making a previous lock smaller.
@@ -659,13 +681,13 @@ private:
     }
   }
 
-  bool contains_exclusive_lock(list<ceph_filelock*>& locks) {
+  ceph_filelock *contains_exclusive_lock(list<ceph_filelock*>& locks) {
     for (list<ceph_filelock*>::iterator iter = locks.begin();
         iter != locks.end();
         ++iter) {
-      if (CEPH_LOCK_EXCL == (*iter)->type) return true;
+      if (CEPH_LOCK_EXCL == (*iter)->type) return *iter;
     }
-    return false;
+    return NULL;
   }
 
 public: