*
* 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 {
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);
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;
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));
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.
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));
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
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));
}
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.
deque<inodeno_t> prealloc_inos; // preallocated, ready to use.
deque<inodeno_t> 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<inodeno_t>::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;