explicit MDCache(MDSRank *m, PurgeQueue &purge_queue_);
~MDCache();
+ void insert_taken_inos(inodeno_t ino) {
+ replay_taken_inos.insert(ino);
+ }
+ void clear_taken_inos(inodeno_t ino) {
+ replay_taken_inos.erase(ino);
+ }
+ bool test_and_clear_taken_inos(inodeno_t ino) {
+ return replay_taken_inos.erase(ino) != 0;
+ }
+
uint64_t cache_limit_memory(void) {
return cache_memory_limit;
}
StrayManager stray_manager;
private:
+ std::set<inodeno_t> replay_taken_inos; // the inos have been taken when replaying
+
// -- fragmenting --
struct ufragment {
ufragment() {}
// while session is opening.
bool allow_prealloc_inos = mdr->session->is_open();
+ inodeno_t _useino = useino;
+
// assign ino
- if (allow_prealloc_inos && (mdr->used_prealloc_ino = _inode->ino = mdr->session->take_ino(useino))) {
- mds->sessionmap.mark_projected(mdr->session);
- dout(10) << "prepare_new_inode used_prealloc " << mdr->used_prealloc_ino
- << " (" << mdr->session->info.prealloc_inos.size() << " left)"
- << dendl;
- } else {
- mdr->alloc_ino =
- _inode->ino = mds->inotable->project_alloc_id(useino);
- dout(10) << "prepare_new_inode alloc " << mdr->alloc_ino << dendl;
- }
+ do {
+ if (allow_prealloc_inos && (mdr->used_prealloc_ino = _inode->ino = mdr->session->take_ino(_useino))) {
+ if (mdcache->test_and_clear_taken_inos(_inode->ino)) {
+ _inode->ino = 0;
+ dout(10) << "prepare_new_inode used_prealloc " << mdr->used_prealloc_ino
+ << " (" << mdr->session->info.prealloc_inos.size() << " left)"
+ << " but has been taken, will try again!" << dendl;
+ } else {
+ mds->sessionmap.mark_projected(mdr->session);
+ dout(10) << "prepare_new_inode used_prealloc " << mdr->used_prealloc_ino
+ << " (" << mdr->session->info.prealloc_inos.size() << " left)"
+ << dendl;
+ }
+ } else {
+ mdr->alloc_ino =
+ _inode->ino = mds->inotable->project_alloc_id(_useino);
+ if (mdcache->test_and_clear_taken_inos(_inode->ino)) {
+ mds->inotable->apply_alloc_id(_inode->ino);
+ _inode->ino = 0;
+ dout(10) << "prepare_new_inode alloc " << mdr->alloc_ino
+ << " but has been taken, will try again!" << dendl;
+ } else {
+ dout(10) << "prepare_new_inode alloc " << mdr->alloc_ino << dendl;
+ }
+ }
+ _useino = 0;
+ } while (!_inode->ino);
if (useino && useino != _inode->ino) {
dout(0) << "WARNING: client specified " << useino << " and i allocated " << _inode->ino << dendl;
<< " but mds." << mds->get_nodeid() << " allocated " << _inode->ino;
//ceph_abort(); // just for now.
}
-
+
if (allow_prealloc_inos &&
mdr->session->get_num_projected_prealloc_inos() < g_conf()->mds_client_prealloc_inos / 2) {
int need = g_conf()->mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos();
if (mds->inotable->get_version() >= inotablev) {
dout(10) << "EMetaBlob.replay inotable tablev " << inotablev
<< " <= table " << mds->inotable->get_version() << dendl;
+ if (allocated_ino)
+ mds->mdcache->insert_taken_inos(allocated_ino);
} else {
dout(10) << "EMetaBlob.replay inotable v " << inotablev
<< " - 1 == table " << mds->inotable->get_version()
if (mds->sessionmap.get_version() >= sessionmapv) {
dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
<< " <= table " << mds->sessionmap.get_version() << dendl;
+ if (used_preallocated_ino)
+ mds->mdcache->insert_taken_inos(used_preallocated_ino);
} else {
dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
<< ", table " << mds->sessionmap.get_version()