]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: early_reply on open, mknod, symlink, mkdir when possible
authorSage Weil <sage@newdream.net>
Tue, 23 Dec 2008 21:36:46 +0000 (13:36 -0800)
committerSage Weil <sage@newdream.net>
Tue, 23 Dec 2008 21:36:46 +0000 (13:36 -0800)
Use client-provided ino, if defined.

src/include/ceph_fs.h
src/mds/Server.cc
src/mds/Server.h
src/mds/SessionMap.h

index 771ee86310a06bda564ee3d1207e2bdd05e10fc6..d733ec044d781281c3862414e06eaf87c2130f13 100644 (file)
@@ -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;
index 63dd8eb3bba542ff3e1304fcf4644a6f9b518d78..ceaae79d63bed2190273d9fbeefc6791807d16be 100644 (file)
@@ -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.
index 041a2d81f5f2916a95ce8fbab686b6f5925b43a7..4f5619dbd930d2f4e54d2ad69cf4d4d7bc534f81 100644 (file)
@@ -95,7 +95,7 @@ public:
   CDir *validate_dentry_dir(MDRequest *mdr, CInode *diri, const string& dname);
   CDir *traverse_to_auth_dir(MDRequest *mdr, vector<CDentry*> &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);
 
index a3a9a17d90f57ee386b53c35710153a1e219d385..e5e230a3dc165aabbe0973806a8a15743d5f0eeb 100644 (file)
@@ -55,12 +55,25 @@ public:
   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;