]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: need_snapflush for all snaps intersecting cowed inode range
authorSage Weil <sage@newdream.net>
Tue, 14 Sep 2010 23:45:05 +0000 (16:45 -0700)
committerSage Weil <sage@newdream.net>
Tue, 14 Sep 2010 23:45:05 +0000 (16:45 -0700)
If the inode is [2,3], and the realm has snaps 2,3 both defined, then we
expect flushed snap info for both 2 and 3.

src/mds/CInode.cc
src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.cc

index 62df123e45c8d4071e88622bef9e190c2b80e224..4344f0845d3931ec9f0f28cb286e8b7fe5b0077a 100644 (file)
@@ -149,7 +149,7 @@ ostream& operator<<(ostream& out, CInode& in)
     out << "/" << in.inode.accounted_rstat;
 
   if (!in.client_need_snapflush.empty())
-    out << " needsnapflush=" << in.client_need_snapflush;
+    out << " need_snapflush=" << in.client_need_snapflush;
 
 
   // locks
index 91aa2a4918d01a3fa9ca5e3aa2e1278936f5102c..9714f4f44ff161359cb2ff9bdcb448b7fbc3c1fe 100644 (file)
@@ -1759,9 +1759,9 @@ void Locker::_do_null_snapflush(CInode *head_in, client_t client, snapid_t follo
       dout(10) << " doing async NULL snapflush on " << p->first << " from client" << p->second << dendl;
       CInode *sin = mdcache->get_inode(head_in->ino(), p->first);
       assert(sin);
-      _do_snap_update(sin, 0, sin->first - 1, client, NULL, NULL);
-      head_in->client_need_snapflush[sin->last].erase(client);
-      if (head_in->client_need_snapflush[sin->last].empty()) {
+      _do_snap_update(sin, p->first, 0, sin->first - 1, client, NULL, NULL);
+      head_in->client_need_snapflush[p->first].erase(client);
+      if (head_in->client_need_snapflush[p->first].empty()) {
        head_in->client_need_snapflush.erase(p++);
        if (head_in->client_need_snapflush.empty())
          head_in->put(CInode::PIN_NEEDSNAPFLUSH);
@@ -1846,11 +1846,16 @@ void Locker::handle_client_caps(MClientCaps *m)
       goto out;
     }
 
+    SnapRealm *realm = in->find_snaprealm();
+    snapid_t snap = realm->get_snap_following(follows);
+    dout(10) << "  flushsnap follows " << follows << " -> snap " << snap << dendl;
+
     if (in == head_in ||
-       (head_in->client_need_snapflush.count(in->last) &&
-        head_in->client_need_snapflush[in->last].count(client))) {
-      dout(7) << " flushsnap follows " << follows
+       (head_in->client_need_snapflush.count(snap) &&
+        head_in->client_need_snapflush[snap].count(client))) {
+      dout(7) << " flushsnap snap " << snap
              << " client" << client << " on " << *in << dendl;
+
       // this cap now follows a later snap (i.e. the one initiating this flush, or later)
       cap->client_follows = MAX(follows, in->first) + 1;
    
@@ -1864,19 +1869,19 @@ void Locker::handle_client_caps(MClientCaps *m)
        ack->set_client_tid(m->get_client_tid());
       }
 
-      _do_snap_update(in, m->get_dirty(), follows, client, m, ack);
+      _do_snap_update(in, snap, m->get_dirty(), follows, client, m, ack);
 
       if (in != head_in) {
-       head_in->client_need_snapflush[in->last].erase(client);
-       if (head_in->client_need_snapflush[in->last].empty()) {
-         head_in->client_need_snapflush.erase(in->last);
+       head_in->client_need_snapflush[snap].erase(client);
+       if (head_in->client_need_snapflush[snap].empty()) {
+         head_in->client_need_snapflush.erase(snap);
          if (head_in->client_need_snapflush.empty())
            head_in->put(CInode::PIN_NEEDSNAPFLUSH);
        }
       }
       
     } else
-      dout(7) << " not expecting flushsnap from client" << client << " on " << *in << dendl;
+      dout(7) << " not expecting flushsnap " << snap << " from client" << client << " on " << *in << dendl;
     goto out;
   }
 
@@ -2044,16 +2049,12 @@ static uint64_t calc_bounding(uint64_t t)
   return t + 1;
 }
 
-void Locker::_do_snap_update(CInode *in, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack)
+void Locker::_do_snap_update(CInode *in, snapid_t snap, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack)
 {
   dout(10) << "_do_snap_update dirty " << ccap_string(dirty)
-          << " follows " << follows
+          << " follows " << follows << " snap " << snap
           << " on " << *in << dendl;
 
-  SnapRealm *realm = in->find_snaprealm();
-  snapid_t snap = realm->get_snap_following(follows);
-
-  dout(10) << "  snap is " << snap << dendl;
   if (snap == CEPH_NOSNAP) {
     // hmm, i guess snap was already deleted?  just ack!
     dout(10) << " wow, the snap following " << follows
index da67cc96eb80ead91b9d731ab695115bc3884275..7bf36b358d7ff796068f90be9c4f82b1041c1f4d 100644 (file)
@@ -184,7 +184,7 @@ public:
   void adjust_cap_wanted(Capability *cap, int wanted, int issue_seq);
   void handle_client_caps(class MClientCaps *m);
   void _update_cap_fields(CInode *in, int dirty, MClientCaps *m, inode_t *pi);
-  void _do_snap_update(CInode *in, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack);
+  void _do_snap_update(CInode *in, snapid_t snap, int dirty, snapid_t follows, client_t client, MClientCaps *m, MClientCaps *ack);
   void _do_null_snapflush(CInode *head_in, client_t client, snapid_t follows);
   bool _do_cap_update(CInode *in, Capability *cap, int dirty, snapid_t follows, MClientCaps *m,
                      MClientCaps *ack=0);
index 8cc3423c916aed3bc49f3063719d7a27cca9749f..b61ac92efe5e7824c4a771b1b8d2e8a9b474bd77 100644 (file)
@@ -1269,6 +1269,9 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
   dout(10) << "cow_inode " << *in << " to " << *oldin << dendl;
   add_inode(oldin);
   
+  SnapRealm *realm = in->find_snaprealm();
+  const set<snapid_t>& snaps = realm->get_snaps();
+
   // clone caps?
   for (map<client_t,Capability*>::iterator p = in->client_caps.begin();
       p != in->client_caps.end();
@@ -1295,7 +1298,15 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
       cap->client_follows = last;
       if (in->client_need_snapflush.empty())
        in->get(CInode::PIN_NEEDSNAPFLUSH);
-      in->client_need_snapflush[last].insert(client);
+      
+      // we need snapflushes for any intervening snaps
+      dout(10) << "  snaps " << snaps << dendl;
+      for (set<snapid_t>::const_iterator q = snaps.lower_bound(oldin->first);
+          q != snaps.end() && *q <= last;
+          q++) {
+       dout(10) << "   need_snapflush on " << *q << dendl;
+       in->client_need_snapflush[*q].insert(client);
+      }
     } else {
       dout(10) << " ignoring client" << client << " cap follows " << cap->client_follows << dendl;
     }