mirror of
https://github.com/ceph/ceph
synced 2025-01-18 09:02:08 +00:00
mds: get_linkage() should return projected if xlocked by self
Also, move set_xlocks_done() to _below_ set_trace_dist, in case some other request comes in and xlocks the dentry. Allow read_projected in XLOCK state too. Note that other requests _still_ won't be able to re-xlock or rdlock until the prior request set xlock done.
This commit is contained in:
parent
b025d4f856
commit
9a2c7e92d9
@ -207,11 +207,12 @@ public:
|
||||
return get_projected_linkage()->inode;
|
||||
}
|
||||
|
||||
bool use_projected(int client) {
|
||||
return lock.can_read_projected(client);
|
||||
bool use_projected(int client, Mutation *mut) {
|
||||
return lock.can_read_projected(client) ||
|
||||
lock.get_xlocked_by() == mut;
|
||||
}
|
||||
linkage_t *get_linkage(int client) {
|
||||
return use_projected(client) ? get_projected_linkage() : get_linkage();
|
||||
linkage_t *get_linkage(int client, Mutation *mut) {
|
||||
return use_projected(client, mut) ? get_projected_linkage() : get_linkage();
|
||||
}
|
||||
|
||||
// ref counts: pin ourselves in the LRU when we're pinned.
|
||||
|
@ -525,9 +525,6 @@ void Server::early_reply(MDRequest *mdr, CInode *tracei, CDentry *tracedn)
|
||||
return;
|
||||
}
|
||||
|
||||
// mark xlocks "done", indicating that we are exposing uncommitted changes
|
||||
mds->locker->set_xlocks_done(mdr);
|
||||
|
||||
MClientRequest *req = mdr->client_request;
|
||||
entity_inst_t client_inst = req->get_orig_source_inst();
|
||||
if (client_inst.name.is_mds())
|
||||
@ -545,9 +542,12 @@ void Server::early_reply(MDRequest *mdr, CInode *tracei, CDentry *tracedn)
|
||||
if (tracei || tracedn)
|
||||
set_trace_dist(mdr->session, reply, tracei, tracedn, snapid, snapdiri, true, mdr);
|
||||
|
||||
mdr->did_early_reply = true;
|
||||
|
||||
messenger->send_message(reply, client_inst);
|
||||
|
||||
// mark xlocks "done", indicating that we are exposing uncommitted changes
|
||||
mds->locker->set_xlocks_done(mdr);
|
||||
|
||||
mdr->did_early_reply = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -685,7 +685,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C
|
||||
// start with dentry or inode?
|
||||
if (!in) {
|
||||
assert(dn);
|
||||
in = dn->get_linkage(client)->get_inode();
|
||||
in = dn->get_linkage(client, mdr)->get_inode();
|
||||
goto dentry;
|
||||
}
|
||||
|
||||
@ -725,7 +725,7 @@ void Server::set_trace_dist(Session *session, MClientReply *reply, CInode *in, C
|
||||
|
||||
if (!dn) {
|
||||
dn = in->get_projected_parent_dn();
|
||||
if (dn && !dn->use_projected(client))
|
||||
if (dn && !dn->use_projected(client, mdr))
|
||||
dn = NULL;
|
||||
if (!dn)
|
||||
dn = in->get_parent_dn();
|
||||
@ -1309,7 +1309,7 @@ CDentry* Server::prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dn
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
if (!dn->get_linkage(client)->is_null()) {
|
||||
if (!dn->get_linkage(client, mdr)->is_null()) {
|
||||
// name already exists
|
||||
dout(10) << "dentry " << dname << " exists in " << *dir << dendl;
|
||||
if (!okexist) {
|
||||
@ -1510,7 +1510,7 @@ CInode* Server::rdlock_path_pin_ref(MDRequest *mdr,
|
||||
ref = mdcache->get_inode(refpath.get_ino());
|
||||
else {
|
||||
CDentry *dn = trace[trace.size()-1];
|
||||
bool dnp = dn->use_projected(client);
|
||||
bool dnp = dn->use_projected(client, mdr);
|
||||
CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage();
|
||||
|
||||
// if no inode (null or unattached remote), fw to dentry auth?
|
||||
@ -1635,7 +1635,7 @@ CDentry* Server::rdlock_path_xlock_dentry(MDRequest *mdr, bool okexist, bool mus
|
||||
}
|
||||
|
||||
// exists?
|
||||
if (!dn || dn->get_linkage(client)->is_null()) {
|
||||
if (!dn || dn->get_linkage(client, mdr)->is_null()) {
|
||||
dout(7) << "dentry " << dname << " dne in " << *dir << dendl;
|
||||
reply_request(mdr, -ENOENT);
|
||||
return 0;
|
||||
@ -1651,7 +1651,7 @@ CDentry* Server::rdlock_path_xlock_dentry(MDRequest *mdr, bool okexist, bool mus
|
||||
|
||||
for (int i=0; i<(int)trace.size(); i++)
|
||||
rdlocks.insert(&trace[i]->lock);
|
||||
if (dn->get_linkage(client)->is_null())
|
||||
if (dn->get_linkage(client, mdr)->is_null())
|
||||
xlocks.insert(&dn->lock); // new dn, xlock
|
||||
else
|
||||
rdlocks.insert(&dn->lock); // existing dn, rdlock
|
||||
@ -2207,7 +2207,7 @@ void Server::handle_client_readdir(MDRequest *mdr)
|
||||
CDentry *dn = it->second;
|
||||
it++;
|
||||
|
||||
bool dnp = dn->use_projected(client);
|
||||
bool dnp = dn->use_projected(client, mdr);
|
||||
CDentry::linkage_t *dnl = dnp ? dn->get_projected_linkage() : dn->get_linkage();
|
||||
|
||||
if (dnl->is_null())
|
||||
@ -3107,7 +3107,7 @@ void Server::handle_client_unlink(MDRequest *mdr)
|
||||
return;
|
||||
}
|
||||
|
||||
CDentry::linkage_t *dnl = dn->get_linkage(client);
|
||||
CDentry::linkage_t *dnl = dn->get_linkage(client, mdr);
|
||||
if (dnl->is_null()) {
|
||||
reply_request(mdr, -ENOENT);
|
||||
return;
|
||||
@ -5223,7 +5223,7 @@ void Server::handle_client_lssnap(MDRequest *mdr)
|
||||
mdcache->request_forward(mdr, dn->authority().first);
|
||||
return;
|
||||
}
|
||||
CDentry::linkage_t *dnl = dn->get_linkage(client);
|
||||
CDentry::linkage_t *dnl = dn->get_linkage(client, mdr);
|
||||
|
||||
// dir only
|
||||
CInode *diri = dnl->get_inode();
|
||||
|
@ -22,9 +22,9 @@ struct sm_state_t simplelock[20] = {
|
||||
[LOCK_SYNC_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, ANY, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_EXCL_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
|
||||
[LOCK_XLOCK] = { 0, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_LOCK_XLOCK]= { LOCK_XLOCK,false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_XLOCK] = { 0, false, LOCK_LOCK, 0, XCL, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_XLOCKDONE] = { LOCK_SYNC, false, LOCK_LOCK, XCL, XCL, XCL, 0, XCL, XCL, 0,0,0 },
|
||||
[LOCK_LOCK_XLOCK]= { LOCK_XLOCK,false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
|
||||
[LOCK_EXCL] = { 0, true, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,CEPH_CAP_GEXCL|CEPH_CAP_GRDCACHE,0 },
|
||||
[LOCK_SYNC_EXCL] = { LOCK_EXCL, true, LOCK_LOCK, ANY, 0, 0, 0, 0, 0, 0,CEPH_CAP_GRDCACHE,0 },
|
||||
@ -88,7 +88,7 @@ struct sm_state_t filelock[30] = {
|
||||
[LOCK_EXCL_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, CEPH_CAP_GRDCACHE|CEPH_CAP_GWRBUFFER,0,CEPH_CAP_GRDCACHE },
|
||||
[LOCK_MIX_LOCK] = { LOCK_LOCK, false, LOCK_LOCK, AUTH, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
|
||||
[LOCK_XLOCK] = { 0, false, LOCK_LOCK, 0, 0, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_XLOCK] = { 0, false, LOCK_LOCK, 0, XCL, 0, 0, 0, 0, 0,0,0 },
|
||||
[LOCK_XLOCKDONE] = { LOCK_SYNC, false, LOCK_LOCK, XCL, XCL, XCL, 0, XCL, XCL, 0,0,0 },
|
||||
|
||||
[LOCK_MIX] = { 0, false, LOCK_MIX, 0, 0, FW, ANY, 0, 0, CEPH_CAP_GRD|CEPH_CAP_GWR,0,CEPH_CAP_GRD },
|
||||
|
Loading…
Reference in New Issue
Block a user