]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add some scatterlock notes
authorSage Weil <sage@newdream.net>
Wed, 3 Nov 2010 18:07:40 +0000 (11:07 -0700)
committerSage Weil <sage@newdream.net>
Wed, 3 Nov 2010 18:07:40 +0000 (11:07 -0700)
Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/CInode.cc
src/mds/Locker.cc

index 69130eee70775a6148a061e1ada7f440fd59c1ad..7f35a54ef7cf20b2380647b7e6c7c0d69f5d528a 100644 (file)
@@ -1176,6 +1176,8 @@ struct C_Inode_FragUpdate : public Context {
 };
 
 
+/* for more info on scatterlocks, see comments by Locker::scatter_writebehind */
+
 void CInode::decode_lock_state(int type, bufferlist& bl)
 {
   bufferlist::iterator p = bl.begin();
@@ -1492,6 +1494,7 @@ void CInode::clear_dirty_scattered(int type)
  * when we initially scatter a lock, we need to check if any of the dirfrags
  * have out of date accounted_rstat/fragstat.  if so, mark the lock stale.
  */
+/* for more info on scatterlocks, see comments by Locker::scatter_writebehind */
 void CInode::start_scatter(ScatterLock *lock)
 {
   dout(10) << "start_scatter " << *lock << " on " << *this << dendl;
@@ -1533,6 +1536,7 @@ void CInode::start_scatter(ScatterLock *lock)
  * because the frag is auth and frozen, or that the replica couldn't for the same
  * reason.  hopefully it will get updated the next time the lock cycles.
  */
+/* for more info on scatterlocks, see comments by Locker::scatter_writebehind */
 void CInode::finish_scatter_gather_update(int type)
 {
   dout(10) << "finish_scatter_gather_update " << type << " on " << *this << dendl;
index 9103dd3f9890308fa8ab7c05849da089a8c09d66..bf4544872f7ac43dbb8842f1c155ffa762fae081 100644 (file)
@@ -3223,6 +3223,44 @@ void Locker::dentry_anon_rdlock_trace_finish(vector<CDentry*>& trace)
 // ==========================================================================
 // scatter lock
 
+/*
+
+Some notes on scatterlocks.
+
+ - The scatter/gather is driven by the inode lock.  The scatter always
+   brings in the latest metadata from the fragments.
+
+ - When in a scattered/MIX state, fragments are only allowed to
+   update/be written to if the accounted stat matches the inode's
+   current version.
+
+ - That means, on gather, we _only_ assimilate diffs for frag metadata
+   that match the current version, because those are the only ones
+   written during this scatter/gather cycle.  (Others didn't permit
+   it.)  We increment the version and journal this to disk.
+
+ - When possible, we also simultaneously update our local frag
+   accounted stats to match.
+
+ - On scatter, the new inode info is broadcast to frags, both local
+   and remote.  If possible (auth and !frozen), the dirfrag auth
+   should update the accounted state (if it isn't already up to date).
+   Note that this may occur on both the local inode auth node and
+   inode replicas, so there are two potential paths. If it is NOT
+   possible, they need to mark_stale to prevent any possible writes.
+
+ - A scatter can be to MIX (potentially writeable) or to SYNC (read
+   only).  Both are opportunities to update the frag accounted stats,
+   even though only the MIX case is affected by a stale dirfrag.
+
+ - Because many scatter/gather cycles can potentially go by without a
+   frag being able to update its accounted stats (due to being frozen
+   by exports/refragments in progress), the frag may have (even very)
+   old stat versions.  That's fine.  It is always stale (MIX_STALE
+   instead of MIX) as a result, and then ignored by the gather.
+
+*/
+
 void Locker::scatter_writebehind(ScatterLock *lock)
 {
   CInode *in = (CInode*)lock->get_parent();