File: | xlators/performance/write-behind/src/write-behind.c |
Location: | line 893, column 25 |
Description: | Access to field 'frame' results in a dereference of a null pointer (loaded from field 'stub') |
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 | ||||
12 | #ifndef _CONFIG_H | |||
13 | #define _CONFIG_H | |||
14 | #include "config.h" | |||
15 | #endif | |||
16 | ||||
17 | #include "glusterfs.h" | |||
18 | #include "logging.h" | |||
19 | #include "dict.h" | |||
20 | #include "xlator.h" | |||
21 | #include "list.h" | |||
22 | #include "compat.h" | |||
23 | #include "compat-errno.h" | |||
24 | #include "common-utils.h" | |||
25 | #include "call-stub.h" | |||
26 | #include "statedump.h" | |||
27 | #include "defaults.h" | |||
28 | #include "write-behind-mem-types.h" | |||
29 | ||||
30 | #define MAX_VECTOR_COUNT8 8 | |||
31 | #define WB_AGGREGATE_SIZE131072 131072 /* 128 KB */ | |||
32 | #define WB_WINDOW_SIZE1048576 1048576 /* 1MB */ | |||
33 | ||||
34 | typedef struct list_head list_head_t; | |||
35 | struct wb_conf; | |||
36 | struct wb_inode; | |||
37 | ||||
38 | typedef struct wb_inode { | |||
39 | ssize_t window_conf; | |||
40 | ssize_t window_current; | |||
41 | ssize_t transit; /* size of data stack_wound, and yet | |||
42 | to be fulfilled (wb_fulfill_cbk). | |||
43 | used for trickling_writes | |||
44 | */ | |||
45 | ||||
46 | list_head_t all; /* All requests, from enqueue() till destroy(). | |||
47 | Used only for resetting generation | |||
48 | number when empty. | |||
49 | */ | |||
50 | list_head_t todo; /* Work to do (i.e, STACK_WIND to server). | |||
51 | Once we STACK_WIND, the entry is taken | |||
52 | off the list. If it is non-sync write, | |||
53 | then we continue to track it via @liability | |||
54 | or @temptation depending on the status | |||
55 | of its writeback. | |||
56 | */ | |||
57 | list_head_t liability; /* Non-sync writes which are lied | |||
58 | (STACK_UNWIND'ed to caller) but ack | |||
59 | from server not yet complete. This | |||
60 | is the "liability" which we hold, and | |||
61 | must guarantee that dependent operations | |||
62 | which arrive later (which overlap, etc.) | |||
63 | are issued only after their dependencies | |||
64 | in this list are "fulfilled". | |||
65 | ||||
66 | Server acks for entries in this list | |||
67 | shrinks the window. | |||
68 | ||||
69 | The sum total of all req->write_size | |||
70 | of entries in this list must be kept less | |||
71 | than the permitted window size. | |||
72 | */ | |||
73 | list_head_t temptation; /* Operations for which we are tempted | |||
74 | to 'lie' (write-behind), but temporarily | |||
75 | holding off (because of insufficient | |||
76 | window capacity, etc.) | |||
77 | ||||
78 | This is the list to look at to grow | |||
79 | the window (in __wb_pick_unwinds()). | |||
80 | ||||
81 | Entries typically get chosen from | |||
82 | write-behind from this list, and therefore | |||
83 | get "upgraded" to the "liability" list. | |||
84 | */ | |||
85 | list_head_t wip; /* List of write calls in progress, SYNC or non-SYNC | |||
86 | which are currently STACK_WIND'ed towards the server. | |||
87 | This is for guaranteeing that no two overlapping | |||
88 | writes are in progress at the same time. Modules | |||
89 | like eager-lock in AFR depend on this behavior. | |||
90 | */ | |||
91 | uint64_t gen; /* Liability generation number. Represents | |||
92 | the current 'state' of liability. Every | |||
93 | new addition to the liability list bumps | |||
94 | the generation number. | |||
95 | ||||
96 | a newly arrived request is only required | |||
97 | to perform causal checks against the entries | |||
98 | in the liability list which were present | |||
99 | at the time of its addition. the generation | |||
100 | number at the time of its addition is stored | |||
101 | in the request and used during checks. | |||
102 | ||||
103 | the liability list can grow while the request | |||
104 | waits in the todo list waiting for its | |||
105 | dependent operations to complete. however | |||
106 | it is not of the request's concern to depend | |||
107 | itself on those new entries which arrived | |||
108 | after it arrived (i.e, those that have a | |||
109 | liability generation higher than itself) | |||
110 | */ | |||
111 | gf_lock_t lock; | |||
112 | xlator_t *this; | |||
113 | } wb_inode_t; | |||
114 | ||||
115 | ||||
116 | typedef struct wb_request { | |||
117 | list_head_t all; | |||
118 | list_head_t todo; | |||
119 | list_head_t lie; /* either in @liability or @temptation */ | |||
120 | list_head_t winds; | |||
121 | list_head_t unwinds; | |||
122 | list_head_t wip; | |||
123 | ||||
124 | call_stub_t *stub; | |||
125 | ||||
126 | ssize_t write_size; /* currently held size | |||
127 | (after collapsing) */ | |||
128 | size_t orig_size; /* size which arrived with the request. | |||
129 | This is the size by which we grow | |||
130 | the window when unwinding the frame. | |||
131 | */ | |||
132 | size_t total_size; /* valid only in @head in wb_fulfill(). | |||
133 | This is the size with which we perform | |||
134 | STACK_WIND to server and therefore the | |||
135 | amount by which we shrink the window. | |||
136 | */ | |||
137 | ||||
138 | int op_ret; | |||
139 | int op_errno; | |||
140 | ||||
141 | int32_t refcount; | |||
142 | wb_inode_t *wb_inode; | |||
143 | glusterfs_fop_t fop; | |||
144 | gf_lkowner_t lk_owner; | |||
145 | struct iobref *iobref; | |||
146 | uint64_t gen; /* inode liability state at the time of | |||
147 | request arrival */ | |||
148 | ||||
149 | fd_t *fd; | |||
150 | struct { | |||
151 | size_t size; /* 0 size == till infinity */ | |||
152 | off_t off; | |||
153 | int append:1; /* offset is invalid. only one | |||
154 | outstanding append at a time */ | |||
155 | int tempted:1; /* true only for non-sync writes */ | |||
156 | int lied:1; /* sin committed */ | |||
157 | int fulfilled:1; /* got server acknowledgement */ | |||
158 | int go:1; /* enough aggregating, good to go */ | |||
159 | } ordering; | |||
160 | } wb_request_t; | |||
161 | ||||
162 | ||||
163 | typedef struct wb_conf { | |||
164 | uint64_t aggregate_size; | |||
165 | uint64_t window_size; | |||
166 | gf_boolean_t flush_behind; | |||
167 | gf_boolean_t trickling_writes; | |||
168 | gf_boolean_t strict_write_ordering; | |||
169 | gf_boolean_t strict_O_DIRECT; | |||
170 | } wb_conf_t; | |||
171 | ||||
172 | ||||
173 | void | |||
174 | wb_process_queue (wb_inode_t *wb_inode); | |||
175 | ||||
176 | ||||
177 | wb_inode_t * | |||
178 | __wb_inode_ctx_get (xlator_t *this, inode_t *inode) | |||
179 | { | |||
180 | uint64_t value = 0; | |||
181 | wb_inode_t *wb_inode = NULL((void*)0); | |||
182 | ||||
183 | __inode_ctx_get (inode, this, &value)__inode_ctx_get2(inode,this,&value,0); | |||
184 | wb_inode = (wb_inode_t *)(unsigned long) value; | |||
185 | ||||
186 | return wb_inode; | |||
187 | } | |||
188 | ||||
189 | ||||
190 | wb_inode_t * | |||
191 | wb_inode_ctx_get (xlator_t *this, inode_t *inode) | |||
192 | { | |||
193 | wb_inode_t *wb_inode = NULL((void*)0); | |||
194 | ||||
195 | GF_VALIDATE_OR_GOTO ("write-behind", this, out)do { if (!this) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 195, GF_LOG_ERROR , "invalid argument: " "this"); } while (0); goto out; } } while (0); | |||
196 | GF_VALIDATE_OR_GOTO (this->name, inode, out)do { if (!inode) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "inode"); } while (0); _gf_log_callingfn (this->name, "write-behind.c", __FUNCTION__, 196, GF_LOG_ERROR , "invalid argument: " "inode"); } while (0); goto out; } } while (0); | |||
197 | ||||
198 | LOCK (&inode->lock)pthread_spin_lock (&inode->lock); | |||
199 | { | |||
200 | wb_inode = __wb_inode_ctx_get (this, inode); | |||
201 | } | |||
202 | UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock); | |||
203 | out: | |||
204 | return wb_inode; | |||
205 | } | |||
206 | ||||
207 | ||||
208 | gf_boolean_t | |||
209 | wb_fd_err (fd_t *fd, xlator_t *this, int32_t *op_errno) | |||
210 | { | |||
211 | gf_boolean_t err = _gf_false; | |||
212 | uint64_t value = 0; | |||
213 | int32_t tmp = 0; | |||
214 | ||||
215 | if (fd_ctx_get (fd, this, &value) == 0) { | |||
216 | if (value != EBADF9) { | |||
217 | fd_ctx_set (fd, this, EBADF9); | |||
218 | } | |||
219 | ||||
220 | if (op_errno != NULL((void*)0)) { | |||
221 | tmp = value; | |||
222 | *op_errno = tmp; | |||
223 | } | |||
224 | ||||
225 | err = _gf_true; | |||
226 | } | |||
227 | ||||
228 | return err; | |||
229 | } | |||
230 | ||||
231 | ||||
232 | /* | |||
233 | Below is a succinct explanation of the code deciding whether two regions | |||
234 | overlap, from Pavan <tcp@gluster.com>. | |||
235 | ||||
236 | For any two ranges to be non-overlapping, either the end of the first | |||
237 | range is lesser than the start of the second, or vice versa. Example - | |||
238 | ||||
239 | <---------> <--------------> | |||
240 | p q x y | |||
241 | ||||
242 | ( q < x ) or (y < p) = > No overlap. | |||
243 | ||||
244 | To check for *overlap*, we can negate this (using de morgan's laws), and | |||
245 | it becomes - | |||
246 | ||||
247 | (q >= x ) and (y >= p) | |||
248 | ||||
249 | Either that, or you write the negation using - | |||
250 | ||||
251 | if (! ((q < x) or (y < p)) ) { | |||
252 | "Overlap" | |||
253 | } | |||
254 | */ | |||
255 | ||||
256 | gf_boolean_t | |||
257 | wb_requests_overlap (wb_request_t *req1, wb_request_t *req2) | |||
258 | { | |||
259 | uint64_t r1_start = 0; | |||
260 | uint64_t r1_end = 0; | |||
261 | uint64_t r2_start = 0; | |||
262 | uint64_t r2_end = 0; | |||
263 | enum _gf_boolean do_overlap = 0; | |||
264 | ||||
265 | r1_start = req1->ordering.off; | |||
266 | if (req1->ordering.size) | |||
267 | r1_end = r1_start + req1->ordering.size - 1; | |||
268 | else | |||
269 | r1_end = ULLONG_MAX(9223372036854775807LL*2ULL+1ULL); | |||
270 | ||||
271 | r2_start = req2->ordering.off; | |||
272 | if (req2->ordering.size) | |||
273 | r2_end = r2_start + req2->ordering.size - 1; | |||
274 | else | |||
275 | r2_end = ULLONG_MAX(9223372036854775807LL*2ULL+1ULL); | |||
276 | ||||
277 | do_overlap = ((r1_end >= r2_start) && (r2_end >= r1_start)); | |||
278 | ||||
279 | return do_overlap; | |||
280 | } | |||
281 | ||||
282 | ||||
283 | gf_boolean_t | |||
284 | wb_requests_conflict (wb_request_t *lie, wb_request_t *req) | |||
285 | { | |||
286 | wb_conf_t *conf = NULL((void*)0); | |||
287 | ||||
288 | conf = req->wb_inode->this->private; | |||
289 | ||||
290 | if (lie == req) | |||
291 | /* request cannot conflict with itself */ | |||
292 | return _gf_false; | |||
293 | ||||
294 | if (lie->gen >= req->gen) | |||
295 | /* this liability entry was behind | |||
296 | us in the todo list */ | |||
297 | return _gf_false; | |||
298 | ||||
299 | if (lie->ordering.append) | |||
300 | /* all modifications wait for the completion | |||
301 | of outstanding append */ | |||
302 | return _gf_true; | |||
303 | ||||
304 | if (conf->strict_write_ordering) | |||
305 | /* We are sure (lie->gen < req->gen) by now. So | |||
306 | skip overlap check if strict write ordering is | |||
307 | requested and always return "conflict" against a | |||
308 | lower generation lie. */ | |||
309 | return _gf_true; | |||
310 | ||||
311 | return wb_requests_overlap (lie, req); | |||
312 | } | |||
313 | ||||
314 | ||||
315 | gf_boolean_t | |||
316 | wb_liability_has_conflict (wb_inode_t *wb_inode, wb_request_t *req) | |||
317 | { | |||
318 | wb_request_t *each = NULL((void*)0); | |||
319 | ||||
320 | list_for_each_entry (each, &wb_inode->liability, lie)for (each = ((typeof(*each) *)((char *)((&wb_inode->liability )->next)-(unsigned long)(&((typeof(*each) *)0)->lie ))); &each->lie != (&wb_inode->liability); each = ((typeof(*each) *)((char *)(each->lie.next)-(unsigned long )(&((typeof(*each) *)0)->lie)))) { | |||
321 | if (wb_requests_conflict (each, req)) | |||
322 | return _gf_true; | |||
323 | } | |||
324 | ||||
325 | return _gf_false; | |||
326 | } | |||
327 | ||||
328 | ||||
329 | gf_boolean_t | |||
330 | wb_wip_has_conflict (wb_inode_t *wb_inode, wb_request_t *req) | |||
331 | { | |||
332 | wb_request_t *each = NULL((void*)0); | |||
333 | ||||
334 | if (req->stub->fop != GF_FOP_WRITE) | |||
335 | /* non-writes fundamentally never conflict with WIP requests */ | |||
336 | return _gf_false; | |||
337 | ||||
338 | list_for_each_entry (each, &wb_inode->wip, wip)for (each = ((typeof(*each) *)((char *)((&wb_inode->wip )->next)-(unsigned long)(&((typeof(*each) *)0)->wip ))); &each->wip != (&wb_inode->wip); each = ((typeof (*each) *)((char *)(each->wip.next)-(unsigned long)(&( (typeof(*each) *)0)->wip)))) { | |||
339 | if (each == req) | |||
340 | /* request never conflicts with itself, | |||
341 | though this condition should never occur. | |||
342 | */ | |||
343 | continue; | |||
344 | ||||
345 | if (wb_requests_overlap (each, req)) | |||
346 | return _gf_true; | |||
347 | } | |||
348 | ||||
349 | return _gf_false; | |||
350 | } | |||
351 | ||||
352 | ||||
353 | static int | |||
354 | __wb_request_unref (wb_request_t *req) | |||
355 | { | |||
356 | int ret = -1; | |||
357 | wb_inode_t *wb_inode = NULL((void*)0); | |||
358 | ||||
359 | wb_inode = req->wb_inode; | |||
360 | ||||
361 | if (req->refcount <= 0) { | |||
362 | gf_log ("wb-request", GF_LOG_WARNING,do { do { if (0) printf ("refcount(%d) is <= 0", req->refcount ); } while (0); _gf_log ("wb-request", "write-behind.c", __FUNCTION__ , 363, GF_LOG_WARNING, "refcount(%d) is <= 0", req->refcount ); } while (0) | |||
363 | "refcount(%d) is <= 0", req->refcount)do { do { if (0) printf ("refcount(%d) is <= 0", req->refcount ); } while (0); _gf_log ("wb-request", "write-behind.c", __FUNCTION__ , 363, GF_LOG_WARNING, "refcount(%d) is <= 0", req->refcount ); } while (0); | |||
364 | goto out; | |||
365 | } | |||
366 | ||||
367 | ret = --req->refcount; | |||
368 | if (req->refcount == 0) { | |||
369 | list_del_init (&req->todo); | |||
370 | list_del_init (&req->lie); | |||
371 | list_del_init (&req->wip); | |||
372 | ||||
373 | list_del_init (&req->all); | |||
374 | if (list_empty (&wb_inode->all)) { | |||
375 | wb_inode->gen = 0; | |||
376 | /* in case of accounting errors? */ | |||
377 | wb_inode->window_current = 0; | |||
378 | } | |||
379 | ||||
380 | list_del_init (&req->winds); | |||
381 | list_del_init (&req->unwinds); | |||
382 | ||||
383 | if (req->stub && req->ordering.tempted) { | |||
384 | call_stub_destroy (req->stub); | |||
385 | req->stub = NULL((void*)0); | |||
386 | } /* else we would have call_resume()'ed */ | |||
387 | ||||
388 | if (req->iobref) | |||
389 | iobref_unref (req->iobref); | |||
390 | ||||
391 | if (req->fd) | |||
392 | fd_unref (req->fd); | |||
393 | ||||
394 | GF_FREE (req)__gf_free (req); | |||
395 | } | |||
396 | out: | |||
397 | return ret; | |||
398 | } | |||
399 | ||||
400 | ||||
401 | static int | |||
402 | wb_request_unref (wb_request_t *req) | |||
403 | { | |||
404 | wb_inode_t *wb_inode = NULL((void*)0); | |||
405 | int ret = -1; | |||
406 | ||||
407 | GF_VALIDATE_OR_GOTO ("write-behind", req, out)do { if (!req) { (*__errno_location ()) = 22; do { do { if (0 ) printf ("invalid argument: " "req"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 407, GF_LOG_ERROR , "invalid argument: " "req"); } while (0); goto out; } } while (0); | |||
408 | ||||
409 | wb_inode = req->wb_inode; | |||
410 | ||||
411 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
412 | { | |||
413 | ret = __wb_request_unref (req); | |||
414 | } | |||
415 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
416 | ||||
417 | out: | |||
418 | return ret; | |||
419 | } | |||
420 | ||||
421 | ||||
422 | static wb_request_t * | |||
423 | __wb_request_ref (wb_request_t *req) | |||
424 | { | |||
425 | GF_VALIDATE_OR_GOTO ("write-behind", req, out)do { if (!req) { (*__errno_location ()) = 22; do { do { if (0 ) printf ("invalid argument: " "req"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 425, GF_LOG_ERROR , "invalid argument: " "req"); } while (0); goto out; } } while (0); | |||
426 | ||||
427 | if (req->refcount < 0) { | |||
428 | gf_log ("wb-request", GF_LOG_WARNING,do { do { if (0) printf ("refcount(%d) is < 0", req->refcount ); } while (0); _gf_log ("wb-request", "write-behind.c", __FUNCTION__ , 429, GF_LOG_WARNING, "refcount(%d) is < 0", req->refcount ); } while (0) | |||
429 | "refcount(%d) is < 0", req->refcount)do { do { if (0) printf ("refcount(%d) is < 0", req->refcount ); } while (0); _gf_log ("wb-request", "write-behind.c", __FUNCTION__ , 429, GF_LOG_WARNING, "refcount(%d) is < 0", req->refcount ); } while (0); | |||
430 | req = NULL((void*)0); | |||
431 | goto out; | |||
432 | } | |||
433 | ||||
434 | req->refcount++; | |||
435 | ||||
436 | out: | |||
437 | return req; | |||
438 | } | |||
439 | ||||
440 | ||||
441 | wb_request_t * | |||
442 | wb_request_ref (wb_request_t *req) | |||
443 | { | |||
444 | wb_inode_t *wb_inode = NULL((void*)0); | |||
445 | ||||
446 | GF_VALIDATE_OR_GOTO ("write-behind", req, out)do { if (!req) { (*__errno_location ()) = 22; do { do { if (0 ) printf ("invalid argument: " "req"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 446, GF_LOG_ERROR , "invalid argument: " "req"); } while (0); goto out; } } while (0); | |||
447 | ||||
448 | wb_inode = req->wb_inode; | |||
449 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
450 | { | |||
451 | req = __wb_request_ref (req); | |||
452 | } | |||
453 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
454 | ||||
455 | out: | |||
456 | return req; | |||
457 | } | |||
458 | ||||
459 | ||||
460 | gf_boolean_t | |||
461 | wb_enqueue_common (wb_inode_t *wb_inode, call_stub_t *stub, int tempted) | |||
462 | { | |||
463 | wb_request_t *req = NULL((void*)0); | |||
464 | ||||
465 | GF_VALIDATE_OR_GOTO ("write-behind", wb_inode, out)do { if (!wb_inode) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "wb_inode"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 465, GF_LOG_ERROR , "invalid argument: " "wb_inode"); } while (0); goto out; } } while (0); | |||
466 | GF_VALIDATE_OR_GOTO (wb_inode->this->name, stub, out)do { if (!stub) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "stub"); } while (0); _gf_log_callingfn (wb_inode->this->name, "write-behind.c", __FUNCTION__, 466, GF_LOG_ERROR, "invalid argument: " "stub"); } while (0) ; goto out; } } while (0); | |||
467 | ||||
468 | req = GF_CALLOC (1, sizeof (*req), gf_wb_mt_wb_request_t)__gf_calloc (1, sizeof (*req), gf_wb_mt_wb_request_t); | |||
469 | if (!req) | |||
470 | goto out; | |||
471 | ||||
472 | INIT_LIST_HEAD (&req->all)do { (&req->all)->next = (&req->all)->prev = &req->all; } while (0); | |||
473 | INIT_LIST_HEAD (&req->todo)do { (&req->todo)->next = (&req->todo)->prev = &req->todo; } while (0); | |||
474 | INIT_LIST_HEAD (&req->lie)do { (&req->lie)->next = (&req->lie)->prev = &req->lie; } while (0); | |||
475 | INIT_LIST_HEAD (&req->winds)do { (&req->winds)->next = (&req->winds)-> prev = &req->winds; } while (0); | |||
476 | INIT_LIST_HEAD (&req->unwinds)do { (&req->unwinds)->next = (&req->unwinds) ->prev = &req->unwinds; } while (0); | |||
477 | INIT_LIST_HEAD (&req->wip)do { (&req->wip)->next = (&req->wip)->prev = &req->wip; } while (0); | |||
478 | ||||
479 | req->stub = stub; | |||
480 | req->wb_inode = wb_inode; | |||
481 | req->fop = stub->fop; | |||
482 | req->ordering.tempted = tempted; | |||
483 | ||||
484 | if (stub->fop == GF_FOP_WRITE) { | |||
485 | req->write_size = iov_length (stub->args.vector, | |||
486 | stub->args.count); | |||
487 | ||||
488 | /* req->write_size can change as we collapse | |||
489 | small writes. But the window needs to grow | |||
490 | only by how much we acknowledge the app. so | |||
491 | copy the original size in orig_size for the | |||
492 | purpose of accounting. | |||
493 | */ | |||
494 | req->orig_size = req->write_size; | |||
495 | ||||
496 | /* Let's be optimistic that we can | |||
497 | lie about it | |||
498 | */ | |||
499 | req->op_ret = req->write_size; | |||
500 | req->op_errno = 0; | |||
501 | ||||
502 | if (stub->args.fd->flags & O_APPEND02000) | |||
503 | req->ordering.append = 1; | |||
504 | } | |||
505 | ||||
506 | req->lk_owner = stub->frame->root->lk_owner; | |||
507 | ||||
508 | switch (stub->fop) { | |||
509 | case GF_FOP_WRITE: | |||
510 | req->ordering.off = stub->args.offset; | |||
511 | req->ordering.size = req->write_size; | |||
512 | ||||
513 | req->fd = fd_ref (stub->args.fd); | |||
514 | ||||
515 | break; | |||
516 | case GF_FOP_READ: | |||
517 | req->ordering.off = stub->args.offset; | |||
518 | req->ordering.size = stub->args.size; | |||
519 | ||||
520 | req->fd = fd_ref (stub->args.fd); | |||
521 | ||||
522 | break; | |||
523 | case GF_FOP_TRUNCATE: | |||
524 | req->ordering.off = stub->args.offset; | |||
525 | req->ordering.size = 0; /* till infinity */ | |||
526 | break; | |||
527 | case GF_FOP_FTRUNCATE: | |||
528 | req->ordering.off = stub->args.offset; | |||
529 | req->ordering.size = 0; /* till infinity */ | |||
530 | ||||
531 | req->fd = fd_ref (stub->args.fd); | |||
532 | ||||
533 | break; | |||
534 | default: | |||
535 | break; | |||
536 | } | |||
537 | ||||
538 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
539 | { | |||
540 | list_add_tail (&req->all, &wb_inode->all); | |||
541 | ||||
542 | req->gen = wb_inode->gen; | |||
543 | ||||
544 | list_add_tail (&req->todo, &wb_inode->todo); | |||
545 | __wb_request_ref (req); /* for wind */ | |||
546 | ||||
547 | if (req->ordering.tempted) { | |||
548 | list_add_tail (&req->lie, &wb_inode->temptation); | |||
549 | __wb_request_ref (req); /* for unwind */ | |||
550 | } | |||
551 | } | |||
552 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
553 | ||||
554 | out: | |||
555 | if (!req) | |||
556 | return _gf_false; | |||
557 | ||||
558 | return _gf_true; | |||
559 | } | |||
560 | ||||
561 | ||||
562 | gf_boolean_t | |||
563 | wb_enqueue (wb_inode_t *wb_inode, call_stub_t *stub) | |||
564 | { | |||
565 | return wb_enqueue_common (wb_inode, stub, 0); | |||
566 | } | |||
567 | ||||
568 | ||||
569 | gf_boolean_t | |||
570 | wb_enqueue_tempted (wb_inode_t *wb_inode, call_stub_t *stub) | |||
571 | { | |||
572 | return wb_enqueue_common (wb_inode, stub, 1); | |||
573 | } | |||
574 | ||||
575 | ||||
576 | wb_inode_t * | |||
577 | __wb_inode_create (xlator_t *this, inode_t *inode) | |||
578 | { | |||
579 | wb_inode_t *wb_inode = NULL((void*)0); | |||
580 | wb_conf_t *conf = NULL((void*)0); | |||
581 | ||||
582 | GF_VALIDATE_OR_GOTO (this->name, inode, out)do { if (!inode) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "inode"); } while (0); _gf_log_callingfn (this->name, "write-behind.c", __FUNCTION__, 582, GF_LOG_ERROR , "invalid argument: " "inode"); } while (0); goto out; } } while (0); | |||
583 | ||||
584 | conf = this->private; | |||
585 | ||||
586 | wb_inode = GF_CALLOC (1, sizeof (*wb_inode), gf_wb_mt_wb_inode_t)__gf_calloc (1, sizeof (*wb_inode), gf_wb_mt_wb_inode_t); | |||
587 | if (!wb_inode) | |||
588 | goto out; | |||
589 | ||||
590 | INIT_LIST_HEAD (&wb_inode->all)do { (&wb_inode->all)->next = (&wb_inode->all )->prev = &wb_inode->all; } while (0); | |||
591 | INIT_LIST_HEAD (&wb_inode->todo)do { (&wb_inode->todo)->next = (&wb_inode->todo )->prev = &wb_inode->todo; } while (0); | |||
592 | INIT_LIST_HEAD (&wb_inode->liability)do { (&wb_inode->liability)->next = (&wb_inode-> liability)->prev = &wb_inode->liability; } while (0 ); | |||
593 | INIT_LIST_HEAD (&wb_inode->temptation)do { (&wb_inode->temptation)->next = (&wb_inode ->temptation)->prev = &wb_inode->temptation; } while (0); | |||
594 | INIT_LIST_HEAD (&wb_inode->wip)do { (&wb_inode->wip)->next = (&wb_inode->wip )->prev = &wb_inode->wip; } while (0); | |||
595 | ||||
596 | wb_inode->this = this; | |||
597 | ||||
598 | wb_inode->window_conf = conf->window_size; | |||
599 | ||||
600 | LOCK_INIT (&wb_inode->lock)pthread_spin_init (&wb_inode->lock, 0); | |||
601 | ||||
602 | __inode_ctx_put (inode, this, (uint64_t)(unsigned long)wb_inode); | |||
603 | ||||
604 | out: | |||
605 | return wb_inode; | |||
606 | } | |||
607 | ||||
608 | ||||
609 | wb_inode_t * | |||
610 | wb_inode_create (xlator_t *this, inode_t *inode) | |||
611 | { | |||
612 | wb_inode_t *wb_inode = NULL((void*)0); | |||
613 | ||||
614 | GF_VALIDATE_OR_GOTO (this->name, inode, out)do { if (!inode) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "inode"); } while (0); _gf_log_callingfn (this->name, "write-behind.c", __FUNCTION__, 614, GF_LOG_ERROR , "invalid argument: " "inode"); } while (0); goto out; } } while (0); | |||
615 | ||||
616 | LOCK (&inode->lock)pthread_spin_lock (&inode->lock); | |||
617 | { | |||
618 | wb_inode = __wb_inode_ctx_get (this, inode); | |||
619 | if (!wb_inode) | |||
620 | wb_inode = __wb_inode_create (this, inode); | |||
621 | } | |||
622 | UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock); | |||
623 | ||||
624 | out: | |||
625 | return wb_inode; | |||
626 | } | |||
627 | ||||
628 | ||||
629 | void | |||
630 | wb_inode_destroy (wb_inode_t *wb_inode) | |||
631 | { | |||
632 | GF_VALIDATE_OR_GOTO ("write-behind", wb_inode, out)do { if (!wb_inode) { (*__errno_location ()) = 22; do { do { if (0) printf ("invalid argument: " "wb_inode"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 632, GF_LOG_ERROR , "invalid argument: " "wb_inode"); } while (0); goto out; } } while (0); | |||
633 | ||||
634 | LOCK_DESTROY (&wb_inode->lock)pthread_spin_destroy (&wb_inode->lock); | |||
635 | GF_FREE (wb_inode)__gf_free (wb_inode); | |||
636 | out: | |||
637 | return; | |||
638 | } | |||
639 | ||||
640 | ||||
641 | void | |||
642 | __wb_fulfill_request (wb_request_t *req) | |||
643 | { | |||
644 | wb_inode_t *wb_inode = NULL((void*)0); | |||
645 | ||||
646 | wb_inode = req->wb_inode; | |||
647 | ||||
648 | req->ordering.fulfilled = 1; | |||
649 | wb_inode->window_current -= req->total_size; | |||
650 | wb_inode->transit -= req->total_size; | |||
651 | ||||
652 | if (!req->ordering.lied) { | |||
653 | /* TODO: fail the req->frame with error if | |||
654 | necessary | |||
655 | */ | |||
656 | } | |||
657 | ||||
658 | __wb_request_unref (req); | |||
659 | } | |||
660 | ||||
661 | ||||
662 | void | |||
663 | wb_head_done (wb_request_t *head) | |||
664 | { | |||
665 | wb_request_t *req = NULL((void*)0); | |||
666 | wb_request_t *tmp = NULL((void*)0); | |||
667 | wb_inode_t *wb_inode = NULL((void*)0); | |||
668 | ||||
669 | wb_inode = head->wb_inode; | |||
670 | ||||
671 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
672 | { | |||
673 | list_for_each_entry_safe (req, tmp, &head->winds, winds)for (req = ((typeof(*req) *)((char *)((&head->winds)-> next)-(unsigned long)(&((typeof(*req) *)0)->winds))), tmp = ((typeof(*req) *)((char *)(req->winds.next)-(unsigned long )(&((typeof(*req) *)0)->winds))); &req->winds != (&head->winds); req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->winds.next)-(unsigned long)(&((typeof(*tmp) * )0)->winds)))) { | |||
674 | __wb_fulfill_request (req); | |||
675 | } | |||
676 | __wb_fulfill_request (head); | |||
677 | } | |||
678 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
679 | } | |||
680 | ||||
681 | ||||
682 | void | |||
683 | wb_fulfill_err (wb_request_t *head, int op_errno) | |||
684 | { | |||
685 | wb_inode_t *wb_inode; | |||
686 | wb_request_t *req; | |||
687 | ||||
688 | wb_inode = head->wb_inode; | |||
689 | ||||
690 | /* for all future requests yet to arrive */ | |||
691 | fd_ctx_set (head->fd, THIS(*__glusterfs_this_location()), op_errno); | |||
692 | ||||
693 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
694 | { | |||
695 | /* for all requests already arrived */ | |||
696 | list_for_each_entry (req, &wb_inode->all, all)for (req = ((typeof(*req) *)((char *)((&wb_inode->all) ->next)-(unsigned long)(&((typeof(*req) *)0)->all)) ); &req->all != (&wb_inode->all); req = ((typeof (*req) *)((char *)(req->all.next)-(unsigned long)(&((typeof (*req) *)0)->all)))) { | |||
697 | if (req->fd != head->fd) | |||
698 | continue; | |||
699 | req->op_ret = -1; | |||
700 | req->op_errno = op_errno; | |||
701 | } | |||
702 | } | |||
703 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
704 | } | |||
705 | ||||
706 | ||||
707 | int | |||
708 | wb_fulfill_cbk (call_frame_t *frame, void *cookie, xlator_t *this, | |||
709 | int32_t op_ret, int32_t op_errno, struct iatt *prebuf, | |||
710 | struct iatt *postbuf, dict_t *xdata) | |||
711 | { | |||
712 | wb_inode_t *wb_inode = NULL((void*)0); | |||
713 | wb_request_t *head = NULL((void*)0); | |||
714 | ||||
715 | head = frame->local; | |||
716 | frame->local = NULL((void*)0); | |||
717 | ||||
718 | wb_inode = head->wb_inode; | |||
719 | ||||
720 | if (op_ret == -1) { | |||
721 | wb_fulfill_err (head, op_errno); | |||
722 | } else if (op_ret < head->total_size) { | |||
723 | /* | |||
724 | * We've encountered a short write, for whatever reason. | |||
725 | * Set an EIO error for the next fop. This should be | |||
726 | * valid for writev or flush (close). | |||
727 | * | |||
728 | * TODO: Retry the write so we can potentially capture | |||
729 | * a real error condition (i.e., ENOSPC). | |||
730 | */ | |||
731 | wb_fulfill_err (head, EIO5); | |||
732 | } | |||
733 | ||||
734 | wb_head_done (head); | |||
735 | ||||
736 | wb_process_queue (wb_inode); | |||
737 | ||||
738 | STACK_DESTROY (frame->root); | |||
739 | ||||
740 | return 0; | |||
741 | } | |||
742 | ||||
743 | ||||
744 | #define WB_IOV_LOAD(vec, cnt, req, head)do { memcpy (&vec[cnt], req->stub->args.vector, (req ->stub->args.count * sizeof(vec[0]))); cnt += req->stub ->args.count; head->total_size += req->write_size; } while (0) do { \ | |||
745 | memcpy (&vec[cnt], req->stub->args.vector, \ | |||
746 | (req->stub->args.count * sizeof(vec[0]))); \ | |||
747 | cnt += req->stub->args.count; \ | |||
748 | head->total_size += req->write_size; \ | |||
749 | } while (0) | |||
750 | ||||
751 | ||||
752 | void | |||
753 | wb_fulfill_head (wb_inode_t *wb_inode, wb_request_t *head) | |||
754 | { | |||
755 | struct iovec vector[MAX_VECTOR_COUNT8]; | |||
756 | int count = 0; | |||
757 | wb_request_t *req = NULL((void*)0); | |||
758 | call_frame_t *frame = NULL((void*)0); | |||
759 | gf_boolean_t fderr = _gf_false; | |||
760 | xlator_t *this = NULL((void*)0); | |||
761 | ||||
762 | this = THIS(*__glusterfs_this_location()); | |||
763 | ||||
764 | /* make sure head->total_size is updated before we run into any | |||
765 | * errors | |||
766 | */ | |||
767 | ||||
768 | WB_IOV_LOAD (vector, count, head, head)do { memcpy (&vector[count], head->stub->args.vector , (head->stub->args.count * sizeof(vector[0]))); count += head->stub->args.count; head->total_size += head-> write_size; } while (0); | |||
769 | ||||
770 | list_for_each_entry (req, &head->winds, winds)for (req = ((typeof(*req) *)((char *)((&head->winds)-> next)-(unsigned long)(&((typeof(*req) *)0)->winds))); & req->winds != (&head->winds); req = ((typeof(*req) * )((char *)(req->winds.next)-(unsigned long)(&((typeof( *req) *)0)->winds)))) { | |||
771 | WB_IOV_LOAD (vector, count, req, head)do { memcpy (&vector[count], req->stub->args.vector , (req->stub->args.count * sizeof(vector[0]))); count += req->stub->args.count; head->total_size += req-> write_size; } while (0); | |||
772 | ||||
773 | iobref_merge (head->stub->args.iobref, | |||
774 | req->stub->args.iobref); | |||
775 | } | |||
776 | ||||
777 | if (wb_fd_err (head->fd, this, NULL((void*)0))) { | |||
778 | fderr = _gf_true; | |||
779 | goto err; | |||
780 | } | |||
781 | ||||
782 | frame = create_frame (wb_inode->this, wb_inode->this->ctx->pool); | |||
783 | if (!frame) | |||
784 | goto err; | |||
785 | ||||
786 | frame->root->lk_owner = head->lk_owner; | |||
787 | frame->local = head; | |||
788 | ||||
789 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
790 | { | |||
791 | wb_inode->transit += head->total_size; | |||
792 | } | |||
793 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
794 | ||||
795 | STACK_WIND (frame, wb_fulfill_cbk, FIRST_CHILD (frame->this),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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
796 | FIRST_CHILD (frame->this)->fops->writev,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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
797 | head->fd, vector, count,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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
798 | head->stub->args.offset,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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
799 | head->stub->args.flags,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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
800 | head->stub->args.iobref, 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", "write-behind.c", __FUNCTION__, 800, GF_LOG_ERROR , "alloc failed"); } while (0); break; } typeof( (frame->this ->children->xlator)->fops->writev_cbk) tmp_cbk = wb_fulfill_cbk ; _new->root = frame->root; _new->this = (frame-> this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (frame->this)->fops->writev" ; _new->unwind_to = "wb_fulfill_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 ()) = (frame->this->children->xlator); if (frame-> this->ctx->measure_latency) gf_latency_begin (_new, (frame ->this->children->xlator)->fops->writev); (frame ->this->children->xlator)->fops->writev (_new, (frame->this->children->xlator), head->fd, vector , count, head->stub->args.offset, head->stub->args .flags, head->stub->args.iobref, ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
801 | ||||
802 | return; | |||
803 | err: | |||
804 | if (!fderr) { | |||
805 | /* frame creation failure */ | |||
806 | wb_fulfill_err (head, ENOMEM12); | |||
807 | } | |||
808 | ||||
809 | wb_head_done (head); | |||
810 | ||||
811 | return; | |||
812 | } | |||
813 | ||||
814 | ||||
815 | #define NEXT_HEAD(head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0) do { \ | |||
816 | if (head) \ | |||
817 | wb_fulfill_head (wb_inode, head); \ | |||
818 | head = req; \ | |||
819 | expected_offset = req->stub->args.offset + \ | |||
820 | req->write_size; \ | |||
821 | curr_aggregate = 0; \ | |||
822 | vector_count = 0; \ | |||
823 | } while (0) | |||
824 | ||||
825 | ||||
826 | void | |||
827 | wb_fulfill (wb_inode_t *wb_inode, list_head_t *liabilities) | |||
828 | { | |||
829 | wb_request_t *req = NULL((void*)0); | |||
830 | wb_request_t *head = NULL((void*)0); | |||
831 | wb_request_t *tmp = NULL((void*)0); | |||
832 | wb_conf_t *conf = NULL((void*)0); | |||
833 | off_t expected_offset = 0; | |||
834 | size_t curr_aggregate = 0; | |||
835 | size_t vector_count = 0; | |||
836 | ||||
837 | conf = wb_inode->this->private; | |||
838 | ||||
839 | list_for_each_entry_safe (req, tmp, liabilities, winds)for (req = ((typeof(*req) *)((char *)((liabilities)->next) -(unsigned long)(&((typeof(*req) *)0)->winds))), tmp = ((typeof(*req) *)((char *)(req->winds.next)-(unsigned long )(&((typeof(*req) *)0)->winds))); &req->winds != (liabilities); req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp ->winds.next)-(unsigned long)(&((typeof(*tmp) *)0)-> winds)))) { | |||
840 | list_del_init (&req->winds); | |||
841 | ||||
842 | if (!head) { | |||
843 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
844 | continue; | |||
845 | } | |||
846 | ||||
847 | if (req->fd != head->fd) { | |||
848 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
849 | continue; | |||
850 | } | |||
851 | ||||
852 | if (!is_same_lkowner (&req->lk_owner, &head->lk_owner)) { | |||
853 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
854 | continue; | |||
855 | } | |||
856 | ||||
857 | if (expected_offset != req->stub->args.offset) { | |||
858 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
859 | continue; | |||
860 | } | |||
861 | ||||
862 | if ((curr_aggregate + req->write_size) > conf->aggregate_size) { | |||
863 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
864 | continue; | |||
865 | } | |||
866 | ||||
867 | if (vector_count + req->stub->args.count > | |||
868 | MAX_VECTOR_COUNT8) { | |||
869 | NEXT_HEAD (head, req)do { if (head) wb_fulfill_head (wb_inode, head); head = req; expected_offset = req->stub->args.offset + req->write_size; curr_aggregate = 0; vector_count = 0; } while (0); | |||
870 | continue; | |||
871 | } | |||
872 | ||||
873 | list_add_tail (&req->winds, &head->winds); | |||
874 | curr_aggregate += req->write_size; | |||
875 | vector_count += req->stub->args.count; | |||
876 | } | |||
877 | ||||
878 | if (head) | |||
879 | wb_fulfill_head (wb_inode, head); | |||
880 | return; | |||
881 | } | |||
882 | ||||
883 | ||||
884 | void | |||
885 | wb_do_unwinds (wb_inode_t *wb_inode, list_head_t *lies) | |||
886 | { | |||
887 | wb_request_t *req = NULL((void*)0); | |||
888 | wb_request_t *tmp = NULL((void*)0); | |||
889 | call_frame_t *frame = NULL((void*)0); | |||
890 | struct iatt buf = {0, }; | |||
891 | ||||
892 | list_for_each_entry_safe (req, tmp, lies, unwinds)for (req = ((typeof(*req) *)((char *)((lies)->next)-(unsigned long)(&((typeof(*req) *)0)->unwinds))), tmp = ((typeof (*req) *)((char *)(req->unwinds.next)-(unsigned long)(& ((typeof(*req) *)0)->unwinds))); &req->unwinds != ( lies); req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->unwinds .next)-(unsigned long)(&((typeof(*tmp) *)0)->unwinds)) )) { | |||
893 | frame = req->stub->frame; | |||
| ||||
894 | ||||
895 | STACK_UNWIND_STRICT (writev, frame, req->op_ret, req->op_errno,do { fop_writev_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 896, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_writev_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, req ->op_ret, req->op_errno, &buf, &buf, ((void*)0) ); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
896 | &buf, &buf, NULL)do { fop_writev_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 896, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_writev_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, req ->op_ret, req->op_errno, &buf, &buf, ((void*)0) ); (*__glusterfs_this_location()) = old_THIS; } while (0); /* :O */ | |||
897 | req->stub->frame = NULL((void*)0); | |||
898 | ||||
899 | list_del_init (&req->unwinds); | |||
900 | wb_request_unref (req); | |||
901 | } | |||
902 | ||||
903 | return; | |||
904 | } | |||
905 | ||||
906 | ||||
907 | void | |||
908 | __wb_pick_unwinds (wb_inode_t *wb_inode, list_head_t *lies) | |||
909 | { | |||
910 | wb_request_t *req = NULL((void*)0); | |||
911 | wb_request_t *tmp = NULL((void*)0); | |||
912 | ||||
913 | list_for_each_entry_safe (req, tmp, &wb_inode->temptation, lie)for (req = ((typeof(*req) *)((char *)((&wb_inode->temptation )->next)-(unsigned long)(&((typeof(*req) *)0)->lie) )), tmp = ((typeof(*req) *)((char *)(req->lie.next)-(unsigned long)(&((typeof(*req) *)0)->lie))); &req->lie != (&wb_inode->temptation); req = tmp, tmp = ((typeof(*tmp ) *)((char *)(tmp->lie.next)-(unsigned long)(&((typeof (*tmp) *)0)->lie)))) { | |||
914 | if (!req->ordering.fulfilled && | |||
915 | wb_inode->window_current > wb_inode->window_conf) | |||
916 | continue; | |||
917 | ||||
918 | list_del_init (&req->lie); | |||
919 | list_move_tail (&req->unwinds, lies); | |||
920 | ||||
921 | wb_inode->window_current += req->orig_size; | |||
922 | ||||
923 | if (!req->ordering.fulfilled) { | |||
924 | /* burden increased */ | |||
925 | list_add_tail (&req->lie, &wb_inode->liability); | |||
926 | ||||
927 | req->ordering.lied = 1; | |||
928 | ||||
929 | wb_inode->gen++; | |||
930 | } | |||
931 | } | |||
932 | ||||
933 | return; | |||
934 | } | |||
935 | ||||
936 | ||||
937 | int | |||
938 | __wb_collapse_small_writes (wb_request_t *holder, wb_request_t *req) | |||
939 | { | |||
940 | char *ptr = NULL((void*)0); | |||
941 | struct iobuf *iobuf = NULL((void*)0); | |||
942 | struct iobref *iobref = NULL((void*)0); | |||
943 | int ret = -1; | |||
944 | ssize_t required_size = 0; | |||
945 | size_t holder_len = 0; | |||
946 | size_t req_len = 0; | |||
947 | ||||
948 | if (!holder->iobref) { | |||
949 | holder_len = iov_length (holder->stub->args.vector, | |||
950 | holder->stub->args.count); | |||
951 | req_len = iov_length (req->stub->args.vector, | |||
952 | req->stub->args.count); | |||
953 | ||||
954 | required_size = max ((THIS->ctx->page_size),((((*__glusterfs_this_location())->ctx->page_size))> ((holder_len + req_len))?(((*__glusterfs_this_location())-> ctx->page_size)):((holder_len + req_len))) | |||
955 | (holder_len + req_len))((((*__glusterfs_this_location())->ctx->page_size))> ((holder_len + req_len))?(((*__glusterfs_this_location())-> ctx->page_size)):((holder_len + req_len))); | |||
956 | iobuf = iobuf_get2 (req->wb_inode->this->ctx->iobuf_pool, | |||
957 | required_size); | |||
958 | if (iobuf == NULL((void*)0)) { | |||
959 | goto out; | |||
960 | } | |||
961 | ||||
962 | iobref = iobref_new (); | |||
963 | if (iobref == NULL((void*)0)) { | |||
964 | iobuf_unref (iobuf); | |||
965 | goto out; | |||
966 | } | |||
967 | ||||
968 | ret = iobref_add (iobref, iobuf); | |||
969 | if (ret != 0) { | |||
970 | iobuf_unref (iobuf); | |||
971 | iobref_unref (iobref); | |||
972 | gf_log (req->wb_inode->this->name, GF_LOG_WARNING,do { do { if (0) printf ("cannot add iobuf (%p) into iobref (%p)" , iobuf, iobref); } while (0); _gf_log (req->wb_inode-> this->name, "write-behind.c", __FUNCTION__, 974, GF_LOG_WARNING , "cannot add iobuf (%p) into iobref (%p)", iobuf, iobref); } while (0) | |||
973 | "cannot add iobuf (%p) into iobref (%p)",do { do { if (0) printf ("cannot add iobuf (%p) into iobref (%p)" , iobuf, iobref); } while (0); _gf_log (req->wb_inode-> this->name, "write-behind.c", __FUNCTION__, 974, GF_LOG_WARNING , "cannot add iobuf (%p) into iobref (%p)", iobuf, iobref); } while (0) | |||
974 | iobuf, iobref)do { do { if (0) printf ("cannot add iobuf (%p) into iobref (%p)" , iobuf, iobref); } while (0); _gf_log (req->wb_inode-> this->name, "write-behind.c", __FUNCTION__, 974, GF_LOG_WARNING , "cannot add iobuf (%p) into iobref (%p)", iobuf, iobref); } while (0); | |||
975 | goto out; | |||
976 | } | |||
977 | ||||
978 | iov_unload (iobuf->ptr, holder->stub->args.vector, | |||
979 | holder->stub->args.count); | |||
980 | holder->stub->args.vector[0].iov_base = iobuf->ptr; | |||
981 | holder->stub->args.count = 1; | |||
982 | ||||
983 | iobref_unref (holder->stub->args.iobref); | |||
984 | holder->stub->args.iobref = iobref; | |||
985 | ||||
986 | iobuf_unref (iobuf); | |||
987 | ||||
988 | holder->iobref = iobref_ref (iobref); | |||
989 | } | |||
990 | ||||
991 | ptr = holder->stub->args.vector[0].iov_base + holder->write_size; | |||
992 | ||||
993 | iov_unload (ptr, req->stub->args.vector, | |||
994 | req->stub->args.count); | |||
995 | ||||
996 | holder->stub->args.vector[0].iov_len += req->write_size; | |||
997 | holder->write_size += req->write_size; | |||
998 | holder->ordering.size += req->write_size; | |||
999 | ||||
1000 | ret = 0; | |||
1001 | out: | |||
1002 | return ret; | |||
1003 | } | |||
1004 | ||||
1005 | ||||
1006 | void | |||
1007 | __wb_preprocess_winds (wb_inode_t *wb_inode) | |||
1008 | { | |||
1009 | off_t offset_expected = 0; | |||
1010 | ssize_t space_left = 0; | |||
1011 | wb_request_t *req = NULL((void*)0); | |||
1012 | wb_request_t *tmp = NULL((void*)0); | |||
1013 | wb_request_t *holder = NULL((void*)0); | |||
1014 | wb_conf_t *conf = NULL((void*)0); | |||
1015 | int ret = 0; | |||
1016 | ssize_t page_size = 0; | |||
1017 | ||||
1018 | /* With asynchronous IO from a VM guest (as a file), there | |||
1019 | can be two sequential writes happening in two regions | |||
1020 | of the file. But individual (broken down) IO requests | |||
1021 | can arrive interleaved. | |||
1022 | ||||
1023 | TODO: cycle for each such sequence sifting | |||
1024 | through the interleaved ops | |||
1025 | */ | |||
1026 | ||||
1027 | page_size = wb_inode->this->ctx->page_size; | |||
1028 | conf = wb_inode->this->private; | |||
1029 | ||||
1030 | list_for_each_entry_safe (req, tmp, &wb_inode->todo, todo)for (req = ((typeof(*req) *)((char *)((&wb_inode->todo )->next)-(unsigned long)(&((typeof(*req) *)0)->todo ))), tmp = ((typeof(*req) *)((char *)(req->todo.next)-(unsigned long)(&((typeof(*req) *)0)->todo))); &req->todo != (&wb_inode->todo); req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->todo.next)-(unsigned long)(&((typeof (*tmp) *)0)->todo)))) { | |||
1031 | if (!req->ordering.tempted) { | |||
1032 | if (holder) { | |||
1033 | if (wb_requests_conflict (holder, req)) | |||
1034 | /* do not hold on write if a | |||
1035 | dependent write is in queue */ | |||
1036 | holder->ordering.go = 1; | |||
1037 | } | |||
1038 | /* collapse only non-sync writes */ | |||
1039 | continue; | |||
1040 | } else if (!holder) { | |||
1041 | /* holder is always a non-sync write */ | |||
1042 | holder = req; | |||
1043 | continue; | |||
1044 | } | |||
1045 | ||||
1046 | offset_expected = holder->stub->args.offset | |||
1047 | + holder->write_size; | |||
1048 | ||||
1049 | if (req->stub->args.offset != offset_expected) { | |||
1050 | holder->ordering.go = 1; | |||
1051 | holder = req; | |||
1052 | continue; | |||
1053 | } | |||
1054 | ||||
1055 | if (!is_same_lkowner (&req->lk_owner, &holder->lk_owner)) { | |||
1056 | holder->ordering.go = 1; | |||
1057 | holder = req; | |||
1058 | continue; | |||
1059 | } | |||
1060 | ||||
1061 | if (req->fd != holder->fd) { | |||
1062 | holder->ordering.go = 1; | |||
1063 | holder = req; | |||
1064 | continue; | |||
1065 | } | |||
1066 | ||||
1067 | space_left = page_size - holder->write_size; | |||
1068 | ||||
1069 | if (space_left < req->write_size) { | |||
1070 | holder->ordering.go = 1; | |||
1071 | holder = req; | |||
1072 | continue; | |||
1073 | } | |||
1074 | ||||
1075 | ret = __wb_collapse_small_writes (holder, req); | |||
1076 | if (ret) | |||
1077 | continue; | |||
1078 | ||||
1079 | /* collapsed request is as good as wound | |||
1080 | (from its p.o.v) | |||
1081 | */ | |||
1082 | list_del_init (&req->todo); | |||
1083 | __wb_fulfill_request (req); | |||
1084 | ||||
1085 | /* Only the last @holder in queue which | |||
1086 | ||||
1087 | - does not have any non-buffered-writes following it | |||
1088 | - has not yet filled its capacity | |||
1089 | ||||
1090 | does not get its 'go' set, in anticipation of the arrival | |||
1091 | of consecutive smaller writes. | |||
1092 | */ | |||
1093 | } | |||
1094 | ||||
1095 | /* but if trickling writes are enabled, then do not hold back | |||
1096 | writes if there are no outstanding requests | |||
1097 | */ | |||
1098 | ||||
1099 | if (conf->trickling_writes && !wb_inode->transit && holder) | |||
1100 | holder->ordering.go = 1; | |||
1101 | ||||
1102 | return; | |||
1103 | } | |||
1104 | ||||
1105 | ||||
1106 | void | |||
1107 | __wb_pick_winds (wb_inode_t *wb_inode, list_head_t *tasks, | |||
1108 | list_head_t *liabilities) | |||
1109 | { | |||
1110 | wb_request_t *req = NULL((void*)0); | |||
1111 | wb_request_t *tmp = NULL((void*)0); | |||
1112 | ||||
1113 | list_for_each_entry_safe (req, tmp, &wb_inode->todo, todo)for (req = ((typeof(*req) *)((char *)((&wb_inode->todo )->next)-(unsigned long)(&((typeof(*req) *)0)->todo ))), tmp = ((typeof(*req) *)((char *)(req->todo.next)-(unsigned long)(&((typeof(*req) *)0)->todo))); &req->todo != (&wb_inode->todo); req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->todo.next)-(unsigned long)(&((typeof (*tmp) *)0)->todo)))) { | |||
1114 | if (wb_liability_has_conflict (wb_inode, req)) | |||
1115 | continue; | |||
1116 | ||||
1117 | if (req->ordering.tempted && !req->ordering.go) | |||
1118 | /* wait some more */ | |||
1119 | continue; | |||
1120 | ||||
1121 | if (req->stub->fop == GF_FOP_WRITE) { | |||
1122 | if (wb_wip_has_conflict (wb_inode, req)) | |||
1123 | continue; | |||
1124 | ||||
1125 | list_add_tail (&req->wip, &wb_inode->wip); | |||
1126 | ||||
1127 | if (!req->ordering.tempted) | |||
1128 | /* unrefed in wb_writev_cbk */ | |||
1129 | req->stub->frame->local = | |||
1130 | __wb_request_ref (req); | |||
1131 | } | |||
1132 | ||||
1133 | list_del_init (&req->todo); | |||
1134 | ||||
1135 | if (req->ordering.tempted) | |||
1136 | list_add_tail (&req->winds, liabilities); | |||
1137 | else | |||
1138 | list_add_tail (&req->winds, tasks); | |||
1139 | } | |||
1140 | } | |||
1141 | ||||
1142 | ||||
1143 | void | |||
1144 | wb_do_winds (wb_inode_t *wb_inode, list_head_t *tasks) | |||
1145 | { | |||
1146 | wb_request_t *req = NULL((void*)0); | |||
1147 | wb_request_t *tmp = NULL((void*)0); | |||
1148 | ||||
1149 | list_for_each_entry_safe (req, tmp, tasks, winds)for (req = ((typeof(*req) *)((char *)((tasks)->next)-(unsigned long)(&((typeof(*req) *)0)->winds))), tmp = ((typeof( *req) *)((char *)(req->winds.next)-(unsigned long)(&(( typeof(*req) *)0)->winds))); &req->winds != (tasks) ; req = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->winds.next )-(unsigned long)(&((typeof(*tmp) *)0)->winds)))) { | |||
1150 | list_del_init (&req->winds); | |||
1151 | ||||
1152 | call_resume (req->stub); | |||
1153 | ||||
1154 | wb_request_unref (req); | |||
1155 | } | |||
1156 | } | |||
1157 | ||||
1158 | ||||
1159 | void | |||
1160 | wb_process_queue (wb_inode_t *wb_inode) | |||
1161 | { | |||
1162 | list_head_t tasks = {0, }; | |||
1163 | list_head_t lies = {0, }; | |||
1164 | list_head_t liabilities = {0, }; | |||
1165 | ||||
1166 | INIT_LIST_HEAD (&tasks)do { (&tasks)->next = (&tasks)->prev = &tasks ; } while (0); | |||
1167 | INIT_LIST_HEAD (&lies)do { (&lies)->next = (&lies)->prev = &lies; } while (0); | |||
1168 | INIT_LIST_HEAD (&liabilities)do { (&liabilities)->next = (&liabilities)->prev = &liabilities; } while (0); | |||
1169 | ||||
1170 | LOCK (&wb_inode->lock)pthread_spin_lock (&wb_inode->lock); | |||
1171 | { | |||
1172 | __wb_preprocess_winds (wb_inode); | |||
1173 | ||||
1174 | __wb_pick_winds (wb_inode, &tasks, &liabilities); | |||
1175 | ||||
1176 | __wb_pick_unwinds (wb_inode, &lies); | |||
1177 | ||||
1178 | } | |||
1179 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
1180 | ||||
1181 | wb_do_unwinds (wb_inode, &lies); | |||
1182 | ||||
1183 | wb_do_winds (wb_inode, &tasks); | |||
1184 | ||||
1185 | wb_fulfill (wb_inode, &liabilities); | |||
1186 | ||||
1187 | return; | |||
1188 | } | |||
1189 | ||||
1190 | ||||
1191 | int | |||
1192 | wb_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, | |||
1193 | int32_t op_ret, int32_t op_errno, | |||
1194 | struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) | |||
1195 | { | |||
1196 | wb_request_t *req = NULL((void*)0); | |||
1197 | ||||
1198 | req = frame->local; | |||
1199 | frame->local = NULL((void*)0); | |||
1200 | ||||
1201 | wb_request_unref (req); | |||
1202 | ||||
1203 | STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,do { fop_writev_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1204, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_writev_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, op_ret , op_errno, prebuf, postbuf, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
1204 | xdata)do { fop_writev_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1204, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_writev_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, op_ret , op_errno, prebuf, postbuf, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1205 | return 0; | |||
1206 | } | |||
1207 | ||||
1208 | ||||
1209 | int | |||
1210 | wb_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, | |||
1211 | struct iovec *vector, int32_t count, off_t offset, | |||
1212 | uint32_t flags, struct iobref *iobref, dict_t *xdata) | |||
1213 | { | |||
1214 | STACK_WIND (frame, wb_writev_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", "write-behind.c", __FUNCTION__, 1216, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->writev_cbk) tmp_cbk = wb_writev_cbk; _new->root = frame->root; _new->this = (this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (this)->fops->writev" ; _new->unwind_to = "wb_writev_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->writev); (this->children->xlator )->fops->writev (_new, (this->children->xlator), fd , vector, count, offset, flags, iobref, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
1215 | FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,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", "write-behind.c", __FUNCTION__, 1216, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->writev_cbk) tmp_cbk = wb_writev_cbk; _new->root = frame->root; _new->this = (this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (this)->fops->writev" ; _new->unwind_to = "wb_writev_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->writev); (this->children->xlator )->fops->writev (_new, (this->children->xlator), fd , vector, count, offset, flags, iobref, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
1216 | fd, vector, count, offset, flags, iobref, xdata)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", "write-behind.c", __FUNCTION__, 1216, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->writev_cbk) tmp_cbk = wb_writev_cbk; _new->root = frame->root; _new->this = (this->children->xlator); _new->ret = (ret_fn_t) tmp_cbk ; _new->parent = frame; _new->cookie = _new; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD (this)->fops->writev" ; _new->unwind_to = "wb_writev_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->writev); (this->children->xlator )->fops->writev (_new, (this->children->xlator), fd , vector, count, offset, flags, iobref, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1217 | return 0; | |||
1218 | } | |||
1219 | ||||
1220 | ||||
1221 | int | |||
1222 | wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector, | |||
1223 | int32_t count, off_t offset, uint32_t flags, struct iobref *iobref, | |||
1224 | dict_t *xdata) | |||
1225 | { | |||
1226 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1227 | wb_conf_t *conf = NULL((void*)0); | |||
1228 | gf_boolean_t wb_disabled = 0; | |||
1229 | call_stub_t *stub = NULL((void*)0); | |||
1230 | int ret = -1; | |||
1231 | int32_t op_errno = EINVAL22; | |||
1232 | int o_direct = O_DIRECT040000; | |||
1233 | ||||
1234 | conf = this->private; | |||
1235 | ||||
1236 | if (wb_fd_err (fd, this, &op_errno)) { | |||
1237 | goto unwind; | |||
1238 | } | |||
1239 | ||||
1240 | wb_inode = wb_inode_create (this, fd->inode); | |||
1241 | if (!wb_inode) { | |||
1242 | op_errno = ENOMEM12; | |||
1243 | goto unwind; | |||
1244 | } | |||
1245 | ||||
1246 | if (!conf->strict_O_DIRECT) | |||
1247 | o_direct = 0; | |||
1248 | ||||
1249 | if (fd->flags & (O_SYNC04010000|O_DSYNC010000|o_direct)) | |||
1250 | wb_disabled = 1; | |||
1251 | ||||
1252 | if (flags & (O_SYNC04010000|O_DSYNC010000|O_DIRECT040000)) | |||
1253 | /* O_DIRECT flag in params of writev must _always_ be honored */ | |||
1254 | wb_disabled = 1; | |||
1255 | ||||
1256 | if (wb_disabled) | |||
1257 | stub = fop_writev_stub (frame, wb_writev_helper, fd, vector, | |||
1258 | count, offset, flags, iobref, xdata); | |||
1259 | else | |||
1260 | stub = fop_writev_stub (frame, NULL((void*)0), fd, vector, count, offset, | |||
1261 | flags, iobref, xdata); | |||
1262 | if (!stub) { | |||
1263 | op_errno = ENOMEM12; | |||
1264 | goto unwind; | |||
1265 | } | |||
1266 | ||||
1267 | if (wb_disabled) | |||
1268 | ret = wb_enqueue (wb_inode, stub); | |||
1269 | else | |||
1270 | ret = wb_enqueue_tempted (wb_inode, stub); | |||
1271 | ||||
1272 | if (!ret) { | |||
1273 | op_errno = ENOMEM12; | |||
1274 | goto unwind; | |||
1275 | } | |||
1276 | ||||
1277 | wb_process_queue (wb_inode); | |||
1278 | ||||
1279 | return 0; | |||
1280 | ||||
1281 | unwind: | |||
1282 | STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, NULL)do { fop_writev_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1282, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_writev_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , op_errno, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1283 | ||||
1284 | if (stub) | |||
1285 | call_stub_destroy (stub); | |||
1286 | ||||
1287 | return 0; | |||
1288 | } | |||
1289 | ||||
1290 | ||||
1291 | int | |||
1292 | wb_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, | |||
1293 | off_t offset, uint32_t flags, dict_t *xdata) | |||
1294 | { | |||
1295 | STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1297, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
1296 | FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,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", "write-behind.c", __FUNCTION__, 1297, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
1297 | xdata)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", "write-behind.c", __FUNCTION__, 1297, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1298 | return 0; | |||
1299 | } | |||
1300 | ||||
1301 | ||||
1302 | int | |||
1303 | wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, | |||
1304 | off_t offset, uint32_t flags, dict_t *xdata) | |||
1305 | { | |||
1306 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1307 | call_stub_t *stub = NULL((void*)0); | |||
1308 | ||||
1309 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1310 | if (!wb_inode) | |||
1311 | goto noqueue; | |||
1312 | ||||
1313 | stub = fop_readv_stub (frame, wb_readv_helper, fd, size, | |||
1314 | offset, flags, xdata); | |||
1315 | if (!stub) | |||
1316 | goto unwind; | |||
1317 | ||||
1318 | if (!wb_enqueue (wb_inode, stub)) | |||
1319 | goto unwind; | |||
1320 | ||||
1321 | wb_process_queue (wb_inode); | |||
1322 | ||||
1323 | return 0; | |||
1324 | ||||
1325 | unwind: | |||
1326 | STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM, NULL, 0, NULL, NULL,do { fop_readv_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1327, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_readv_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), 0, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
1327 | NULL)do { fop_readv_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1327, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_readv_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), 0, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1328 | return 0; | |||
1329 | ||||
1330 | noqueue: | |||
1331 | STACK_WIND (frame, default_readv_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1333, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
1332 | FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,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", "write-behind.c", __FUNCTION__, 1333, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
1333 | xdata)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", "write-behind.c", __FUNCTION__, 1333, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->readv_cbk) tmp_cbk = default_readv_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->readv" ; _new->unwind_to = "default_readv_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->readv); (this->children->xlator )->fops->readv (_new, (this->children->xlator), fd , size, offset, flags, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1334 | return 0; | |||
1335 | } | |||
1336 | ||||
1337 | ||||
1338 | int | |||
1339 | wb_flush_bg_cbk (call_frame_t *frame, void *cookie, xlator_t *this, | |||
1340 | int32_t op_ret, int32_t op_errno, dict_t *xdata) | |||
1341 | { | |||
1342 | STACK_DESTROY (frame->root); | |||
1343 | return 0; | |||
1344 | } | |||
1345 | ||||
1346 | ||||
1347 | int | |||
1348 | wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) | |||
1349 | { | |||
1350 | wb_conf_t *conf = NULL((void*)0); | |||
1351 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1352 | call_frame_t *bg_frame = NULL((void*)0); | |||
1353 | int32_t op_errno = 0; | |||
1354 | int op_ret = 0; | |||
1355 | ||||
1356 | conf = this->private; | |||
1357 | ||||
1358 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1359 | if (!wb_inode) { | |||
1360 | op_ret = -1; | |||
1361 | op_errno = EINVAL22; | |||
1362 | goto unwind; | |||
1363 | } | |||
1364 | ||||
1365 | if (wb_fd_err (fd, this, &op_errno)) { | |||
1366 | op_ret = -1; | |||
1367 | goto unwind; | |||
1368 | } | |||
1369 | ||||
1370 | if (conf->flush_behind) | |||
1371 | goto flushbehind; | |||
1372 | ||||
1373 | STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1374, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = default_flush_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "default_flush_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->flush); (this->children->xlator )->fops->flush (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1374 | FIRST_CHILD(this)->fops->flush, fd, xdata)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", "write-behind.c", __FUNCTION__, 1374, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = default_flush_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "default_flush_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->flush); (this->children->xlator )->fops->flush (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1375 | return 0; | |||
1376 | ||||
1377 | flushbehind: | |||
1378 | bg_frame = copy_frame (frame); | |||
1379 | if (!bg_frame) { | |||
1380 | op_ret = -1; | |||
1381 | op_errno = ENOMEM12; | |||
1382 | goto unwind; | |||
1383 | } | |||
1384 | ||||
1385 | STACK_WIND (bg_frame, wb_flush_bg_cbk, FIRST_CHILD(this),do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (bg_frame->root->pool->frame_mem_pool ); if (!_new) { do { do { if (0) printf ("alloc failed"); } while (0); _gf_log ("stack", "write-behind.c", __FUNCTION__, 1386, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = wb_flush_bg_cbk; _new->root = bg_frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = bg_frame; _new->cookie = _new ; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "wb_flush_bg_cbk"; pthread_spin_init ( &_new->lock, 0); pthread_spin_lock (&bg_frame-> root->stack_lock); { _new->next = bg_frame->root-> frames.next; _new->prev = &bg_frame->root->frames ; if (bg_frame->root->frames.next) bg_frame->root-> frames.next->prev = _new; bg_frame->root->frames.next = _new; bg_frame->ref_count++; } pthread_spin_unlock (& bg_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (this->children-> xlator); if (bg_frame->this->ctx->measure_latency) gf_latency_begin (_new, (this->children->xlator)->fops->flush); ( this->children->xlator)->fops->flush (_new, (this ->children->xlator), fd, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0) | |||
1386 | FIRST_CHILD(this)->fops->flush, fd, xdata)do { call_frame_t *_new = ((void*)0); xlator_t *old_THIS = (( void*)0); _new = mem_get0 (bg_frame->root->pool->frame_mem_pool ); if (!_new) { do { do { if (0) printf ("alloc failed"); } while (0); _gf_log ("stack", "write-behind.c", __FUNCTION__, 1386, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = wb_flush_bg_cbk; _new->root = bg_frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = bg_frame; _new->cookie = _new ; _new->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "wb_flush_bg_cbk"; pthread_spin_init ( &_new->lock, 0); pthread_spin_lock (&bg_frame-> root->stack_lock); { _new->next = bg_frame->root-> frames.next; _new->prev = &bg_frame->root->frames ; if (bg_frame->root->frames.next) bg_frame->root-> frames.next->prev = _new; bg_frame->root->frames.next = _new; bg_frame->ref_count++; } pthread_spin_unlock (& bg_frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = (this->children-> xlator); if (bg_frame->this->ctx->measure_latency) gf_latency_begin (_new, (this->children->xlator)->fops->flush); ( this->children->xlator)->fops->flush (_new, (this ->children->xlator), fd, xdata); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1387 | /* fall through */ | |||
1388 | unwind: | |||
1389 | STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, NULL)do { fop_flush_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1389, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_flush_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, op_ret , op_errno, ((void*)0)); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1390 | ||||
1391 | return 0; | |||
1392 | } | |||
1393 | ||||
1394 | ||||
1395 | int | |||
1396 | wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) | |||
1397 | { | |||
1398 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1399 | call_stub_t *stub = NULL((void*)0); | |||
1400 | ||||
1401 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1402 | if (!wb_inode) | |||
1403 | goto noqueue; | |||
1404 | ||||
1405 | stub = fop_flush_stub (frame, wb_flush_helper, fd, xdata); | |||
1406 | if (!stub) | |||
1407 | goto unwind; | |||
1408 | ||||
1409 | if (!wb_enqueue (wb_inode, stub)) | |||
1410 | goto unwind; | |||
1411 | ||||
1412 | wb_process_queue (wb_inode); | |||
1413 | ||||
1414 | return 0; | |||
1415 | ||||
1416 | unwind: | |||
1417 | STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL)do { fop_flush_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1417, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_flush_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1418 | ||||
1419 | return 0; | |||
1420 | ||||
1421 | noqueue: | |||
1422 | STACK_WIND (frame, default_flush_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1423, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = default_flush_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "default_flush_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->flush); (this->children->xlator )->fops->flush (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1423 | FIRST_CHILD(this)->fops->flush, fd, xdata)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", "write-behind.c", __FUNCTION__, 1423, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->flush_cbk) tmp_cbk = default_flush_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->flush" ; _new->unwind_to = "default_flush_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->flush); (this->children->xlator )->fops->flush (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1424 | return 0; | |||
1425 | } | |||
1426 | ||||
1427 | ||||
1428 | ||||
1429 | int | |||
1430 | wb_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, | |||
1431 | int32_t datasync, dict_t *xdata) | |||
1432 | { | |||
1433 | STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1434, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsync_cbk) tmp_cbk = default_fsync_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsync" ; _new->unwind_to = "default_fsync_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsync); (this->children->xlator )->fops->fsync (_new, (this->children->xlator), fd , datasync, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1434 | FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata)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", "write-behind.c", __FUNCTION__, 1434, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsync_cbk) tmp_cbk = default_fsync_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsync" ; _new->unwind_to = "default_fsync_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsync); (this->children->xlator )->fops->fsync (_new, (this->children->xlator), fd , datasync, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1435 | return 0; | |||
1436 | } | |||
1437 | ||||
1438 | ||||
1439 | int | |||
1440 | wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, | |||
1441 | dict_t *xdata) | |||
1442 | { | |||
1443 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1444 | call_stub_t *stub = NULL((void*)0); | |||
1445 | int32_t op_errno = EINVAL22; | |||
1446 | ||||
1447 | if (wb_fd_err (fd, this, &op_errno)) | |||
1448 | goto unwind; | |||
1449 | ||||
1450 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1451 | if (!wb_inode) | |||
1452 | goto noqueue; | |||
1453 | ||||
1454 | stub = fop_fsync_stub (frame, wb_fsync_helper, fd, datasync, xdata); | |||
1455 | if (!stub) | |||
1456 | goto unwind; | |||
1457 | ||||
1458 | if (!wb_enqueue (wb_inode, stub)) | |||
1459 | goto unwind; | |||
1460 | ||||
1461 | wb_process_queue (wb_inode); | |||
1462 | ||||
1463 | return 0; | |||
1464 | ||||
1465 | unwind: | |||
1466 | STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, NULL)do { fop_fsync_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1466, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_fsync_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , op_errno, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1467 | ||||
1468 | return 0; | |||
1469 | ||||
1470 | noqueue: | |||
1471 | STACK_WIND (frame, default_fsync_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1472, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsync_cbk) tmp_cbk = default_fsync_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsync" ; _new->unwind_to = "default_fsync_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsync); (this->children->xlator )->fops->fsync (_new, (this->children->xlator), fd , datasync, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1472 | FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata)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", "write-behind.c", __FUNCTION__, 1472, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsync_cbk) tmp_cbk = default_fsync_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsync" ; _new->unwind_to = "default_fsync_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsync); (this->children->xlator )->fops->fsync (_new, (this->children->xlator), fd , datasync, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1473 | return 0; | |||
1474 | } | |||
1475 | ||||
1476 | ||||
1477 | int | |||
1478 | wb_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) | |||
1479 | { | |||
1480 | STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1481, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->stat_cbk) tmp_cbk = default_stat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->stat" ; _new->unwind_to = "default_stat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->stat); (this->children->xlator )->fops->stat (_new, (this->children->xlator), loc , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1481 | FIRST_CHILD(this)->fops->stat, loc, xdata)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", "write-behind.c", __FUNCTION__, 1481, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->stat_cbk) tmp_cbk = default_stat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->stat" ; _new->unwind_to = "default_stat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->stat); (this->children->xlator )->fops->stat (_new, (this->children->xlator), loc , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1482 | return 0; | |||
1483 | } | |||
1484 | ||||
1485 | ||||
1486 | int | |||
1487 | wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) | |||
1488 | { | |||
1489 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1490 | call_stub_t *stub = NULL((void*)0); | |||
1491 | ||||
1492 | ||||
1493 | wb_inode = wb_inode_ctx_get (this, loc->inode); | |||
1494 | if (!wb_inode) | |||
1495 | goto noqueue; | |||
1496 | ||||
1497 | stub = fop_stat_stub (frame, wb_stat_helper, loc, xdata); | |||
1498 | if (!stub) | |||
1499 | goto unwind; | |||
1500 | ||||
1501 | if (!wb_enqueue (wb_inode, stub)) | |||
1502 | goto unwind; | |||
1503 | ||||
1504 | wb_process_queue (wb_inode); | |||
1505 | ||||
1506 | return 0; | |||
1507 | ||||
1508 | unwind: | |||
1509 | STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM, NULL, NULL)do { fop_stat_cbk_t fn = ((void*)0); call_frame_t *_parent = ( (void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1509, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_stat_cbk_t )frame->ret; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1510 | ||||
1511 | if (stub) | |||
1512 | call_stub_destroy (stub); | |||
1513 | return 0; | |||
1514 | ||||
1515 | noqueue: | |||
1516 | STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1517, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->stat_cbk) tmp_cbk = default_stat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->stat" ; _new->unwind_to = "default_stat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->stat); (this->children->xlator )->fops->stat (_new, (this->children->xlator), loc , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1517 | FIRST_CHILD(this)->fops->stat, loc, xdata)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", "write-behind.c", __FUNCTION__, 1517, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->stat_cbk) tmp_cbk = default_stat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->stat" ; _new->unwind_to = "default_stat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->stat); (this->children->xlator )->fops->stat (_new, (this->children->xlator), loc , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1518 | return 0; | |||
1519 | } | |||
1520 | ||||
1521 | ||||
1522 | int | |||
1523 | wb_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) | |||
1524 | { | |||
1525 | STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1526, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fstat_cbk) tmp_cbk = default_fstat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fstat" ; _new->unwind_to = "default_fstat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fstat); (this->children->xlator )->fops->fstat (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1526 | FIRST_CHILD(this)->fops->fstat, fd, xdata)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", "write-behind.c", __FUNCTION__, 1526, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fstat_cbk) tmp_cbk = default_fstat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fstat" ; _new->unwind_to = "default_fstat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fstat); (this->children->xlator )->fops->fstat (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1527 | return 0; | |||
1528 | } | |||
1529 | ||||
1530 | ||||
1531 | int | |||
1532 | wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) | |||
1533 | { | |||
1534 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1535 | call_stub_t *stub = NULL((void*)0); | |||
1536 | ||||
1537 | ||||
1538 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1539 | if (!wb_inode) | |||
1540 | goto noqueue; | |||
1541 | ||||
1542 | stub = fop_fstat_stub (frame, wb_fstat_helper, fd, xdata); | |||
1543 | if (!stub) | |||
1544 | goto unwind; | |||
1545 | ||||
1546 | if (!wb_enqueue (wb_inode, stub)) | |||
1547 | goto unwind; | |||
1548 | ||||
1549 | wb_process_queue (wb_inode); | |||
1550 | ||||
1551 | return 0; | |||
1552 | ||||
1553 | unwind: | |||
1554 | STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL, NULL)do { fop_fstat_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1554, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_fstat_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1555 | ||||
1556 | if (stub) | |||
1557 | call_stub_destroy (stub); | |||
1558 | return 0; | |||
1559 | ||||
1560 | noqueue: | |||
1561 | STACK_WIND (frame, default_fstat_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1562, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fstat_cbk) tmp_cbk = default_fstat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fstat" ; _new->unwind_to = "default_fstat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fstat); (this->children->xlator )->fops->fstat (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0) | |||
1562 | FIRST_CHILD(this)->fops->fstat, fd, xdata)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", "write-behind.c", __FUNCTION__, 1562, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fstat_cbk) tmp_cbk = default_fstat_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fstat" ; _new->unwind_to = "default_fstat_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fstat); (this->children->xlator )->fops->fstat (_new, (this->children->xlator), fd , xdata); (*__glusterfs_this_location()) = old_THIS; } while ( 0); | |||
1563 | return 0; | |||
1564 | } | |||
1565 | ||||
1566 | ||||
1567 | int | |||
1568 | wb_truncate_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, | |||
1569 | off_t offset, dict_t *xdata) | |||
1570 | { | |||
1571 | STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1572, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->truncate_cbk) tmp_cbk = default_truncate_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->truncate" ; _new->unwind_to = "default_truncate_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->truncate); (this->children->xlator )->fops->truncate (_new, (this->children->xlator) , loc, offset, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1572 | FIRST_CHILD(this)->fops->truncate, loc, offset, xdata)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", "write-behind.c", __FUNCTION__, 1572, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->truncate_cbk) tmp_cbk = default_truncate_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->truncate" ; _new->unwind_to = "default_truncate_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->truncate); (this->children->xlator )->fops->truncate (_new, (this->children->xlator) , loc, offset, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1573 | return 0; | |||
1574 | } | |||
1575 | ||||
1576 | ||||
1577 | int | |||
1578 | wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, | |||
1579 | dict_t *xdata) | |||
1580 | { | |||
1581 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1582 | call_stub_t *stub = NULL((void*)0); | |||
1583 | ||||
1584 | wb_inode = wb_inode_create (this, loc->inode); | |||
1585 | if (!wb_inode) | |||
1586 | goto unwind; | |||
1587 | ||||
1588 | stub = fop_truncate_stub (frame, wb_truncate_helper, loc, | |||
1589 | offset, xdata); | |||
1590 | if (!stub) | |||
1591 | goto unwind; | |||
1592 | ||||
1593 | if (!wb_enqueue (wb_inode, stub)) | |||
1594 | goto unwind; | |||
1595 | ||||
1596 | wb_process_queue (wb_inode); | |||
1597 | ||||
1598 | return 0; | |||
1599 | ||||
1600 | unwind: | |||
1601 | STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL)do { fop_truncate_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1601, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_truncate_cbk_t )frame-> ret; _parent = frame->parent; pthread_spin_lock (&frame ->root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1602 | ||||
1603 | if (stub) | |||
1604 | call_stub_destroy (stub); | |||
1605 | ||||
1606 | return 0; | |||
1607 | } | |||
1608 | ||||
1609 | ||||
1610 | int | |||
1611 | wb_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, | |||
1612 | off_t offset, dict_t *xdata) | |||
1613 | { | |||
1614 | STACK_WIND (frame, default_ftruncate_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1615, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->ftruncate_cbk) tmp_cbk = default_ftruncate_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->ftruncate" ; _new->unwind_to = "default_ftruncate_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->ftruncate); (this->children-> xlator)->fops->ftruncate (_new, (this->children-> xlator), fd, offset, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0) | |||
1615 | FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata)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", "write-behind.c", __FUNCTION__, 1615, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->ftruncate_cbk) tmp_cbk = default_ftruncate_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->ftruncate" ; _new->unwind_to = "default_ftruncate_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->ftruncate); (this->children-> xlator)->fops->ftruncate (_new, (this->children-> xlator), fd, offset, xdata); (*__glusterfs_this_location()) = old_THIS; } while (0); | |||
1616 | return 0; | |||
1617 | } | |||
1618 | ||||
1619 | ||||
1620 | int | |||
1621 | wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, | |||
1622 | dict_t *xdata) | |||
1623 | { | |||
1624 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1625 | call_stub_t *stub = NULL((void*)0); | |||
1626 | int32_t op_errno = 0; | |||
1627 | ||||
1628 | wb_inode = wb_inode_create (this, fd->inode); | |||
1629 | if (!wb_inode) { | |||
1630 | op_errno = ENOMEM12; | |||
1631 | goto unwind; | |||
1632 | } | |||
1633 | ||||
1634 | if (wb_fd_err (fd, this, &op_errno)) | |||
1635 | goto unwind; | |||
1636 | ||||
1637 | stub = fop_ftruncate_stub (frame, wb_ftruncate_helper, fd, | |||
1638 | offset, xdata); | |||
1639 | if (!stub) { | |||
1640 | op_errno = ENOMEM12; | |||
1641 | goto unwind; | |||
1642 | } | |||
1643 | ||||
1644 | if (!wb_enqueue (wb_inode, stub)) { | |||
1645 | op_errno = ENOMEM12; | |||
1646 | goto unwind; | |||
1647 | } | |||
1648 | ||||
1649 | wb_process_queue (wb_inode); | |||
1650 | ||||
1651 | return 0; | |||
1652 | ||||
1653 | unwind: | |||
1654 | STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, NULL)do { fop_ftruncate_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1654, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_ftruncate_cbk_t )frame-> ret; _parent = frame->parent; pthread_spin_lock (&frame ->root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , op_errno, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1655 | ||||
1656 | if (stub) | |||
1657 | call_stub_destroy (stub); | |||
1658 | return 0; | |||
1659 | } | |||
1660 | ||||
1661 | ||||
1662 | int | |||
1663 | wb_setattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, | |||
1664 | struct iatt *stbuf, int32_t valid, dict_t *xdata) | |||
1665 | { | |||
1666 | STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1667, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->setattr_cbk) tmp_cbk = default_setattr_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->setattr" ; _new->unwind_to = "default_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->setattr); (this->children->xlator )->fops->setattr (_new, (this->children->xlator), loc, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1667 | FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata)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", "write-behind.c", __FUNCTION__, 1667, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->setattr_cbk) tmp_cbk = default_setattr_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->setattr" ; _new->unwind_to = "default_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->setattr); (this->children->xlator )->fops->setattr (_new, (this->children->xlator), loc, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1668 | return 0; | |||
1669 | } | |||
1670 | ||||
1671 | ||||
1672 | int | |||
1673 | wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, | |||
1674 | struct iatt *stbuf, int32_t valid, dict_t *xdata) | |||
1675 | { | |||
1676 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1677 | call_stub_t *stub = NULL((void*)0); | |||
1678 | ||||
1679 | wb_inode = wb_inode_ctx_get (this, loc->inode); | |||
1680 | if (!wb_inode) | |||
1681 | goto noqueue; | |||
1682 | ||||
1683 | stub = fop_setattr_stub (frame, wb_setattr_helper, loc, stbuf, | |||
1684 | valid, xdata); | |||
1685 | if (!stub) | |||
1686 | goto unwind; | |||
1687 | ||||
1688 | if (!wb_enqueue (wb_inode, stub)) | |||
1689 | goto unwind; | |||
1690 | ||||
1691 | wb_process_queue (wb_inode); | |||
1692 | ||||
1693 | return 0; | |||
1694 | unwind: | |||
1695 | STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL)do { fop_setattr_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1695, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_setattr_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1696 | ||||
1697 | if (stub) | |||
1698 | call_stub_destroy (stub); | |||
1699 | return 0; | |||
1700 | ||||
1701 | noqueue: | |||
1702 | STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1703, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->setattr_cbk) tmp_cbk = default_setattr_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->setattr" ; _new->unwind_to = "default_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->setattr); (this->children->xlator )->fops->setattr (_new, (this->children->xlator), loc, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1703 | FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata)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", "write-behind.c", __FUNCTION__, 1703, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->setattr_cbk) tmp_cbk = default_setattr_cbk; _new->root = frame->root; _new-> this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->setattr" ; _new->unwind_to = "default_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->setattr); (this->children->xlator )->fops->setattr (_new, (this->children->xlator), loc, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1704 | return 0; | |||
1705 | } | |||
1706 | ||||
1707 | ||||
1708 | int | |||
1709 | wb_fsetattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, | |||
1710 | struct iatt *stbuf, int32_t valid, dict_t *xdata) | |||
1711 | { | |||
1712 | STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1713, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsetattr_cbk) tmp_cbk = default_fsetattr_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsetattr" ; _new->unwind_to = "default_fsetattr_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsetattr); (this->children->xlator )->fops->fsetattr (_new, (this->children->xlator) , fd, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1713 | FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata)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", "write-behind.c", __FUNCTION__, 1713, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsetattr_cbk) tmp_cbk = default_fsetattr_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsetattr" ; _new->unwind_to = "default_fsetattr_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsetattr); (this->children->xlator )->fops->fsetattr (_new, (this->children->xlator) , fd, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1714 | return 0; | |||
1715 | } | |||
1716 | ||||
1717 | ||||
1718 | int | |||
1719 | wb_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, | |||
1720 | struct iatt *stbuf, int32_t valid, dict_t *xdata) | |||
1721 | { | |||
1722 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1723 | call_stub_t *stub = NULL((void*)0); | |||
1724 | ||||
1725 | wb_inode = wb_inode_ctx_get (this, fd->inode); | |||
1726 | if (!wb_inode) | |||
| ||||
1727 | goto noqueue; | |||
1728 | ||||
1729 | stub = fop_fsetattr_stub (frame, wb_fsetattr_helper, fd, stbuf, | |||
1730 | valid, xdata); | |||
1731 | if (!stub) | |||
1732 | goto unwind; | |||
1733 | ||||
1734 | if (!wb_enqueue (wb_inode, stub)) | |||
1735 | goto unwind; | |||
1736 | ||||
1737 | wb_process_queue (wb_inode); | |||
1738 | ||||
1739 | return 0; | |||
1740 | unwind: | |||
1741 | STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL)do { fop_fsetattr_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "write-behind.c", __FUNCTION__, 1741, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_fsetattr_cbk_t )frame-> ret; _parent = frame->parent; pthread_spin_lock (&frame ->root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, -1 , 12, ((void*)0), ((void*)0), ((void*)0)); (*__glusterfs_this_location ()) = old_THIS; } while (0); | |||
1742 | ||||
1743 | if (stub) | |||
1744 | call_stub_destroy (stub); | |||
1745 | return 0; | |||
1746 | ||||
1747 | noqueue: | |||
1748 | STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this),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", "write-behind.c", __FUNCTION__, 1749, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsetattr_cbk) tmp_cbk = default_fsetattr_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsetattr" ; _new->unwind_to = "default_fsetattr_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsetattr); (this->children->xlator )->fops->fsetattr (_new, (this->children->xlator) , fd, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0) | |||
1749 | FIRST_CHILD(this)->fops->fsetattr, fd, stbuf, valid, xdata)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", "write-behind.c", __FUNCTION__, 1749, GF_LOG_ERROR, "alloc failed"); } while (0); break; } typeof( (this->children->xlator)->fops->fsetattr_cbk) tmp_cbk = default_fsetattr_cbk; _new->root = frame->root; _new ->this = (this->children->xlator); _new->ret = (ret_fn_t ) tmp_cbk; _new->parent = frame; _new->cookie = _new; _new ->wind_from = __FUNCTION__; _new->wind_to = "FIRST_CHILD(this)->fops->fsetattr" ; _new->unwind_to = "default_fsetattr_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 ()) = (this->children->xlator); if (frame->this-> ctx->measure_latency) gf_latency_begin (_new, (this->children ->xlator)->fops->fsetattr); (this->children->xlator )->fops->fsetattr (_new, (this->children->xlator) , fd, stbuf, valid, xdata); (*__glusterfs_this_location()) = old_THIS ; } while (0); | |||
1750 | return 0; | |||
1751 | } | |||
1752 | ||||
1753 | ||||
1754 | int | |||
1755 | wb_forget (xlator_t *this, inode_t *inode) | |||
1756 | { | |||
1757 | uint64_t tmp = 0; | |||
1758 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1759 | ||||
1760 | inode_ctx_del (inode, this, &tmp)inode_ctx_del2(inode,this,&tmp,0); | |||
1761 | ||||
1762 | wb_inode = (wb_inode_t *)(long)tmp; | |||
1763 | ||||
1764 | if (!wb_inode) | |||
1765 | return 0; | |||
1766 | ||||
1767 | GF_ASSERT (list_empty (&wb_inode->todo))do { if (!(list_empty (&wb_inode->todo))) { do { do { if (0) printf ("Assertion failed: " "list_empty (&wb_inode->todo)" ); } while (0); _gf_log_callingfn ("", "write-behind.c", __FUNCTION__ , 1767, GF_LOG_ERROR, "Assertion failed: " "list_empty (&wb_inode->todo)" ); } while (0); } } while (0); | |||
1768 | GF_ASSERT (list_empty (&wb_inode->liability))do { if (!(list_empty (&wb_inode->liability))) { do { do { if (0) printf ("Assertion failed: " "list_empty (&wb_inode->liability)" ); } while (0); _gf_log_callingfn ("", "write-behind.c", __FUNCTION__ , 1768, GF_LOG_ERROR, "Assertion failed: " "list_empty (&wb_inode->liability)" ); } while (0); } } while (0); | |||
1769 | GF_ASSERT (list_empty (&wb_inode->temptation))do { if (!(list_empty (&wb_inode->temptation))) { do { do { if (0) printf ("Assertion failed: " "list_empty (&wb_inode->temptation)" ); } while (0); _gf_log_callingfn ("", "write-behind.c", __FUNCTION__ , 1769, GF_LOG_ERROR, "Assertion failed: " "list_empty (&wb_inode->temptation)" ); } while (0); } } while (0); | |||
1770 | ||||
1771 | GF_FREE (wb_inode)__gf_free (wb_inode); | |||
1772 | ||||
1773 | return 0; | |||
1774 | } | |||
1775 | ||||
1776 | ||||
1777 | int | |||
1778 | wb_release (xlator_t *this, fd_t *fd) | |||
1779 | { | |||
1780 | uint64_t tmp = 0; | |||
1781 | ||||
1782 | fd_ctx_del (fd, this, &tmp); | |||
1783 | ||||
1784 | return 0; | |||
1785 | } | |||
1786 | ||||
1787 | ||||
1788 | int | |||
1789 | wb_priv_dump (xlator_t *this) | |||
1790 | { | |||
1791 | wb_conf_t *conf = NULL((void*)0); | |||
1792 | char key_prefix[GF_DUMP_MAX_BUF_LEN4096] = {0, }; | |||
1793 | int ret = -1; | |||
1794 | ||||
1795 | GF_VALIDATE_OR_GOTO ("write-behind", this, out)do { if (!this) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 1795, GF_LOG_ERROR , "invalid argument: " "this"); } while (0); goto out; } } while (0); | |||
1796 | ||||
1797 | conf = this->private; | |||
1798 | GF_VALIDATE_OR_GOTO (this->name, conf, out)do { if (!conf) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "conf"); } while (0); _gf_log_callingfn (this->name, "write-behind.c", __FUNCTION__, 1798, GF_LOG_ERROR , "invalid argument: " "conf"); } while (0); goto out; } } while (0); | |||
1799 | ||||
1800 | gf_proc_dump_build_key (key_prefix, "xlator.performance.write-behind",{ _gf_proc_dump_build_key(key_prefix, "xlator.performance.write-behind" , "priv"); } | |||
1801 | "priv"){ _gf_proc_dump_build_key(key_prefix, "xlator.performance.write-behind" , "priv"); }; | |||
1802 | ||||
1803 | gf_proc_dump_add_section (key_prefix); | |||
1804 | ||||
1805 | gf_proc_dump_write ("aggregate_size", "%d", conf->aggregate_size); | |||
1806 | gf_proc_dump_write ("window_size", "%d", conf->window_size); | |||
1807 | gf_proc_dump_write ("flush_behind", "%d", conf->flush_behind); | |||
1808 | gf_proc_dump_write ("trickling_writes", "%d", conf->trickling_writes); | |||
1809 | ||||
1810 | ret = 0; | |||
1811 | out: | |||
1812 | return ret; | |||
1813 | } | |||
1814 | ||||
1815 | ||||
1816 | void | |||
1817 | __wb_dump_requests (struct list_head *head, char *prefix) | |||
1818 | { | |||
1819 | char key[GF_DUMP_MAX_BUF_LEN4096] = {0, }; | |||
1820 | char key_prefix[GF_DUMP_MAX_BUF_LEN4096] = {0, }, flag = 0; | |||
1821 | wb_request_t *req = NULL((void*)0); | |||
1822 | ||||
1823 | list_for_each_entry (req, head, all)for (req = ((typeof(*req) *)((char *)((head)->next)-(unsigned long)(&((typeof(*req) *)0)->all))); &req->all != (head); req = ((typeof(*req) *)((char *)(req->all.next)-( unsigned long)(&((typeof(*req) *)0)->all)))) { | |||
1824 | gf_proc_dump_build_key (key_prefix, key,{ _gf_proc_dump_build_key(key_prefix, key, (char *)gf_fop_list [req->fop]); } | |||
1825 | (char *)gf_fop_list[req->fop]){ _gf_proc_dump_build_key(key_prefix, key, (char *)gf_fop_list [req->fop]); }; | |||
1826 | ||||
1827 | gf_proc_dump_add_section(key_prefix); | |||
1828 | ||||
1829 | gf_proc_dump_write ("request-ptr", "%p", req); | |||
1830 | ||||
1831 | gf_proc_dump_write ("refcount", "%d", req->refcount); | |||
1832 | ||||
1833 | if (list_empty (&req->todo)) | |||
1834 | gf_proc_dump_write ("wound", "yes"); | |||
1835 | else | |||
1836 | gf_proc_dump_write ("wound", "no"); | |||
1837 | ||||
1838 | if (req->fop == GF_FOP_WRITE) { | |||
1839 | gf_proc_dump_write ("size", "%"GF_PRI_SIZET"zu", | |||
1840 | req->write_size); | |||
1841 | ||||
1842 | gf_proc_dump_write ("offset", "%"PRId64"ll" "d", | |||
1843 | req->stub->args.offset); | |||
1844 | ||||
1845 | flag = req->ordering.lied; | |||
1846 | gf_proc_dump_write ("lied", "%d", flag); | |||
1847 | ||||
1848 | flag = req->ordering.append; | |||
1849 | gf_proc_dump_write ("append", "%d", flag); | |||
1850 | ||||
1851 | flag = req->ordering.fulfilled; | |||
1852 | gf_proc_dump_write ("fulfilled", "%d", flag); | |||
1853 | ||||
1854 | flag = req->ordering.go; | |||
1855 | gf_proc_dump_write ("go", "%d", flag); | |||
1856 | } | |||
1857 | } | |||
1858 | } | |||
1859 | ||||
1860 | ||||
1861 | int | |||
1862 | wb_inode_dump (xlator_t *this, inode_t *inode) | |||
1863 | { | |||
1864 | wb_inode_t *wb_inode = NULL((void*)0); | |||
1865 | int32_t ret = -1; | |||
1866 | char *path = NULL((void*)0); | |||
1867 | char key_prefix[GF_DUMP_MAX_BUF_LEN4096] = {0, }; | |||
1868 | char uuid_str[64] = {0,}; | |||
1869 | ||||
1870 | if ((inode == NULL((void*)0)) || (this == NULL((void*)0))) { | |||
1871 | ret = 0; | |||
1872 | goto out; | |||
1873 | } | |||
1874 | ||||
1875 | wb_inode = wb_inode_ctx_get (this, inode); | |||
1876 | if (wb_inode == NULL((void*)0)) { | |||
1877 | ret = 0; | |||
1878 | goto out; | |||
1879 | } | |||
1880 | ||||
1881 | gf_proc_dump_build_key (key_prefix, "xlator.performance.write-behind",{ _gf_proc_dump_build_key(key_prefix, "xlator.performance.write-behind" , "wb_inode"); } | |||
1882 | "wb_inode"){ _gf_proc_dump_build_key(key_prefix, "xlator.performance.write-behind" , "wb_inode"); }; | |||
1883 | ||||
1884 | gf_proc_dump_add_section (key_prefix); | |||
1885 | ||||
1886 | __inode_path (inode, NULL((void*)0), &path); | |||
1887 | if (path != NULL((void*)0)) { | |||
1888 | gf_proc_dump_write ("path", "%s", path); | |||
1889 | GF_FREE (path)__gf_free (path); | |||
1890 | } | |||
1891 | ||||
1892 | gf_proc_dump_write ("inode", "%p", inode); | |||
1893 | ||||
1894 | gf_proc_dump_write ("window_conf", "%"GF_PRI_SIZET"zu", | |||
1895 | wb_inode->window_conf); | |||
1896 | ||||
1897 | gf_proc_dump_write ("window_current", "%"GF_PRI_SIZET"zu", | |||
1898 | wb_inode->window_current); | |||
1899 | ||||
1900 | ||||
1901 | ret = TRY_LOCK (&wb_inode->lock)pthread_spin_trylock (&wb_inode->lock); | |||
1902 | if (!ret) | |||
1903 | { | |||
1904 | if (!list_empty (&wb_inode->all)) { | |||
1905 | __wb_dump_requests (&wb_inode->all, key_prefix); | |||
1906 | } | |||
1907 | UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock); | |||
1908 | } | |||
1909 | ||||
1910 | if (ret && wb_inode) | |||
1911 | gf_proc_dump_write ("Unable to dump the inode information", | |||
1912 | "(Lock acquisition failed) %p (gfid: %s)", | |||
1913 | wb_inode, | |||
1914 | uuid_utoa_r (inode->gfid, uuid_str)); | |||
1915 | ret = 0; | |||
1916 | out: | |||
1917 | return ret; | |||
1918 | } | |||
1919 | ||||
1920 | ||||
1921 | int | |||
1922 | mem_acct_init (xlator_t *this) | |||
1923 | { | |||
1924 | int ret = -1; | |||
1925 | ||||
1926 | if (!this) { | |||
1927 | goto out; | |||
1928 | } | |||
1929 | ||||
1930 | ret = xlator_mem_acct_init (this, gf_wb_mt_end + 1); | |||
1931 | ||||
1932 | if (ret != 0) { | |||
1933 | gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"do { do { if (0) printf ("Memory accounting init" "failed"); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__ , 1934, GF_LOG_ERROR, "Memory accounting init" "failed"); } while (0) | |||
1934 | "failed")do { do { if (0) printf ("Memory accounting init" "failed"); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__ , 1934, GF_LOG_ERROR, "Memory accounting init" "failed"); } while (0); | |||
1935 | } | |||
1936 | ||||
1937 | out: | |||
1938 | return ret; | |||
1939 | } | |||
1940 | ||||
1941 | ||||
1942 | int | |||
1943 | reconfigure (xlator_t *this, dict_t *options) | |||
1944 | { | |||
1945 | wb_conf_t *conf = NULL((void*)0); | |||
1946 | int ret = -1; | |||
1947 | ||||
1948 | conf = this->private; | |||
1949 | ||||
1950 | GF_OPTION_RECONF ("cache-size", conf->window_size, options, size, out)do { int val_ret = 0; val_ret = xlator_option_reconf_size ((* __glusterfs_this_location()), options, "cache-size", &(conf ->window_size)); if (val_ret) goto out; } while (0); | |||
1951 | ||||
1952 | GF_OPTION_RECONF ("flush-behind", conf->flush_behind, options, bool,do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "flush-behind", &( conf->flush_behind)); if (val_ret) goto out; } while (0) | |||
1953 | out)do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "flush-behind", &( conf->flush_behind)); if (val_ret) goto out; } while (0); | |||
1954 | ||||
1955 | GF_OPTION_RECONF ("trickling-writes", conf->trickling_writes, options,do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "trickling-writes", & (conf->trickling_writes)); if (val_ret) goto out; } while ( 0) | |||
1956 | bool, out)do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "trickling-writes", & (conf->trickling_writes)); if (val_ret) goto out; } while ( 0); | |||
1957 | ||||
1958 | GF_OPTION_RECONF ("strict-O_DIRECT", conf->strict_O_DIRECT, options,do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "strict-O_DIRECT", & (conf->strict_O_DIRECT)); if (val_ret) goto out; } while ( 0) | |||
1959 | bool, out)do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "strict-O_DIRECT", & (conf->strict_O_DIRECT)); if (val_ret) goto out; } while ( 0); | |||
1960 | ||||
1961 | GF_OPTION_RECONF ("strict-write-ordering", conf->strict_write_ordering,do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "strict-write-ordering" , &(conf->strict_write_ordering)); if (val_ret) goto out ; } while (0) | |||
1962 | options, bool, out)do { int val_ret = 0; val_ret = xlator_option_reconf_bool ((* __glusterfs_this_location()), options, "strict-write-ordering" , &(conf->strict_write_ordering)); if (val_ret) goto out ; } while (0); | |||
1963 | ret = 0; | |||
1964 | out: | |||
1965 | return ret; | |||
1966 | } | |||
1967 | ||||
1968 | ||||
1969 | int32_t | |||
1970 | init (xlator_t *this) | |||
1971 | { | |||
1972 | wb_conf_t *conf = NULL((void*)0); | |||
1973 | int32_t ret = -1; | |||
1974 | ||||
1975 | if ((this->children == NULL((void*)0)) | |||
1976 | || this->children->next) { | |||
1977 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0); _gf_log (this-> name, "write-behind.c", __FUNCTION__, 1979, GF_LOG_ERROR, "FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0) | |||
1978 | "FATAL: write-behind (%s) not configured with exactly "do { do { if (0) printf ("FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0); _gf_log (this-> name, "write-behind.c", __FUNCTION__, 1979, GF_LOG_ERROR, "FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0) | |||
1979 | "one child", this->name)do { do { if (0) printf ("FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0); _gf_log (this-> name, "write-behind.c", __FUNCTION__, 1979, GF_LOG_ERROR, "FATAL: write-behind (%s) not configured with exactly " "one child", this->name); } while (0); | |||
1980 | goto out; | |||
1981 | } | |||
1982 | ||||
1983 | if (this->parents == NULL((void*)0)) { | |||
1984 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("dangling volume. check volfilex"); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__ , 1985, GF_LOG_WARNING, "dangling volume. check volfilex"); } while (0) | |||
1985 | "dangling volume. check volfilex")do { do { if (0) printf ("dangling volume. check volfilex"); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__ , 1985, GF_LOG_WARNING, "dangling volume. check volfilex"); } while (0); | |||
1986 | } | |||
1987 | ||||
1988 | conf = GF_CALLOC (1, sizeof (*conf), gf_wb_mt_wb_conf_t)__gf_calloc (1, sizeof (*conf), gf_wb_mt_wb_conf_t); | |||
1989 | if (conf == NULL((void*)0)) { | |||
1990 | goto out; | |||
1991 | } | |||
1992 | ||||
1993 | /* configure 'options aggregate-size <size>' */ | |||
1994 | conf->aggregate_size = WB_AGGREGATE_SIZE131072; | |||
1995 | ||||
1996 | /* configure 'option window-size <size>' */ | |||
1997 | GF_OPTION_INIT ("cache-size", conf->window_size, size, out)do { int val_ret = 0; val_ret = xlator_option_init_size ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "cache-size" , &(conf->window_size)); if (val_ret) goto out; } while (0); | |||
1998 | ||||
1999 | if (!conf->window_size && conf->aggregate_size) { | |||
2000 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("setting window-size to be equal to " "aggregate-size(%""ll" "u"")", conf->aggregate_size); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__, 2003, GF_LOG_WARNING, "setting window-size to be equal to " "aggregate-size(%" "ll" "u"")", conf->aggregate_size); } while (0) | |||
2001 | "setting window-size to be equal to "do { do { if (0) printf ("setting window-size to be equal to " "aggregate-size(%""ll" "u"")", conf->aggregate_size); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__, 2003, GF_LOG_WARNING, "setting window-size to be equal to " "aggregate-size(%" "ll" "u"")", conf->aggregate_size); } while (0) | |||
2002 | "aggregate-size(%"PRIu64")",do { do { if (0) printf ("setting window-size to be equal to " "aggregate-size(%""ll" "u"")", conf->aggregate_size); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__, 2003, GF_LOG_WARNING, "setting window-size to be equal to " "aggregate-size(%" "ll" "u"")", conf->aggregate_size); } while (0) | |||
2003 | conf->aggregate_size)do { do { if (0) printf ("setting window-size to be equal to " "aggregate-size(%""ll" "u"")", conf->aggregate_size); } while (0); _gf_log (this->name, "write-behind.c", __FUNCTION__, 2003, GF_LOG_WARNING, "setting window-size to be equal to " "aggregate-size(%" "ll" "u"")", conf->aggregate_size); } while (0); | |||
2004 | conf->window_size = conf->aggregate_size; | |||
2005 | } | |||
2006 | ||||
2007 | if (conf->window_size < conf->aggregate_size) { | |||
2008 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("aggregate-size(%""ll" "u"") cannot be more than " "window-size(%""ll" "u"")", conf->aggregate_size, conf-> window_size); } while (0); _gf_log (this->name, "write-behind.c" , __FUNCTION__, 2011, GF_LOG_ERROR, "aggregate-size(%""ll" "u" ") cannot be more than " "window-size(%""ll" "u"")", conf-> aggregate_size, conf->window_size); } while (0) | |||
2009 | "aggregate-size(%"PRIu64") cannot be more than "do { do { if (0) printf ("aggregate-size(%""ll" "u"") cannot be more than " "window-size(%""ll" "u"")", conf->aggregate_size, conf-> window_size); } while (0); _gf_log (this->name, "write-behind.c" , __FUNCTION__, 2011, GF_LOG_ERROR, "aggregate-size(%""ll" "u" ") cannot be more than " "window-size(%""ll" "u"")", conf-> aggregate_size, conf->window_size); } while (0) | |||
2010 | "window-size(%"PRIu64")", conf->aggregate_size,do { do { if (0) printf ("aggregate-size(%""ll" "u"") cannot be more than " "window-size(%""ll" "u"")", conf->aggregate_size, conf-> window_size); } while (0); _gf_log (this->name, "write-behind.c" , __FUNCTION__, 2011, GF_LOG_ERROR, "aggregate-size(%""ll" "u" ") cannot be more than " "window-size(%""ll" "u"")", conf-> aggregate_size, conf->window_size); } while (0) | |||
2011 | conf->window_size)do { do { if (0) printf ("aggregate-size(%""ll" "u"") cannot be more than " "window-size(%""ll" "u"")", conf->aggregate_size, conf-> window_size); } while (0); _gf_log (this->name, "write-behind.c" , __FUNCTION__, 2011, GF_LOG_ERROR, "aggregate-size(%""ll" "u" ") cannot be more than " "window-size(%""ll" "u"")", conf-> aggregate_size, conf->window_size); } while (0); | |||
2012 | goto out; | |||
2013 | } | |||
2014 | ||||
2015 | /* configure 'option flush-behind <on/off>' */ | |||
2016 | GF_OPTION_INIT ("flush-behind", conf->flush_behind, bool, out)do { int val_ret = 0; val_ret = xlator_option_init_bool ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "flush-behind" , &(conf->flush_behind)); if (val_ret) goto out; } while (0); | |||
2017 | ||||
2018 | GF_OPTION_INIT ("trickling-writes", conf->trickling_writes, bool, out)do { int val_ret = 0; val_ret = xlator_option_init_bool ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "trickling-writes" , &(conf->trickling_writes)); if (val_ret) goto out; } while (0); | |||
2019 | ||||
2020 | GF_OPTION_INIT ("strict-O_DIRECT", conf->strict_O_DIRECT, bool, out)do { int val_ret = 0; val_ret = xlator_option_init_bool ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "strict-O_DIRECT" , &(conf->strict_O_DIRECT)); if (val_ret) goto out; } while (0); | |||
2021 | ||||
2022 | GF_OPTION_INIT ("strict-write-ordering", conf->strict_write_ordering,do { int val_ret = 0; val_ret = xlator_option_init_bool ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "strict-write-ordering" , &(conf->strict_write_ordering)); if (val_ret) goto out ; } while (0) | |||
2023 | bool, out)do { int val_ret = 0; val_ret = xlator_option_init_bool ((*__glusterfs_this_location ()), (*__glusterfs_this_location())->options, "strict-write-ordering" , &(conf->strict_write_ordering)); if (val_ret) goto out ; } while (0); | |||
2024 | ||||
2025 | this->private = conf; | |||
2026 | ret = 0; | |||
2027 | ||||
2028 | out: | |||
2029 | if (ret) { | |||
2030 | GF_FREE (conf)__gf_free (conf); | |||
2031 | } | |||
2032 | return ret; | |||
2033 | } | |||
2034 | ||||
2035 | ||||
2036 | void | |||
2037 | fini (xlator_t *this) | |||
2038 | { | |||
2039 | wb_conf_t *conf = NULL((void*)0); | |||
2040 | ||||
2041 | GF_VALIDATE_OR_GOTO ("write-behind", this, out)do { if (!this) { (*__errno_location ()) = 22; do { do { if ( 0) printf ("invalid argument: " "this"); } while (0); _gf_log_callingfn ("write-behind", "write-behind.c", __FUNCTION__, 2041, GF_LOG_ERROR , "invalid argument: " "this"); } while (0); goto out; } } while (0); | |||
2042 | ||||
2043 | conf = this->private; | |||
2044 | if (!conf) { | |||
2045 | goto out; | |||
2046 | } | |||
2047 | ||||
2048 | this->private = NULL((void*)0); | |||
2049 | GF_FREE (conf)__gf_free (conf); | |||
2050 | ||||
2051 | out: | |||
2052 | return; | |||
2053 | } | |||
2054 | ||||
2055 | ||||
2056 | struct xlator_fops fops = { | |||
2057 | .writev = wb_writev, | |||
2058 | .readv = wb_readv, | |||
2059 | .flush = wb_flush, | |||
2060 | .fsync = wb_fsync, | |||
2061 | .stat = wb_stat, | |||
2062 | .fstat = wb_fstat, | |||
2063 | .truncate = wb_truncate, | |||
2064 | .ftruncate = wb_ftruncate, | |||
2065 | .setattr = wb_setattr, | |||
2066 | .fsetattr = wb_fsetattr, | |||
2067 | }; | |||
2068 | ||||
2069 | ||||
2070 | struct xlator_cbks cbks = { | |||
2071 | .forget = wb_forget, | |||
2072 | .release = wb_release | |||
2073 | }; | |||
2074 | ||||
2075 | ||||
2076 | struct xlator_dumpops dumpops = { | |||
2077 | .priv = wb_priv_dump, | |||
2078 | .inodectx = wb_inode_dump, | |||
2079 | }; | |||
2080 | ||||
2081 | ||||
2082 | struct volume_options options[] = { | |||
2083 | { .key = {"flush-behind"}, | |||
2084 | .type = GF_OPTION_TYPE_BOOL, | |||
2085 | .default_value = "on", | |||
2086 | .description = "If this option is set ON, instructs write-behind " | |||
2087 | "translator to perform flush in background, by " | |||
2088 | "returning success (or any errors, if any of " | |||
2089 | "previous writes were failed) to application even " | |||
2090 | "before flush FOP is sent to backend filesystem. " | |||
2091 | }, | |||
2092 | { .key = {"cache-size", "window-size"}, | |||
2093 | .type = GF_OPTION_TYPE_SIZET, | |||
2094 | .min = 512 * GF_UNIT_KB1024ULL, | |||
2095 | .max = 1 * GF_UNIT_GB1073741824ULL, | |||
2096 | .default_value = "1MB", | |||
2097 | .description = "Size of the write-behind buffer for a single file " | |||
2098 | "(inode)." | |||
2099 | }, | |||
2100 | { .key = {"trickling-writes"}, | |||
2101 | .type = GF_OPTION_TYPE_BOOL, | |||
2102 | .default_value = "on", | |||
2103 | }, | |||
2104 | { .key = {"strict-O_DIRECT"}, | |||
2105 | .type = GF_OPTION_TYPE_BOOL, | |||
2106 | .default_value = "off", | |||
2107 | .description = "This option when set to off, ignores the " | |||
2108 | "O_DIRECT flag." | |||
2109 | }, | |||
2110 | { .key = {"strict-write-ordering"}, | |||
2111 | .type = GF_OPTION_TYPE_BOOL, | |||
2112 | .default_value = "off", | |||
2113 | .description = "Do not let later writes overtake earlier writes even " | |||
2114 | "if they do not overlap", | |||
2115 | }, | |||
2116 | { .key = {NULL((void*)0)} }, | |||
2117 | }; |