From: Sage Weil Date: Wed, 10 Dec 2014 18:05:57 +0000 (-0800) Subject: osdc/Objecter: only issue one error per watch; do it through one path X-Git-Tag: v0.91~66 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=320c25607ca75d82d02393a96c63195779cdaf9b;p=ceph.git osdc/Objecter: only issue one error per watch; do it through one path Send all errors through C_DoWatchError for simplicity. Only deliver one error per watch. This simplifies callers logic and avoids a very rare case that they need to deal with. Signed-off-by: Sage Weil --- diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index 88b7d304dbef..2ae8774c9025 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -510,9 +510,11 @@ void Objecter::_linger_reconnect(LingerOp *info, int r) << " (last_error " << info->last_error << ")" << dendl; if (r < 0) { info->watch_lock.get_write(); - info->last_error = r; - if (info->watch_context) - finisher->queue(new C_DoWatchError(info, r)); + if (!info->last_error) { + info->last_error = r; + if (info->watch_context) + finisher->queue(new C_DoWatchError(info, r)); + } info->watch_lock.put_write(); } } @@ -569,7 +571,7 @@ void Objecter::_linger_ping(LingerOp *info, int r, utime_t sent, if (info->register_gen == register_gen) { if (r == 0) { info->watch_valid_thru = sent; - } else if (r < 0) { + } else if (r < 0 && !info->last_error) { info->last_error = r; if (info->watch_context) finisher->queue(new C_DoWatchError(info, r)); @@ -752,9 +754,14 @@ void Objecter::handle_watch_notify(MWatchNotify *m) } RWLock::WLocker wl(info->watch_lock); if (m->opcode == CEPH_WATCH_EVENT_DISCONNECT) { - info->last_error = -ENOTCONN; + if (!info->last_error) { + info->last_error = -ENOTCONN; + if (info->watch_context) + finisher->queue(new C_DoWatchError(info, -ENOTCONN)); + } + } else { + finisher->queue(new C_DoWatchNotify(this, info, m)); } - finisher->queue(new C_DoWatchNotify(this, info, m)); } void Objecter::_do_watch_notify(LingerOp *info, MWatchNotify *m) @@ -783,6 +790,8 @@ void Objecter::_do_watch_notify(LingerOp *info, MWatchNotify *m) assert(info->is_watch); assert(info->watch_context); + assert(m->opcode != CEPH_WATCH_EVENT_DISCONNECT); + rwlock.put_read(); switch (m->opcode) { @@ -790,10 +799,6 @@ void Objecter::_do_watch_notify(LingerOp *info, MWatchNotify *m) info->watch_context->handle_notify(m->notify_id, m->cookie, m->notifier_gid, m->bl); break; - - case CEPH_WATCH_EVENT_DISCONNECT: - info->watch_context->handle_error(m->cookie, -ENOTCONN); - break; } out: