]>
Commit | Line | Data |
---|---|---|
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #ifndef CEPH_CLS_LOCK_TYPES_H | |
5 | #define CEPH_CLS_LOCK_TYPES_H | |
6 | ||
7 | #include "include/encoding.h" | |
8 | #include "include/types.h" | |
9 | #include "include/utime.h" | |
10 | #include "msg/msg_types.h" | |
11 | ||
12 | /* lock flags */ | |
13 | #define LOCK_FLAG_MAY_RENEW 0x1 /* idempotent lock acquire */ | |
14 | #define LOCK_FLAG_MUST_RENEW 0x2 /* lock must already be acquired */ | |
15 | ||
16 | enum class ClsLockType { | |
17 | NONE = 0, | |
18 | EXCLUSIVE = 1, | |
19 | SHARED = 2, | |
20 | EXCLUSIVE_EPHEMERAL = 3, /* lock object is removed @ unlock */ | |
21 | }; | |
22 | ||
23 | inline const char *cls_lock_type_str(ClsLockType type) | |
24 | { | |
25 | switch (type) { | |
26 | case ClsLockType::NONE: | |
27 | return "none"; | |
28 | case ClsLockType::EXCLUSIVE: | |
29 | return "exclusive"; | |
30 | case ClsLockType::SHARED: | |
31 | return "shared"; | |
32 | case ClsLockType::EXCLUSIVE_EPHEMERAL: | |
33 | return "exclusive-ephemeral"; | |
34 | default: | |
35 | return "<unknown>"; | |
36 | } | |
37 | } | |
38 | ||
39 | inline bool cls_lock_is_exclusive(ClsLockType type) { | |
40 | return ClsLockType::EXCLUSIVE == type || ClsLockType::EXCLUSIVE_EPHEMERAL == type; | |
41 | } | |
42 | ||
43 | inline bool cls_lock_is_ephemeral(ClsLockType type) { | |
44 | return ClsLockType::EXCLUSIVE_EPHEMERAL == type; | |
45 | } | |
46 | ||
47 | inline bool cls_lock_is_valid(ClsLockType type) { | |
48 | return ClsLockType::SHARED == type || | |
49 | ClsLockType::EXCLUSIVE == type || | |
50 | ClsLockType::EXCLUSIVE_EPHEMERAL == type; | |
51 | } | |
52 | ||
53 | namespace rados { | |
54 | namespace cls { | |
55 | namespace lock { | |
56 | ||
57 | /* | |
58 | * locker_id_t: the locker id, needs to be unique in a single lock | |
59 | */ | |
60 | struct locker_id_t { | |
61 | entity_name_t locker; // locker's client name | |
62 | std::string cookie; // locker's cookie. | |
63 | ||
64 | locker_id_t() {} | |
65 | locker_id_t(entity_name_t& _n, const std::string& _c) : locker(_n), cookie(_c) {} | |
66 | ||
67 | void encode(ceph::buffer::list &bl) const { | |
68 | ENCODE_START(1, 1, bl); | |
69 | encode(locker, bl); | |
70 | encode(cookie, bl); | |
71 | ENCODE_FINISH(bl); | |
72 | } | |
73 | void decode(ceph::buffer::list::const_iterator &bl) { | |
74 | DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); | |
75 | decode(locker, bl); | |
76 | decode(cookie, bl); | |
77 | DECODE_FINISH(bl); | |
78 | } | |
79 | ||
80 | bool operator<(const locker_id_t& rhs) const { | |
81 | if (locker == rhs.locker) | |
82 | return cookie.compare(rhs.cookie) < 0; | |
83 | if (locker < rhs.locker) | |
84 | return true; | |
85 | return false; | |
86 | } | |
87 | void dump(ceph::Formatter *f) const; | |
88 | friend std::ostream& operator<<(std::ostream& out, | |
89 | const locker_id_t& data) { | |
90 | out << data.locker; | |
91 | return out; | |
92 | } | |
93 | static void generate_test_instances(std::list<locker_id_t*>& o); | |
94 | }; | |
95 | WRITE_CLASS_ENCODER(locker_id_t) | |
96 | ||
97 | struct locker_info_t | |
98 | { | |
99 | utime_t expiration; // expiration: non-zero means epoch of locker expiration | |
100 | entity_addr_t addr; // addr: locker address | |
101 | std::string description; // description: locker description, may be empty | |
102 | ||
103 | locker_info_t() {} | |
104 | locker_info_t(const utime_t& _e, const entity_addr_t& _a, | |
105 | const std::string& _d) : expiration(_e), addr(_a), description(_d) {} | |
106 | ||
107 | void encode(ceph::buffer::list &bl, uint64_t features) const { | |
108 | ENCODE_START(1, 1, bl); | |
109 | encode(expiration, bl); | |
110 | encode(addr, bl, features); | |
111 | encode(description, bl); | |
112 | ENCODE_FINISH(bl); | |
113 | } | |
114 | void decode(ceph::buffer::list::const_iterator &bl) { | |
115 | DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); | |
116 | decode(expiration, bl); | |
117 | decode(addr, bl); | |
118 | decode(description, bl); | |
119 | DECODE_FINISH(bl); | |
120 | } | |
121 | void dump(ceph::Formatter *f) const; | |
122 | friend std::ostream& operator<<(std::ostream& out, | |
123 | const locker_info_t& data) { | |
124 | using ceph::operator <<; | |
125 | out << "{addr:" << data.addr << ", exp:"; | |
126 | ||
127 | const auto& exp = data.expiration; | |
128 | if (exp.is_zero()) { | |
129 | out << "never}"; | |
130 | } else { | |
131 | out << exp.to_real_time() << "}"; | |
132 | } | |
133 | ||
134 | return out; | |
135 | } | |
136 | static void generate_test_instances(std::list<locker_info_t *>& o); | |
137 | }; | |
138 | WRITE_CLASS_ENCODER_FEATURES(locker_info_t) | |
139 | ||
140 | struct lock_info_t { | |
141 | std::map<locker_id_t, locker_info_t> lockers; // map of lockers | |
142 | ClsLockType lock_type; // lock type (exclusive / shared) | |
143 | std::string tag; // tag: operations on lock can only succeed with this tag | |
144 | // as long as set of non expired lockers | |
145 | // is bigger than 0. | |
146 | ||
147 | void encode(ceph::buffer::list &bl, uint64_t features) const { | |
148 | ENCODE_START(1, 1, bl); | |
149 | encode(lockers, bl, features); | |
150 | uint8_t t = (uint8_t)lock_type; | |
151 | encode(t, bl); | |
152 | encode(tag, bl); | |
153 | ENCODE_FINISH(bl); | |
154 | } | |
155 | void decode(ceph::buffer::list::const_iterator &bl) { | |
156 | DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); | |
157 | decode(lockers, bl); | |
158 | uint8_t t; | |
159 | decode(t, bl); | |
160 | lock_type = (ClsLockType)t; | |
161 | decode(tag, bl); | |
162 | DECODE_FINISH(bl); | |
163 | } | |
164 | ||
165 | lock_info_t() : lock_type(ClsLockType::NONE) {} | |
166 | void dump(ceph::Formatter *f) const; | |
167 | static void generate_test_instances(std::list<lock_info_t *>& o); | |
168 | }; | |
169 | WRITE_CLASS_ENCODER_FEATURES(lock_info_t); | |
170 | } | |
171 | } | |
172 | } | |
173 | ||
174 | #endif |