]>
git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/cyan_store.cc
1 #include "cyan_store.h"
3 #include <fmt/format.h>
5 #include "common/safe_io.h"
7 #include "crimson/os/cyan_collection.h"
8 #include "crimson/os/cyan_object.h"
9 #include "crimson/os/Transaction.h"
12 seastar::logger
& logger() {
13 return ceph::get_logger(ceph_subsys_filestore
);
19 using ObjectRef
= boost::intrusive_ptr
<Object
>;
21 CyanStore::CyanStore(const std::string
& path
)
25 CyanStore::~CyanStore() = default;
27 seastar::future
<> CyanStore::mount()
30 string fn
= path
+ "/collections";
32 if (int r
= bl
.read_file(fn
.c_str(), &err
); r
< 0) {
33 throw std::runtime_error("read_file");
36 set
<coll_t
> collections
;
38 decode(collections
, p
);
40 for (auto& coll
: collections
) {
41 string fn
= fmt::format("{}/{}", path
, coll
);
43 if (int r
= cbl
.read_file(fn
.c_str(), &err
); r
< 0) {
44 throw std::runtime_error("read_file");
46 CollectionRef c
{new Collection
{coll
}};
47 auto p
= cbl
.cbegin();
50 used_bytes
+= c
->used_bytes();
52 return seastar::now();
55 seastar::future
<> CyanStore::umount()
57 set
<coll_t
> collections
;
58 for (auto& [col
, ch
] : coll_map
) {
59 collections
.insert(col
);
63 string fn
= fmt::format("{}/{}", path
, col
);
64 if (int r
= bl
.write_file(fn
.c_str()); r
< 0) {
65 throw std::runtime_error("write_file");
69 string fn
= path
+ "/collections";
71 encode(collections
, bl
);
72 if (int r
= bl
.write_file(fn
.c_str()); r
< 0) {
73 throw std::runtime_error("write_file");
75 return seastar::now();
78 seastar::future
<> CyanStore::mkfs(uuid_d osd_fsid
)
81 int r
= read_meta("fsid", &fsid_str
);
83 write_meta("fsid", fmt::format("{}", osd_fsid
));
85 throw std::runtime_error("read_meta");
87 logger().error("{} already has fsid {}", __func__
, fsid_str
);
88 throw std::runtime_error("mkfs");
91 string fn
= path
+ "/collections";
93 set
<coll_t
> collections
;
94 encode(collections
, bl
);
95 r
= bl
.write_file(fn
.c_str());
97 throw std::runtime_error("write_file");
99 write_meta("type", "memstore");
100 return seastar::now();
103 CyanStore::CollectionRef
CyanStore::create_new_collection(const coll_t
& cid
)
105 auto c
= new Collection
{cid
};
106 return new_coll_map
[cid
] = c
;
109 CyanStore::CollectionRef
CyanStore::open_collection(const coll_t
& cid
)
111 auto cp
= coll_map
.find(cid
);
112 if (cp
== coll_map
.end())
117 std::vector
<coll_t
> CyanStore::list_collections()
119 std::vector
<coll_t
> collections
;
120 for (auto& coll
: coll_map
) {
121 collections
.push_back(coll
.first
);
126 seastar::future
<bufferlist
> CyanStore::read(CollectionRef c
,
127 const ghobject_t
& oid
,
132 logger().info("{} {} {} {}~{}",
133 __func__
, c
->cid
, oid
, offset
, len
);
135 throw std::runtime_error(fmt::format("collection does not exist: {}", c
->cid
));
137 ObjectRef o
= c
->get_object(oid
);
139 throw std::runtime_error(fmt::format("object does not exist: {}", oid
));
141 if (offset
>= o
->get_size())
142 return seastar::make_ready_future
<bufferlist
>();
144 if (l
== 0 && offset
== 0) // note: len == 0 means read the entire object
146 else if (offset
+ l
> o
->get_size())
147 l
= o
->get_size() - offset
;
149 if (int r
= o
->read(offset
, l
, bl
); r
< 0) {
150 throw std::runtime_error("read");
152 return seastar::make_ready_future
<bufferlist
>(std::move(bl
));
155 seastar::future
<CyanStore::omap_values_t
>
156 CyanStore::omap_get_values(CollectionRef c
,
157 const ghobject_t
& oid
,
158 std::vector
<std::string
>&& keys
)
160 logger().info("{} {} {}",
161 __func__
, c
->cid
, oid
);
162 auto o
= c
->get_object(oid
);
164 throw std::runtime_error(fmt::format("object does not exist: {}", oid
));
166 omap_values_t values
;
167 for (auto& key
: keys
) {
168 if (auto found
= o
->omap
.find(key
); found
!= o
->omap
.end()) {
169 values
.insert(*found
);
172 return seastar::make_ready_future
<omap_values_t
>(std::move(values
));
175 seastar::future
<> CyanStore::do_transaction(CollectionRef ch
,
179 while (i
.have_op()) {
180 Transaction::Op
* op
= i
.decode_op();
183 case Transaction::OP_NOP
:
185 case Transaction::OP_WRITE
:
187 coll_t cid
= i
.get_cid(op
->cid
);
188 ghobject_t oid
= i
.get_oid(op
->oid
);
189 uint64_t off
= op
->off
;
190 uint64_t len
= op
->len
;
191 uint32_t fadvise_flags
= i
.get_fadvise_flags();
194 r
= _write(cid
, oid
, off
, len
, bl
, fadvise_flags
);
197 case Transaction::OP_MKCOLL
:
199 coll_t cid
= i
.get_cid(op
->cid
);
200 r
= _create_collection(cid
, op
->split_bits
);
204 logger().error("bad op {}", static_cast<unsigned>(op
->op
));
211 return seastar::now();
214 int CyanStore::_write(const coll_t
& cid
, const ghobject_t
& oid
,
215 uint64_t offset
, size_t len
, const bufferlist
& bl
,
216 uint32_t fadvise_flags
)
218 logger().info("{} {} {} {} ~ {}",
219 __func__
, cid
, oid
, offset
, len
);
220 assert(len
== bl
.length());
222 auto c
= open_collection(cid
);
226 ObjectRef o
= c
->get_or_create_object(oid
);
228 const ssize_t old_size
= o
->get_size();
229 o
->write(offset
, bl
);
230 used_bytes
+= (o
->get_size() - old_size
);
236 int CyanStore::_create_collection(const coll_t
& cid
, int bits
)
238 auto result
= coll_map
.insert(std::make_pair(cid
, CollectionRef()));
241 auto p
= new_coll_map
.find(cid
);
242 assert(p
!= new_coll_map
.end());
243 result
.first
->second
= p
->second
;
244 result
.first
->second
->bits
= bits
;
245 new_coll_map
.erase(p
);
249 void CyanStore::write_meta(const std::string
& key
,
250 const std::string
& value
)
252 std::string v
= value
;
254 if (int r
= safe_write_file(path
.c_str(), key
.c_str(),
255 v
.c_str(), v
.length(), 0600);
257 throw std::runtime_error
{fmt::format("unable to write_meta({})", key
)};
261 int CyanStore::read_meta(const std::string
& key
,
265 int r
= safe_read_file(path
.c_str(), key
.c_str(),
270 // drop trailing newlines
271 while (r
&& isspace(buf
[r
-1])) {
274 *value
= string
{buf
, static_cast<size_t>(r
)};