]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix potentially invalid read in trim_caps
authorJohn Spray <john.spray@redhat.com>
Wed, 3 Sep 2014 18:31:38 +0000 (19:31 +0100)
committerJohn Spray <john.spray@redhat.com>
Mon, 15 Sep 2014 14:05:13 +0000 (15:05 +0100)
trim_dentry can potentially free an inode, so get/put
it around the block where we use the inode's dn_set.

Signed-off-by: John Spray <john.spray@redhat.com>
src/client/Client.cc

index 840b55257a94898169904fe1412dfb51da2d8b68..ae4df676512017f5c92ae995fa2733d343c50fcb 100644 (file)
@@ -3170,10 +3170,12 @@ void Client::trim_caps(MetaSession *s, int max)
       ldout(cct, 20) << " trying to trim dentries for " << *in << dendl;
       bool all = true;
       set<Dentry*>::iterator q = in->dn_set.begin();
+      in->get();
       while (q != in->dn_set.end()) {
        Dentry *dn = *q++;
        if (dn->lru_is_expireable()) {
          trim_dentry(dn);
+
         } else {
           ldout(cct, 20) << "  not expirable: " << dn->name << dendl;
          all = false;
@@ -3183,6 +3185,8 @@ void Client::trim_caps(MetaSession *s, int max)
         ldout(cct, 20) << __func__ << " counting as trimmed: " << *in << dendl;
        trimmed++;
       }
+
+      put_inode(in);
     }
 
     ++p;
@@ -3193,6 +3197,7 @@ void Client::trim_caps(MetaSession *s, int max)
   }
   s->s_cap_iterator = NULL;
 
+
   // notify kernel to invalidate top level directory entries. As a side effect,
   // unused inodes underneath these entries get pruned.
   if (dentry_invalidate_cb && s->caps.size() > max) {