summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-09-26 09:08:36 +0800
committerYan, Zheng <zheng.z.yan@intel.com>2013-09-26 10:16:10 +0800
commitb4eb9200cbee5ada9c1fd0bfc2ebba1667d71268 (patch)
tree1a47c030c1ba98bb5e1b18b7f5eb00b7dc47ca4a
parent52c7f2796397b5e3aa24c24bf0c6615cadf927c6 (diff)
downloadceph-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.cc4
-rw-r--r--src/osd/ReplicatedPG.cc11
-rw-r--r--src/osdc/Filer.h17
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,