]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/include/rocksdb/io_status.h
1 // Copyright (c) 2019-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 // An IOStatus encapsulates the result of an operation. It may indicate
7 // success, or it may indicate an error with an associated error message.
9 // Multiple threads can invoke const methods on an IOStatus without
10 // external synchronization, but if any of the threads may call a
11 // non-const method, all threads accessing the same IOStatus must use
12 // external synchronization.
17 #include "rocksdb/slice.h"
24 namespace ROCKSDB_NAMESPACE
{
26 class IOStatus
: public Status
{
28 using Code
= Status::Code
;
29 using SubCode
= Status::SubCode
;
32 kIOErrorScopeFileSystem
,
38 // Create a success status.
39 IOStatus() : IOStatus(kOk
, kNone
) {}
42 // Copy the specified status.
43 IOStatus(const IOStatus
& s
);
44 IOStatus
& operator=(const IOStatus
& s
);
45 IOStatus(IOStatus
&& s
)
46 #if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
50 IOStatus
& operator=(IOStatus
&& s
)
51 #if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
55 bool operator==(const IOStatus
& rhs
) const;
56 bool operator!=(const IOStatus
& rhs
) const;
58 void SetRetryable(bool retryable
) { retryable_
= retryable
; }
59 void SetDataLoss(bool data_loss
) { data_loss_
= data_loss
; }
60 void SetScope(IOErrorScope scope
) { scope_
= scope
; }
62 bool GetRetryable() const { return retryable_
; }
63 bool GetDataLoss() const { return data_loss_
; }
64 IOErrorScope
GetScope() const { return scope_
; }
66 // Return a success status.
67 static IOStatus
OK() { return IOStatus(); }
69 static IOStatus
NotSupported(const Slice
& msg
, const Slice
& msg2
= Slice()) {
70 return IOStatus(kNotSupported
, msg
, msg2
);
72 static IOStatus
NotSupported(SubCode msg
= kNone
) {
73 return IOStatus(kNotSupported
, msg
);
76 // Return error status of an appropriate type.
77 static IOStatus
NotFound(const Slice
& msg
, const Slice
& msg2
= Slice()) {
78 return IOStatus(kNotFound
, msg
, msg2
);
80 // Fast path for not found without malloc;
81 static IOStatus
NotFound(SubCode msg
= kNone
) {
82 return IOStatus(kNotFound
, msg
);
85 static IOStatus
Corruption(const Slice
& msg
, const Slice
& msg2
= Slice()) {
86 return IOStatus(kCorruption
, msg
, msg2
);
88 static IOStatus
Corruption(SubCode msg
= kNone
) {
89 return IOStatus(kCorruption
, msg
);
92 static IOStatus
InvalidArgument(const Slice
& msg
,
93 const Slice
& msg2
= Slice()) {
94 return IOStatus(kInvalidArgument
, msg
, msg2
);
96 static IOStatus
InvalidArgument(SubCode msg
= kNone
) {
97 return IOStatus(kInvalidArgument
, msg
);
100 static IOStatus
IOError(const Slice
& msg
, const Slice
& msg2
= Slice()) {
101 return IOStatus(kIOError
, msg
, msg2
);
103 static IOStatus
IOError(SubCode msg
= kNone
) {
104 return IOStatus(kIOError
, msg
);
107 static IOStatus
Busy(SubCode msg
= kNone
) { return IOStatus(kBusy
, msg
); }
108 static IOStatus
Busy(const Slice
& msg
, const Slice
& msg2
= Slice()) {
109 return IOStatus(kBusy
, msg
, msg2
);
112 static IOStatus
TimedOut(SubCode msg
= kNone
) {
113 return IOStatus(kTimedOut
, msg
);
115 static IOStatus
TimedOut(const Slice
& msg
, const Slice
& msg2
= Slice()) {
116 return IOStatus(kTimedOut
, msg
, msg2
);
119 static IOStatus
NoSpace() { return IOStatus(kIOError
, kNoSpace
); }
120 static IOStatus
NoSpace(const Slice
& msg
, const Slice
& msg2
= Slice()) {
121 return IOStatus(kIOError
, kNoSpace
, msg
, msg2
);
124 static IOStatus
PathNotFound() { return IOStatus(kIOError
, kPathNotFound
); }
125 static IOStatus
PathNotFound(const Slice
& msg
, const Slice
& msg2
= Slice()) {
126 return IOStatus(kIOError
, kPathNotFound
, msg
, msg2
);
129 static IOStatus
IOFenced() { return IOStatus(kIOError
, kIOFenced
); }
130 static IOStatus
IOFenced(const Slice
& msg
, const Slice
& msg2
= Slice()) {
131 return IOStatus(kIOError
, kIOFenced
, msg
, msg2
);
134 // Return a string representation of this status suitable for printing.
135 // Returns the string "OK" for success.
136 // std::string ToString() const;
139 friend IOStatus
status_to_io_status(Status
&&);
144 explicit IOStatus(Code _code
, SubCode _subcode
= kNone
)
145 : Status(_code
, _subcode
),
148 scope_(kIOErrorScopeFileSystem
) {}
150 IOStatus(Code _code
, SubCode _subcode
, const Slice
& msg
, const Slice
& msg2
);
151 IOStatus(Code _code
, const Slice
& msg
, const Slice
& msg2
)
152 : IOStatus(_code
, kNone
, msg
, msg2
) {}
155 inline IOStatus::IOStatus(Code _code
, SubCode _subcode
, const Slice
& msg
,
157 : Status(_code
, _subcode
),
160 scope_(kIOErrorScopeFileSystem
) {
161 assert(code_
!= kOk
);
162 assert(subcode_
!= kMaxSubCode
);
163 const size_t len1
= msg
.size();
164 const size_t len2
= msg2
.size();
165 const size_t size
= len1
+ (len2
? (2 + len2
) : 0);
166 char* const result
= new char[size
+ 1]; // +1 for null terminator
167 memcpy(result
, msg
.data(), len1
);
170 result
[len1
+ 1] = ' ';
171 memcpy(result
+ len1
+ 2, msg2
.data(), len2
);
173 result
[size
] = '\0'; // null terminator for C style string
177 inline IOStatus::IOStatus(const IOStatus
& s
) : Status(s
.code_
, s
.subcode_
) {
178 #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
180 #endif // ROCKSDB_ASSERT_STATUS_CHECKED
181 retryable_
= s
.retryable_
;
182 data_loss_
= s
.data_loss_
;
184 state_
= (s
.state_
== nullptr) ? nullptr : CopyState(s
.state_
);
186 inline IOStatus
& IOStatus::operator=(const IOStatus
& s
) {
187 // The following condition catches both aliasing (when this == &s),
188 // and the common case where both s and *this are ok.
190 #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
193 #endif // ROCKSDB_ASSERT_STATUS_CHECKED
195 subcode_
= s
.subcode_
;
196 retryable_
= s
.retryable_
;
197 data_loss_
= s
.data_loss_
;
200 state_
= (s
.state_
== nullptr) ? nullptr : CopyState(s
.state_
);
205 inline IOStatus::IOStatus(IOStatus
&& s
)
206 #if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
210 *this = std::move(s
);
213 inline IOStatus
& IOStatus::operator=(IOStatus
&& s
)
214 #if !(defined _MSC_VER) || ((defined _MSC_VER) && (_MSC_VER >= 1900))
219 #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
222 #endif // ROCKSDB_ASSERT_STATUS_CHECKED
223 code_
= std::move(s
.code_
);
225 subcode_
= std::move(s
.subcode_
);
227 retryable_
= s
.retryable_
;
228 data_loss_
= s
.data_loss_
;
230 s
.scope_
= kIOErrorScopeFileSystem
;
233 std::swap(state_
, s
.state_
);
238 inline bool IOStatus::operator==(const IOStatus
& rhs
) const {
239 #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
242 #endif // ROCKSDB_ASSERT_STATUS_CHECKED
243 return (code_
== rhs
.code_
);
246 inline bool IOStatus::operator!=(const IOStatus
& rhs
) const {
247 #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
250 #endif // ROCKSDB_ASSERT_STATUS_CHECKED
251 return !(*this == rhs
);
254 inline IOStatus
status_to_io_status(Status
&& status
) {
257 return IOStatus::OK();
259 const char* state
= status
.getState();
261 return IOStatus(status
.code(), status
.subcode(),
262 Slice(state
, strlen(status
.getState()) + 1), Slice());
264 return IOStatus(status
.code(), status
.subcode());
269 } // namespace ROCKSDB_NAMESPACE