From f9b7dff70a4c78ab4af139df55bea530bd5d1320 Mon Sep 17 00:00:00 2001 From: Sam Lang Date: Thu, 28 Mar 2013 11:02:49 -0500 Subject: [PATCH 1/2] client: log inode when waiting on max size Logging the specific inode that the get_caps() is waiting for helps during debugging of stuck waiters. Signed-off-by: Sam Lang --- src/client/Client.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 5fa0fdce576..447d44d618f 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -2230,7 +2230,7 @@ int Client::get_caps(Inode *in, int need, int want, int *phave, loff_t endoff) } if (endoff >= 0 && endoff > (loff_t)in->max_size) { - ldout(cct, 10) << "waiting on max_size, endoff " << endoff << " max_size " << in->max_size << dendl; + ldout(cct, 10) << "waiting on max_size, endoff " << endoff << " max_size " << in->max_size << " on " << *in << dendl; } else if (!in->cap_snaps.empty() && in->cap_snaps.rbegin()->second->writing) { ldout(cct, 10) << "waiting on cap_snap write to complete" << dendl; } else { From 0ce09fad559700de3975e7152adb948ecff23303 Mon Sep 17 00:00:00 2001 From: Sam Lang Date: Mon, 1 Apr 2013 09:06:59 -0500 Subject: [PATCH 2/2] client: Kick waiters for max size If the mds restarts without successfully logging a max size cap update, the client waits indefinitely in Client::get_caps on the waitfor_caps list. So when the client gets an mds map indicating a new active mds has replaced a down mds, we need to kick the caps update request. This patch mimics the behavior in the kernel by setting the wanted_max_size and requested_max_size to 0 and wakes up the waiters. Fixes #4582. Signed-off-by: Sam Lang --- src/client/Client.cc | 13 +++++++++++++ src/client/Client.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/client/Client.cc b/src/client/Client.cc index 447d44d618f..420c3ad00f2 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1890,6 +1890,8 @@ void Client::handle_mds_map(MMDSMap* m) kick_requests(p->second, false); kick_flushing_caps(p->second); signal_cond_list(p->second->waiting_for_open); + kick_maxsize_requests(p->second); + wake_inode_waiters(p->second); } connect_mds_targets(p->first); } @@ -3031,6 +3033,17 @@ void Client::kick_flushing_caps(MetaSession *session) } } +void Client::kick_maxsize_requests(MetaSession *session) +{ + xlist::iterator iter = session->caps.begin(); + while (!iter.end()){ + (*iter)->inode->requested_max_size = 0; + (*iter)->inode->wanted_max_size = 0; + signal_cond_list((*iter)->inode->waitfor_caps); + ++iter; + } +} + void SnapRealm::build_snap_context() { set snaps; diff --git a/src/client/Client.h b/src/client/Client.h index 03764aee240..29a5020c6a6 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -426,6 +426,7 @@ protected: void flush_caps(); void flush_caps(Inode *in, MetaSession *session); void kick_flushing_caps(MetaSession *session); + void kick_maxsize_requests(MetaSession *session); int get_caps(Inode *in, int need, int want, int *have, loff_t endoff); void maybe_update_snaprealm(SnapRealm *realm, snapid_t snap_created, snapid_t snap_highwater,