diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-09-26 09:08:36 +0800 |
---|---|---|
committer | Yan, Zheng <zheng.z.yan@intel.com> | 2013-09-26 10:16:10 +0800 |
commit | b4eb9200cbee5ada9c1fd0bfc2ebba1667d71268 (patch) | |
tree | 1a47c030c1ba98bb5e1b18b7f5eb00b7dc47ca4a | |
parent | 52c7f2796397b5e3aa24c24bf0c6615cadf927c6 (diff) | |
download | ceph-b4eb9200cbee5ada9c1fd0bfc2ebba1667d71268.tar.gz |
Filer: purge stripe objects that are truncated to zero
When truncating a file, current filer implementation does not delete
stripe objects that are truncated to zero. If we delete the file later,
these zero sized objects become orphans.
This patch fixes the issue by changing the meaning of TRIMTRUNC OSD
operation. When OSD handles TRIMTRUNC operation that truncates object
size to 0, it compares the operation's truncate seq with the object's
truncate seq. If the operation's truncate seq is larger, it delete the
object. If the truncate seq check is for the case that OSD receives
client's write before receiving MDS's truncate.
Also set length field of TRIMTRUNC operation to (uint64_t)-1. OSD uses
it to distinguish requests sent by old clients.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
-rw-r--r-- | src/mds/MDCache.cc | 4 | ||||
-rw-r--r-- | src/osd/ReplicatedPG.cc | 11 | ||||
-rw-r--r-- | src/osdc/Filer.h | 17 |
3 files changed, 28 insertions, 4 deletions
diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9dc1229fbb9..dc5a38c9178 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -5902,8 +5902,8 @@ void MDCache::_truncate_inode(CInode *in, LogSegment *ls) } dout(10) << "_truncate_inode snapc " << snapc << " on " << *in << dendl; mds->filer->truncate(in->inode.ino, &in->inode.layout, *snapc, - pi->truncate_size, pi->truncate_from-pi->truncate_size, pi->truncate_seq, utime_t(), 0, - 0, new C_MDC_TruncateFinish(this, in, ls)); + pi->truncate_size, pi->truncate_from-pi->truncate_size, pi->truncate_seq, + utime_t(), 0, true, 0, new C_MDC_TruncateFinish(this, in, ls)); } struct C_MDC_TruncateLogged : public Context { diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 7d1738da572..99cf5832613 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -2189,6 +2189,17 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) << " -> TRUNCATE " << op.extent.offset << " (old size is " << oi.size << ")" << dendl; op.op = CEPH_OSD_OP_TRUNCATE; } + + if (op.op == CEPH_OSD_OP_TRIMTRUNC && + obs.exists && + op.extent.offset == 0 && + op.extent.length == (uint64_t)-1 && + op.extent.truncate_size == 0 && + op.extent.truncate_seq > oi.truncate_seq) { + dout(10) << " munging TRIMTRUNC -> DELETE (truncate seq " << op.extent.truncate_seq + << " > current " << oi.truncate_seq << ")" << dendl; + op.op = CEPH_OSD_OP_DELETE; + } switch (op.op) { diff --git a/src/osdc/Filer.h b/src/osdc/Filer.h index 607dc7b30d5..ea8cc9b5eaf 100644 --- a/src/osdc/Filer.h +++ b/src/osdc/Filer.h @@ -173,13 +173,20 @@ class Filer { __u32 truncate_seq, utime_t mtime, int flags, + bool keep_first, Context *onack, Context *oncommit) { vector<ObjectExtent> extents; Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents); if (extents.size() == 1) { vector<OSDOp> ops(1); - ops[0].op.op = CEPH_OSD_OP_TRIMTRUNC; + if (keep_first && extents[0].objectno == 0) { + ops[0].op.op = CEPH_OSD_OP_TRUNCATE; + ops[0].op.extent.offset = extents[0].offset; + } else { + ops[0].op.op = CEPH_OSD_OP_TRIMTRUNC; + ops[0].op.extent.length = (uint64_t)-1; + } ops[0].op.extent.truncate_seq = truncate_seq; ops[0].op.extent.truncate_size = extents[0].offset; objecter->_modify(extents[0].oid, extents[0].oloc, ops, mtime, snapc, flags, onack, oncommit); @@ -188,7 +195,13 @@ class Filer { C_GatherBuilder gcom(cct, oncommit); for (vector<ObjectExtent>::iterator p = extents.begin(); p != extents.end(); ++p) { vector<OSDOp> ops(1); - ops[0].op.op = CEPH_OSD_OP_TRIMTRUNC; + if (keep_first && p->objectno == 0) { + ops[0].op.op = CEPH_OSD_OP_TRUNCATE; + ops[0].op.extent.offset = p->offset; + } else { + ops[0].op.op = CEPH_OSD_OP_TRIMTRUNC; + ops[0].op.extent.length = (uint64_t)-1; + } ops[0].op.extent.truncate_size = p->offset; ops[0].op.extent.truncate_seq = truncate_seq; objecter->_modify(p->oid, p->oloc, ops, mtime, snapc, flags, |