From: huanwen ren Date: Wed, 26 Sep 2018 11:52:14 +0000 (+0800) Subject: client: support for exporting multiple subdirectories in faked mode X-Git-Tag: v14.1.0~1089^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e09659b563f7993607936944751001cc26b96785;p=ceph.git client: support for exporting multiple subdirectories in faked mode 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 --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 82577eff64f..dbef9169698 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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::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::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) { diff --git a/src/client/Client.h b/src/client/Client.h index 8aacf6d07ed..b0b50c3f5d0 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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 faked_ino_map; interval_set 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