From 6bf2f4613f98156a876801124dbc1fbce0ae6d27 Mon Sep 17 00:00:00 2001 From: sageweil Date: Thu, 11 Oct 2007 03:22:52 +0000 Subject: [PATCH] fixed up scatterlocks; minor discover bugfix git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1920 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/sage/mds/Makefile | 10 ++--- branches/sage/mds/mds/CInode.cc | 16 ++++++- branches/sage/mds/mds/Locker.cc | 68 +++++++++++++++++++++--------- branches/sage/mds/mds/Locker.h | 5 ++- branches/sage/mds/mds/MDCache.cc | 38 ++++++++--------- branches/sage/mds/mds/Migrator.cc | 27 +++++++++--- branches/sage/mds/mds/Migrator.h | 8 ++-- branches/sage/mds/mds/Server.cc | 5 ++- branches/sage/mds/mds/journal.cc | 19 ++++++++- branches/sage/mds/messages/MLock.h | 2 + 10 files changed, 140 insertions(+), 58 deletions(-) diff --git a/branches/sage/mds/Makefile b/branches/sage/mds/Makefile index 6295940ebc64e..f1dc7b3d4d60a 100644 --- a/branches/sage/mds/Makefile +++ b/branches/sage/mds/Makefile @@ -145,22 +145,22 @@ mkmonmap: mkmonmap.cc common.o extractosdmaps: extractosdmaps.cc common.o osd.o mon.o ebofs.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ -cmon: cmon.cc mon.o msg/SimpleMessenger.o common.o +cmon: cmon.o mon.o msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ cmonctl: cmonctl.cc msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ -cosd: cosd.cc osd.o ebofs.o msg/SimpleMessenger.o common.o +cosd: cosd.o osd.o ebofs.o msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ -cmds: cmds.cc mds.o osdc.o msg/SimpleMessenger.o common.o +cmds: cmds.o mds.o osdc.o msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ -csyn: csyn.cc client.o osdc.o msg/SimpleMessenger.o common.o +csyn: csyn.o client.o osdc.o msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} $^ -o $@ -cfuse: cfuse.cc client.o osdc.o client/fuse.o client/fuse_ll.o msg/SimpleMessenger.o common.o +cfuse: cfuse.o client.o osdc.o client/fuse.o client/fuse_ll.o msg/SimpleMessenger.o common.o ${CC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@ diff --git a/branches/sage/mds/mds/CInode.cc b/branches/sage/mds/mds/CInode.cc index 4cb1159fafbe2..d315dd12cc77b 100644 --- a/branches/sage/mds/mds/CInode.cc +++ b/branches/sage/mds/mds/CInode.cc @@ -565,7 +565,12 @@ void CInode::decode_lock_state(int type, bufferlist& bl) _decode(tm, bl, off); if (inode.mtime < tm) { inode.mtime = tm; - dirlock.set_updated(); + if (is_auth()) { + dout(10) << "decode_lock_state auth got mtime " << tm << " > my " << inode.mtime + << ", setting dirlock updated flag on " << *this + << dendl; + dirlock.set_updated(); + } } if (0) { map dfsz; @@ -788,13 +793,22 @@ void CInode::encode_export(bufferlist& bl) void CInode::finish_export(utime_t now) { pop.zero(now); + + // just in case! + dirlock.clear_updated(); } void CInode::decode_import(bufferlist::iterator& p, set& new_client_caps, LogSegment *ls) { + utime_t old_mtime = inode.mtime; ::_decode_simple(inode, p); + if (old_mtime > inode.mtime) { + assert(dirlock.is_updated()); + inode.mtime = old_mtime; // preserve our mtime, if it is larger + } + ::_decode_simple(symlink, p); dirfragtree._decode(p); diff --git a/branches/sage/mds/mds/Locker.cc b/branches/sage/mds/mds/Locker.cc index 0e6156cb80cc3..3cde2bb5e45e8 100644 --- a/branches/sage/mds/mds/Locker.cc +++ b/branches/sage/mds/mds/Locker.cc @@ -1471,7 +1471,6 @@ void Locker::scatter_eval_gather(ScatterLock *lock) auth, MDS_PORT_LOCKER); } lock->set_state(LOCK_LOCK); - //lock->get_parent()->put(CInode::PIN_SCATTERED); } } else { @@ -1499,7 +1498,6 @@ void Locker::scatter_eval_gather(ScatterLock *lock) dout(7) << "scatter_eval finished lock gather/un-wrlock on " << *lock << " on " << *lock->get_parent() << dendl; lock->set_state(LOCK_LOCK); - //lock->get_parent()->put(CInode::PIN_SCATTERED); lock->finish_waiters(ScatterLock::WAIT_XLOCK|ScatterLock::WAIT_STABLE); lock->get_parent()->auth_unpin(); } @@ -1535,7 +1533,6 @@ void Locker::scatter_eval_gather(ScatterLock *lock) send_lock_message(lock, LOCK_AC_SCATTER, data); } lock->set_state(LOCK_SCATTER); - //lock->get_parent()->get(CInode::PIN_SCATTERED); lock->finish_waiters(ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE); lock->get_parent()->auth_unpin(); } @@ -1566,10 +1563,11 @@ void Locker::scatter_eval_gather(ScatterLock *lock) void Locker::scatter_writebehind(ScatterLock *lock) { CInode *in = (CInode*)lock->get_parent(); - dout(10) << "scatter_writebehind on " << *lock << " on " << *in << dendl; + dout(10) << "scatter_writebehind " << in->inode.mtime << " on " << *lock << " on " << *in << dendl; // journal write-behind. inode_t *pi = in->project_inode(); + pi->mtime = in->inode.mtime; // make sure an intermediate version isn't goofing us up pi->version = in->pre_dirty(); EUpdate *le = new EUpdate(mds->mdlog, "scatter writebehind"); @@ -1617,6 +1615,27 @@ void Locker::scatter_eval(ScatterLock *lock) } +/* + * this is called by LogSegment::try_to_trim() when trying to + * flush dirty scattered data (e.g. inode->dirlock mtime) back + * to the auth node. + */ +void Locker::scatter_try_unscatter(ScatterLock *lock, Context *c) +{ + dout(10) << "scatter_try_unscatter " << *lock << " on " << *lock->get_parent() << dendl; + assert(!lock->get_parent()->is_auth()); + assert(!lock->get_parent()->is_ambiguous_auth()); + + // request unscatter? + if (lock->get_state() == LOCK_SCATTER) + mds->send_message_mds(new MLock(lock, LOCK_AC_REQUNSCATTER, mds->get_nodeid()), + lock->get_parent()->authority().first, MDS_PORT_LOCKER); + + // wait... + lock->add_waiter(SimpleLock::WAIT_STABLE, c); +} + + void Locker::scatter_sync(ScatterLock *lock) { dout(10) << "scatter_sync " << *lock @@ -1646,7 +1665,6 @@ void Locker::scatter_sync(ScatterLock *lock) lock->init_gather(); } else { if (!lock->is_wrlocked()) { - //lock->get_parent()->put(CInode::PIN_SCATTERED); break; // do it now, we're fine } } @@ -1720,7 +1738,6 @@ void Locker::scatter_scatter(ScatterLock *lock) send_lock_message(lock, LOCK_AC_SCATTER, data); } lock->set_state(LOCK_SCATTER); - //lock->get_parent()->get(CInode::PIN_SCATTERED); lock->finish_waiters(ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE); } @@ -1729,6 +1746,7 @@ void Locker::scatter_lock(ScatterLock *lock) dout(10) << "scatter_lock " << *lock << " on " << *lock->get_parent() << dendl; assert(lock->get_parent()->is_auth()); + assert(lock->get_parent()->can_auth_pin()); assert(lock->is_stable()); switch (lock->get_state()) { @@ -1751,7 +1769,6 @@ void Locker::scatter_lock(ScatterLock *lock) case LOCK_SCATTER: if (!lock->is_wrlocked() && !lock->get_parent()->is_replicated()) { - //lock->get_parent()->put(CInode::PIN_SCATTERED); break; // do it. } @@ -1800,7 +1817,6 @@ void Locker::scatter_tempsync(ScatterLock *lock) case LOCK_SCATTER: if (!lock->is_wrlocked() && !lock->get_parent()->is_replicated()) { - //lock->get_parent()->put(CInode::PIN_SCATTERED); break; // do it. } @@ -1824,8 +1840,6 @@ void Locker::scatter_tempsync(ScatterLock *lock) - - void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m) { int from = m->get_asker(); @@ -1853,7 +1867,7 @@ void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m) case LOCK_AC_LOCK: assert(lock->get_state() == LOCK_SCATTER || lock->get_state() == LOCK_SYNC); - + // wait for wrlocks to close? if (lock->is_wrlocked()) { assert(lock->get_state() == LOCK_SCATTER); @@ -1866,9 +1880,9 @@ void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m) << " on " << *lock->get_parent() << dendl; lock->set_state(LOCK_GLOCKS); } else { - //if (lock->get_state() == LOCK_SCATTER) - //lock->get_parent()->put(CInode::PIN_SCATTERED); - + dout(7) << "handle_scatter_lock has no rd|wrlocks, sending lockack for " << *lock + << " on " << *lock->get_parent() << dendl; + // encode and reply bufferlist data; lock->encode_locked_state(data); @@ -1881,8 +1895,8 @@ void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m) case LOCK_AC_SCATTER: assert(lock->get_state() == LOCK_LOCK); lock->decode_locked_state(m->get_data()); + lock->clear_updated(); lock->set_state(LOCK_SCATTER); - //lock->get_parent()->get(CInode::PIN_SCATTERED); lock->finish_waiters(ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE); break; @@ -1910,15 +1924,31 @@ void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m) case LOCK_AC_REQSCATTER: if (lock->is_stable()) { - dout(7) << "handle_scatter_lock got scatter request on " << *lock << " on " << *lock->get_parent() - << dendl; + /* NOTE: we can do this _even_ if !can_auth_pin (i.e. freezing) + * because the replica should be holding an auth_pin if they're + * doing this (and thus, we are freezing, not frozen, and indefinite + * starvation isn't an issue). + */ + dout(7) << "handle_scatter_lock got scatter request on " << *lock + << " on " << *lock->get_parent() << dendl; scatter_scatter(lock); } else { - dout(7) << "handle_scatter_lock ignoring scatter request on " << *lock << " on " << *lock->get_parent() - << dendl; + dout(7) << "handle_scatter_lock ignoring scatter request on " << *lock + << " on " << *lock->get_parent() << dendl; } break; + case LOCK_AC_REQUNSCATTER: + if (lock->is_stable() && + lock->get_parent()->can_auth_pin()) { + dout(7) << "handle_scatter_lock got unscatter request on " << *lock + << " on " << *lock->get_parent() << dendl; + scatter_lock(lock); + } else { + dout(7) << "handle_scatter_lock ignoring unscatter request on " << *lock + << " on " << *lock->get_parent() << dendl; + /* FIXME: if we can't auth_pin here, this request is effectively lost... */ + } } delete m; diff --git a/branches/sage/mds/mds/Locker.h b/branches/sage/mds/mds/Locker.h index 7a45d74ac37f1..7867606238b34 100644 --- a/branches/sage/mds/mds/Locker.h +++ b/branches/sage/mds/mds/Locker.h @@ -119,11 +119,14 @@ public: void scatter_eval_gather(ScatterLock *lock); void scatter_unscatter_autoscattered(); + void scatter_try_unscatter(ScatterLock *lock, Context *c); + + void scatter_lock(ScatterLock *lock); // called by LogSegment::try_to_expire protected: void handle_scatter_lock(ScatterLock *lock, MLock *m); + void _scatter_replica_lock(ScatterLock *lock, int auth); void scatter_sync(ScatterLock *lock); - void scatter_lock(ScatterLock *lock); void scatter_scatter(ScatterLock *lock); void scatter_tempsync(ScatterLock *lock); bool scatter_rdlock_start(ScatterLock *lock, MDRequest *mdr); diff --git a/branches/sage/mds/mds/MDCache.cc b/branches/sage/mds/mds/MDCache.cc index 38c95be1e18c2..be6f046f7667c 100644 --- a/branches/sage/mds/mds/MDCache.cc +++ b/branches/sage/mds/mds/MDCache.cc @@ -3612,8 +3612,8 @@ bool MDCache::shutdown_pass() show_subtrees(); migrator->show_importing(); migrator->show_exporting(); - //if (!migrator->is_importing() && !migrator->is_exporting()) - //show_cache(); + if (!migrator->is_importing() && !migrator->is_exporting()) + show_cache(); return false; } assert(subtrees.empty()); @@ -5018,10 +5018,8 @@ void MDCache::handle_discover(MDiscover *dis) if (!cur) { dout(7) << "handle_discover mds" << dis->get_asker() << " don't have base ino " << dis->get_base_ino() - << ", dropping" << dendl; - delete reply; - assert(0); // hmm: when does this happen? - return; + << dendl; + reply->set_flag_error_dir(); } if (dis->wants_base_dir()) { @@ -5038,12 +5036,11 @@ void MDCache::handle_discover(MDiscover *dis) } assert(reply); - assert(cur); // add content // do some fidgeting to include a dir if they asked for the base dir, or just root. for (unsigned i = 0; - i < dis->get_want().depth() || dis->get_want().depth() == 0; + cur && (i < dis->get_want().depth() || dis->get_want().depth() == 0); i++) { // -- figure out the dir @@ -5354,10 +5351,18 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) cur = add_replica_inode(m->get_inode(i), dn, finished); } - // dir_auth hint? - if (m->get_dir_auth_hint() != CDIR_AUTH_UNKNOWN && - m->get_dir_auth_hint() != mds->get_nodeid()) { - dout(7) << " dir_auth_hint is " << m->get_dir_auth_hint() << dendl; + // dir error? + // or dir_auth hint? + if (m->is_flag_error_dir() && !cur->is_dir()) { + // not a dir. + cur->take_waiting(CInode::WAIT_DIR, error); + } else if (m->is_flag_error_dir() || + (m->get_dir_auth_hint() != CDIR_AUTH_UNKNOWN && + m->get_dir_auth_hint() != mds->get_nodeid())) { + int who = m->get_dir_auth_hint(); + if (who == mds->get_nodeid()) who = -1; + if (who >= 0) + dout(7) << " dir_auth_hint is " << m->get_dir_auth_hint() << dendl; // try again? if (m->get_error_dentry().length()) { @@ -5374,8 +5379,7 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) << m->get_error_dentry() << dendl; } else { if (cur->is_waiter_for(CInode::WAIT_DIR)) - discover_path(cur, m->get_error_dentry(), 0, m->get_wanted_xlocked(), - m->get_dir_auth_hint()); + discover_path(cur, m->get_error_dentry(), 0, m->get_wanted_xlocked(), who); else dout(7) << " doing nothing, nobody is waiting for dir" << dendl; } @@ -5383,14 +5387,10 @@ void MDCache::handle_discover_reply(MDiscoverReply *m) // wanted just the dir frag_t fg = m->get_base_dir_frag(); if (cur->get_dirfrag(fg) == 0 && cur->is_waiter_for(CInode::WAIT_DIR)) - discover_dir_frag(cur, fg, 0, m->get_dir_auth_hint()); + discover_dir_frag(cur, fg, 0, who); else dout(7) << " doing nothing, nobody is waiting for dir" << dendl; } - } else if (m->is_flag_error_dir()) { - dout(7) << " flag_error_dir on " << *cur << dendl; - //assert(!cur->is_dir()); // this assert might be racey if dir auth != inode auth? - cur->take_waiting(CInode::WAIT_DIR, error); } // waiters diff --git a/branches/sage/mds/mds/Migrator.cc b/branches/sage/mds/mds/Migrator.cc index d44aa4d1c1cde..d9f64ef89a33a 100644 --- a/branches/sage/mds/mds/Migrator.cc +++ b/branches/sage/mds/mds/Migrator.cc @@ -583,7 +583,7 @@ void Migrator::export_dir(CDir *dir, int dest) dir->get(CDir::PIN_EXPORTING); // send ExportDirDiscover (ask target) - mds->send_message_mds(new MExportDirDiscover(dir), export_peer[dir], MDS_PORT_MIGRATOR); + mds->send_message_mds(new MExportDirDiscover(dir), dest, MDS_PORT_MIGRATOR); // start the freeze, but hold it up with an auth_pin. dir->auth_pin(); @@ -1604,7 +1604,8 @@ void Migrator::handle_export_dir(MExportDir *m) dir, // import root le, imported_client_map, - mds->mdlog->get_current_segment()); + mds->mdlog->get_current_segment(), + import_updated_scatterlocks[dir]); } dout(10) << " " << m->get_bounds().size() << " imported bounds" << dendl; @@ -1782,6 +1783,7 @@ void Migrator::import_reverse_final(CDir *dir) import_peer.erase(dir->dirfrag()); import_bystanders.erase(dir); import_bound_ls.erase(dir); + import_updated_scatterlocks.erase(dir); // send pending import_maps? mds->mdcache->maybe_send_pending_resolves(); @@ -1823,6 +1825,12 @@ void Migrator::import_finish(CDir *dir) // log finish mds->mdlog->submit_entry(new EImportFinish(dir, true)); + // clear updated scatterlocks + for (list::iterator p = import_updated_scatterlocks[dir].begin(); + p != import_updated_scatterlocks[dir].end(); + ++p) + (*p)->clear_updated(); + // remove pins set bounds; cache->get_subtree_bounds(dir, bounds); @@ -1837,6 +1845,7 @@ void Migrator::import_finish(CDir *dir) import_peer.erase(dir->dirfrag()); import_bystanders.erase(dir); import_bound_ls.erase(dir); + import_updated_scatterlocks.erase(dir); // process delayed expires cache->process_delayed_expire(dir); @@ -1861,7 +1870,8 @@ void Migrator::import_finish(CDir *dir) void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int oldauth, map& imported_client_map, - LogSegment *ls) + LogSegment *ls, + list& updated_scatterlocks) { dout(15) << "decode_import_inode on " << *dn << dendl; @@ -1895,8 +1905,10 @@ void Migrator::decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int o dout(10) << " had " << *in << dendl; } - // clear if dirtyscattered, since we're journaling this - in->dirlock.clear_updated(); + // clear if dirtyscattered, since we're going to journal this + // but not until we _actually_ finish the import... + if (in->dirlock.is_updated()) + updated_scatterlocks.push_back(&in->dirlock); // adjust replica list //assert(!in->is_replica(oldauth)); // not true on failed export @@ -1925,7 +1937,8 @@ int Migrator::decode_import_dir(bufferlist::iterator& blp, CDir *import_root, EImportStart *le, map& imported_client_map, - LogSegment *ls) + LogSegment *ls, + list& updated_scatterlocks) { // set up dir dirfrag_t df; @@ -2019,7 +2032,7 @@ int Migrator::decode_import_dir(bufferlist::iterator& blp, } else if (icode == 'I') { // inode - decode_import_inode(dn, blp, oldauth, imported_client_map, ls); + decode_import_inode(dn, blp, oldauth, imported_client_map, ls, updated_scatterlocks); } // add dentry to journal entry diff --git a/branches/sage/mds/mds/Migrator.h b/branches/sage/mds/mds/Migrator.h index c4ee234546c3b..07a8731868a92 100644 --- a/branches/sage/mds/mds/Migrator.h +++ b/branches/sage/mds/mds/Migrator.h @@ -113,7 +113,7 @@ protected: map import_peer; map > import_bystanders; map > import_bound_ls; - + map > import_updated_scatterlocks; /* // -- hashing madness -- @@ -224,13 +224,15 @@ public: public: void decode_import_inode(CDentry *dn, bufferlist::iterator& blp, int oldauth, map& imported_client_map, - LogSegment *ls); + LogSegment *ls, + list& updated_scatterlocks); int decode_import_dir(bufferlist::iterator& blp, int oldauth, CDir *import_root, EImportStart *le, map& imported_client_map, - LogSegment *ls); + LogSegment *ls, + list& updated_scatterlocks); public: void import_reverse(CDir *dir); diff --git a/branches/sage/mds/mds/Server.cc b/branches/sage/mds/mds/Server.cc index 2d855898eaf95..6390a8ae2eed3 100644 --- a/branches/sage/mds/mds/Server.cc +++ b/branches/sage/mds/mds/Server.cc @@ -3192,11 +3192,14 @@ void Server::_rename_apply(MDRequest *mdr, CDentry *srcdn, CDentry *destdn, CDen assert(mdr->inode_import.length() > 0); bufferlist::iterator blp = mdr->inode_import.begin(); map imported_client_map; + list updated_scatterlocks; // we clear_updated explicitly below ::_decode_simple(imported_client_map, blp); mdcache->migrator->decode_import_inode(destdn, blp, srcdn->authority().first, imported_client_map, - mdr->ls); + mdr->ls, + updated_scatterlocks); + destdn->inode->dirlock.clear_updated(); } if (destdn->inode->is_auth()) destdn->inode->mark_dirty(mdr->pvmap[destdn], mdr->ls); diff --git a/branches/sage/mds/mds/journal.cc b/branches/sage/mds/mds/journal.cc index b78f516546aec..1f27cf713a078 100644 --- a/branches/sage/mds/mds/journal.cc +++ b/branches/sage/mds/mds/journal.cc @@ -42,6 +42,7 @@ #include "AnchorTable.h" #include "AnchorClient.h" #include "IdAllocator.h" +#include "Locker.h" #include "config.h" @@ -98,9 +99,23 @@ C_Gather *LogSegment::try_to_expire(MDS *mds) // dirty non-auth mtimes for (xlist::iterator p = dirty_inode_mtimes.begin(); !p.end(); ++p) { - dout(10) << "try_to_expire waiting for dirlock mtime flush on " << **p << dendl; + CInode *in = *p; + dout(10) << "try_to_expire waiting for dirlock mtime flush on " << *in << dendl; if (!gather) gather = new C_Gather; - (*p)->dirlock.add_waiter(SimpleLock::WAIT_STABLE, gather->new_sub()); + + if (in->is_ambiguous_auth()) { + dout(10) << " waiting for single auth on " << *in << dendl; + in->add_waiter(MDSCacheObject::WAIT_SINGLEAUTH, gather->new_sub()); + } else if (in->is_auth()) { + dout(10) << " i'm auth, unscattering dirlock on " << *in << dendl; + assert(in->is_replicated()); // hrm! + mds->locker->scatter_lock(&in->dirlock); + in->dirlock.add_waiter(SimpleLock::WAIT_STABLE, gather->new_sub()); + } else { + dout(10) << " i'm a replica, requesting dirlock unscatter of " << *in << dendl; + mds->locker->scatter_try_unscatter(&in->dirlock, gather->new_sub()); + } + //(*p)->dirlock.add_waiter(SimpleLock::WAIT_STABLE, gather->new_sub()); } // open files diff --git a/branches/sage/mds/messages/MLock.h b/branches/sage/mds/messages/MLock.h index 4fd027f4bf902..95c3e5f325212 100644 --- a/branches/sage/mds/messages/MLock.h +++ b/branches/sage/mds/messages/MLock.h @@ -32,6 +32,7 @@ #define LOCK_AC_LOCKACK 3 #define LOCK_AC_REQSCATTER 7 +#define LOCK_AC_REQUNSCATTER 8 #define LOCK_AC_FOR_REPLICA(a) ((a) < 0) #define LOCK_AC_FOR_AUTH(a) ((a) > 0) @@ -47,6 +48,7 @@ static const char *get_lock_action_name(int a) { case LOCK_AC_MIXEDACK: return "mixedack"; case LOCK_AC_LOCKACK: return "lockack"; case LOCK_AC_REQSCATTER: return "reqscatter"; + case LOCK_AC_REQUNSCATTER: return "requnscatter"; default: assert(0); return 0; } } -- 2.39.5