]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix fnode.snap_purged_thru check
authorYan, Zheng <zyan@redhat.com>
Wed, 18 Mar 2015 06:12:50 +0000 (14:12 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 18 Mar 2015 06:12:50 +0000 (14:12 +0800)
We do not alway succeed in purging all stale snap dentries
(stale snap dentris can be in-use or have been trimmed from
cache). Updating fnode.snap_purged_thru prematurely will make
us not purge the remainning stale snap dentries. If CDir
has no cached snap dentry when fetching dirfrag, we can
guaranee that all stale snap dentries will be purged.
So we only update fnode.snap_purged_thru in this case.

Now the code that purges stale snap dentries is executed more
frequently. So this patch also make readdir not purge stale
snap dentries

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CDir.cc
src/mds/Server.cc

index 4471c5740b468805cbf278908d8349a70a1a812c..adf77f354f3fb36edfdf231975bce7b1aa14f867 100644 (file)
@@ -1585,6 +1585,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
 
   // purge stale snaps?
   // only if we have past_parents open!
+  bool force_dirty = false;
   const set<snapid_t> *snaps = NULL;
   SnapRealm *realm = inode->find_snaprealm();
   if (!realm->have_past_parents_open()) {
@@ -1594,7 +1595,10 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
     dout(10) << " snap_purged_thru " << fnode.snap_purged_thru
             << " < " << realm->get_last_destroyed()
             << ", snap purge based on " << *snaps << dendl;
-    fnode.snap_purged_thru = realm->get_last_destroyed();
+    if (get_num_snap_items() == 0) {
+      fnode.snap_purged_thru = realm->get_last_destroyed();
+      force_dirty = true;
+    }
   }
 
   bool stray = inode->is_stray();
@@ -1648,8 +1652,10 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
       ::decode(d_type, q);
 
       if (stale) {
-       if (!dn)
+       if (!dn) {
          stale_items.insert(p->first);
+         force_dirty = true;
+       }
        continue;
       }
 
@@ -1681,8 +1687,10 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
       inode_data.decode_bare(q);
       
       if (stale) {
-       if (!dn)
+       if (!dn) {
          stale_items.insert(p->first);
+         force_dirty = true;
+       }
        continue;
       }
 
@@ -1806,7 +1814,7 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   }
 
   // dirty myself to remove stale snap dentries
-  if (!stale_items.empty() && !inode->mdcache->is_readonly())
+  if (force_dirty && !is_dirty() && !inode->mdcache->is_readonly())
     log_mark_dirty();
 
   auth_unpin(this);
@@ -1892,6 +1900,7 @@ void CDir::_omap_commit(int op_prio)
     dout(10) << " snap_purged_thru " << fnode.snap_purged_thru
             << " < " << realm->get_last_destroyed()
             << ", snap purge based on " << *snaps << dendl;
+    // fnode.snap_purged_thru = realm->get_last_destroyed();
   }
 
   set<string> to_remove;
index d69a935b988dad6d261bc03c379c24091c647413..b5a31e6adb39b80ba105a353dc7d4e7fc8c62335 100644 (file)
@@ -3134,16 +3134,7 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
   snapid_t snapid = mdr->snapid;
   dout(10) << "snapid " << snapid << dendl;
 
-  // purge stale snap data?
-  const set<snapid_t> *snaps = 0;
   SnapRealm *realm = diri->find_snaprealm();
-  if (realm->get_last_destroyed() > dir->fnode.snap_purged_thru) {
-    snaps = &realm->get_snaps();
-    dout(10) << " last_destroyed " << realm->get_last_destroyed() << " > " << dir->fnode.snap_purged_thru
-            << ", doing snap purge with " << *snaps << dendl;
-    dir->fnode.snap_purged_thru = realm->get_last_destroyed();
-    assert(snapid == CEPH_NOSNAP || snaps->count(snapid));  // just checkin'! 
-  }
 
   unsigned max = req->head.args.readdir.max_entries;
   if (!max)
@@ -3180,9 +3171,7 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
 
     if (dnl->is_null())
       continue;
-    if (snaps && dn->last != CEPH_NOSNAP)
-      if (dir->try_trim_snap_dentry(dn, *snaps))
-       continue;
+
     if (dn->last < snapid || dn->first > snapid) {
       dout(20) << "skipping non-overlapping snap " << *dn << dendl;
       continue;
@@ -3265,9 +3254,6 @@ void Server::handle_client_readdir(MDRequestRef& mdr)
   ::encode(complete, dirbl);
   dirbl.claim_append(dnbl);
   
-  if (snaps)
-    dir->log_mark_dirty();
-
   // yay, reply
   dout(10) << "reply to " << *req << " readdir num=" << numfiles
           << " bytes=" << dirbl.length()