%.o: %.cc
${CC} ${CFLAGS} -c $< -o $@
+count:
+ cat *.cc */*.cc */*.h */*/*.h | wc -l
+ cat *.cc */*.cc */*.h */*/*.h | grep -c \;
+
.depend:
touch .depend
HARD LINKS
--> discover mechanism
+- discover_ino
+ - called by path_traverse
+- clean up inode file concept, #define's, etc.
+- unlink
+ - migrate to inode file
+- reclaim from inode file on discover...
+
/- link
discover
-int Client::mount()
+int Client::mount(bool mkfs)
{
assert(!mounted); // caller is confused?
dout(1) << "mounting" << endl;
- MClientMountAck *reply = (MClientMountAck*)messenger->sendrecv(new MClientMount(),
+ MClientMount *m = new MClientMount();
+ if (mkfs) m->set_mkfs();
+ MClientMountAck *reply = (MClientMountAck*)messenger->sendrecv(m,
MSG_ADDR_MDS(0), MDS_PORT_SERVER);
assert(reply);
// ----------------------
// fs ops.
- int mount();
+ int mount(bool mkfs=false);
int unmount();
// these shoud (more or less) mirror the actual system calls.
fake_clock: false,
fakemessenger_serialize: true,
- debug: 20,
+ debug: 13,
// --- client ---
client_cache_size: 400,
// start messenger thread
fakemessenger_startthread();
- g_timer.add_event_after(5.0, new C_Test2);
- g_timer.add_event_after(10.0, new C_Test);
-
+ //g_timer.add_event_after(5.0, new C_Test2);
+ //g_timer.add_event_after(10.0, new C_Test);
+
+ bool mkfs = false;
+ for (int i=1; i<argc; i++)
+ if (strcmp(argv[i], "--mkfs") == 0) {
+ mkfs = true;
+ argv[i] = 0;
+ argc--;
+ break;
+ }
// create mds
MDS *mds[NUMMDS];
// start up fuse
// use my argc, argv (make sure you pass a mount point!)
cout << "starting fuse on pid " << getpid() << endl;
- client[i]->mount();
+ client[i]->mount(mkfs);
ceph_fuse_main(client[i], argc, argv);
client[i]->unmount();
cout << "fuse finished on pid " << getpid() << endl;
dir->mark_dirty();
// pin inode?
- if (is_primary() && !dirty) inode->get(CINODE_PIN_DNDIRTY);
+ if (is_primary() && !dirty && inode) inode->get(CINODE_PIN_DNDIRTY);
// i now live in that (potentially newly dirty) version
parent_dir_version = dir->get_version();
void CDentry::mark_clean() {
dout(10) << " mark_clean " << *this << endl;
- if (is_primary() && dirty) inode->put(CINODE_PIN_DNDIRTY);
+ if (is_primary() && dirty && inode) inode->put(CINODE_PIN_DNDIRTY);
dirty = false;
}
}
};
-void MDCache::open_remote_dir(CInode *diri,
- Context *fin)
-{
- dout(10) << "open_remote_dir on " << *diri << endl;
-
- assert(diri->is_dir());
- assert(!diri->dir_is_auth());
- assert(!diri->is_auth());
- assert(diri->dir == 0);
-
- filepath want; // no dentries, i just want the dir open
- mds->messenger->send_message(new MDiscover(mds->get_nodeid(),
- diri->ino(),
- want,
- true), // need the dir open
- MSG_ADDR_MDS(diri->authority()), MDS_PORT_CACHE,
- MDS_PORT_CACHE);
-
- diri->add_waiter(CINODE_WAIT_DIR, fin);
-}
-
-
int MDCache::path_traverse(filepath& origpath,
vector<CDentry*>& trace,
bool follow_trailing_symlink,
continue;
}
+
// dentry
CDentry *dn = cur->dir->lookup(path[depth]);
- // xlocked by me?
- if (dn && !dn->inode && dn->is_xlockedbyme(req) &&
+ // null and last_bit and xlocked by me?
+ if (dn && dn->is_null() &&
+ dn->is_xlockedbyme(req) &&
depth == path.depth()-1) {
dout(10) << "traverse: hit (my) xlocked dentry at tail of traverse, succeeding" << endl;
trace.push_back(dn);
break; // done!
}
- if (dn && dn->inode) {
- // have it. locked?
+ if (dn && !dn->is_null()) {
+ // dentry exists. xlocked?
if (!noperm && dn->is_xlockedbyother(req)) {
dout(10) << "traverse: xlocked dentry at " << *dn << endl;
cur->dir->add_waiter(CDIR_WAIT_DNREAD,
return 1;
}
+ // do we have inode?
+ if (!dn->inode) {
+ assert(dn->is_remote());
+ // do i have it?
+ CInode *in = get_inode(dn->get_remote_ino());
+ if (in) {
+ dout(7) << "linking in remote in " << *in << endl;
+ dn->link_remote(in);
+ } else {
+ dout(7) << "remote link to " << dn->get_remote_ino() << ", which i don't have" << endl;
+ open_remote_ino(dn->get_remote_ino(), req,
+ ondelay);
+ return 1;
+ }
+ }
+
+ // symlink?
if (dn->inode->is_symlink() &&
(follow_trailing_symlink || depth < path.depth()-1)) {
// symlink, resolve!
}
}
- // don't have it.
+ // MISS. don't have it.
+
int dauth = cur->dir->dentry_authority( path[depth] );
dout(12) << "traverse: miss on dentry " << path[depth] << " dauth " << dauth << " in " << *cur->dir << endl;
+void MDCache::open_remote_dir(CInode *diri,
+ Context *fin)
+{
+ dout(10) << "open_remote_dir on " << *diri << endl;
+
+ assert(diri->is_dir());
+ assert(!diri->dir_is_auth());
+ assert(!diri->is_auth());
+ assert(diri->dir == 0);
+
+ filepath want; // no dentries, i just want the dir open
+ mds->messenger->send_message(new MDiscover(mds->get_nodeid(),
+ diri->ino(),
+ want,
+ true), // need the dir open
+ MSG_ADDR_MDS(diri->authority()), MDS_PORT_CACHE,
+ MDS_PORT_CACHE);
+
+ diri->add_waiter(CINODE_WAIT_DIR, fin);
+}
+
+
+
+class C_MDC_OpenRemoteInoLookup : public Context {
+ MDCache *mdc;
+ inodeno_t ino;
+ Message *req;
+ Context *onfinish;
+public:
+ vector<Anchor*> anchortrace;
+ C_MDC_OpenRemoteInoLookup(MDCache *mdc, inodeno_t ino, Message *req, Context *onfinish) {
+ this->mdc = mdc;
+ this->ino = ino;
+ this->req = req;
+ this->onfinish = onfinish;
+ }
+ void finish(int r) {
+ assert(r == 0);
+ if (r == 0)
+ mdc->open_remote_ino_2(ino, req, anchortrace, onfinish);
+ else {
+ onfinish->finish(r);
+ delete onfinish;
+ }
+ }
+};
+
+void MDCache::open_remote_ino(inodeno_t ino,
+ Message *req,
+ Context *onfinish)
+{
+ dout(7) << "open_remote_ino on " << ino << endl;
+
+ C_MDC_OpenRemoteInoLookup *c = new C_MDC_OpenRemoteInoLookup(this, ino, req, onfinish);
+ mds->anchormgr->lookup(ino, c->anchortrace, c);
+}
+
+void MDCache::open_remote_ino_2(inodeno_t ino,
+ Message *req,
+ vector<Anchor*>& anchortrace,
+ Context *onfinish)
+{
+ dout(7) << "open_remote_ino_2 on " << ino << ", trace depth is " << anchortrace.size() << endl;
+
+ // construct path
+ filepath path;
+ for (int i=0; i<anchortrace.size(); i++)
+ path.add_dentry(anchortrace[i]->ref_dn);
+
+ dout(7) << " path is " << path << endl;
+
+ vector<CDentry*> trace;
+ int r = path_traverse(path, trace, false,
+ req,
+ onfinish, // delay actually
+ MDS_TRAVERSE_DISCOVER);
+ if (r > 0) return;
+
+ onfinish->finish(r);
+ delete onfinish;
+}
+
+
+
+
+// path pins
+
bool MDCache::path_pin(vector<CDentry*>& trace,
Message *m,
Context *c)
int onfail,
Context *onfinish=0);
void open_remote_dir(CInode *diri, Context *fin);
- void open_remote_ino(inodeno_t ino, Context *fin);
+ void open_remote_ino(inodeno_t ino, Message *req, Context *fin);
+ void open_remote_ino_2(inodeno_t ino, Message *req,
+ vector<Anchor*>& anchortrace,
+ Context *onfinish);
bool path_pin(vector<CDentry*>& trace, Message *m, Context *c);
void path_unpin(vector<CDentry*>& trace, Message *m);
// HACK FOR NOW
static bool did_heartbeat_hack = false;
- if (!did_heartbeat_hack) osdmonitor->initiate_heartbeat();
+ if (!shutting_down && !shut_down &&
+ //false &&
+ !did_heartbeat_hack) {
+ osdmonitor->initiate_heartbeat();
+ did_heartbeat_hack = true;
+ }
// finish any triggered contexts
assert(whoami == 0); // mds0 mounts/unmounts
+ // mkfs? (sorta hack!)
+ if (m->get_mkfs()) {
+ dout(3) << "MKFS flag is set" << endl;
+ if (mdcache->get_root()) {
+ dout(3) << " TOO BAD, root inode is already open" << endl;
+ } else {
+ dout(3) << " root inode isn't open yet, inventing a fresh filesystem" << endl;
+
+ mdcache->open_root(0);
+
+ // force empty root dir
+ CDir *dir = mdcache->get_root()->dir;
+ dir->mark_complete();
+ dir->mark_dirty();
+ }
+ }
+
+
// ack
messenger->send_message(new MClientMountAck(m, osdcluster),
m->get_source(), m->get_source_port());
class MClientMount : public Message {
long pcid;
+ bool mkfs;
public:
- MClientMount() : Message(MSG_CLIENT_MOUNT) { }
+ MClientMount() : Message(MSG_CLIENT_MOUNT) {
+ mkfs = false;
+ }
+
+ void set_mkfs() { mkfs = true; }
+ bool get_mkfs() { return mkfs; }
void set_pcid(long pcid) { this->pcid = pcid; }
long get_pcid() { return pcid; }
virtual void decode_payload(crope& s, int& off) {
s.copy(off, sizeof(pcid), (char*)&pcid);
off += sizeof(pcid);
+ s.copy(off, sizeof(mkfs), (char*)&mkfs);
+ off += sizeof(mkfs);
}
virtual void encode_payload(crope& s) {
s.append((char*)&pcid, sizeof(pcid));
+ s.append((char*)&mkfs, sizeof(mkfs));
}
};
map<int, FakeMessenger*>::iterator it = directory.begin();
while (it != directory.end()) {
- //dout(18) << "messenger " << it->second << " has " << it->second->num_incoming() << " queued" << endl;
+ dout(18) << "messenger " << it->second << " at " << MSG_ADDR_NICE(it->first) << " has " << it->second->num_incoming() << " queued" << endl;
Message *m = it->second->get_message();
if (m) {