]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
7c673cae FG |
20 | #include "include/rados/librados.h" |
21 | #include "include/rados/librados.hpp" | |
22 | #include "include/radosstriper/libradosstriper.h" | |
23 | #include "include/radosstriper/libradosstriper.hpp" | |
224ce89b | 24 | #include "MultiAioCompletionImpl.h" |
7c673cae FG |
25 | |
26 | #include "librados/IoCtxImpl.h" | |
27 | #include "librados/AioCompletionImpl.h" | |
28 | #include "common/RefCountedObj.h" | |
29 | ||
224ce89b | 30 | namespace libradosstriper { |
7c673cae | 31 | |
224ce89b WB |
32 | using MultiAioCompletionImplPtr = |
33 | boost::intrusive_ptr<MultiAioCompletionImpl>; | |
7c673cae | 34 | |
224ce89b | 35 | struct RadosStriperImpl { |
7c673cae FG |
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, | |
224ce89b | 155 | MultiAioCompletionImplPtr c, |
7c673cae FG |
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, | |
224ce89b | 174 | MultiAioCompletionImplPtr multi_completion, |
7c673cae FG |
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, | |
224ce89b | 237 | MultiAioCompletionImplPtr c, |
7c673cae FG |
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 | }; | |
224ce89b | 273 | } |
7c673cae | 274 | #endif |