Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / osdc / Filer.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) 2004-2006 Sage Weil <sage@newdream.net>
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
16 #ifndef CEPH_FILER_H
17 #define CEPH_FILER_H
18
19 /*** Filer
20  *
21  * stripe file ranges onto objects.
22  * build list<ObjectExtent> for the objecter or objectcacher.
23  *
24  * also, provide convenience methods that call objecter for you.
25  *
26  * "files" are identified by ino.
27  */
28
29
30 #include <mutex>
31
32 #include "include/types.h"
33
34 #include "common/ceph_time.h"
35
36 #include "osd/OSDMap.h"
37 #include "Objecter.h"
38 #include "Striper.h"
39
40 class Context;
41 class Messenger;
42 class OSDMap;
43 class Finisher;
44
45
46 /**** Filer interface ***/
47
48 class Filer {
49   CephContext *cct;
50   Objecter   *objecter;
51   Finisher   *finisher;
52
53   // probes
54   struct Probe {
55     std::mutex lock;
56     typedef std::lock_guard<std::mutex> lock_guard;
57     typedef std::unique_lock<std::mutex> unique_lock;
58     inodeno_t ino;
59     file_layout_t layout;
60     snapid_t snapid;
61
62     uint64_t *psize;
63     ceph::real_time *pmtime;
64     utime_t *pumtime;
65
66     int flags;
67
68     bool fwd;
69
70     Context *onfinish;
71
72     vector<ObjectExtent> probing;
73     uint64_t probing_off, probing_len;
74
75     map<object_t, uint64_t> known_size;
76     ceph::real_time max_mtime;
77
78     set<object_t> ops;
79
80     int err;
81     bool found_size;
82
83     Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
84           uint64_t f, uint64_t *e, ceph::real_time *m, int fl, bool fw,
85           Context *c) :
86       ino(i), layout(l), snapid(sn),
87       psize(e), pmtime(m), pumtime(nullptr), flags(fl), fwd(fw), onfinish(c),
88       probing_off(f), probing_len(0),
89       err(0), found_size(false) {}
90
91     Probe(inodeno_t i, file_layout_t &l, snapid_t sn,
92           uint64_t f, uint64_t *e, utime_t *m, int fl, bool fw,
93           Context *c) :
94       ino(i), layout(l), snapid(sn),
95       psize(e), pmtime(nullptr), pumtime(m), flags(fl), fwd(fw),
96       onfinish(c), probing_off(f), probing_len(0),
97       err(0), found_size(false) {}
98   };
99
100   class C_Probe;
101
102   void _probe(Probe *p, Probe::unique_lock& pl);
103   bool _probed(Probe *p, const object_t& oid, uint64_t size,
104                ceph::real_time mtime, Probe::unique_lock& pl);
105
106  public:
107   Filer(const Filer& other);
108   const Filer operator=(const Filer& other);
109
110   Filer(Objecter *o, Finisher *f) : cct(o->cct), objecter(o), finisher(f) {}
111   ~Filer() {}
112
113   bool is_active() {
114     return objecter->is_active(); // || (oc && oc->is_active());
115   }
116
117
118   /*** async file interface.  scatter/gather as needed. ***/
119
120   void read(inodeno_t ino,
121            file_layout_t *layout,
122            snapid_t snap,
123            uint64_t offset,
124            uint64_t len,
125            bufferlist *bl,   // ptr to data
126            int flags,
127            Context *onfinish,
128            int op_flags = 0) {
129     assert(snap);  // (until there is a non-NOSNAP write)
130     vector<ObjectExtent> extents;
131     Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
132     objecter->sg_read(extents, snap, bl, flags, onfinish, op_flags);
133   }
134
135   void read_trunc(inodeno_t ino,
136                  file_layout_t *layout,
137                  snapid_t snap,
138                  uint64_t offset,
139                  uint64_t len,
140                  bufferlist *bl, // ptr to data
141                  int flags,
142                  uint64_t truncate_size,
143                  __u32 truncate_seq,
144                  Context *onfinish,
145                  int op_flags = 0) {
146     assert(snap);  // (until there is a non-NOSNAP write)
147     vector<ObjectExtent> extents;
148     Striper::file_to_extents(cct, ino, layout, offset, len, truncate_size,
149                              extents);
150     objecter->sg_read_trunc(extents, snap, bl, flags,
151                             truncate_size, truncate_seq, onfinish, op_flags);
152   }
153
154   void write(inodeno_t ino,
155             file_layout_t *layout,
156             const SnapContext& snapc,
157             uint64_t offset,
158             uint64_t len,
159             bufferlist& bl,
160             ceph::real_time mtime,
161             int flags,
162             Context *oncommit,
163             int op_flags = 0) {
164     vector<ObjectExtent> extents;
165     Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
166     objecter->sg_write(extents, snapc, bl, mtime, flags, oncommit, op_flags);
167   }
168
169   void write_trunc(inodeno_t ino,
170                   file_layout_t *layout,
171                   const SnapContext& snapc,
172                   uint64_t offset,
173                   uint64_t len,
174                   bufferlist& bl,
175                   ceph::real_time mtime,
176                   int flags,
177                   uint64_t truncate_size,
178                   __u32 truncate_seq,
179                   Context *oncommit,
180                   int op_flags = 0) {
181     vector<ObjectExtent> extents;
182     Striper::file_to_extents(cct, ino, layout, offset, len, truncate_size,
183                              extents);
184     objecter->sg_write_trunc(extents, snapc, bl, mtime, flags,
185                        truncate_size, truncate_seq, oncommit, op_flags);
186   }
187
188   void truncate(inodeno_t ino,
189                file_layout_t *layout,
190                const SnapContext& snapc,
191                uint64_t offset,
192                uint64_t len,
193                __u32 truncate_seq,
194                ceph::real_time mtime,
195                int flags,
196                Context *oncommit);
197   void _do_truncate_range(struct TruncRange *pr, int fin);
198
199   void zero(inodeno_t ino,
200            const file_layout_t *layout,
201            const SnapContext& snapc,
202            uint64_t offset,
203            uint64_t len,
204            ceph::real_time mtime,
205            int flags,
206            bool keep_first,
207            Context *oncommit) {
208     vector<ObjectExtent> extents;
209     Striper::file_to_extents(cct, ino, layout, offset, len, 0, extents);
210     if (extents.size() == 1) {
211       if (extents[0].offset == 0 && extents[0].length == layout->object_size
212           && (!keep_first || extents[0].objectno != 0))
213         objecter->remove(extents[0].oid, extents[0].oloc,
214                          snapc, mtime, flags, oncommit);
215       else
216         objecter->zero(extents[0].oid, extents[0].oloc, extents[0].offset,
217                        extents[0].length, snapc, mtime, flags, oncommit);
218     } else {
219       C_GatherBuilder gcom(cct, oncommit);
220       for (vector<ObjectExtent>::iterator p = extents.begin();
221            p != extents.end();
222            ++p) {
223         if (p->offset == 0 && p->length == layout->object_size &&
224             (!keep_first || p->objectno != 0))
225           objecter->remove(p->oid, p->oloc,
226                            snapc, mtime, flags,
227                            oncommit ? gcom.new_sub():0);
228         else
229           objecter->zero(p->oid, p->oloc, p->offset, p->length,
230                          snapc, mtime, flags,
231                          oncommit ? gcom.new_sub():0);
232       }
233       gcom.activate();
234     }
235   }
236
237   void zero(inodeno_t ino,
238            file_layout_t *layout,
239            const SnapContext& snapc,
240            uint64_t offset,
241            uint64_t len,
242            ceph::real_time mtime,
243            int flags,
244            Context *oncommit) {
245     zero(ino, layout,
246          snapc, offset,
247          len, mtime,
248          flags, false,
249          oncommit);
250   }
251   // purge range of ino.### objects
252   int purge_range(inodeno_t ino,
253                   const file_layout_t *layout,
254                   const SnapContext& snapc,
255                   uint64_t first_obj, uint64_t num_obj,
256                   ceph::real_time mtime,
257                   int flags, Context *oncommit);
258   void _do_purge_range(struct PurgeRange *pr, int fin);
259
260   /*
261    * probe
262    *  specify direction,
263    *  and whether we stop when we find data, or hole.
264    */
265   int probe(inodeno_t ino,
266             file_layout_t *layout,
267             snapid_t snapid,
268             uint64_t start_from,
269             uint64_t *end,
270             ceph::real_time *mtime,
271             bool fwd,
272             int flags,
273             Context *onfinish);
274
275   int probe(inodeno_t ino,
276             file_layout_t *layout,
277             snapid_t snapid,
278             uint64_t start_from,
279             uint64_t *end,
280             bool fwd,
281             int flags,
282             Context *onfinish) {
283     return probe(ino, layout, snapid, start_from, end,
284                  (ceph::real_time* )0, fwd, flags, onfinish);
285   }
286
287   int probe(inodeno_t ino,
288             file_layout_t *layout,
289             snapid_t snapid,
290             uint64_t start_from,
291             uint64_t *end,
292             utime_t *mtime,
293             bool fwd,
294             int flags,
295             Context *onfinish);
296
297 private:
298   int probe_impl(Probe* probe, file_layout_t *layout,
299                  uint64_t start_from, uint64_t *end);
300 };
301
302 #endif // !CEPH_FILER_H