if (cwd) { // stat root if we don't have it.
if (r < 10)
op = MDS_OP_TOUCH;
- else if (false && r < 11)
+ else if (r < 11)
op = MDS_OP_CHMOD;
else if (r < 20 && !is_open(cwd) && !cwd->isdir)
op = MDS_OP_OPENRD;
mdcache_mid: .8,
mdcache_sticky_sync_normal: true,
mdcache_sticky_sync_softasync: false,
- mdcache_sticky_lock: false, // sticky probably a bad idea
+ mdcache_sticky_lock: false, // sticky is probably a bad idea!
mdbal_replicate_threshold: 500,
mdbal_unreplicate_threshold: 200,
dout(10) << "take_waiting dentry " << dentry << " mask " << mask << " took " << it->second << " tag " << it->first << " on dir " << *inode << endl;
waiting_on_dentry[dentry].erase(it++);
} else {
- dout(10) << "take_waiting dentry " << dentry << " SKIPPING mask " << mask << " took " << it->second << " tag " << it->first << " on dir " << *inode << endl;
+ dout(10) << "take_waiting dentry " << dentry << " mask " << mask << " SKIPPING " << it->second << " tag " << it->first << " on dir " << *inode << endl;
it++;
}
}
hash_map<string, multimap<int,Context*> >::iterator it =
it = waiting_on_dentry.begin();
while (it != waiting_on_dentry.end()) {
- take_waiting(mask, it->first, ls);
+ take_waiting(mask, (it++)->first, ls); // not post-inc
}
}
void CDir::auth_pin() {
inode->get(CINODE_PIN_DAUTHPIN + auth_pins);
auth_pins++;
- dout(7) << "auth_unpin on " << *inode << " count now " << auth_pins << endl;
+ dout(7) << "auth_pin on dir " << *inode << " count now " << auth_pins << " + " << nested_auth_pins << endl;
inode->adjust_nested_auth_pins( 1 );
}
auth_pins--;
inode->put(CINODE_PIN_DAUTHPIN + auth_pins);
assert(auth_pins >= 0);
- dout(7) << "auth_unpin on " << *inode << " count now " << auth_pins << endl;
+ dout(7) << "auth_unpin on dir " << *inode << " count now " << auth_pins << " + " << nested_auth_pins << endl;
// pending freeze?
if (auth_pins + nested_auth_pins == 0) {
int CDir::adjust_nested_auth_pins(int a) {
nested_auth_pins += a;
+ dout(11) << "adjust_nested_auth_pins on dir " << *inode << " count now " << auth_pins << " + " << nested_auth_pins << endl;
+
// pending freeze?
if (auth_pins + nested_auth_pins == 0) {
list<Context*> waiting_to_freeze;
// auth_pins
int CInode::adjust_nested_auth_pins(int a) {
nested_auth_pins += a;
+ dout(11) << "adjust_nested_auth_pins on " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
if (parent)
parent->dir->adjust_nested_auth_pins(a);
}
void CInode::auth_pin() {
get(CINODE_PIN_IAUTHPIN + auth_pins);
auth_pins++;
+ dout(7) << "auth_pin on inode " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
if (parent)
parent->dir->adjust_nested_auth_pins( 1 );
}
void CInode::auth_unpin() {
auth_pins--;
+ dout(7) << "auth_unpin on inode " << *this << " count now " << auth_pins << " + " << nested_auth_pins << endl;
put(CINODE_PIN_IAUTHPIN + auth_pins);
if (parent)
parent->dir->adjust_nested_auth_pins( -1 );
}
+void MDCache::shutdown_start()
+{
+ dout(1) << "unsync, unlock everything" << endl;
+
+ // walk cache
+ bool didsomething = false;
+ for (hash_map<inodeno_t, CInode*>::iterator it = inode_map.begin();
+ it != inode_map.end();
+ it++) {
+ CInode *in = it->second;
+ if (in->is_auth()) {
+ if (in->is_syncbyme()) sync_release(in);
+ if (in->is_lockbyme()) inode_lock_release(in);
+ }
+ }
+
+ // make sure sticky sync is off
+ g_conf.mdcache_sticky_sync_normal = false;
+
+}
+
bool MDCache::shutdown_pass()
{
static bool did_inode_updates = false;
if (mds->mdlog->get_num_events()) {
dout(7) << "waiting for log to flush" << endl;
- } else {
- dout(7) << "log is empty; flushing cache" << endl;
- trim(0);
+ return false;
+ }
- dout(7) << "walking remaining cache for loose ends" << endl;
- // walk cache
- bool didsomething = false;
- for (hash_map<inodeno_t, CInode*>::iterator it = inode_map.begin();
- it != inode_map.end();
- it++) {
- CInode *in = it->second;
- if (in->is_auth()) {
- // cached_by
- // unpin inodes on shut down nodes.
- // NOTE: this happens when they expire during an export; expires reference inodes, and can thus
- // be missed.
- if (mds->get_nodeid() == 0 &&
- in->is_cached_by_anyone()) {
- for (set<int>::iterator by = in->cached_by.begin();
- by != in->cached_by.end();
- ) {
- int who = *by;
- by++;
- if (mds->is_shut_down(who)) {
- in->cached_by_remove(who);
- didsomething = true;
- }
+ dout(7) << "log is empty; flushing cache" << endl;
+ trim(0);
+
+ // walk cache
+ dout(7) << "walking remaining cache for items cached_by shut down nodes" << endl;
+ bool didsomething = false;
+ for (hash_map<inodeno_t, CInode*>::iterator it = inode_map.begin();
+ it != inode_map.end();
+ it++) {
+ CInode *in = it->second;
+ if (in->is_auth()) {
+ // cached_by
+ // unpin inodes on shut down nodes.
+ // NOTE: this happens when they expire during an export; expires reference inodes, and can thus
+ // be missed.
+ if (mds->get_nodeid() == 0 &&
+ in->is_cached_by_anyone()) {
+ for (set<int>::iterator by = in->cached_by.begin();
+ by != in->cached_by.end();
+ ) {
+ int who = *by;
+ by++;
+ if (mds->is_shut_down(who)) {
+ in->cached_by_remove(who);
+ didsomething = true;
}
}
-
- // sync, lock release
- if (in->is_syncbyme())
- sync_release(in);
- if (in->is_lockbyme())
- inode_lock_release(in);
}
}
- if (didsomething)
- trim(0);
-
}
-
+ if (didsomething)
+ trim(0);
+
dout(7) << "cache size now " << lru->lru_get_size() << endl;
// send inode_expire's on all potentially cache pinned items
- if (0 &&
+ if (false &&
!did_inode_updates) {
did_inode_updates = true;
export_dir(im,0);
}
} else {
- // shut down root
+ // shut down root?
if (lru->lru_get_size() == 1) {
// all i have left is root.. wtf?
dout(7) << "wahoo, all i have left is root!" << endl;
}
size_t get_cache_size() { lru->lru_get_size(); }
bool trim(__int32_t max = -1); // trim cache
- bool shutdown_pass();
+ void shutdown_start();
+ bool shutdown_pass();
bool shutdown(); // clear cache (ie at shutodwn)
// have_inode?
// set flag
shutting_down = true;
+
+ mdcache->shutdown_start();
// flush log
mdlog->set_max_events(0);
dout(7) << "commit_dir " << *in << " can't auth_pin, waiting" << endl;
in->dir->add_waiter(CDIR_WAIT_AUTHPINNABLE,
new C_MDS_CommitDirDelay(mds, in->inode.ino, c) );
+ return false;
}
dout(7) << "inode " << inode.ino << " not in cache, must have exported" << endl;
return true;
}
- if (in->authority(mds->get_cluster()) != mds->get_nodeid())
+ if (!in->is_auth())
return true; // not my inode anymore!
if (in->get_version() != version)
return true; // i'm obsolete! (another log entry follows)
+
+ // frozen -> exporting -> obsolete (FOR NOW?)
+ if (in->is_frozen())
+ return true;
+
return false;
}
my %waiting; # context => what where what is "inode ..." or "dir ..."
my %hist; # context => history since waited
+my @waiting;
while (<>) {
if (/add_waiter/) {
# print "add_waiter $c $what\n";
$waiting{$c} = $what;
$hist{$c} .= $_;
+ push( @waiting, $c );
}
if (/take_waiting/) {
if (/SKIPPING/) {
my ($c) = /took (0x\w+)/;
delete $waiting{$c};
delete $hist{$c};
+ @waiting = grep {$_ ne $c} @waiting;
} else {
die "i don't understand: $_";
}
}
}
-for my $c (keys %waiting) {
+for my $c (@waiting) {
print "---- lost waiter $c $waiting{$c}
$hist{$c}
-
";
}
int play();
int main(int argc, char **argv) {
- cout << "hi there" << endl;
+ cerr << "hi there" << endl;
MDCluster *mdc = new MDCluster(NUMMDS, NUMOSD);