1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include <boost/lexical_cast.hpp>
5 #include <boost/algorithm/string.hpp>
7 #include "librbd/io/Types.h"
8 #include "librbd/io/IoOperations.h"
16 #define RBD_IO_OPERATION_NAME_READ "read"
17 #define RBD_IO_OPERATION_NAME_WRITE "write"
18 #define RBD_IO_OPERATION_NAME_DISCARD "discard"
19 #define RBD_IO_OPERATION_NAME_WRITE_SAME "write_same"
20 #define RBD_IO_OPERATION_NAME_COMPARE_AND_WRITE "compare_and_write"
22 static const std::map
<std::string
, uint64_t> RBD_IO_OPERATION_MAP
= {
23 {RBD_IO_OPERATION_NAME_READ
, RBD_IO_OPERATION_READ
},
24 {RBD_IO_OPERATION_NAME_WRITE
, RBD_IO_OPERATION_WRITE
},
25 {RBD_IO_OPERATION_NAME_DISCARD
, RBD_IO_OPERATION_DISCARD
},
26 {RBD_IO_OPERATION_NAME_WRITE_SAME
, RBD_IO_OPERATION_WRITE_SAME
},
27 {RBD_IO_OPERATION_NAME_COMPARE_AND_WRITE
, RBD_IO_OPERATION_COMPARE_AND_WRITE
},
29 static_assert((RBD_IO_OPERATION_COMPARE_AND_WRITE
<< 1) > RBD_IO_OPERATIONS_ALL
,
30 "new RBD io operation added");
32 std::string
rbd_io_operations_to_string(uint64_t operations
,
36 for (auto& i
: RBD_IO_OPERATION_MAP
) {
37 if (operations
& i
.second
) {
42 operations
&= ~i
.second
;
45 if (err
&& operations
) {
46 *err
<< "ignoring unknown io operation mask 0x"
47 << std::hex
<< operations
<< std::dec
;
52 uint64_t rbd_io_operations_from_string(const std::string
& orig_value
,
55 uint64_t operations
= 0;
56 std::string value
= orig_value
;
59 // empty string means default operations
61 return RBD_IO_OPERATIONS_DEFAULT
;
66 operations
= boost::lexical_cast
<uint64_t>(value
);
68 // drop unrecognized bits
69 uint64_t unsupported_operations
= (operations
& ~RBD_IO_OPERATIONS_ALL
);
70 if (unsupported_operations
!= 0ull) {
71 operations
&= RBD_IO_OPERATIONS_ALL
;
73 *err
<< "ignoring unknown operation mask 0x"
74 << std::hex
<< unsupported_operations
<< std::dec
;
77 } catch (boost::bad_lexical_cast
&) {
78 // operation name list?
80 std::vector
<std::string
> operation_names
;
81 boost::split(operation_names
, value
, boost::is_any_of(","));
82 for (auto operation_name
: operation_names
) {
83 boost::trim(operation_name
);
84 auto operation_it
= RBD_IO_OPERATION_MAP
.find(operation_name
);
85 if (operation_it
!= RBD_IO_OPERATION_MAP
.end()) {
86 operations
+= operation_it
->second
;
93 *err
<< "ignoring unknown operation " << operation_name
;
101 } // namespace librbd