- libtool
- libfcgi
- libfcgi-dev
+- xfslibs-dev
- libfuse-dev
- linux-kernel-headers
- libcrypto++-dev
For example:
- $ apt-get install automake autoconf pkg-config gcc g++ make libboost-dev libedit-dev libssl-dev libtool libfcgi libfcgi-dev libfuse-dev linux-kernel-headers libcrypto++-dev libaio-dev libgoogle-perftools-dev libkeyutils-dev uuid-dev libblkid-dev libatomic-ops-dev libboost-program-options-dev libboost-thread-dev libexpat1-dev libleveldb-dev libsnappy-dev libcurl4-gnutls-dev python-argparse python-flask
+ $ apt-get install automake autoconf pkg-config gcc g++ make libboost-dev libedit-dev libssl-dev libtool libfcgi libfcgi-dev xfslibs-dev libfuse-dev linux-kernel-headers libcrypto++-dev libaio-dev libgoogle-perftools-dev libkeyutils-dev uuid-dev libblkid-dev libatomic-ops-dev libboost-program-options-dev libboost-thread-dev libexpat1-dev libleveldb-dev libsnappy-dev libcurl4-gnutls-dev python-argparse python-flask
rpm-based
---------
fcgi-devel
expat-devel
libcurl-devel
+ xfsprogs-devel
fuse-devel
gperftools-devel
libedit-devel
For example:
- $ yum install autoconf automake gcc gcc-c++ make libtool python-argparse python-flask libuuid-devel libblkid-devel keyutils-libs-devel cryptopp-devel nss-devel fcgi-devel expat-devel libcurl-devel fuse-devel gperftools-devel libedit-devel libatomic_ops-devel snappy-devel leveldb-devel libaio-devel boost-devel
+ $ yum install autoconf automake gcc gcc-c++ make libtool python-argparse python-flask libuuid-devel libblkid-devel keyutils-libs-devel cryptopp-devel nss-devel fcgi-devel expat-devel libcurl-devel xfsprogs-devel fuse-devel gperftools-devel libedit-devel libatomic_ops-devel snappy-devel leveldb-devel libaio-devel boost-devel
BuildRequires: libuuid-devel
BuildRequires: libblkid-devel >= 2.17
BuildRequires: leveldb-devel > 1.2
+BuildRequires: xfsprogs-devel
BuildRequires: yasm
%if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora}
BuildRequires: snappy-devel
AC_MSG_NOTICE([F_SETPIPE_SZ not found, zero-copy may be less efficent])
])
+# XFS_XFLAG_EXTSIZE in xfs/xfs.h on Linux
+AS_IF([test "x$linux" = "xyes"], [
+ AC_CHECK_HEADER([xfs/xfs.h], [], AC_MSG_ERROR([xfs/xfs.h not found]))
+ AC_MSG_CHECKING([for XFS_XFLAG_EXTSIZE in xfs/xfs.h])
+ AC_EGREP_CPP([yes_have_xfs_xflag_extsize], [
+ #include <xfs/xfs.h>
+ #ifdef XFS_XFLAG_EXTSIZE
+ yes_have_xfs_xflag_extsize
+ #endif
+ ], AC_MSG_RESULT([yes]), [
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([XFS_XFLAG_EXTSIZE not found])
+ ])
+])
+
AC_CHECK_FUNCS([posix_fallocate])
AC_CHECK_HEADERS([sys/prctl.h])
AC_CHECK_FUNCS([prctl])
python-nose,
uuid-dev,
uuid-runtime,
+ xfslibs-dev,
yasm
Standards-Version: 3.9.3
#include "FileStore.h"
#include "GenericFileStoreBackend.h"
#include "BtrfsFileStoreBackend.h"
+#include "XfsFileStoreBackend.h"
#include "ZFSFileStoreBackend.h"
#include "common/BackTrace.h"
#include "include/types.h"
if (basefs.f_type == BTRFS_SUPER_MAGIC) {
#if defined(__linux__)
backend = new BtrfsFileStoreBackend(this);
+#endif
+ } else if (basefs.f_type == XFS_SUPER_MAGIC) {
+#if defined(__linux__)
+ backend = new XfsFileStoreBackend(this);
#endif
} else if (basefs.f_type == ZFS_SUPER_MAGIC) {
#ifdef HAVE_LIBZFS
#endif
} else if (st.f_type == XFS_SUPER_MAGIC) {
#if defined(__linux__)
- dout(0) << "mount detected xfs" << dendl;
+ dout(0) << "mount detected xfs (libxfs)" << dendl;
+ backend = new XfsFileStoreBackend(this);
m_fs_type = FS_TYPE_XFS;
// wbthrottle is constructed with fs(WBThrottle::XFS)
if LINUX
libos_la_SOURCES += os/BtrfsFileStoreBackend.cc
+libos_la_SOURCES += os/XfsFileStoreBackend.cc
endif
if WITH_LIBZFS
os/ObjectStore.h \
os/SequencerPosition.h \
os/WBThrottle.h \
+ os/XfsFileStoreBackend.h \
os/ZFSFileStoreBackend.h
if WITH_LIBZFS
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2014 Inktank, Inc
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include "XfsFileStoreBackend.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <xfs/xfs.h>
+
+#include "common/errno.h"
+#include "include/assert.h"
+#include "include/compat.h"
+
+#define dout_subsys ceph_subsys_filestore
+#undef dout_prefix
+#define dout_prefix *_dout << "xfsfilestorebackend(" << get_basedir_path() << ") "
+
+XfsFileStoreBackend::XfsFileStoreBackend(FileStore *fs):
+ GenericFileStoreBackend(fs), m_has_extsize(false) { }
+
+/*
+ * Set extsize attr on a file to val. Should be a free-standing
+ * function, but dout_prefix expanding to a call to get_basedir_path()
+ * protected member function won't let it.
+ */
+int XfsFileStoreBackend::set_extsize(int fd, unsigned int val)
+{
+ struct fsxattr fsx;
+ struct stat sb;
+ int ret;
+
+ if (fstat(fd, &sb) < 0) {
+ ret = -errno;
+ dout(0) << "set_extsize: fstat: " << cpp_strerror(ret) << dendl;
+ goto out;
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ ret = -EINVAL;
+ dout(0) << "set_extsize: invalid target file type" << dendl;
+ goto out;
+ }
+
+ if (ioctl(fd, XFS_IOC_FSGETXATTR, &fsx) < 0) {
+ ret = -errno;
+ dout(0) << "set_extsize: FSGETXATTR: " << cpp_strerror(ret) << dendl;
+ goto out;
+ }
+
+ fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE;
+ fsx.fsx_extsize = val;
+
+ if (ioctl(fd, XFS_IOC_FSSETXATTR, &fsx) < 0) {
+ ret = -errno;
+ dout(0) << "set_extsize: FSSETXATTR: " << cpp_strerror(ret) << dendl;
+ goto out;
+ }
+ ret = 0;
+
+out:
+ return ret;
+}
+
+int XfsFileStoreBackend::detect_features()
+{
+ int ret;
+
+ ret = GenericFileStoreBackend::detect_features();
+ if (ret < 0)
+ return ret;
+
+ // extsize?
+ int fd = ::openat(get_basedir_fd(), "extsize_test", O_CREAT|O_WRONLY, 0600);
+ if (fd < 0) {
+ ret = -errno;
+ dout(0) << "detect_feature: failed to create test file for extsize attr: "
+ << cpp_strerror(ret) << dendl;
+ goto out;
+ }
+ if (::unlinkat(get_basedir_fd(), "extsize_test", 0) < 0) {
+ ret = -errno;
+ dout(0) << "detect_feature: failed to unlink test file for extsize attr: "
+ << cpp_strerror(ret) << dendl;
+ goto out_close;
+ }
+
+ ret = set_extsize(fd, 1U << 15); // a few pages
+ if (ret) {
+ ret = 0;
+ dout(0) << "detect_feature: failed to set test file extsize, assuming extsize is NOT supported" << dendl;
+ goto out_close;
+ }
+
+ dout(0) << "detect_feature: extsize is supported" << dendl;
+ m_has_extsize = true;
+
+out_close:
+ TEMP_FAILURE_RETRY(::close(fd));
+out:
+ return ret;
+}
+
+int XfsFileStoreBackend::set_alloc_hint(int fd, uint64_t hint)
+{
+ if (!m_has_extsize)
+ return -EOPNOTSUPP;
+
+ assert(hint < UINT_MAX);
+ return set_extsize(fd, hint);
+}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2014 Inktank, Inc
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_XFSFILESTOREBACKEND_H
+#define CEPH_XFSFILESTOREBACKEND_H
+
+#include "GenericFileStoreBackend.h"
+
+#include "include/int_types.h"
+
+class XfsFileStoreBackend : public GenericFileStoreBackend {
+private:
+ bool m_has_extsize;
+ int set_extsize(int fd, unsigned int val);
+public:
+ XfsFileStoreBackend(FileStore *fs);
+ ~XfsFileStoreBackend() {};
+ int detect_features();
+ int set_alloc_hint(int fd, uint64_t hint);
+};
+
+#endif /* CEPH_XFSFILESTOREBACKEND_H */