From: Sage Weil Date: Tue, 7 Apr 2015 22:21:50 +0000 (-0700) Subject: os/fs: add simple FS abstraction layer X-Git-Tag: v9.1.0~324^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c33b6fbc1d73b3e00214da86cae89c23264906f4;p=ceph.git os/fs: add simple FS abstraction layer - open by handle - xfs allocation hint Signed-off-by: Sage Weil --- diff --git a/configure.ac b/configure.ac index ebf280e830c1..6a1ab8a0d2fb 100644 --- a/configure.ac +++ b/configure.ac @@ -954,6 +954,11 @@ AC_CHECK_HEADERS([ \ utime.h \ ]) +# name_to_handle_at +AC_CHECK_FUNC([name_to_handle_at], + [AC_DEFINE([HAVE_NAME_TO_HANDLE_AT], [], [name_to_handle_at exists])], + []) + # sync_file_range AC_CHECK_FUNC([sync_file_range], [AC_DEFINE([HAVE_SYNC_FILE_RANGE], [], [sync_file_range(2) is supported])], diff --git a/src/os/Makefile.am b/src/os/Makefile.am index 0b990d03066b..ba80fd356db8 100644 --- a/src/os/Makefile.am +++ b/src/os/Makefile.am @@ -7,6 +7,8 @@ if ENABLE_SERVER libos_la_SOURCES = \ os/chain_xattr.cc \ + os/fs/FS.cc \ + os/fs/XFS.cc \ os/DBObjectMap.cc \ os/GenericObjectMap.cc \ os/FileJournal.cc \ @@ -54,6 +56,8 @@ noinst_HEADERS += \ os/FileJournal.h \ os/FileStore.h \ os/FDCache.h \ + os/fs/FS.h \ + os/fs/XFS.h \ os/GenericFileStoreBackend.h \ os/HashIndex.h \ os/IndexManager.h \ diff --git a/src/os/fs/FS.cc b/src/os/fs/FS.cc new file mode 100644 index 000000000000..e64e324155a3 --- /dev/null +++ b/src/os/fs/FS.cc @@ -0,0 +1,105 @@ +// -*- 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 Red Hat + * + * 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 +#include +#include +#include +#include + +#include "FS.h" + +#include "XFS.h" + +#include "acconfig.h" + +// --------------- + +FS *FS::create(uint64_t f_type) +{ + switch (f_type) { +#ifdef HAVE_LIBXFS + case XFS_SUPER_MAGIC: + return new XFS; +#endif + default: + return new FS; + } +} + +FS *FS::create_by_fd(int fd) +{ + struct statfs st; + ::fstatfs(fd, &st); + return create(st.f_type); +} + +// --------------- + +int FS::set_alloc_hint(int fd, uint64_t hint) +{ + return 0; // no-op +} + +#ifdef HAVE_NAME_TO_HANDLE_AT +int FS::get_handle(int fd, std::string *h) +{ + char buf[sizeof(struct file_handle) + MAX_HANDLE_SZ]; + struct file_handle *fh = (struct file_handle *)buf; + int mount_id; + + fh->handle_bytes = MAX_HANDLE_SZ; + int r = name_to_handle_at(fd, "", fh, &mount_id, AT_EMPTY_PATH); + if (r < 0) { + return -errno; + } + *h = std::string(buf, fh->handle_bytes + sizeof(struct file_handle)); + return 0; +} + +int FS::open_handle(int mount_fd, const std::string& h, int flags) +{ + if (h.length() < sizeof(struct file_handle)) { + return -EINVAL; + } + struct file_handle *fh = (struct file_handle *)h.data(); + if (fh->handle_bytes > h.length()) { + return -ERANGE; + } + int fd = open_by_handle_at(mount_fd, fh, flags); + if (fd < 0) + return -errno; + return fd; +} + +#else // HAVE_NAME_TO_HANDLE_AT + +int FS::get_handle(int fd, std::string *h) +{ + return -EOPNOTSUPP; +} + +int FS::open_handle(int mount_fd, const std::string& h) +{ + return -EOPNOTSUPP; +} + +#endif // HAVE_NAME_TO_HANDLE_AT + +int FS::copy_file_range(int to_fd, uint64_t to_offset, + int from_fd, + uint64_t from_offset, uint64_t from_len) +{ + assert(0 == "write me"); +} diff --git a/src/os/fs/FS.h b/src/os/fs/FS.h new file mode 100644 index 000000000000..6a02b2721142 --- /dev/null +++ b/src/os/fs/FS.h @@ -0,0 +1,43 @@ +// -*- 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 Red Hat + * + * 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_OS_FS_H +#define CEPH_OS_FS_H + +#include + +#include "include/types.h" + +class FS { +public: + virtual ~FS() { } + + static FS *create(uint64_t f_type); + static FS *create_by_fd(int fd); + + virtual const char *get_name() { + return "generic"; + } + + virtual int set_alloc_hint(int fd, uint64_t hint); + + virtual int get_handle(int fd, std::string *h); + virtual int open_handle(int mount_fd, const std::string& h, int flags); + + virtual int copy_file_range(int to_fd, uint64_t to_offset, + int from_fd, + uint64_t from_offset, uint64_t from_len); +}; + +#endif diff --git a/src/os/fs/XFS.cc b/src/os/fs/XFS.cc new file mode 100644 index 000000000000..c72ee1a0855f --- /dev/null +++ b/src/os/fs/XFS.cc @@ -0,0 +1,55 @@ +// -*- 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 Red Hat + * + * 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 "XFS.h" + +#include + +int XFS::set_alloc_hint(int fd, uint64_t val) +{ + struct fsxattr fsx; + struct stat sb; + int ret; + + if (fstat(fd, &sb) < 0) { + ret = -errno; + return ret; + } + if (!S_ISREG(sb.st_mode)) { + return -EINVAL; + } + + if (ioctl(fd, XFS_IOC_FSGETXATTR, &fsx) < 0) { + ret = -errno; + return ret; + } + + // already set? + if ((fsx.fsx_xflags & XFS_XFLAG_EXTSIZE) && fsx.fsx_extsize == val) + return 0; + + // xfs won't change extent size if any extents are allocated + if (fsx.fsx_nextents != 0) + return 0; + + fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE; + fsx.fsx_extsize = val; + + if (ioctl(fd, XFS_IOC_FSSETXATTR, &fsx) < 0) { + ret = -errno; + return ret; + } + + return 0; +} diff --git a/src/os/fs/XFS.h b/src/os/fs/XFS.h new file mode 100644 index 000000000000..1c3c3c4c493c --- /dev/null +++ b/src/os/fs/XFS.h @@ -0,0 +1,31 @@ +// -*- 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 Red Hat + * + * 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_OS_XFS_H +#define CEPH_OS_XFS_H + +#include "FS.h" + +# ifndef XFS_SUPER_MAGIC +static const __SWORD_TYPE XFS_SUPER_MAGIC(0x58465342); +# endif + +class XFS : public FS { + const char *get_name() { + return "xfs"; + } + int set_alloc_hint(int fd, uint64_t hint); +}; + +#endif