From 74cf3e7c42ff2b45ed9cee81eb8f243653049c06 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 23 Dec 2008 13:36:46 -0800 Subject: [PATCH] mds: early_reply on open, mknod, symlink, mkdir when possible Use client-provided ino, if defined. --- src/include/ceph_fs.h | 3 +++ src/mds/Server.cc | 29 ++++++++++++++++++++--------- src/mds/Server.h | 2 +- src/mds/SessionMap.h | 23 ++++++++++++++++++----- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 771ee86310a06..d733ec044d781 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -782,6 +782,9 @@ struct ceph_mds_request_head { __le32 rdev; __le64 ino; } __attribute__ ((packed)) mknod; + struct { + __le64 ino; + } __attribute__ ((packed)) symlink; struct { __le32 mode; __le64 ino; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 63dd8eb3bba54..ceaae79d63bed 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1318,14 +1318,14 @@ CDentry* Server::prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dn * * create a new inode. set c/m/atime. hit dir pop. */ -CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir) +CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino) { CInode *in = new CInode(mdcache); // assign ino if (mdr->session->prealloc_inos.size()) { mdr->used_prealloc_ino = - in->inode.ino = mdr->session->take_ino(); // prealloc -> used + in->inode.ino = mdr->session->take_ino(useino); // prealloc -> used mds->sessionmap.projected++; dout(10) << "prepare_new_inode used_prealloc " << mdr->used_prealloc_ino << dendl; } else { @@ -1333,7 +1333,16 @@ CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir) in->inode.ino = mds->inotable->project_alloc_id(); dout(10) << "prepare_new_inode alloc " << mdr->alloc_ino << dendl; } - + + if (useino && useino != in->inode.ino) { + dout(0) << "WARNING: client specified " << useino << " and i allocated " << in->inode.ino << dendl; + stringstream ss; + ss << mdr->client_request->get_orig_source() << " specified ino " << useino << " but mds" << mds->whoami + << " allocated " << in->inode.ino; + mds->logclient.log(LOG_ERROR, ss); + assert(0); // just for now. + } + int want = g_conf.mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos(); if (want > 0) { mds->inotable->project_alloc_ids(mdr->prealloc_inos, want); @@ -2265,7 +2274,7 @@ void Server::handle_client_mknod(MDRequest *mdr) snapid_t follows = dn->dir->inode->find_snaprealm()->get_newest_seq(); mdr->now = g_clock.real_now(); - CInode *newi = prepare_new_inode(mdr, dn->dir); + CInode *newi = prepare_new_inode(mdr, dn->dir, inodeno_t(req->head.args.mknod.ino)); assert(newi); newi->projected_parent = dn; @@ -2290,7 +2299,7 @@ void Server::handle_client_mknod(MDRequest *mdr) mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); le->metablob.add_primary_dentry(dn, true, newi); - //early_reply(mdr, newi, 0); + early_reply(mdr, newi, 0); // log + wait mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows)); @@ -2311,7 +2320,7 @@ void Server::handle_client_mkdir(MDRequest *mdr) snapid_t follows = dn->dir->inode->find_snaprealm()->get_newest_seq(); mdr->now = g_clock.real_now(); - CInode *newi = prepare_new_inode(mdr, dn->dir); + CInode *newi = prepare_new_inode(mdr, dn->dir, inodeno_t(req->head.args.mkdir.ino)); assert(newi); // it's a directory. @@ -2341,7 +2350,7 @@ void Server::handle_client_mkdir(MDRequest *mdr) le->metablob.add_primary_dentry(dn, true, newi, &newi->inode); le->metablob.add_dir(newdir, true, true, true); // dirty AND complete AND new - //early_reply(mdr, newi, 0); + early_reply(mdr, newi, 0); // log + wait mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows)); @@ -2360,7 +2369,7 @@ void Server::handle_client_symlink(MDRequest *mdr) mdr->now = g_clock.real_now(); snapid_t follows = dn->dir->inode->find_snaprealm()->get_newest_seq(); - CInode *newi = prepare_new_inode(mdr, dn->dir); + CInode *newi = prepare_new_inode(mdr, dn->dir, inodeno_t(req->head.args.symlink.ino)); assert(newi); // it's a symlink @@ -2384,6 +2393,8 @@ void Server::handle_client_symlink(MDRequest *mdr) mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->dir, PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); le->metablob.add_primary_dentry(dn, true, newi); + early_reply(mdr, newi, 0); + // log + wait mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows)); } @@ -5007,7 +5018,7 @@ void Server::handle_client_openc(MDRequest *mdr) mdr->now = g_clock.real_now(); snapid_t follows = dn->dir->inode->find_snaprealm()->get_newest_seq(); - CInode *in = prepare_new_inode(mdr, dn->dir); + CInode *in = prepare_new_inode(mdr, dn->dir, inodeno_t(req->head.args.open.ino)); assert(in); // it's a file. diff --git a/src/mds/Server.h b/src/mds/Server.h index 041a2d81f5f29..4f5619dbd930d 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -95,7 +95,7 @@ public: CDir *validate_dentry_dir(MDRequest *mdr, CInode *diri, const string& dname); CDir *traverse_to_auth_dir(MDRequest *mdr, vector &trace, filepath refpath); CDentry *prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dname, bool okexist=false); - CInode* prepare_new_inode(MDRequest *mdr, CDir *dir); + CInode* prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino); void journal_allocated_inos(MDRequest *mdr, EMetaBlob *blob); void apply_allocated_inos(MDRequest *mdr); diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index a3a9a17d90f57..e5e230a3dc165 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -55,12 +55,25 @@ public: deque prealloc_inos; // preallocated, ready to use. deque used_inos; // journaling use - inodeno_t take_ino() { + inodeno_t take_ino(inodeno_t ino = 0) { assert(!prealloc_inos.empty()); - inodeno_t i = prealloc_inos.front(); - prealloc_inos.pop_front(); - used_inos.push_back(i); - return i; + + if (ino) { + deque::iterator p; + for (p = prealloc_inos.begin(); p != prealloc_inos.end(); p++) + if (*p == ino) + break; + if (p != prealloc_inos.end()) + prealloc_inos.erase(p); + else + ino = 0; + } + if (!ino) { + ino = prealloc_inos.front(); + prealloc_inos.pop_front(); + } + used_inos.push_back(ino); + return ino; } int get_num_projected_prealloc_inos() { return prealloc_inos.size() + projected_inos; -- 2.39.5