From b76d0dc0f2a276594b23afb670301278426c0670 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 12 Jan 2015 13:59:39 -0800 Subject: [PATCH] os/FileStore: verify kernel is new enough before using extsize ioctl Old kernels have an XFS bug that exposes uninitialized data when the extsize hint is set and only partially written. This is fixed by Linux commit aff3a9edb7080f69f07fe76a8bd089b3dfa4cb5d, documented in XFS bug http://oss.sgi.com/bugzilla/show_bug.cgi?id=874, and tested by XFS test xfs/229 to prevent regressions. Notably the original bug affects kernel 3.2, which is widely deployed with ubuntu precise 12.04. Backport: giant, firefly Signed-off-by: Sage Weil --- src/os/XfsFileStoreBackend.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/os/XfsFileStoreBackend.cc b/src/os/XfsFileStoreBackend.cc index bff9402dacb99..abff01844ea9d 100644 --- a/src/os/XfsFileStoreBackend.cc +++ b/src/os/XfsFileStoreBackend.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -109,15 +110,36 @@ int XfsFileStoreBackend::detect_features() ret = 0; dout(0) << "detect_feature: failed to set test file extsize, assuming extsize is NOT supported" << dendl; goto out_close; + } + + // make sure we have 3.5 or newer, which includes this fix + // aff3a9edb7080f69f07fe76a8bd089b3dfa4cb5d + // for this set_extsize bug + // http://oss.sgi.com/bugzilla/show_bug.cgi?id=874 + struct utsname u; + int r = uname(&u); + assert(r == 0); + int major = 0, minor = 0, patch = 0; + r = sscanf(u.release, "%d.%d.%d", &major, &minor, &patch); + if (r != 3) { + ret = 0; + dout(0) << __func__ << ": failed to parse kernel version " + << u.release << " to verify extsize not buggy, disabling extsize" + << dendl; + m_has_extsize = false; + } else if (major < 3 || (major == 3 && minor < 5)) { + dout(0) << __func__ << ": disabling extsize, kernel " << u.release + << " is older than 3.5 and has buggy extsize ioctl" << dendl; + m_has_extsize = false; } else { - dout(0) << "detect_feature: extsize is supported" << dendl; + dout(0) << "detect_feature: extsize is supported and kernel " + << u.release << " >= 3.5" << dendl; m_has_extsize = true; } } else { dout(0) << "detect_feature: extsize is disabled by conf" << dendl; } - out_close: TEMP_FAILURE_RETRY(::close(fd)); out: -- 2.39.5