Bug Summary

File:xlators/cluster/dht/src/dht-selfheal.c
Location:line 441, column 17
Description:Access to field 'name' results in a dereference of a null pointer (loaded from variable 'this')

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11#ifndef _CONFIG_H
12#define _CONFIG_H
13#include "config.h"
14#endif
15
16
17#include "glusterfs.h"
18#include "xlator.h"
19#include "dht-common.h"
20
21#define DHT_SET_LAYOUT_RANGE(layout,i,srt,chunk,cnt,path)do { layout->list[i].start = srt; layout->list[i].stop =
srt + chunk - 1; do { do { if (0) printf ("gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 21, GF_LOG_TRACE, "gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0); } while (0)
do { \
22 layout->list[i].start = srt; \
23 layout->list[i].stop = srt + chunk - 1; \
24 \
25 gf_log (this->name, GF_LOG_TRACE, \do { do { if (0) printf ("gave fix: %u - %u on %s for %s", layout
->list[i].start, layout->list[i].stop, layout->list[
i].xlator->name, path); } while (0); _gf_log (this->name
, "dht-selfheal.c", __FUNCTION__, 28, GF_LOG_TRACE, "gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0)
26 "gave fix: %u - %u on %s for %s", \do { do { if (0) printf ("gave fix: %u - %u on %s for %s", layout
->list[i].start, layout->list[i].stop, layout->list[
i].xlator->name, path); } while (0); _gf_log (this->name
, "dht-selfheal.c", __FUNCTION__, 28, GF_LOG_TRACE, "gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0)
27 layout->list[i].start, layout->list[i].stop, \do { do { if (0) printf ("gave fix: %u - %u on %s for %s", layout
->list[i].start, layout->list[i].stop, layout->list[
i].xlator->name, path); } while (0); _gf_log (this->name
, "dht-selfheal.c", __FUNCTION__, 28, GF_LOG_TRACE, "gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0)
28 layout->list[i].xlator->name, path)do { do { if (0) printf ("gave fix: %u - %u on %s for %s", layout
->list[i].start, layout->list[i].stop, layout->list[
i].xlator->name, path); } while (0); _gf_log (this->name
, "dht-selfheal.c", __FUNCTION__, 28, GF_LOG_TRACE, "gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, path); } while (0)
; \
29 } while (0)
30
31#define DHT_RESET_LAYOUT_RANGE(layout)do { int cnt = 0; for (cnt = 0; cnt < layout->cnt; cnt++
) { layout->list[cnt].start = 0; layout->list[cnt].stop
= 0; } } while (0)
do { \
32 int cnt = 0; \
33 for (cnt = 0; cnt < layout->cnt; cnt++ ) { \
34 layout->list[cnt].start = 0; \
35 layout->list[cnt].stop = 0; \
36 } \
37 } while (0)
38
39static uint32_t
40dht_overlap_calc (dht_layout_t *old, int o, dht_layout_t *new, int n)
41{
42 if (o >= old->cnt || n >= new->cnt)
43 return 0;
44
45 if (old->list[o].err > 0 || new->list[n].err > 0)
46 return 0;
47
48 if (old->list[o].start == old->list[o].stop) {
49 return 0;
50 }
51
52 if (new->list[n].start == new->list[n].stop) {
53 return 0;
54 }
55
56 if ((old->list[o].start > new->list[n].stop) ||
57 (old->list[o].stop < new->list[n].start))
58 return 0;
59
60 return min (old->list[o].stop, new->list[n].stop)((old->list[o].stop)<(new->list[n].stop)?(old->list
[o].stop):(new->list[n].stop))
-
61 max (old->list[o].start, new->list[n].start)((old->list[o].start)>(new->list[n].start)?(old->
list[o].start):(new->list[n].start))
+ 1;
62}
63
64
65int
66dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
67{
68 dht_local_t *local = NULL((void*)0);
69
70 local = frame->local;
71 local->selfheal.dir_cbk (frame, NULL((void*)0), frame->this, ret,
72 local->op_errno, NULL((void*)0));
73
74 return 0;
75}
76
77
78int
79dht_selfheal_dir_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
80 int op_ret, int op_errno, dict_t *xdata)
81{
82 dht_local_t *local = NULL((void*)0);
83 call_frame_t *prev = NULL((void*)0);
84 xlator_t *subvol = NULL((void*)0);
85 int i = 0;
86 dht_layout_t *layout = NULL((void*)0);
87 int err = 0;
88 int this_call_cnt = 0;
89
90 local = frame->local;
91 layout = local->selfheal.layout;
92 prev = cookie;
93 subvol = prev->this;
94
95 if (op_ret == 0)
96 err = 0;
97 else
98 err = op_errno;
99
100 for (i = 0; i < layout->cnt; i++) {
101 if (layout->list[i].xlator == subvol) {
102 layout->list[i].err = err;
103 break;
104 }
105 }
106
107 this_call_cnt = dht_frame_return (frame);
108
109 if (is_last_call (this_call_cnt)(this_call_cnt == 0)) {
110 dht_selfheal_dir_finish (frame, this, 0);
111 }
112
113 return 0;
114}
115
116
117int
118dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
119 dht_layout_t *layout, int i,
120 xlator_t *req_subvol)
121{
122 xlator_t *subvol = NULL((void*)0);
123 dict_t *xattr = NULL((void*)0);
124 int ret = 0;
125 xlator_t *this = NULL((void*)0);
126 int32_t *disk_layout = NULL((void*)0);
127 dht_local_t *local = NULL((void*)0);
128 dht_conf_t *conf = NULL((void*)0);
129
130 local = frame->local;
131 if (req_subvol)
132 subvol = req_subvol;
133 else
134 subvol = layout->list[i].xlator;
135 this = frame->this;
136
137 GF_VALIDATE_OR_GOTO ("", this, err)do { if (!this) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn
("", "dht-selfheal.c", __FUNCTION__, 137, GF_LOG_ERROR, "invalid argument: "
"this"); } while (0); goto err; } } while (0)
;
138 GF_VALIDATE_OR_GOTO (this->name, layout, err)do { if (!layout) { (*__errno_location ()) = 22; do { do { if
(0) printf ("invalid argument: " "layout"); } while (0); _gf_log_callingfn
(this->name, "dht-selfheal.c", __FUNCTION__, 138, GF_LOG_ERROR
, "invalid argument: " "layout"); } while (0); goto err; } } while
(0)
;
139 GF_VALIDATE_OR_GOTO (this->name, local, err)do { if (!local) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "local"); } while (0); _gf_log_callingfn
(this->name, "dht-selfheal.c", __FUNCTION__, 139, GF_LOG_ERROR
, "invalid argument: " "local"); } while (0); goto err; } } while
(0)
;
140 GF_VALIDATE_OR_GOTO (this->name, subvol, err)do { if (!subvol) { (*__errno_location ()) = 22; do { do { if
(0) printf ("invalid argument: " "subvol"); } while (0); _gf_log_callingfn
(this->name, "dht-selfheal.c", __FUNCTION__, 140, GF_LOG_ERROR
, "invalid argument: " "subvol"); } while (0); goto err; } } while
(0)
;
141 VALIDATE_OR_GOTO (this->private, err)do { if (!this->private) { (*__errno_location ()) = 22; do
{ do { if (0) printf ("invalid argument: " "this->private"
); } while (0); _gf_log_callingfn ((this ? (this->name) : "(Govinda! Govinda!)"
), "dht-selfheal.c", __FUNCTION__, 141, GF_LOG_WARNING, "invalid argument: "
"this->private"); } while (0); goto err; } } while (0)
;
142
143 conf = this->private;
144
145 xattr = get_new_dict ();
146 if (!xattr) {
147 goto err;
148 }
149
150 ret = dht_disk_layout_extract (this, layout, i, &disk_layout);
151 if (ret == -1) {
152 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 154, GF_LOG_WARNING, "%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0)
153 "%s: (subvol %s) failed to extract disk layout",do { do { if (0) printf ("%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 154, GF_LOG_WARNING, "%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0)
154 loc->path, subvol->name)do { do { if (0) printf ("%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 154, GF_LOG_WARNING, "%s: (subvol %s) failed to extract disk layout"
, loc->path, subvol->name); } while (0)
;
155 goto err;
156 }
157
158 ret = dict_set_bin (xattr, conf->xattr_name, disk_layout, 4 * 4);
159 if (ret == -1) {
160 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 162, GF_LOG_WARNING, "%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0)
161 "%s: (subvol %s) failed to set xattr dictionary",do { do { if (0) printf ("%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 162, GF_LOG_WARNING, "%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0)
162 loc->path, subvol->name)do { do { if (0) printf ("%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 162, GF_LOG_WARNING, "%s: (subvol %s) failed to set xattr dictionary"
, loc->path, subvol->name); } while (0)
;
163 goto err;
164 }
165 disk_layout = NULL((void*)0);
166
167 gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0); _gf_log (this
->name, "dht-selfheal.c", __FUNCTION__, 170, GF_LOG_TRACE,
"setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0)
168 "setting hash range %u - %u (type %d) on subvolume %s for %s",do { do { if (0) printf ("setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0); _gf_log (this
->name, "dht-selfheal.c", __FUNCTION__, 170, GF_LOG_TRACE,
"setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0)
169 layout->list[i].start, layout->list[i].stop,do { do { if (0) printf ("setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0); _gf_log (this
->name, "dht-selfheal.c", __FUNCTION__, 170, GF_LOG_TRACE,
"setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0)
170 layout->type, subvol->name, loc->path)do { do { if (0) printf ("setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0); _gf_log (this
->name, "dht-selfheal.c", __FUNCTION__, 170, GF_LOG_TRACE,
"setting hash range %u - %u (type %d) on subvolume %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
type, subvol->name, loc->path); } while (0)
;
171
172 dict_ref (xattr);
173
174 if (!uuid_is_null (local->gfid))
175 uuid_copy (loc->gfid, local->gfid);
176
177 STACK_WIND (frame, dht_selfheal_dir_xattr_cbk,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 179, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( subvol->fops
->setxattr_cbk) tmp_cbk = dht_selfheal_dir_xattr_cbk; _new
->root = frame->root; _new->this = subvol; _new->
ret = (ret_fn_t) tmp_cbk; _new->parent = frame; _new->cookie
= _new; _new->wind_from = __FUNCTION__; _new->wind_to =
"subvol->fops->setxattr"; _new->unwind_to = "dht_selfheal_dir_xattr_cbk"
; pthread_spin_init (&_new->lock, 0); pthread_spin_lock
(&frame->root->stack_lock); { _new->next = frame
->root->frames.next; _new->prev = &frame->root
->frames; if (frame->root->frames.next) frame->root
->frames.next->prev = _new; frame->root->frames.next
= _new; frame->ref_count++; } pthread_spin_unlock (&frame
->root->stack_lock); old_THIS = (*__glusterfs_this_location
()); (*__glusterfs_this_location()) = subvol; if (frame->this
->ctx->measure_latency) gf_latency_begin (_new, subvol->
fops->setxattr); subvol->fops->setxattr (_new, subvol
, loc, xattr, 0, ((void*)0)); (*__glusterfs_this_location()) =
old_THIS; } while (0)
178 subvol, subvol->fops->setxattr,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 179, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( subvol->fops
->setxattr_cbk) tmp_cbk = dht_selfheal_dir_xattr_cbk; _new
->root = frame->root; _new->this = subvol; _new->
ret = (ret_fn_t) tmp_cbk; _new->parent = frame; _new->cookie
= _new; _new->wind_from = __FUNCTION__; _new->wind_to =
"subvol->fops->setxattr"; _new->unwind_to = "dht_selfheal_dir_xattr_cbk"
; pthread_spin_init (&_new->lock, 0); pthread_spin_lock
(&frame->root->stack_lock); { _new->next = frame
->root->frames.next; _new->prev = &frame->root
->frames; if (frame->root->frames.next) frame->root
->frames.next->prev = _new; frame->root->frames.next
= _new; frame->ref_count++; } pthread_spin_unlock (&frame
->root->stack_lock); old_THIS = (*__glusterfs_this_location
()); (*__glusterfs_this_location()) = subvol; if (frame->this
->ctx->measure_latency) gf_latency_begin (_new, subvol->
fops->setxattr); subvol->fops->setxattr (_new, subvol
, loc, xattr, 0, ((void*)0)); (*__glusterfs_this_location()) =
old_THIS; } while (0)
179 loc, xattr, 0, NULL)do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 179, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( subvol->fops
->setxattr_cbk) tmp_cbk = dht_selfheal_dir_xattr_cbk; _new
->root = frame->root; _new->this = subvol; _new->
ret = (ret_fn_t) tmp_cbk; _new->parent = frame; _new->cookie
= _new; _new->wind_from = __FUNCTION__; _new->wind_to =
"subvol->fops->setxattr"; _new->unwind_to = "dht_selfheal_dir_xattr_cbk"
; pthread_spin_init (&_new->lock, 0); pthread_spin_lock
(&frame->root->stack_lock); { _new->next = frame
->root->frames.next; _new->prev = &frame->root
->frames; if (frame->root->frames.next) frame->root
->frames.next->prev = _new; frame->root->frames.next
= _new; frame->ref_count++; } pthread_spin_unlock (&frame
->root->stack_lock); old_THIS = (*__glusterfs_this_location
()); (*__glusterfs_this_location()) = subvol; if (frame->this
->ctx->measure_latency) gf_latency_begin (_new, subvol->
fops->setxattr); subvol->fops->setxattr (_new, subvol
, loc, xattr, 0, ((void*)0)); (*__glusterfs_this_location()) =
old_THIS; } while (0)
;
180
181 dict_unref (xattr);
182
183 return 0;
184
185err:
186 if (xattr)
187 dict_destroy (xattr);
188
189 GF_FREE (disk_layout)__gf_free (disk_layout);
190
191 dht_selfheal_dir_xattr_cbk (frame, subvol, frame->this,
192 -1, ENOMEM12, NULL((void*)0));
193 return 0;
194}
195
196int
197dht_fix_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
198{
199 dht_local_t *local = NULL((void*)0);
200 int i = 0;
201 int count = 0;
202 xlator_t *this = NULL((void*)0);
203 dht_conf_t *conf = NULL((void*)0);
204 dht_layout_t *dummy = NULL((void*)0);
205
206 local = frame->local;
207 this = frame->this;
208 conf = this->private;
209
210 gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("writing the new range for all subvolumes"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 211, GF_LOG_DEBUG, "writing the new range for all subvolumes"
); } while (0)
211 "writing the new range for all subvolumes")do { do { if (0) printf ("writing the new range for all subvolumes"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 211, GF_LOG_DEBUG, "writing the new range for all subvolumes"
); } while (0)
;
212
213 local->call_cnt = count = conf->subvolume_cnt;
214
215 for (i = 0; i < layout->cnt; i++) {
216 dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL((void*)0));
217
218 if (--count == 0)
219 goto out;
220 }
221 /* if we are here, subvolcount > layout_count. subvols-per-directory
222 * option might be set here. We need to clear out layout from the
223 * non-participating subvolumes, else it will result in overlaps */
224 dummy = dht_layout_new (this, 1);
225 if (!dummy)
226 goto out;
227 for (i = 0; i < conf->subvolume_cnt; i++) {
228 if (_gf_false ==
229 dht_is_subvol_in_layout (layout, conf->subvolumes[i])) {
230 dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
231 conf->subvolumes[i]);
232 if (--count == 0)
233 break;
234 }
235 }
236
237 dht_layout_unref (this, dummy);
238out:
239 return 0;
240}
241
242int
243dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
244{
245 dht_local_t *local = NULL((void*)0);
246 int missing_xattr = 0;
247 int i = 0;
248 xlator_t *this = NULL((void*)0);
249 dht_conf_t *conf = NULL((void*)0);
250 dht_layout_t *dummy = NULL((void*)0);
251
252 local = frame->local;
253 this = frame->this;
254 conf = this->private;
255
256 for (i = 0; i < layout->cnt; i++) {
257 if (layout->list[i].err != -1 || !layout->list[i].stop) {
258 /* err != -1 would mean xattr present on the directory
259 * or the directory is non existent.
260 * !layout->list[i].stop would mean layout absent
261 */
262
263 continue;
264 }
265 missing_xattr++;
266 }
267
268 gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 270, GF_LOG_TRACE, "%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0)
269 "%d subvolumes missing xattr for %s",do { do { if (0) printf ("%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 270, GF_LOG_TRACE, "%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0)
270 missing_xattr, loc->path)do { do { if (0) printf ("%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0); _gf_log (this->
name, "dht-selfheal.c", __FUNCTION__, 270, GF_LOG_TRACE, "%d subvolumes missing xattr for %s"
, missing_xattr, loc->path); } while (0)
;
271
272 if (missing_xattr == 0) {
273 dht_selfheal_dir_finish (frame, this, 0);
274 return 0;
275 }
276
277 local->call_cnt = missing_xattr;
278
279 for (i = 0; i < layout->cnt; i++) {
280 if (layout->list[i].err != -1 || !layout->list[i].stop)
281 continue;
282
283 dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i, NULL((void*)0));
284
285 if (--missing_xattr == 0)
286 break;
287 }
288 dummy = dht_layout_new (this, 1);
289 if (!dummy)
290 goto out;
291 for (i = 0; i < conf->subvolume_cnt; i++) {
292 if (_gf_false ==
293 dht_is_subvol_in_layout (layout, conf->subvolumes[i])) {
294 dht_selfheal_dir_xattr_persubvol (frame, loc, dummy, 0,
295 conf->subvolumes[i]);
296 }
297 }
298 dht_layout_unref (this, dummy);
299out:
300 return 0;
301}
302
303int
304dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
305 int op_ret, int op_errno, struct iatt *statpre,
306 struct iatt *statpost, dict_t *xdata)
307{
308 dht_local_t *local = NULL((void*)0);
309 dht_layout_t *layout = NULL((void*)0);
310 int this_call_cnt = 0;
311
312 local = frame->local;
313 layout = local->selfheal.layout;
314
315 this_call_cnt = dht_frame_return (frame);
316
317 if (is_last_call (this_call_cnt)(this_call_cnt == 0)) {
318 dht_selfheal_dir_xattr (frame, &local->loc, layout);
319 }
320
321 return 0;
322}
323
324
325int
326dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
327 int32_t valid, dht_layout_t *layout)
328{
329 int missing_attr = 0;
330 int i = 0;
331 dht_local_t *local = NULL((void*)0);
332 xlator_t *this = NULL((void*)0);
333
334 local = frame->local;
335 this = frame->this;
336
337 for (i = 0; i < layout->cnt; i++) {
338 if (layout->list[i].err == -1)
339 missing_attr++;
340 }
341
342 if (missing_attr == 0) {
343 dht_selfheal_dir_xattr (frame, loc, layout);
344 return 0;
345 }
346
347 if (!uuid_is_null (local->gfid))
348 uuid_copy (loc->gfid, local->gfid);
349
350 local->call_cnt = missing_attr;
351 for (i = 0; i < layout->cnt; i++) {
352 if (layout->list[i].err == -1) {
353 gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("setattr for %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 355, GF_LOG_TRACE
, "setattr for %s on subvol %s", loc->path, layout->list
[i].xlator->name); } while (0)
354 "setattr for %s on subvol %s",do { do { if (0) printf ("setattr for %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 355, GF_LOG_TRACE
, "setattr for %s on subvol %s", loc->path, layout->list
[i].xlator->name); } while (0)
355 loc->path, layout->list[i].xlator->name)do { do { if (0) printf ("setattr for %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 355, GF_LOG_TRACE
, "setattr for %s on subvol %s", loc->path, layout->list
[i].xlator->name); } while (0)
;
356
357 STACK_WIND (frame, dht_selfheal_dir_setattr_cbk,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 360, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->setattr_cbk) tmp_cbk = dht_selfheal_dir_setattr_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->setattr"
; _new->unwind_to = "dht_selfheal_dir_setattr_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->setattr); layout->list[i].xlator->fops->
setattr (_new, layout->list[i].xlator, loc, stbuf, valid, (
(void*)0)); (*__glusterfs_this_location()) = old_THIS; } while
(0)
358 layout->list[i].xlator,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 360, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->setattr_cbk) tmp_cbk = dht_selfheal_dir_setattr_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->setattr"
; _new->unwind_to = "dht_selfheal_dir_setattr_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->setattr); layout->list[i].xlator->fops->
setattr (_new, layout->list[i].xlator, loc, stbuf, valid, (
(void*)0)); (*__glusterfs_this_location()) = old_THIS; } while
(0)
359 layout->list[i].xlator->fops->setattr,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 360, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->setattr_cbk) tmp_cbk = dht_selfheal_dir_setattr_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->setattr"
; _new->unwind_to = "dht_selfheal_dir_setattr_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->setattr); layout->list[i].xlator->fops->
setattr (_new, layout->list[i].xlator, loc, stbuf, valid, (
(void*)0)); (*__glusterfs_this_location()) = old_THIS; } while
(0)
360 loc, stbuf, valid, NULL)do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 360, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->setattr_cbk) tmp_cbk = dht_selfheal_dir_setattr_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->setattr"
; _new->unwind_to = "dht_selfheal_dir_setattr_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->setattr); layout->list[i].xlator->fops->
setattr (_new, layout->list[i].xlator, loc, stbuf, valid, (
(void*)0)); (*__glusterfs_this_location()) = old_THIS; } while
(0)
;
361 }
362 }
363
364 return 0;
365}
366
367int
368dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
369 int op_ret, int op_errno,
370 inode_t *inode, struct iatt *stbuf,
371 struct iatt *preparent, struct iatt *postparent,
372 dict_t *xdata)
373{
374 dht_local_t *local = NULL((void*)0);
375 dht_layout_t *layout = NULL((void*)0);
376 call_frame_t *prev = NULL((void*)0);
377 xlator_t *subvol = NULL((void*)0);
378 int i = 0;
379 int this_call_cnt = 0;
380
381
382 local = frame->local;
383 layout = local->selfheal.layout;
384 prev = cookie;
385 subvol = prev->this;
386
387 if ((op_ret == 0) || ((op_ret == -1) && (op_errno == EEXIST17))) {
388 for (i = 0; i < layout->cnt; i++) {
389 if (layout->list[i].xlator == subvol) {
390 layout->list[i].err = -1;
391 break;
392 }
393 }
394 }
395
396 if (op_ret) {
397 gf_log (this->name, ((op_errno == EEXIST) ? GF_LOG_DEBUG :do { do { if (0) printf ("selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 400, ((op_errno
== 17) ? GF_LOG_DEBUG : GF_LOG_WARNING), "selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0)
398 GF_LOG_WARNING),do { do { if (0) printf ("selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 400, ((op_errno
== 17) ? GF_LOG_DEBUG : GF_LOG_WARNING), "selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0)
399 "selfhealing directory %s failed: %s",do { do { if (0) printf ("selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 400, ((op_errno
== 17) ? GF_LOG_DEBUG : GF_LOG_WARNING), "selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0)
400 local->loc.path, strerror (op_errno))do { do { if (0) printf ("selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0); _gf_log
(this->name, "dht-selfheal.c", __FUNCTION__, 400, ((op_errno
== 17) ? GF_LOG_DEBUG : GF_LOG_WARNING), "selfhealing directory %s failed: %s"
, local->loc.path, strerror (op_errno)); } while (0)
;
401 goto out;
402 }
403
404 dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
405 dht_iatt_merge (this, &local->preparent, preparent, prev->this);
406 dht_iatt_merge (this, &local->postparent, postparent, prev->this);
407
408out:
409 this_call_cnt = dht_frame_return (frame);
410
411 if (is_last_call (this_call_cnt)(this_call_cnt == 0)) {
412 dht_selfheal_dir_setattr (frame, &local->loc, &local->stbuf, 0xffffff, layout);
413 }
414
415 return 0;
416}
417
418void
419dht_selfheal_dir_mkdir_setacl (dict_t *xattr, dict_t *dict)
420{
421 data_t *acl_default = NULL((void*)0);
422 data_t *acl_access = NULL((void*)0);
423 xlator_t *this = NULL((void*)0);
424 int ret = -1;
425
426 GF_ASSERT (xattr)do { if (!(xattr)) { do { do { if (0) printf ("Assertion failed: "
"xattr"); } while (0); _gf_log_callingfn ("", "dht-selfheal.c"
, __FUNCTION__, 426, GF_LOG_ERROR, "Assertion failed: " "xattr"
); } while (0); } } while (0)
;
427 GF_ASSERT (dict)do { if (!(dict)) { do { do { if (0) printf ("Assertion failed: "
"dict"); } while (0); _gf_log_callingfn ("", "dht-selfheal.c"
, __FUNCTION__, 427, GF_LOG_ERROR, "Assertion failed: " "dict"
); } while (0); } } while (0)
;
428
429 this = THIS(*__glusterfs_this_location());
1
Value assigned to 'this'
430 GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: "
"this"); } while (0); _gf_log_callingfn ("", "dht-selfheal.c"
, __FUNCTION__, 430, GF_LOG_ERROR, "Assertion failed: " "this"
); } while (0); } } while (0)
;
2
Within the expansion of the macro 'GF_ASSERT':
a
Assuming 'this' is null
431
432 acl_default = dict_get (xattr, POSIX_ACL_DEFAULT_XATTR"system.posix_acl_default");
433
434 if (!acl_default) {
3
Assuming 'acl_default' is non-null
4
Taking false branch
435 gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("ACL_DEFAULT xattr not present"); } while
(0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__,
436, GF_LOG_DEBUG, "ACL_DEFAULT xattr not present"); } while
(0)
436 "ACL_DEFAULT xattr not present")do { do { if (0) printf ("ACL_DEFAULT xattr not present"); } while
(0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__,
436, GF_LOG_DEBUG, "ACL_DEFAULT xattr not present"); } while
(0)
;
437 goto cont;
438 }
439 ret = dict_set (dict, POSIX_ACL_DEFAULT_XATTR"system.posix_acl_default", acl_default);
440 if (ret)
5
Assuming 'ret' is not equal to 0
6
Taking true branch
441 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("Could not set ACL_DEFAULT xattr"); }
while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 442, GF_LOG_WARNING, "Could not set ACL_DEFAULT xattr"); } while
(0)
7
Within the expansion of the macro 'gf_log':
a
Access to field 'name' results in a dereference of a null pointer (loaded from variable 'this')
442 "Could not set ACL_DEFAULT xattr")do { do { if (0) printf ("Could not set ACL_DEFAULT xattr"); }
while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 442, GF_LOG_WARNING, "Could not set ACL_DEFAULT xattr"); } while
(0)
;
443cont:
444 acl_access = dict_get (xattr, POSIX_ACL_ACCESS_XATTR"system.posix_acl_access");
445 if (!acl_access) {
446 gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("ACL_ACCESS xattr not present"); } while
(0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__,
447, GF_LOG_DEBUG, "ACL_ACCESS xattr not present"); } while (
0)
447 "ACL_ACCESS xattr not present")do { do { if (0) printf ("ACL_ACCESS xattr not present"); } while
(0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__,
447, GF_LOG_DEBUG, "ACL_ACCESS xattr not present"); } while (
0)
;
448 goto out;
449 }
450 ret = dict_set (dict, POSIX_ACL_ACCESS_XATTR"system.posix_acl_access", acl_access);
451 if (ret)
452 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("Could not set ACL_ACCESS xattr"); }
while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 453, GF_LOG_WARNING, "Could not set ACL_ACCESS xattr"); } while
(0)
453 "Could not set ACL_ACCESS xattr")do { do { if (0) printf ("Could not set ACL_ACCESS xattr"); }
while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 453, GF_LOG_WARNING, "Could not set ACL_ACCESS xattr"); } while
(0)
;
454
455out:
456 return;
457}
458
459int
460dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
461 dht_layout_t *layout, int force)
462{
463 int missing_dirs = 0;
464 int i = 0;
465 int ret = -1;
466 dht_local_t *local = NULL((void*)0);
467 xlator_t *this = NULL((void*)0);
468 dict_t *dict = NULL((void*)0);
469
470 local = frame->local;
471 this = frame->this;
472
473 for (i = 0; i < layout->cnt; i++) {
474 if (layout->list[i].err == ENOENT2 || force)
475 missing_dirs++;
476 }
477
478 if (missing_dirs == 0) {
479 dht_selfheal_dir_setattr (frame, loc, &local->stbuf, 0xffffffff, layout);
480 return 0;
481 }
482
483 local->call_cnt = missing_dirs;
484 if (!uuid_is_null (local->gfid)) {
485 dict = dict_new ();
486 if (!dict)
487 return -1;
488
489 ret = dict_set_static_bin (dict, "gfid-req", local->gfid, 16);
490 if (ret)
491 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%s: failed to set gfid in dict", loc
->path); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 492, GF_LOG_WARNING, "%s: failed to set gfid in dict"
, loc->path); } while (0)
492 "%s: failed to set gfid in dict", loc->path)do { do { if (0) printf ("%s: failed to set gfid in dict", loc
->path); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 492, GF_LOG_WARNING, "%s: failed to set gfid in dict"
, loc->path); } while (0)
;
493 } else if (local->params) {
494 /* Send the dictionary from higher layers directly */
495 dict = dict_ref (local->params);
496 }
497 /* Set acls */
498 if (local->xattr && dict)
499 dht_selfheal_dir_mkdir_setacl (local->xattr, dict);
500
501 if (!dict)
502 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("dict is NULL, need to make sure gfids are same"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 503, GF_LOG_WARNING, "dict is NULL, need to make sure gfids are same"
); } while (0)
503 "dict is NULL, need to make sure gfids are same")do { do { if (0) printf ("dict is NULL, need to make sure gfids are same"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 503, GF_LOG_WARNING, "dict is NULL, need to make sure gfids are same"
); } while (0)
;
504
505 for (i = 0; i < layout->cnt; i++) {
506 if (layout->list[i].err == ENOENT2 || force) {
507 gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("creating directory %s on subvol %s"
, loc->path, layout->list[i].xlator->name); } while (
0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__, 509
, GF_LOG_DEBUG, "creating directory %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0)
508 "creating directory %s on subvol %s",do { do { if (0) printf ("creating directory %s on subvol %s"
, loc->path, layout->list[i].xlator->name); } while (
0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__, 509
, GF_LOG_DEBUG, "creating directory %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0)
509 loc->path, layout->list[i].xlator->name)do { do { if (0) printf ("creating directory %s on subvol %s"
, loc->path, layout->list[i].xlator->name); } while (
0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__, 509
, GF_LOG_DEBUG, "creating directory %s on subvol %s", loc->
path, layout->list[i].xlator->name); } while (0)
;
510
511 STACK_WIND (frame, dht_selfheal_dir_mkdir_cbk,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
512 layout->list[i].xlator,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
513 layout->list[i].xlator->fops->mkdir,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
514 loc,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
515 st_mode_from_ia (local->stbuf.ia_prot,do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
516 local->stbuf.ia_type),do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
517 0, dict)do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = ((
void*)0); _new = mem_get0 (frame->root->pool->frame_mem_pool
); if (!_new) { do { do { if (0) printf ("alloc failed"); } while
(0); _gf_log ("stack", "dht-selfheal.c", __FUNCTION__, 517, GF_LOG_ERROR
, "alloc failed"); } while (0); break; } typeof( layout->list
[i].xlator->fops->mkdir_cbk) tmp_cbk = dht_selfheal_dir_mkdir_cbk
; _new->root = frame->root; _new->this = layout->
list[i].xlator; _new->ret = (ret_fn_t) tmp_cbk; _new->parent
= frame; _new->cookie = _new; _new->wind_from = __FUNCTION__
; _new->wind_to = "layout->list[i].xlator->fops->mkdir"
; _new->unwind_to = "dht_selfheal_dir_mkdir_cbk"; pthread_spin_init
(&_new->lock, 0); pthread_spin_lock (&frame->root
->stack_lock); { _new->next = frame->root->frames
.next; _new->prev = &frame->root->frames; if (frame
->root->frames.next) frame->root->frames.next->
prev = _new; frame->root->frames.next = _new; frame->
ref_count++; } pthread_spin_unlock (&frame->root->stack_lock
); old_THIS = (*__glusterfs_this_location()); (*__glusterfs_this_location
()) = layout->list[i].xlator; if (frame->this->ctx->
measure_latency) gf_latency_begin (_new, layout->list[i].xlator
->fops->mkdir); layout->list[i].xlator->fops->
mkdir (_new, layout->list[i].xlator, loc, st_mode_from_ia (
local->stbuf.ia_prot, local->stbuf.ia_type), 0, dict); (
*__glusterfs_this_location()) = old_THIS; } while (0)
;
518 }
519 }
520
521 if (dict)
522 dict_unref (dict);
523
524 return 0;
525}
526
527
528int
529dht_selfheal_layout_alloc_start (xlator_t *this, loc_t *loc,
530 dht_layout_t *layout)
531{
532 int start = 0;
533 uint32_t hashval = 0;
534 int ret = 0;
535
536 ret = dht_hash_compute (this, layout->type, loc->path, &hashval);
537 if (ret == 0) {
538 start = (hashval % layout->cnt);
539 }
540
541 return start;
542}
543
544static inline int
545dht_get_layout_count (xlator_t *this, dht_layout_t *layout, int new_layout)
546{
547 int i = 0;
548 int j = 0;
549 int err = 0;
550 int count = 0;
551 dht_conf_t *conf = NULL((void*)0);
552
553 /* Gets in use only for replace-brick, remove-brick */
554 conf = this->private;
555 for (i = 0; i < layout->cnt; i++) {
556 for (j = 0; j < conf->subvolume_cnt; j++) {
557 if (conf->decommissioned_bricks[j] &&
558 conf->decommissioned_bricks[j] == layout->list[i].xlator) {
559 layout->list[i].err = EINVAL22;
560 break;
561 }
562 }
563 }
564
565 for (i = 0; i < layout->cnt; i++) {
566 err = layout->list[i].err;
567 if (err == -1 || err == 0) {
568 layout->list[i].err = -1;
569 count++;
570 }
571 }
572
573 /* no subvolume has enough space, but can't stop directory creation */
574 if (!count || !new_layout) {
575 for (i = 0; i < layout->cnt; i++) {
576 err = layout->list[i].err;
577 if (err == ENOSPC28) {
578 layout->list[i].err = -1;
579 count++;
580 }
581 }
582 }
583
584 /* if layout->spread_cnt is set, check if it is <= available
585 * subvolumes (down brick and decommissioned bricks are considered
586 * un-availbale). Else return count (available up bricks) */
587 count = ((layout->spread_cnt &&
588 (layout->spread_cnt <= count)) ?
589 layout->spread_cnt : ((count) ? count : 1));
590
591 return count;
592}
593
594
595void dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
596 dht_layout_t *new_layout);
597
598void dht_layout_entry_swap (dht_layout_t *layout, int i, int j);
599void dht_layout_range_swap (dht_layout_t *layout, int i, int j);
600
601/*
602 * It's a bit icky using local variables in a macro, but it makes the rest
603 * of the code a lot clearer.
604 */
605#define OV_ENTRY(x,y)table[x*new->cnt+y] table[x*new->cnt+y]
606
607void
608dht_selfheal_layout_maximize_overlap (call_frame_t *frame, loc_t *loc,
609 dht_layout_t *new, dht_layout_t *old)
610{
611 int i = 0;
612 int j = 0;
613 uint32_t curr_overlap = 0;
614 uint32_t max_overlap = 0;
615 int max_overlap_idx = -1;
616 uint32_t overlap = 0;
617 uint32_t *table = NULL((void*)0);
618
619 dht_layout_sort_volname (old);
620 /* Now both old_layout->list[] and new_layout->list[]
621 are match the same xlators/subvolumes. i.e,
622 old_layout->[i] and new_layout->[i] are referring
623 to the same subvolumes
624 */
625
626 /* Build a table of overlaps between new[i] and old[j]. */
627 table = alloca(sizeof(overlap)*old->cnt*new->cnt)__builtin_alloca (sizeof(overlap)*old->cnt*new->cnt);
628 if (!table) {
629 return;
630 }
631 memset(table,0,sizeof(overlap)*old->cnt*new->cnt);
632 for (i = 0; i < new->cnt; ++i) {
633 for (j = 0; j < old->cnt; ++j) {
634 OV_ENTRY(i,j)table[i*new->cnt+j] = dht_overlap_calc(old,j,new,i);
635 }
636 }
637
638 for (i = 0; i < new->cnt; i++) {
639 if (new->list[i].err > 0) {
640 /* Subvol might be marked for decommission
641 with EINVAL, or some other serious error
642 marked with positive errno.
643 */
644 continue;
645 }
646
647 max_overlap = 0;
648 max_overlap_idx = i;
649 for (j = (i + 1); j < new->cnt; ++j) {
650 /* Calculate the overlap now. */
651 curr_overlap = OV_ENTRY(i,i)table[i*new->cnt+i] + OV_ENTRY(j,j)table[j*new->cnt+j];
652 /* Calculate the overlap after the proposed swap. */
653 overlap = OV_ENTRY(i,j)table[i*new->cnt+j] + OV_ENTRY(j,i)table[j*new->cnt+i];
654 /* Are we better than status quo? */
655 if (overlap > curr_overlap) {
656 overlap -= curr_overlap;
657 /* Are we better than the previous choice? */
658 if (overlap > max_overlap) {
659 max_overlap = overlap;
660 max_overlap_idx = j;
661 }
662 }
663 }
664
665 if (max_overlap_idx != i) {
666 dht_layout_range_swap (new, i, max_overlap_idx);
667 /* Need to swap the table values too. */
668 for (j = 0; j < old->cnt; ++j) {
669 overlap = OV_ENTRY(i,j)table[i*new->cnt+j];
670 OV_ENTRY(i,j)table[i*new->cnt+j] = OV_ENTRY(max_overlap_idx,j)table[max_overlap_idx*new->cnt+j];
671 OV_ENTRY(max_overlap_idx,j)table[max_overlap_idx*new->cnt+j] = overlap;
672 }
673 }
674 }
675}
676
677
678dht_layout_t *
679dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc,
680 dht_layout_t *layout)
681{
682 int i = 0;
683 xlator_t *this = NULL((void*)0);
684 dht_layout_t *new_layout = NULL((void*)0);
685 dht_conf_t *priv = NULL((void*)0);
686 dht_local_t *local = NULL((void*)0);
687 uint32_t subvol_down = 0;
688 int ret = 0;
689
690 this = frame->this;
691 priv = this->private;
692 local = frame->local;
693
694 if (layout->type == DHT_HASH_TYPE_DM_USER) {
695 gf_log (THIS->name, GF_LOG_DEBUG, "leaving %s alone",do { do { if (0) printf ("leaving %s alone", loc->path); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"dht-selfheal.c", __FUNCTION__, 696, GF_LOG_DEBUG, "leaving %s alone"
, loc->path); } while (0)
696 loc->path)do { do { if (0) printf ("leaving %s alone", loc->path); }
while (0); _gf_log ((*__glusterfs_this_location())->name,
"dht-selfheal.c", __FUNCTION__, 696, GF_LOG_DEBUG, "leaving %s alone"
, loc->path); } while (0)
;
697 goto done;
698 }
699
700 new_layout = dht_layout_new (this, priv->subvolume_cnt);
701 if (!new_layout)
702 goto done;
703
704 /* If a subvolume is down, do not re-write the layout. */
705 ret = dht_layout_anomalies (this, loc, layout, NULL((void*)0), NULL((void*)0), NULL((void*)0),
706 &subvol_down, NULL((void*)0), NULL((void*)0));
707
708 if (subvol_down || (ret == -1)) {
709 gf_log (this->name, GF_LOG_WARNING, "%u subvolume(s) are down"do { do { if (0) printf ("%u subvolume(s) are down" ". Skipping fix layout."
, subvol_down); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 710, GF_LOG_WARNING, "%u subvolume(s) are down"
". Skipping fix layout.", subvol_down); } while (0)
710 ". Skipping fix layout.", subvol_down)do { do { if (0) printf ("%u subvolume(s) are down" ". Skipping fix layout."
, subvol_down); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 710, GF_LOG_WARNING, "%u subvolume(s) are down"
". Skipping fix layout.", subvol_down); } while (0)
;
711 GF_FREE (new_layout)__gf_free (new_layout);
712 return NULL((void*)0);
713 }
714
715 for (i = 0; i < new_layout->cnt; i++) {
716 if (layout->list[i].err != ENOSPC28)
717 new_layout->list[i].err = layout->list[i].err;
718 else
719 new_layout->list[i].err = -1;
720
721 new_layout->list[i].xlator = layout->list[i].xlator;
722 }
723
724 /* First give it a layout as though it is a new directory. This
725 ensures rotation to kick in */
726 dht_layout_sort_volname (new_layout);
727 dht_selfheal_layout_new_directory (frame, loc, new_layout);
728
729 /* Now selectively re-assign ranges only when it helps */
730 dht_selfheal_layout_maximize_overlap (frame, loc, new_layout, layout);
731
732done:
733 if (new_layout) {
734 /* Now that the new layout has all the proper layout, change the
735 inode context */
736 dht_layout_set (this, loc->inode, new_layout);
737
738 /* Make sure the extra 'ref' for existing layout is removed */
739 dht_layout_unref (this, local->layout);
740
741 local->layout = new_layout;
742 }
743
744 return local->layout;
745}
746
747
748void
749dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
750 dht_layout_t *layout)
751{
752 xlator_t *this = NULL((void*)0);
753 uint32_t chunk = 0;
754 int i = 0;
755 uint32_t start = 0;
756 int cnt = 0;
757 int err = 0;
758 int start_subvol = 0;
759
760 this = frame->this;
761
762 cnt = dht_get_layout_count (this, layout, 1);
763
764 chunk = ((unsigned long) 0xffffffff) / ((cnt) ? cnt : 1);
765
766 start_subvol = dht_selfheal_layout_alloc_start (this, loc, layout);
767
768 /* clear out the range, as we are re-computing here */
769 DHT_RESET_LAYOUT_RANGE (layout)do { int cnt = 0; for (cnt = 0; cnt < layout->cnt; cnt++
) { layout->list[cnt].start = 0; layout->list[cnt].stop
= 0; } } while (0)
;
770 for (i = start_subvol; i < layout->cnt; i++) {
771 err = layout->list[i].err;
772 if (err == -1) {
773 DHT_SET_LAYOUT_RANGE(layout, i, start, chunk,do { layout->list[i].start = start; layout->list[i].stop
= start + chunk - 1; do { do { if (0) printf ("gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, loc->path); } while (0); _gf_log (
this->name, "dht-selfheal.c", __FUNCTION__, 774, GF_LOG_TRACE
, "gave fix: %u - %u on %s for %s", layout->list[i].start,
layout->list[i].stop, layout->list[i].xlator->name,
loc->path); } while (0); } while (0)
774 cnt, loc->path)do { layout->list[i].start = start; layout->list[i].stop
= start + chunk - 1; do { do { if (0) printf ("gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, loc->path); } while (0); _gf_log (
this->name, "dht-selfheal.c", __FUNCTION__, 774, GF_LOG_TRACE
, "gave fix: %u - %u on %s for %s", layout->list[i].start,
layout->list[i].stop, layout->list[i].xlator->name,
loc->path); } while (0); } while (0)
;
775 if (--cnt == 0) {
776 layout->list[i].stop = 0xffffffff;
777 goto done;
778 }
779 start += chunk;
780 }
781 }
782
783 for (i = 0; i < start_subvol; i++) {
784 err = layout->list[i].err;
785 if (err == -1) {
786 DHT_SET_LAYOUT_RANGE(layout, i, start, chunk,do { layout->list[i].start = start; layout->list[i].stop
= start + chunk - 1; do { do { if (0) printf ("gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, loc->path); } while (0); _gf_log (
this->name, "dht-selfheal.c", __FUNCTION__, 787, GF_LOG_TRACE
, "gave fix: %u - %u on %s for %s", layout->list[i].start,
layout->list[i].stop, layout->list[i].xlator->name,
loc->path); } while (0); } while (0)
787 cnt, loc->path)do { layout->list[i].start = start; layout->list[i].stop
= start + chunk - 1; do { do { if (0) printf ("gave fix: %u - %u on %s for %s"
, layout->list[i].start, layout->list[i].stop, layout->
list[i].xlator->name, loc->path); } while (0); _gf_log (
this->name, "dht-selfheal.c", __FUNCTION__, 787, GF_LOG_TRACE
, "gave fix: %u - %u on %s for %s", layout->list[i].start,
layout->list[i].stop, layout->list[i].xlator->name,
loc->path); } while (0); } while (0)
;
788 if (--cnt == 0) {
789 layout->list[i].stop = 0xffffffff;
790 goto done;
791 }
792 start += chunk;
793 }
794 }
795
796done:
797 return;
798}
799
800int
801dht_selfheal_dir_getafix (call_frame_t *frame, loc_t *loc,
802 dht_layout_t *layout)
803{
804 dht_local_t *local = NULL((void*)0);
805 uint32_t holes = 0;
806 int ret = -1;
807 int i = -1;
808 uint32_t overlaps = 0;
809
810 local = frame->local;
811
812 holes = local->selfheal.hole_cnt;
813 overlaps = local->selfheal.overlaps_cnt;
814
815 if (holes || overlaps) {
816 dht_selfheal_layout_new_directory (frame, loc, layout);
817 ret = 0;
818 }
819
820 for (i = 0; i < layout->cnt; i++) {
821 /* directory not present */
822 if (layout->list[i].err == ENOENT2) {
823 ret = 0;
824 break;
825 }
826 }
827
828 /* TODO: give a fix to these non-virgins */
829
830 return ret;
831}
832
833int
834dht_selfheal_new_directory (call_frame_t *frame,
835 dht_selfheal_dir_cbk_t dir_cbk,
836 dht_layout_t *layout)
837{
838 dht_local_t *local = NULL((void*)0);
839
840 local = frame->local;
841
842 local->selfheal.dir_cbk = dir_cbk;
843 local->selfheal.layout = dht_layout_ref (frame->this, layout);
844
845 dht_layout_sort_volname (layout);
846 dht_selfheal_layout_new_directory (frame, &local->loc, layout);
847 dht_selfheal_dir_xattr (frame, &local->loc, layout);
848 return 0;
849}
850
851int
852dht_fix_directory_layout (call_frame_t *frame,
853 dht_selfheal_dir_cbk_t dir_cbk,
854 dht_layout_t *layout)
855{
856 dht_local_t *local = NULL((void*)0);
857 dht_layout_t *tmp_layout = NULL((void*)0);
858
859 local = frame->local;
860
861 local->selfheal.dir_cbk = dir_cbk;
862 local->selfheal.layout = dht_layout_ref (frame->this, layout);
863
864 /* No layout sorting required here */
865 tmp_layout = dht_fix_layout_of_directory (frame, &local->loc, layout);
866 if (!tmp_layout) {
867 return -1;
868 }
869 dht_fix_dir_xattr (frame, &local->loc, tmp_layout);
870
871 return 0;
872}
873
874
875int
876dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
877 loc_t *loc, dht_layout_t *layout)
878{
879 dht_local_t *local = NULL((void*)0);
880 uint32_t down = 0;
881 uint32_t misc = 0;
882 int ret = 0;
883 xlator_t *this = NULL((void*)0);
884
885 local = frame->local;
886 this = frame->this;
887
888 dht_layout_anomalies (this, loc, layout,
889 &local->selfheal.hole_cnt,
890 &local->selfheal.overlaps_cnt,
891 NULL((void*)0), &local->selfheal.down,
892 &local->selfheal.misc, NULL((void*)0));
893
894 down = local->selfheal.down;
895 misc = local->selfheal.misc;
896
897 local->selfheal.dir_cbk = dir_cbk;
898 local->selfheal.layout = dht_layout_ref (this, layout);
899
900 if (down) {
901 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%d subvolumes down -- not fixing", down
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 902, GF_LOG_WARNING, "%d subvolumes down -- not fixing", down
); } while (0)
902 "%d subvolumes down -- not fixing", down)do { do { if (0) printf ("%d subvolumes down -- not fixing", down
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 902, GF_LOG_WARNING, "%d subvolumes down -- not fixing", down
); } while (0)
;
903 ret = 0;
904 goto sorry_no_fix;
905 }
906
907 if (misc) {
908 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("%d subvolumes have unrecoverable errors"
, misc); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 909, GF_LOG_WARNING, "%d subvolumes have unrecoverable errors"
, misc); } while (0)
909 "%d subvolumes have unrecoverable errors", misc)do { do { if (0) printf ("%d subvolumes have unrecoverable errors"
, misc); } while (0); _gf_log (this->name, "dht-selfheal.c"
, __FUNCTION__, 909, GF_LOG_WARNING, "%d subvolumes have unrecoverable errors"
, misc); } while (0)
;
910 ret = 0;
911 goto sorry_no_fix;
912 }
913
914 dht_layout_sort_volname (layout);
915 ret = dht_selfheal_dir_getafix (frame, loc, layout);
916
917 if (ret == -1) {
918 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("not able to form layout for the directory"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 919, GF_LOG_WARNING, "not able to form layout for the directory"
); } while (0)
919 "not able to form layout for the directory")do { do { if (0) printf ("not able to form layout for the directory"
); } while (0); _gf_log (this->name, "dht-selfheal.c", __FUNCTION__
, 919, GF_LOG_WARNING, "not able to form layout for the directory"
); } while (0)
;
920 goto sorry_no_fix;
921 }
922
923 dht_selfheal_dir_mkdir (frame, loc, layout, 0);
924
925 return 0;
926
927sorry_no_fix:
928 /* TODO: need to put appropriate local->op_errno */
929 dht_selfheal_dir_finish (frame, this, ret);
930
931 return 0;
932}
933
934
935int
936dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
937 loc_t *loc, dht_layout_t *layout)
938{
939 int ret = 0;
940 dht_local_t *local = NULL((void*)0);
941
942 local = frame->local;
943
944 local->selfheal.dir_cbk = dir_cbk;
945 local->selfheal.layout = dht_layout_ref (frame->this, layout);
946
947 ret = dht_selfheal_dir_mkdir (frame, loc, layout, 1);
948
949 return ret;
950}
951
952int
953dht_dir_attr_heal (void *data)
954{
955 call_frame_t *frame = NULL((void*)0);
956 dht_local_t *local = NULL((void*)0);
957 xlator_t *subvol = NULL((void*)0);
958 xlator_t *this = NULL((void*)0);
959 dht_conf_t *conf = NULL((void*)0);
960 int call_cnt = 0;
961 int ret = -1;
962 int i = 0;
963
964 GF_VALIDATE_OR_GOTO ("dht", data, out)do { if (!data) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "data"); } while (0); _gf_log_callingfn
("dht", "dht-selfheal.c", __FUNCTION__, 964, GF_LOG_ERROR, "invalid argument: "
"data"); } while (0); goto out; } } while (0)
;
965
966 frame = data;
967 local = frame->local;
968 this = frame->this;
969 GF_VALIDATE_OR_GOTO ("dht", this, out)do { if (!this) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn
("dht", "dht-selfheal.c", __FUNCTION__, 969, GF_LOG_ERROR, "invalid argument: "
"this"); } while (0); goto out; } } while (0)
;
970 GF_VALIDATE_OR_GOTO ("dht", local, out)do { if (!local) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "local"); } while (0); _gf_log_callingfn
("dht", "dht-selfheal.c", __FUNCTION__, 970, GF_LOG_ERROR, "invalid argument: "
"local"); } while (0); goto out; } } while (0)
;
971 conf = this->private;
972 GF_VALIDATE_OR_GOTO ("dht", conf, out)do { if (!conf) { (*__errno_location ()) = 22; do { do { if (
0) printf ("invalid argument: " "conf"); } while (0); _gf_log_callingfn
("dht", "dht-selfheal.c", __FUNCTION__, 972, GF_LOG_ERROR, "invalid argument: "
"conf"); } while (0); goto out; } } while (0)
;
973
974 call_cnt = conf->subvolume_cnt;
975
976 for (i = 0; i < call_cnt; i++) {
977 subvol = conf->subvolumes[i];
978 if (!subvol || (subvol == dht_first_up_subvol (this)))
979 continue;
980 ret = syncop_setattr (subvol, &local->loc, &local->stbuf,
981 (GF_SET_ATTR_UID0x2 | GF_SET_ATTR_GID0x4),
982 NULL((void*)0), NULL((void*)0));
983 if (ret)
984 gf_log ("dht", GF_LOG_ERROR, "Failed to set uid/gid on"do { do { if (0) printf ("Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0); _gf_log ("dht", "dht-selfheal.c", __FUNCTION__
, 986, GF_LOG_ERROR, "Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0)
985 " %s on %s subvol (%s)", local->loc.path,do { do { if (0) printf ("Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0); _gf_log ("dht", "dht-selfheal.c", __FUNCTION__
, 986, GF_LOG_ERROR, "Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0)
986 subvol->name, strerror (errno))do { do { if (0) printf ("Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0); _gf_log ("dht", "dht-selfheal.c", __FUNCTION__
, 986, GF_LOG_ERROR, "Failed to set uid/gid on" " %s on %s subvol (%s)"
, local->loc.path, subvol->name, strerror ((*__errno_location
()))); } while (0)
;
987 }
988out:
989 return 0;
990}
991
992int
993dht_dir_attr_heal_done (int ret, call_frame_t *sync_frame, void *data)
994{
995 DHT_STACK_DESTROY (sync_frame)do { dht_local_t *__local = ((void*)0); xlator_t *__xl = ((void
*)0); __xl = sync_frame->this; __local = sync_frame->local
; sync_frame->local = ((void*)0); STACK_DESTROY (sync_frame
->root); dht_local_wipe (__xl, __local); } while (0)
;
996 return 0;
997}