]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Ceph - scalable distributed file system | |
3 | * | |
4 | * This is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License version 2.1, as published by the Free Software | |
7 | * Foundation. See file COPYING. | |
8 | * | |
9 | * Copyright Inktank 2013 | |
10 | */ | |
11 | ||
12 | #include "objclass/objclass.h" | |
7c673cae FG |
13 | |
14 | #include "cls_replica_log_types.h" | |
15 | #include "cls_replica_log_ops.h" | |
16 | ||
17 | CLS_VER(1, 0) | |
18 | CLS_NAME(replica_log) | |
19 | ||
20 | static const string replica_log_prefix = "rl_"; | |
21 | static const string replica_log_bounds = replica_log_prefix + "bounds"; | |
22 | ||
23 | static int get_bounds(cls_method_context_t hctx, cls_replica_log_bound& bound) | |
24 | { | |
25 | bufferlist bounds_bl; | |
26 | int rc = cls_cxx_map_get_val(hctx, replica_log_bounds, &bounds_bl); | |
27 | if (rc < 0) { | |
28 | return rc; | |
29 | } | |
30 | ||
31 | try { | |
32 | bufferlist::iterator bounds_bl_i = bounds_bl.begin(); | |
33 | ::decode(bound, bounds_bl_i); | |
34 | } catch (buffer::error& err) { | |
35 | bound = cls_replica_log_bound(); | |
36 | CLS_LOG(0, "ERROR: get_bounds(): failed to decode on-disk bounds object"); | |
37 | return -EIO; | |
38 | } | |
39 | ||
40 | return 0; | |
41 | } | |
42 | ||
43 | static int write_bounds(cls_method_context_t hctx, | |
44 | const cls_replica_log_bound& bound) | |
45 | { | |
46 | bufferlist bounds_bl; | |
47 | ::encode(bound, bounds_bl); | |
48 | return cls_cxx_map_set_val(hctx, replica_log_bounds, &bounds_bl); | |
49 | } | |
50 | ||
51 | static int cls_replica_log_set(cls_method_context_t hctx, | |
52 | bufferlist *in, bufferlist *out) | |
53 | { | |
54 | bufferlist::iterator in_iter = in->begin(); | |
55 | ||
56 | cls_replica_log_set_marker_op op; | |
57 | try { | |
58 | ::decode(op, in_iter); | |
59 | } catch (buffer::error& err) { | |
60 | CLS_LOG(0, "ERROR: cls_replica_log_set(): failed to decode op"); | |
61 | return -EINVAL; | |
62 | } | |
63 | ||
64 | cls_replica_log_bound bound; | |
65 | int rc = get_bounds(hctx, bound); | |
66 | if (rc < 0 && rc != -ENOENT) { | |
67 | return rc; | |
68 | } | |
69 | ||
70 | rc = bound.update_marker(op.marker); | |
71 | if (rc < 0) { | |
72 | return rc; | |
73 | } | |
74 | ||
75 | return write_bounds(hctx, bound); | |
76 | } | |
77 | ||
78 | static int cls_replica_log_delete(cls_method_context_t hctx, | |
79 | bufferlist *in, bufferlist *out) | |
80 | { | |
81 | bufferlist::iterator in_iter = in->begin(); | |
82 | ||
83 | cls_replica_log_delete_marker_op op; | |
84 | try { | |
85 | ::decode(op, in_iter); | |
86 | } catch (buffer::error& err) { | |
87 | CLS_LOG(0, "ERROR: cls_replica_log_delete(): failed to decode op"); | |
88 | return -EINVAL; | |
89 | } | |
90 | ||
91 | cls_replica_log_bound bound; | |
92 | int rc = get_bounds(hctx, bound); | |
93 | if (rc < 0 && rc != -ENOENT) { | |
94 | return rc; | |
95 | } | |
96 | ||
97 | rc = bound.delete_marker(op.entity_id); | |
98 | if (rc < 0) { | |
99 | return rc; | |
100 | } | |
101 | ||
102 | return write_bounds(hctx, bound); | |
103 | } | |
104 | ||
105 | static int cls_replica_log_get(cls_method_context_t hctx, | |
106 | bufferlist *in, bufferlist *out) | |
107 | { | |
108 | bufferlist::iterator in_iter = in->begin(); | |
109 | ||
110 | cls_replica_log_get_bounds_op op; | |
111 | try { | |
112 | ::decode(op, in_iter); | |
113 | } catch (buffer::error& err) { | |
114 | CLS_LOG(0, "ERROR: cls_replica_log_get(): failed to decode op"); | |
115 | return -EINVAL; | |
116 | } | |
117 | ||
118 | cls_replica_log_bound bound; | |
119 | int rc = get_bounds(hctx, bound); | |
120 | if (rc < 0) { | |
121 | return rc; | |
122 | } | |
123 | ||
124 | cls_replica_log_get_bounds_ret ret; | |
125 | ret.oldest_time = bound.get_oldest_time(); | |
126 | ret.position_marker = bound.get_lowest_marker_bound(); | |
127 | bound.get_markers(ret.markers); | |
128 | ||
129 | ::encode(ret, *out); | |
130 | return 0; | |
131 | } | |
132 | ||
133 | CLS_INIT(replica_log) | |
134 | { | |
135 | CLS_LOG(1, "Loaded replica log class!"); | |
136 | ||
137 | cls_handle_t h_class; | |
138 | cls_method_handle_t h_replica_log_set; | |
139 | cls_method_handle_t h_replica_log_delete; | |
140 | cls_method_handle_t h_replica_log_get; | |
141 | ||
142 | cls_register("replica_log", &h_class); | |
143 | ||
144 | cls_register_cxx_method(h_class, "set", CLS_METHOD_RD | CLS_METHOD_WR, | |
145 | cls_replica_log_set, &h_replica_log_set); | |
146 | cls_register_cxx_method(h_class, "get", CLS_METHOD_RD, | |
147 | cls_replica_log_get, &h_replica_log_get); | |
148 | cls_register_cxx_method(h_class, "delete", CLS_METHOD_RD | CLS_METHOD_WR, | |
149 | cls_replica_log_delete, &h_replica_log_delete); | |
150 | } |