snapc = &nullsnap;
assert(in->last == CEPH_NOSNAP);
}
- dout(10) << "truncate_inode snapc " << snapc << " on " << *in << dendl;
+ 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, 0,
0, new C_MDC_TruncateFinish(this, in, ls));
MDS *mds;
MDRequest *mdr;
CInode *in;
+ bool smaller;
public:
- C_MDS_truncate_logged(MDS *m, MDRequest *r, CInode *i) :
- mds(m), mdr(r), in(i) {}
+ C_MDS_truncate_logged(MDS *m, MDRequest *r, CInode *i, bool sm) :
+ mds(m), mdr(r), in(i), smaller(sm) {}
void finish(int r) {
assert(r == 0);
// notify any clients
mds->locker->issue_truncate(in);
- if (in->inode.is_truncating())
+ if (smaller && in->inode.is_truncating())
mds->mdcache->truncate_inode(in, mdr->ls);
mds->balancer->hit_inode(mdr->now, in, META_POP_IWR);
CInode *cur = rdlock_path_pin_ref(mdr, true);
if (!cur) return;
- dout(10) << "handle_client_truncate " << req->head.args.truncate.length << " on " << *cur << dendl;
+ dout(10) << "handle_client_truncate " << cur->get_projected_inode()->size << " -> " << req->head.args.truncate.length
+ << " on " << *cur << dendl;
if (mdr->ref_snapid != CEPH_NOSNAP) {
reply_request(mdr, -EINVAL);
return;
}
- if (old_size > req->head.args.truncate.length && pi->is_truncating()) {
+ // trunc from bigger -> smaller
+ bool smaller = req->head.args.truncate.length < old_size;
+
+ if (smaller && pi->is_truncating()) {
dout(10) << " waiting for pending truncate from " << pi->truncate_from
<< " to " << pi->truncate_size << " to complete on " << *cur << dendl;
cur->add_waiter(CInode::WAIT_TRUNC, new C_MDS_RetryRequest(mdcache, mdr));
+ mds->mdlog->flush();
return;
}
pi->mtime = ctime;
pi->ctime = ctime;
pi->version = pdv;
- if (old_size > req->head.args.truncate.length) {
+ if (smaller) {
// truncate to smaller size
pi->truncate_from = old_size;
pi->size = req->head.args.truncate.length;
mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
mdcache->journal_dirty_inode(mdr, &le->metablob, cur);
- journal_and_reply(mdr, cur, 0, le, new C_MDS_truncate_logged(mds, mdr, cur));
+ journal_and_reply(mdr, cur, 0, le, new C_MDS_truncate_logged(mds, mdr, cur, smaller));
}
LogSegment *ls = mds->mdlog->get_current_segment();
ls->open_files.push_back(&in->xlist_open_file);
- journal_and_reply(mdr, in, 0, le, new C_MDS_truncate_logged(mds, mdr, in));
+ journal_and_reply(mdr, in, 0, le, new C_MDS_truncate_logged(mds, mdr, in, true));
}