MDRequestRef mdr = request_get(*p);
mdr->aborted = true;
if (mdr->slave_request) {
- if (mdr->more()->slave_commit) // journaling slave prepare ?
+ if (mdr->slave_did_prepare()) // journaling slave prepare ?
add_rollback(*p, from);
} else {
request_finish(mdr);
void MDCache::dispatch_request(MDRequestRef& mdr)
{
- if (mdr->killed) {
- dout(10) << "request " << *mdr << " was killed" << dendl;
- return;
- }
if (mdr->client_request) {
mds->server->dispatch_client_request(mdr);
} else if (mdr->slave_request) {
MMDSSlaveRequest *r = new MMDSSlaveRequest(mdr->reqid, mdr->attempt,
MMDSSlaveRequest::OP_FINISH);
- // information about rename imported caps
- if (mdr->more()->srcdn_auth_mds == *p &&
- mdr->more()->inode_import.length() > 0)
+ if (mdr->killed && !mdr->committing) {
+ r->mark_abort();
+ } else if (mdr->more()->srcdn_auth_mds == *p &&
+ mdr->more()->inode_import.length() > 0) {
+ // information about rename imported caps
r->inode_export.claim(mdr->more()->inode_import);
+ }
mds->send_message_mds(r, *p);
}
void MDCache::request_kill(MDRequestRef& mdr)
{
+ // rollback slave requests is tricky. just let the request proceed.
+ if (mdr->done_locking && mdr->has_more() &&
+ (!mdr->more()->witnessed.empty() || !mdr->more()->waiting_on_slave.empty())) {
+ dout(10) << "request_kill " << *mdr << " -- already started slave requests, no-op" << dendl;
+
+ assert(mdr->used_prealloc_ino == 0);
+ assert(mdr->prealloc_inos.empty());
+
+ mdr->session = NULL;
+ mdr->item_session_request.remove_myself();
+ return;
+ }
+
mdr->killed = true;
mdr->mark_event("killing request");
- if (!mdr->committing) {
+
+ if (mdr->committing) {
+ dout(10) << "request_kill " << *mdr << " -- already committing, no-op" << dendl;
+ } else {
dout(10) << "request_kill " << *mdr << dendl;
request_cleanup(mdr);
- } else {
- dout(10) << "request_kill " << *mdr << " -- already committing, no-op" << dendl;
}
}
mdr->mark_event("replying");
+ Session *session = mdr->session;
+
// note successful request in session map?
//
// setfilelock requests are special, they only modify states in MDS memory.
// setfilelock request, it means that client did not receive corresponding
// setfilelock reply. So MDS should re-execute the setfilelock request.
if (req->may_write() && req->get_op() != CEPH_MDS_OP_SETFILELOCK &&
- reply->get_result() == 0 && mdr->session) {
+ reply->get_result() == 0 && session) {
inodeno_t created = mdr->alloc_ino ? mdr->alloc_ino : mdr->used_prealloc_ino;
- mdr->session->add_completed_request(mdr->reqid.tid, created);
+ session->add_completed_request(mdr->reqid.tid, created);
if (mdr->ls) {
- mdr->ls->touched_sessions.insert(mdr->session->info.inst.name);
+ mdr->ls->touched_sessions.insert(session->info.inst.name);
}
}
// give any preallocated inos to the session
- apply_allocated_inos(mdr);
+ apply_allocated_inos(mdr, session);
// get tracei/tracedn from mdr?
snapid_t snapid = mdr->snapid;
bool is_replay = mdr->client_request->is_replay();
bool did_early_reply = mdr->did_early_reply;
- Session *session = mdr->session;
entity_inst_t client_inst = req->get_source_inst();
int dentry_wanted = req->get_dentry_wanted();
mdr->cap_releases.erase(tracedn->get_dir()->get_inode()->vino());
}
- // note client connection to direct my reply
- ConnectionRef client_con = req->get_connection();
-
// drop non-rdlocks before replying, so that we can issue leases
mdcache->request_drop_non_rdlocks(mdr);
// reply at all?
- if (client_inst.name.is_mds()) {
+ if (client_inst.name.is_mds() || !session) {
reply->put(); // mds doesn't need a reply
reply = 0;
} else {
reply->set_extra_bl(mdr->reply_extra_bl);
reply->set_mdsmap_epoch(mds->mdsmap->get_epoch());
- client_con->send_message(reply);
+ req->get_connection()->send_message(reply);
}
const bool completed = mdr->has_completed;
void Server::dispatch_client_request(MDRequestRef& mdr)
{
+ // we shouldn't be waiting on anyone.
+ assert(!mdr->has_more() || mdr->more()->waiting_on_slave.empty());
+
+ if (mdr->killed) {
+ dout(10) << "request " << *mdr << " was killed" << dendl;
+ return;
+ }
+
MClientRequest *req = mdr->client_request;
if (logger) logger->inc(l_mdss_dispatch_client_request);
dout(7) << "dispatch_client_request " << *req << dendl;
- // we shouldn't be waiting on anyone.
- assert(!mdr->has_more() || mdr->more()->waiting_on_slave.empty());
-
if (req->may_write()) {
if (mdcache->is_readonly()) {
dout(10) << " read-only FS" << dendl;
m->put();
return;
}
+
+ if (m->get_op() == MMDSSlaveRequest::OP_FINISH && m->is_abort()) {
+ mdr->aborted = true;
+ if (mdr->slave_request) {
+ // only abort on-going xlock, wrlock and auth pin
+ assert(!mdr->slave_did_prepare());
+ } else {
+ mdcache->request_finish(mdr);
+ }
+ return;
+ }
}
if (!mdr.get()) {
// new?
mds->inotable->get_projected_version());
}
-void Server::apply_allocated_inos(MDRequestRef& mdr)
+void Server::apply_allocated_inos(MDRequestRef& mdr, Session *session)
{
- Session *session = mdr->session;
dout(10) << "apply_allocated_inos " << mdr->alloc_ino
<< " / " << mdr->prealloc_inos
<< " / " << mdr->used_prealloc_ino << dendl;
__s16 op;
__u16 flags;
- static const unsigned FLAG_NONBLOCK = 1;
- static const unsigned FLAG_WOULDBLOCK = 2;
- static const unsigned FLAG_NOTJOURNALED = 4;
- static const unsigned FLAG_EROFS = 8;
+ static const unsigned FLAG_NONBLOCK = 1<<0;
+ static const unsigned FLAG_WOULDBLOCK = 1<<1;
+ static const unsigned FLAG_NOTJOURNALED = 1<<2;
+ static const unsigned FLAG_EROFS = 1<<3;
+ static const unsigned FLAG_ABORT = 1<<4;
// for locking
__u16 lock_type; // lock object type
bool is_not_journaled() { return (flags & FLAG_NOTJOURNALED); }
void mark_error_rofs() { flags |= FLAG_EROFS; }
bool is_error_rofs() { return (flags & FLAG_EROFS); }
+ bool is_abort() { return (flags & FLAG_ABORT); }
+ void mark_abort() { flags |= FLAG_ABORT; }
void set_lock_type(int t) { lock_type = t; }