From bc0d400c8bd367cfaf05d9ec839f12d97f64e4ed Mon Sep 17 00:00:00 2001 From: sageweil Date: Sat, 17 Feb 2007 19:03:06 +0000 Subject: [PATCH] openc hack, works for now git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1104 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/sage/cephmds2/mds/Server.cc | 97 +++++++++++++++++---- branches/sage/cephmds2/mds/Server.h | 6 +- branches/sage/cephmds2/mds/events/EString.h | 5 +- branches/sage/cephmds2/mds/journal.cc | 20 +++++ 4 files changed, 107 insertions(+), 21 deletions(-) diff --git a/branches/sage/cephmds2/mds/Server.cc b/branches/sage/cephmds2/mds/Server.cc index 5ea354d76e041..e9e41414ac2bf 100644 --- a/branches/sage/cephmds2/mds/Server.cc +++ b/branches/sage/cephmds2/mds/Server.cc @@ -1164,10 +1164,15 @@ CDir *Server::validate_new_dentry_dir(MClientRequest *req, CInode *diri, string& * create the inode and dentry, but do not link them. * pre_dirty the dentry+dir. * xlock the dentry. + * + * return val + * 0 - wait for something + * 1 - created + * 2 - already exists (only if okexist=true) */ -bool Server::prepare_mknod(MClientRequest *req, CInode *diri, - CInode **pin, CDentry **pdn, - bool okexist) +int Server::prepare_mknod(MClientRequest *req, CInode *diri, + CInode **pin, CDentry **pdn, + bool okexist) { dout(10) << "prepare_mknod " << req->get_filepath() << " in " << *diri << endl; @@ -1176,7 +1181,7 @@ bool Server::prepare_mknod(MClientRequest *req, CInode *diri, string name = req->get_filepath().last_bit(); CDir *dir = validate_new_dentry_dir(req, diri, name); - if (!dir) return false; + if (!dir) return 0; // make sure name doesn't already exist *pdn = dir->lookup(name); @@ -1184,7 +1189,7 @@ bool Server::prepare_mknod(MClientRequest *req, CInode *diri, if (!(*pdn)->can_read(req)) { dout(10) << "waiting on (existing!) dentry " << **pdn << endl; dir->add_waiter(CDIR_WAIT_DNREAD, name, new C_MDS_RetryRequest(mds, req, diri)); - return false; + return 0; } if (!(*pdn)->is_null()) { @@ -1192,11 +1197,11 @@ bool Server::prepare_mknod(MClientRequest *req, CInode *diri, if (okexist) { dout(10) << "dentry " << name << " exists in " << *dir << endl; *pin = (*pdn)->inode; - return true; + return 2; } else { dout(10) << "dentry " << name << " exists in " << *dir << endl; reply_request(req, -EEXIST); - return false; + return 0; } } } @@ -1205,7 +1210,7 @@ bool Server::prepare_mknod(MClientRequest *req, CInode *diri, if (!dir->is_complete()) { dout(7) << " incomplete dir contents for " << *dir << ", fetching" << endl; mds->mdstore->fetch_dir(dir, new C_MDS_RetryRequest(mds, req, diri)); - return false; + return 0; } // make sure dir is pinnable @@ -1231,7 +1236,7 @@ bool Server::prepare_mknod(MClientRequest *req, CInode *diri, // bump modify pop mds->balancer->hit_dir(dir, META_POP_DWR); - return true; + return 1; } @@ -2234,7 +2239,7 @@ void Server::handle_client_truncate(MClientRequest *req, CInode *cur) // open, openc, close void Server::handle_client_open(MClientRequest *req, - CInode *cur) + CInode *cur) { int flags = req->get_iarg(); int mode = req->get_iarg2(); @@ -2282,19 +2287,77 @@ void Server::handle_client_open(MClientRequest *req, } +class C_MDS_openc_finish : public Context { + MDS *mds; + MClientRequest *req; + CDentry *dn; + CInode *newi; + version_t pv; +public: + C_MDS_openc_finish(MDS *m, MClientRequest *r, CDentry *d, CInode *ni) : + mds(m), req(r), dn(d), newi(ni), + pv(d->get_projected_version()) {} + void finish(int r) { + assert(r == 0); + + // link the inode + dn->get_dir()->link_inode(dn, newi); + + // dirty inode, dn, dir + newi->mark_dirty(pv); + + // unlock + mds->locker->dentry_xlock_finish(dn); + + // hit pop + mds->balancer->hit_inode(newi, META_POP_IWR); + + // ok, do the open. + mds->server->handle_client_open(req, newi); + } +}; + -void Server::handle_client_openc(MClientRequest *req, CInode *ref) +void Server::handle_client_openc(MClientRequest *req, CInode *diri) { dout(7) << "open w/ O_CREAT on " << req->get_filepath() << endl; - assert(0); - CInode *in = 0;//mknod(req, ref, true); // FIXME FIXME - if (!in) return; + CInode *in = 0; + CDentry *dn = 0; + + // make dentry and inode, xlock dentry. + int r = prepare_mknod(req, diri, &in, &dn); + if (!r) + return; // wait on something + assert(in); + assert(dn); - in->inode.mode = 0644; // wtf FIXME - in->inode.mode |= INODE_MODE_FILE; + if (r == 1) { + // created. + // it's a file. + in->inode.mode = 0644; // FIXME req should have a umask + in->inode.mode |= INODE_MODE_FILE; + + // prepare finisher + C_MDS_openc_finish *fin = new C_MDS_openc_finish(mds, req, dn, in); + EUpdate *le = new EUpdate("openc"); + le->metablob.add_dir_context(diri->dir); + inode_t *pi = le->metablob.add_dentry(dn, true, in); + pi->version = dn->get_projected_version(); + + // log + wait + mdlog->submit_entry(le); + mdlog->wait_for_sync(fin); - handle_client_open(req, in); + /* + FIXME. this needs to be rewritten when the write capability stuff starts + getting journaled. + */ + } else { + // exists! + // FIXME: do i need to repin path based existant inode? hmm. + handle_client_open(req, in); + } } diff --git a/branches/sage/cephmds2/mds/Server.h b/branches/sage/cephmds2/mds/Server.h index 59382370ee0f9..d4509f1418e07 100644 --- a/branches/sage/cephmds2/mds/Server.h +++ b/branches/sage/cephmds2/mds/Server.h @@ -127,9 +127,9 @@ public: CInode *mknod(MClientRequest *req, CInode *ref, bool okexist=false); // used by mknod, symlink, mkdir, openc CDir *validate_new_dentry_dir(MClientRequest *req, CInode *diri, string& dname); - bool prepare_mknod(MClientRequest *req, CInode *diri, - CInode **pin, CDentry **pdn, - bool okexist=false); + int prepare_mknod(MClientRequest *req, CInode *diri, + CInode **pin, CDentry **pdn, + bool okexist=false); diff --git a/branches/sage/cephmds2/mds/events/EString.h b/branches/sage/cephmds2/mds/events/EString.h index 6bd10030549ba..0ef7577406454 100644 --- a/branches/sage/cephmds2/mds/events/EString.h +++ b/branches/sage/cephmds2/mds/events/EString.h @@ -39,7 +39,6 @@ class EString : public LogEvent { event = bl.c_str() + off; off += event.length() + 1; } - void encode_payload(bufferlist& bl) { bl.append(event.c_str(), event.length()+1); } @@ -48,6 +47,10 @@ class EString : public LogEvent { out << '"' << event << '"'; } + bool has_expired(MDS *mds); + void expire(MDS *mds, Context *c); + void replay(MDS *mds); + }; #endif diff --git a/branches/sage/cephmds2/mds/journal.cc b/branches/sage/cephmds2/mds/journal.cc index 49af089fec466..2182d33ffc878 100644 --- a/branches/sage/cephmds2/mds/journal.cc +++ b/branches/sage/cephmds2/mds/journal.cc @@ -11,6 +11,8 @@ * */ +#include "events/EString.h" + #include "events/EMetaBlob.h" #include "events/EAlloc.h" #include "events/EUpdate.h" @@ -35,6 +37,24 @@ #define derr(l) if (l<=g_conf.debug_mds || l <= g_conf.debug_mds_log) cout << g_clock.now() << " mds" << mds->get_nodeid() << ".journal " +// ----------------------- +// EString + +bool EString::has_expired(MDS *mds) { + dout(10) << "EString.has_expired " << event << endl; + return true; +} +void EString::expire(MDS *mds, Context *c) +{ + dout(10) << "EString.expire " << event << endl; +} +void EString::replay(MDS *mds) +{ + dout(10) << "EString.replay " << event << endl; +} + + + // ----------------------- // EMetaBlob -- 2.39.5