delete reply;
dout(10) << "rename result is " << res << endl;
+ // renamed item from our cache
+
trim_cache();
dout(3) << "rename(\"" << from << "\", \"" << to << "\") = " << res << endl;
return res;
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
_ll_get(in);
- dout(3) << "ll_lookup " << parent << " " << name << " -> " << in->inode.ino
- << " (" << in << ")" << endl;
assert(inode_map[in->inode.ino] == in);
} else {
r = -ENOENT;
tout << ino.val << endl;
Inode *in = _ll_get_inode(ino);
+ int r = 0;
if (in->inode.is_symlink()) {
*value = in->symlink->c_str();
- return 0;
} else {
- return -EINVAL;
+ *value = "";
+ r = -EINVAL;
}
+ dout(3) << "ll_readlink " << ino << " = " << r << " (" << *value << ")" << endl;
+ return r;
}
int Client::ll_mknod(inodeno_t parent, const char *name, mode_t mode, dev_t rdev, struct stat *attr)
cap->set_suppress(true);
} else {
// make sure it has sufficient caps
- if (cap->wanted() & ~my_want) {
+ if (my_want & ~cap->wanted()) {
// augment wanted caps for this client
cap->set_wanted( cap->wanted() | my_want );
}
<< endl;
// update wanted
- if (cap->wanted() != wanted)
- cap->set_wanted(wanted);
+ if (cap->wanted() != wanted) {
+ if (m->get_seq() < cap->get_last_seq()) {
+ /* this is awkward.
+ client may be trying to release caps (i.e. inode closed, etc.) by setting reducing wanted
+ set.
+ but it may also be opening the same filename, not sure that it'll map to the same inode.
+ so, we don't want wanted reductions to clobber mds's notion of wanted unless we're
+ sure the client has seen all the latest caps.
+ */
+ dout(-10) << "handle_client_file_caps ignoring wanted " << cap_string(m->get_wanted())
+ << " bc seq " << m->get_seq() << " < " << cap->get_last_seq() << endl;
+ } else {
+ cap->set_wanted(wanted);
+ }
+ }
// confirm caps
int had = cap->confirm_receipt(m->get_seq(), m->get_caps());
// reply
MClientReply *reply = new MClientReply(mdr->client_request, 0);
- reply_request(mdr, reply, destdn->dir->get_inode()); // FIXME: imprecise ref
+ reply_request(mdr, reply, destdn->get_inode()); // FIXME: imprecise ref
// clean up?
if (straydn)
print_map(mdsmap);
for (map<int,int>::iterator p = mdsmap.mds_state.begin();
p != mdsmap.mds_state.end();
- ++p)
- if (mdsmap.is_active(p->first))
+ ++p) {
+ switch (p->second) {
+ case MDSMap::STATE_ACTIVE:
+ case MDSMap::STATE_STOPPING:
pending_mdsmap.mds_state[p->first] = MDSMap::STATE_STOPPING;
+ break;
+ case MDSMap::STATE_CREATING:
+ case MDSMap::STATE_STANDBY:
+ pending_mdsmap.mds_state[p->first] = MDSMap::STATE_DNE;
+ break;
+ case MDSMap::STATE_STARTING:
+ pending_mdsmap.mds_state[p->first] = MDSMap::STATE_STOPPED;
+ break;
+ case MDSMap::STATE_REPLAY:
+ case MDSMap::STATE_RESOLVE:
+ case MDSMap::STATE_RECONNECT:
+ case MDSMap::STATE_REJOIN:
+ // BUG: hrm, if this is the case, the STOPPING gusy won't be able to stop, will they?
+ pending_mdsmap.mds_state[p->first] = MDSMap::STATE_FAILED;
+ break;
+ }
+ }
propose_pending();
}