]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/filestore: is_rotational()
authorSage Weil <sage@redhat.com>
Thu, 1 Jun 2017 20:54:28 +0000 (16:54 -0400)
committerSage Weil <sage@redhat.com>
Fri, 2 Jun 2017 03:52:18 +0000 (23:52 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/filestore/FileStore.cc
src/os/filestore/FileStore.h
src/os/filestore/GenericFileStoreBackend.cc
src/os/filestore/GenericFileStoreBackend.h

index 1d527e0c12004ca2c99bbd87de015b3972b756f6..f01ae5cd2007127111229b9b22ec83ad686c09be 100644 (file)
@@ -1123,6 +1123,30 @@ bool FileStore::test_mount_in_use()
   return inuse;
 }
 
+bool FileStore::is_rotational()
+{
+  bool rotational;
+  if (backend) {
+    rotational = backend->is_rotational();
+  } else {
+    int fd = ::open(basedir.c_str(), O_RDONLY);
+    if (fd < 0)
+      return true;
+    struct statfs st;
+    int r = ::fstatfs(fd, &st);
+    ::close(fd);
+    if (r < 0) {
+      return true;
+    }
+    create_backend(st.f_type);
+    rotational = backend->is_rotational();
+    delete backend;
+    backend = NULL;
+  }
+  dout(10) << __func__ << " " << (int)rotational << dendl;
+  return rotational;
+}
+
 int FileStore::_detect_fs()
 {
   struct statfs st;
index 63523ec11fe15366d4cf4e9a7f6c53a1793ba904..88a1d3170d08bb0e0fd3dad151117406b6f147a6 100644 (file)
@@ -481,6 +481,9 @@ public:
   bool needs_journal() override {
     return false;
   }
+
+  bool is_rotational() override;
+
   void dump_perf_counters(Formatter *f) override {
     f->open_object_section("perf_counters");
     logger->dump_formatted(f, false);
@@ -864,6 +867,7 @@ public:
   virtual int syncfs() = 0;
   virtual bool has_fiemap() = 0;
   virtual bool has_seek_data_hole() = 0;
+  virtual bool is_rotational() = 0;
   virtual int do_fiemap(int fd, off_t start, size_t len, struct fiemap **pfiemap) = 0;
   virtual int clone_range(int from, int to, uint64_t srcoff, uint64_t len, uint64_t dstoff) = 0;
   virtual int set_alloc_hint(int fd, uint64_t hint) = 0;
index 4821621f456613ee166c92204722d91c7d73e088..33680a4ca6b79ad5ac36fc97dbbfbcb12722ee4f 100644 (file)
@@ -39,6 +39,7 @@
 #include "common/errno.h"
 #include "common/config.h"
 #include "common/sync_filesystem.h"
+#include "common/blkdev.h"
 
 #include "common/SloppyCRCMap.h"
 #include "os/filestore/chain_xattr.h"
@@ -63,7 +64,30 @@ GenericFileStoreBackend::GenericFileStoreBackend(FileStore *fs):
   m_filestore_fiemap(cct()->_conf->filestore_fiemap),
   m_filestore_seek_data_hole(cct()->_conf->filestore_seek_data_hole),
   m_filestore_fsync_flushes_journal_data(cct()->_conf->filestore_fsync_flushes_journal_data),
-  m_filestore_splice(cct()->_conf->filestore_splice) {}
+  m_filestore_splice(cct()->_conf->filestore_splice)
+{
+  // rotational?
+  {
+    // NOTE: the below won't work on btrfs; we'll assume rotational.
+    string fn = get_basedir_path();
+    int fd = ::open(fn.c_str(), O_RDONLY);
+    if (fd < 0) {
+      return;
+    }
+    char partition[PATH_MAX], devname[PATH_MAX];
+    int r = get_device_by_fd(fd, partition, devname, sizeof(devname));
+    if (r < 0) {
+      dout(1) << "unable to get device name for " << get_basedir_path() << ": "
+             << cpp_strerror(r) << dendl;
+      m_rotational = true;
+    } else {
+      m_rotational = block_device_is_rotational(devname);
+      dout(20) << __func__ << " devname " << devname
+              << " rotational " << (int)m_rotational << dendl;
+    }
+    ::close(fd);
+  }
+}
 
 int GenericFileStoreBackend::detect_features()
 {
index df5d1acf3076505bfdc0cf68e1f2dab11acf3f5e..8478067fa8fb86b72e13621e0bc29a60be359be3 100644 (file)
@@ -28,6 +28,7 @@ private:
   bool m_filestore_seek_data_hole;
   bool m_filestore_fsync_flushes_journal_data;
   bool m_filestore_splice;
+  bool m_rotational = true;
 public:
   explicit GenericFileStoreBackend(FileStore *fs);
   ~GenericFileStoreBackend() override {}
@@ -38,6 +39,9 @@ public:
   int detect_features() override;
   int create_current() override;
   bool can_checkpoint() override { return false; }
+  bool is_rotational() override {
+    return m_rotational;
+  }
   int list_checkpoints(list<string>& ls) override { return 0; }
   int create_checkpoint(const string& name, uint64_t *cid) override { return -EOPNOTSUPP; }
   int sync_checkpoint(uint64_t id) override { return -EOPNOTSUPP; }