Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / os / bluestore / BlockDevice.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5   *
6  * Copyright (C) 2015 XSky <haomai@xsky.com>
7  *
8  * Author: Haomai Wang <haomaiwang@gmail.com>
9  *
10  * This is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License version 2.1, as published by the Free Software
13  * Foundation.  See file COPYING.
14  *
15  */
16
17 #ifndef CEPH_OS_BLUESTORE_BLOCKDEVICE_H
18 #define CEPH_OS_BLUESTORE_BLOCKDEVICE_H
19
20 #include <atomic>
21 #include <condition_variable>
22 #include <mutex>
23 #include <list>
24
25 #include "acconfig.h"
26 #include "aio.h"
27
28 #define SPDK_PREFIX "spdk:"
29
30 /// track in-flight io
31 struct IOContext {
32 private:
33   std::mutex lock;
34   std::condition_variable cond;
35
36 public:
37   CephContext* cct;
38   void *priv;
39 #ifdef HAVE_SPDK
40   void *nvme_task_first = nullptr;
41   void *nvme_task_last = nullptr;
42 #endif
43
44
45   std::list<aio_t> pending_aios;    ///< not yet submitted
46   std::list<aio_t> running_aios;    ///< submitting or submitted
47   std::atomic_int num_pending = {0};
48   std::atomic_int num_running = {0};
49
50   explicit IOContext(CephContext* cct, void *p)
51     : cct(cct), priv(p)
52     {}
53
54   // no copying
55   IOContext(const IOContext& other) = delete;
56   IOContext &operator=(const IOContext& other) = delete;
57
58   bool has_pending_aios() {
59     return num_pending.load();
60   }
61
62   void aio_wait();
63
64   void try_aio_wake() {
65     if (num_running == 1) {
66
67       // we might have some pending IOs submitted after the check
68       // as there is no lock protection for aio_submit.
69       // Hence we might have false conditional trigger.
70       // aio_wait has to handle that hence do not care here.
71       std::lock_guard<std::mutex> l(lock);
72       cond.notify_all();
73       --num_running;
74       assert(num_running >= 0);
75     } else {
76       --num_running;
77     }
78   }
79 };
80
81
82 class BlockDevice {
83 public:
84   CephContext* cct;
85 private:
86   std::mutex ioc_reap_lock;
87   std::vector<IOContext*> ioc_reap_queue;
88   std::atomic_int ioc_reap_count = {0};
89
90 protected:
91   bool rotational = true;
92
93 public:
94   BlockDevice(CephContext* cct) : cct(cct) {}
95   virtual ~BlockDevice() = default;
96   typedef void (*aio_callback_t)(void *handle, void *aio);
97
98   static BlockDevice *create(
99     CephContext* cct, const std::string& path, aio_callback_t cb, void *cbpriv);
100   virtual bool supported_bdev_label() { return true; }
101   virtual bool is_rotational() { return rotational; }
102
103   virtual void aio_submit(IOContext *ioc) = 0;
104
105   virtual uint64_t get_size() const = 0;
106   virtual uint64_t get_block_size() const = 0;
107
108   virtual int collect_metadata(std::string prefix, std::map<std::string,std::string> *pm) const = 0;
109
110   virtual int read(
111     uint64_t off,
112     uint64_t len,
113     bufferlist *pbl,
114     IOContext *ioc,
115     bool buffered) = 0;
116   virtual int read_random(
117     uint64_t off,
118     uint64_t len,
119     char *buf,
120     bool buffered) = 0;
121   virtual int write(
122     uint64_t off,
123     bufferlist& bl,
124     bool buffered) = 0;
125
126   virtual int aio_read(
127     uint64_t off,
128     uint64_t len,
129     bufferlist *pbl,
130     IOContext *ioc) = 0;
131   virtual int aio_write(
132     uint64_t off,
133     bufferlist& bl,
134     IOContext *ioc,
135     bool buffered) = 0;
136   virtual int flush() = 0;
137
138   void queue_reap_ioc(IOContext *ioc);
139   void reap_ioc();
140
141   // for managing buffered readers/writers
142   virtual int invalidate_cache(uint64_t off, uint64_t len) = 0;
143   virtual int open(const std::string& path) = 0;
144   virtual void close() = 0;
145 };
146
147 #endif //CEPH_OS_BLUESTORE_BLOCKDEVICE_H