From b9e2aab80707b22e617a4a0ec337d75f6ccefa8d Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 11 Oct 2013 14:03:13 +0800 Subject: mds: avoid leaking objects after purging file. 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 --- src/mds/MDCache.cc | 8 ++++++-- src/mds/mdstypes.cc | 5 ++++- src/mds/mdstypes.h | 6 +++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9dc1229fbb9..d3980b3766b 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -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 diff --git a/src/mds/mdstypes.cc b/src/mds/mdstypes.cc index 6886786f27e..362f74774c4 100644 --- a/src/mds/mdstypes.cc +++ b/src/mds/mdstypes.cc @@ -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); } diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 2a3874818b7..bd53c85b48d 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -329,6 +329,7 @@ struct inode_t { ceph_file_layout layout; vector 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; -- cgit v1.2.1