osdc/Objecter: skip sparse-read result decode if bufferlist is empty

If the OSD does not execute sub-ops due to errors encountered prior to
the sub-op, the sub-op result remains zeroed with empty out data.
Attempting to decode the empty bufferlist results in large exception
handling CPU overhead.

Fixes: http://tracker.ceph.com/issues/21844
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2017-10-19 22:24:31 -04:00
parent 34951266fe
commit dc9b309d03

View File

@ -335,13 +335,20 @@ struct ObjectOperation {
void finish(int r) override {
bufferlist::iterator iter = bl.begin();
if (r >= 0) {
try {
::decode(*extents, iter);
::decode(*data_bl, iter);
} catch (buffer::error& e) {
if (prval)
*prval = -EIO;
}
// NOTE: it's possible the sub-op has not been executed but the result
// code remains zeroed. Avoid the costly exception handling on a
// potential IO path.
if (bl.length() > 0) {
try {
::decode(*extents, iter);
::decode(*data_bl, iter);
} catch (buffer::error& e) {
if (prval)
*prval = -EIO;
}
} else if (prval) {
*prval = -EIO;
}
}
}
};