Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / libradosstriper / RadosStriperImpl.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) 2014 Sebastien Ponce <sebastien.ponce@cern.ch>
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14
15 #ifndef CEPH_LIBRADOSSTRIPER_RADOSSTRIPERIMPL_H
16 #define CEPH_LIBRADOSSTRIPER_RADOSSTRIPERIMPL_H
17
18 #include <string>
19
20 #include "include/rados/librados.h"
21 #include "include/rados/librados.hpp"
22 #include "include/radosstriper/libradosstriper.h"
23 #include "include/radosstriper/libradosstriper.hpp"
24 #include "MultiAioCompletionImpl.h"
25
26 #include "librados/IoCtxImpl.h"
27 #include "librados/AioCompletionImpl.h"
28 #include "common/RefCountedObj.h"
29
30 namespace libradosstriper {
31
32 using MultiAioCompletionImplPtr =
33     boost::intrusive_ptr<MultiAioCompletionImpl>;
34
35 struct RadosStriperImpl {
36
37   /**
38    * exception wrapper around an error code
39    */
40   struct ErrorCode {
41     ErrorCode(int error) : m_code(error) {};
42     int m_code;
43   };
44
45   /*
46    * Constructor
47    * @param cluster_name name of the cluster, can be NULL
48    * @param client_name has 2 meanings depending on cluster_name
49    *          - if cluster_name is null : this is the client id
50    *          - else : this is the full client name in format type.id
51    */
52   RadosStriperImpl(librados::IoCtx& ioctx, librados::IoCtxImpl *ioctx_impl);
53   /// Destructor
54   ~RadosStriperImpl() {};
55
56   // configuration
57   int setObjectLayoutStripeUnit(unsigned int stripe_unit);
58   int setObjectLayoutStripeCount(unsigned int stripe_count);
59   int setObjectLayoutObjectSize(unsigned int object_size);
60
61   // xattrs
62   int getxattr(const object_t& soid, const char *name, bufferlist& bl);
63   int setxattr(const object_t& soid, const char *name, bufferlist& bl);
64   int getxattrs(const object_t& soid, map<string, bufferlist>& attrset);
65   int rmxattr(const object_t& soid, const char *name);
66
67   // io
68   int write(const std::string& soid, const bufferlist& bl, size_t len, uint64_t off);
69   int append(const std::string& soid, const bufferlist& bl, size_t len);
70   int write_full(const std::string& soid, const bufferlist& bl);
71   int read(const std::string& soid, bufferlist* pbl, size_t len, uint64_t off);
72
73   // asynchronous io
74   int aio_write(const std::string& soid, librados::AioCompletionImpl *c,
75                 const bufferlist& bl, size_t len, uint64_t off);
76   int aio_append(const std::string& soid, librados::AioCompletionImpl *c,
77                  const bufferlist& bl, size_t len);
78   int aio_write_full(const std::string& soid, librados::AioCompletionImpl *c,
79                      const bufferlist& bl);
80   int aio_read(const std::string& soid, librados::AioCompletionImpl *c,
81                bufferlist* pbl, size_t len, uint64_t off);
82   int aio_read(const std::string& soid, librados::AioCompletionImpl *c,
83                char* buf, size_t len, uint64_t off);
84   int aio_flush();
85
86   // stat, deletion and truncation
87   int stat(const std::string& soid, uint64_t *psize, time_t *pmtime);
88   int stat2(const std::string& soid, uint64_t *psize, struct timespec *pts);
89   template<class TimeType>
90   struct StatFunction {
91     typedef int (librados::IoCtxImpl::*Type) (const object_t& oid,
92                                               librados::AioCompletionImpl *c,
93                                               uint64_t *psize, TimeType *pmtime);
94   };
95   template<class TimeType>
96   int aio_generic_stat(const std::string& soid, librados::AioCompletionImpl *c,
97                        uint64_t *psize, TimeType *pmtime,
98                        typename StatFunction<TimeType>::Type statFunction);
99   int aio_stat(const std::string& soid, librados::AioCompletionImpl *c,
100                uint64_t *psize, time_t *pmtime);
101   int aio_stat2(const std::string& soid, librados::AioCompletionImpl *c,
102                 uint64_t *psize, struct timespec *pts);
103   int remove(const std::string& soid, int flags=0);
104   int trunc(const std::string& soid, uint64_t size);
105
106   // asynchronous remove. Note that the removal is not 100% parallelized :
107   // the removal of the first rados object of the striped object will be
108   // done via a syncrhonous call after the completion of all other removals.
109   // These are done asynchrounously and in parallel
110   int aio_remove(const std::string& soid, librados::AioCompletionImpl *c, int flags=0);
111
112   // reference counting
113   void get() {
114     lock.Lock();
115     m_refCnt ++ ;
116     lock.Unlock();
117   }
118   void put() {
119     bool deleteme = false;
120     lock.Lock();
121     m_refCnt --;
122     if (m_refCnt == 0)
123       deleteme = true;
124     cond.Signal();
125     lock.Unlock();
126     if (deleteme)
127       delete this;
128   }
129
130   // objectid manipulation
131   std::string getObjectId(const object_t& soid, long long unsigned objectno);
132
133   // opening and closing of striped objects
134   void unlockObject(const std::string& soid,
135                     const std::string& lockCookie);
136   void aio_unlockObject(const std::string& soid,
137                         const std::string& lockCookie,
138                         librados::AioCompletion *c);
139
140   // internal versions of IO method
141   int write_in_open_object(const std::string& soid,
142                            const ceph_file_layout& layout,
143                            const std::string& lockCookie,
144                            const bufferlist& bl,
145                            size_t len,
146                            uint64_t off);
147   int aio_write_in_open_object(const std::string& soid,
148                                librados::AioCompletionImpl *c,
149                                const ceph_file_layout& layout,
150                                const std::string& lockCookie,
151                                const bufferlist& bl,
152                                size_t len,
153                                uint64_t off);
154   int internal_aio_write(const std::string& soid,
155                          MultiAioCompletionImplPtr c,
156                          const bufferlist& bl,
157                          size_t len,
158                          uint64_t off,
159                          const ceph_file_layout& layout);
160
161   int extract_uint32_attr(std::map<std::string, bufferlist> &attrs,
162                           const std::string& key,
163                           ceph_le32 *value);
164
165   int extract_sizet_attr(std::map<std::string, bufferlist> &attrs,
166                          const std::string& key,
167                          size_t *value);
168
169   int internal_get_layout_and_size(const std::string& oid,
170                                    ceph_file_layout *layout,
171                                    uint64_t *size);
172
173   int internal_aio_remove(const std::string& soid,
174                           MultiAioCompletionImplPtr multi_completion,
175                           int flags=0);
176
177   /**
178    * opens an existing striped object and takes a shared lock on it
179    * @return 0 if everything is ok and the lock was taken. -errcode otherwise
180    * In particulae, if the striped object does not exists, -ENOENT is returned
181    * In case the return code in not 0, no lock is taken
182    */
183   int openStripedObjectForRead(const std::string& soid,
184                                ceph_file_layout *layout,
185                                uint64_t *size,
186                                std::string *lockCookie);
187
188   /**
189    * opens an existing striped object, takes a shared lock on it
190    * and sets its size to the size it will have after the write.
191    * In case the striped object does not exists, it will create it by
192    * calling createOrOpenStripedObject.
193    * @param layout this is filled with the layout of the file
194    * @param size new size of the file (together with isFileSizeAbsolute)
195    * In case of success, this is filled with the size of the file before the opening
196    * @param isFileSizeAbsolute if false, this means that the given size should
197    * be added to the current file size (append mode)
198    * @return 0 if everything is ok and the lock was taken. -errcode otherwise
199    * In case the return code in not 0, no lock is taken
200    */
201   int openStripedObjectForWrite(const std::string& soid,
202                                 ceph_file_layout *layout,
203                                 uint64_t *size,
204                                 std::string *lockCookie,
205                                 bool isFileSizeAbsolute);
206   /**
207    * creates an empty striped object with the given size and opens it calling
208    * openStripedObjectForWrite, which implies taking a shared lock on it
209    * Also deals with the cases where the object was created in the mean time
210    * @param isFileSizeAbsolute if false, this means that the given size should
211    * be added to the current file size (append mode). This of course only makes
212    * sense in case the striped object already exists
213    * @return 0 if everything is ok and the lock was taken. -errcode otherwise
214    * In case the return code in not 0, no lock is taken
215    */
216   int createAndOpenStripedObject(const std::string& soid,
217                                  ceph_file_layout *layout,
218                                  uint64_t size,
219                                  std::string *lockCookie,
220                                  bool isFileSizeAbsolute);
221
222   /**
223    * truncates an object synchronously. Should only be called with size < original_size
224    */
225   int truncate(const std::string& soid,
226                uint64_t original_size,
227                uint64_t size,
228                ceph_file_layout &layout);
229
230   /**
231    * truncates an object asynchronously. Should only be called with size < original_size
232    * note that the method is not 100% asynchronous, only the removal of rados objects
233    * is, the (potential) truncation of the rados object residing just at the truncation
234    * point is synchronous for lack of asynchronous truncation in the rados layer
235    */
236   int aio_truncate(const std::string& soid,
237                    MultiAioCompletionImplPtr c,
238                    uint64_t original_size,
239                    uint64_t size,
240                    ceph_file_layout &layout);
241
242   /**
243    * grows an object (adding 0s). Should only be called with size > original_size
244    */
245   int grow(const std::string& soid,
246            uint64_t original_size,
247            uint64_t size,
248            ceph_file_layout &layout);
249
250   /**
251    * creates a unique identifier
252    */
253   static std::string getUUID();
254
255   CephContext *cct() {
256     return (CephContext*)m_radosCluster.cct();
257   }
258
259   // reference counting
260   Cond  cond;
261   int m_refCnt;
262   Mutex lock;
263
264
265   // Context
266   librados::Rados m_radosCluster;
267   librados::IoCtx m_ioCtx;
268   librados::IoCtxImpl *m_ioCtxImpl;
269
270   // Default layout
271   ceph_file_layout m_layout;
272 };
273 }
274 #endif