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') |
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 | ||||||
39 | static uint32_t | |||||
40 | dht_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 | ||||||
65 | int | |||||
66 | dht_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 | ||||||
78 | int | |||||
79 | dht_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 | ||||||
117 | int | |||||
118 | dht_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 | ||||||
185 | err: | |||||
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 | ||||||
196 | int | |||||
197 | dht_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); | |||||
238 | out: | |||||
239 | return 0; | |||||
240 | } | |||||
241 | ||||||
242 | int | |||||
243 | dht_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); | |||||
299 | out: | |||||
300 | return 0; | |||||
301 | } | |||||
302 | ||||||
303 | int | |||||
304 | dht_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 | ||||||
325 | int | |||||
326 | dht_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 | ||||||
367 | int | |||||
368 | dht_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 | ||||||
408 | out: | |||||
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 | ||||||
418 | void | |||||
419 | dht_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()); | |||||
| ||||||
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); | |||||
431 | ||||||
432 | acl_default = dict_get (xattr, POSIX_ACL_DEFAULT_XATTR"system.posix_acl_default"); | |||||
433 | ||||||
434 | if (!acl_default) { | |||||
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) | |||||
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) | |||||
| ||||||
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); | |||||
443 | cont: | |||||
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 | ||||||
455 | out: | |||||
456 | return; | |||||
457 | } | |||||
458 | ||||||
459 | int | |||||
460 | dht_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 | ||||||
528 | int | |||||
529 | dht_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 | ||||||
544 | static inline int | |||||
545 | dht_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 | ||||||
595 | void dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc, | |||||
596 | dht_layout_t *new_layout); | |||||
597 | ||||||
598 | void dht_layout_entry_swap (dht_layout_t *layout, int i, int j); | |||||
599 | void 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 | ||||||
607 | void | |||||
608 | dht_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 | ||||||
678 | dht_layout_t * | |||||
679 | dht_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 | ||||||
732 | done: | |||||
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 | ||||||
748 | void | |||||
749 | dht_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 | ||||||
796 | done: | |||||
797 | return; | |||||
798 | } | |||||
799 | ||||||
800 | int | |||||
801 | dht_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 | ||||||
833 | int | |||||
834 | dht_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 | ||||||
851 | int | |||||
852 | dht_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 | ||||||
875 | int | |||||
876 | dht_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 | ||||||
927 | sorry_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 | ||||||
935 | int | |||||
936 | dht_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 | ||||||
952 | int | |||||
953 | dht_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 | } | |||||
988 | out: | |||||
989 | return 0; | |||||
990 | } | |||||
991 | ||||||
992 | int | |||||
993 | dht_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 | } |