]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/FileStore: verify kernel is new enough before using extsize ioctl
authorSage Weil <sage@redhat.com>
Mon, 12 Jan 2015 21:59:39 +0000 (13:59 -0800)
committerSage Weil <sage@redhat.com>
Mon, 12 Jan 2015 21:59:39 +0000 (13:59 -0800)
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 <sage@redhat.com>
src/os/XfsFileStoreBackend.cc

index bff9402dacb999500b45803bce638044f0acb8aa..abff01844ea9d055082c3729f114d045f538aa31 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <sys/utsname.h>
 
 #include <xfs/xfs.h>
 
@@ -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: