]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: support for exporting multiple subdirectories in faked mode 24283/head
authorhuanwen ren <ren.huanwen@zte.com.cn>
Wed, 26 Sep 2018 11:52:14 +0000 (19:52 +0800)
committerhuanwen ren <ren.huanwen@zte.com.cn>
Wed, 10 Oct 2018 09:51:40 +0000 (17:51 +0800)
In the faked mode, if you export multiple subdirectories(such as nfs-ganesha
you can export "/test1" and "/test2",etc), you will see that the inodes of the
exported subdirectories are the same.
This feature is modified to provide the export subdirectory by reserving
1024(1024~2048)fake ids.

Signed-off-by: huanwen ren <ren.huanwen@zte.com.cn>
src/client/Client.cc
src/client/Client.h

index 82577eff64fe56f92b71e00d0f6b8435abe81806..dbef9169698cf4d51657d955fcd7afb8d2a8e7bf 100644 (file)
@@ -178,14 +178,17 @@ void Client::_reset_faked_inos()
   free_faked_inos.clear();
   free_faked_inos.insert(start, (uint32_t)-1 - start + 1);
   last_used_faked_ino = 0;
+  last_used_faked_root = 0;
   _use_faked_inos = sizeof(ino_t) < 8 || cct->_conf->client_use_faked_inos;
 }
 
 void Client::_assign_faked_ino(Inode *in)
 {
+  if (0 == last_used_faked_ino)
+    last_used_faked_ino = last_used_faked_ino + 2048; // start(1024)~2048 reserved for _assign_faked_root
   interval_set<ino_t>::const_iterator it = free_faked_inos.lower_bound(last_used_faked_ino + 1);
   if (it == free_faked_inos.end() && last_used_faked_ino > 0) {
-    last_used_faked_ino = 0;
+    last_used_faked_ino = 2048;
     it = free_faked_inos.lower_bound(last_used_faked_ino + 1);
   }
   ceph_assert(it != free_faked_inos.end());
@@ -201,6 +204,32 @@ void Client::_assign_faked_ino(Inode *in)
   faked_ino_map[in->faked_ino] = in->vino();
 }
 
+/*
+ * In the faked mode, if you export multiple subdirectories,
+ * you will see that the inode numbers of the exported subdirectories
+ * are the same. so we distinguish the mount point by reserving 
+ * the "fake ids" between "1024~2048" and combining the last 
+ * 10bits(0x3ff) of the "root inodes".
+*/
+void Client::_assign_faked_root(Inode *in)
+{
+  interval_set<ino_t>::const_iterator it = free_faked_inos.lower_bound(last_used_faked_root + 1);
+  if (it == free_faked_inos.end() && last_used_faked_root > 0) {
+    last_used_faked_root = 0;
+    it = free_faked_inos.lower_bound(last_used_faked_root + 1);
+  }
+  assert(it != free_faked_inos.end());
+  vinodeno_t inode_info = in->vino();
+  uint64_t inode_num = (uint64_t)inode_info.ino;
+  ldout(cct, 10) << "inode_num " << inode_num << "inode_num & 0x3ff=" << (inode_num & 0x3ff)<< dendl;
+  last_used_faked_root = it.get_start()  + (inode_num & 0x3ff); // 0x3ff mask and get_start will not exceed 2048
+  assert(it.get_start() + it.get_len() > last_used_faked_root);
+
+  in->faked_ino = last_used_faked_root;
+  free_faked_inos.erase(in->faked_ino);
+  faked_ino_map[in->faked_ino] = in->vino();
+}
+
 void Client::_release_faked_ino(Inode *in)
 {
   free_faked_inos.insert(in->faked_ino);
@@ -787,6 +816,8 @@ Inode * Client::add_update_inode(InodeStat *st, utime_t from,
 
     if (!root) {
       root = in;
+      if (use_faked_inos())
+        _assign_faked_root(root);
       root_ancestor = in;
       cwd = root;
     } else if (!mounted) {
index 8aacf6d07eda4ff217cf1f68c103924aca2c9465..b0b50c3f5d049ca2d1efdd7db99af534f31f6011 100644 (file)
@@ -815,6 +815,7 @@ protected:
 
   // fake inode number for 32-bits ino_t
   void _assign_faked_ino(Inode *in);
+  void _assign_faked_root(Inode *in);
   void _release_faked_ino(Inode *in);
   void _reset_faked_inos();
   vinodeno_t _map_faked_ino(ino_t ino);
@@ -1241,6 +1242,7 @@ private:
   ceph::unordered_map<ino_t, vinodeno_t> faked_ino_map;
   interval_set<ino_t> free_faked_inos;
   ino_t last_used_faked_ino;
+  ino_t last_used_faked_root;
 
   // When an MDS has sent us a REJECT, remember that and don't
   // contact it again.  Remember which inst rejected us, so that