]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid leaking objects when purging file. 708/head
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 11 Oct 2013 06:03:13 +0000 (14:03 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Fri, 11 Oct 2013 09:24:33 +0000 (17:24 +0800)
The filer implementation does not delete stripe objects that are truncated
to zero. When purging a deleted file, we need to purge stripe objects up to
the max size the file has ever been.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/MDCache.cc
src/mds/mdstypes.cc
src/mds/mdstypes.h

index 9dc1229fbb96336a99b045fe965734acaa48d3f6..d3980b3766b181b3a2e40f1bdca223df3d90aad4 100644 (file)
@@ -9354,8 +9354,12 @@ void MDCache::purge_stray(CDentry *dn)
   if (in->is_file()) {
     uint64_t period = (uint64_t)in->inode.layout.fl_object_size *
                      (uint64_t)in->inode.layout.fl_stripe_count;
-    uint64_t cur_max_size = in->inode.get_max_size();
-    uint64_t to = MAX(in->inode.size, cur_max_size);
+    uint64_t to = in->inode.get_max_size();
+    to = MAX(in->inode.size, to);
+    // when truncating a file, the filer does not delete stripe objects that are
+    // truncated to zero. so we need to purge stripe objects up to the max size
+    // the file has ever been.
+    to = MAX(in->inode.max_size_ever, to);
     if (to && period) {
       uint64_t num = (to + period - 1) / period;
       dout(10) << "purge_stray 0~" << to << " objects 0~" << num
index 6886786f27e27d5c3cdfb410f48882eb87a4f9df..362f74774c40f714f045b38147b446f0ad18d490 100644 (file)
@@ -204,7 +204,7 @@ ostream& operator<<(ostream& out, const client_writeable_range_t& r)
  */
 void inode_t::encode(bufferlist &bl) const
 {
-  ENCODE_START(7, 6, bl);
+  ENCODE_START(8, 6, bl);
 
   ::encode(ino, bl);
   ::encode(rdev, bl);
@@ -238,6 +238,7 @@ void inode_t::encode(bufferlist &bl) const
   ::encode(xattr_version, bl);
   ::encode(backtrace_version, bl);
   ::encode(old_pools, bl);
+  ::encode(max_size_ever, bl);
 
   ENCODE_FINISH(bl);
 }
@@ -294,6 +295,8 @@ void inode_t::decode(bufferlist::iterator &p)
     ::decode(backtrace_version, p);
   if (struct_v >= 7)
     ::decode(old_pools, p);
+  if (struct_v >= 8)
+    ::decode(max_size_ever, p);
 
   DECODE_FINISH(p);
 }
index 2a3874818b7ae8869cd7cb9b6c51dd0afac64f27..bd53c85b48d2a5c6cfebd8461c8fd3adfc31e9fe 100644 (file)
@@ -329,6 +329,7 @@ struct inode_t {
   ceph_file_layout layout;
   vector <int64_t> old_pools;
   uint64_t   size;        // on directory, # dentries
+  uint64_t   max_size_ever; // max size the file has ever been
   uint32_t   truncate_seq;
   uint64_t   truncate_size, truncate_from;
   uint32_t   truncate_pending;
@@ -353,7 +354,8 @@ struct inode_t {
   inode_t() : ino(0), rdev(0),
              mode(0), uid(0), gid(0),
              nlink(0), anchored(false),
-             size(0), truncate_seq(0), truncate_size(0), truncate_from(0),
+             size(0), max_size_ever(0),
+             truncate_seq(0), truncate_size(0), truncate_from(0),
              truncate_pending(0),
              time_warp_seq(0),
              version(0), file_data_version(0), xattr_version(0), backtrace_version(0) {
@@ -369,6 +371,8 @@ struct inode_t {
   bool is_truncating() const { return (truncate_pending > 0); }
   void truncate(uint64_t old_size, uint64_t new_size) {
     assert(new_size < old_size);
+    if (old_size > max_size_ever)
+      max_size_ever = old_size;
     truncate_from = old_size;
     size = new_size;
     rstat.rbytes = new_size;