Bug Summary

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')

Annotated Source Code

1/*
2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
4
5 This file is licensed to you under your choice of the GNU Lesser
6 General Public License, version 3 or any later version (LGPLv3 or
7 later), or the GNU General Public License, version 2 (GPLv2), in all
8 cases as published by the Free Software Foundation.
9*/
10
11
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
34typedef struct list_head list_head_t;
35struct wb_conf;
36struct wb_inode;
37
38typedef 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
116typedef 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
163typedef 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
173void
174wb_process_queue (wb_inode_t *wb_inode);
175
176
177wb_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
190wb_inode_t *
191wb_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);
203out:
204 return wb_inode;
205}
206
207
208gf_boolean_t
209wb_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
256gf_boolean_t
257wb_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
283gf_boolean_t
284wb_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
315gf_boolean_t
316wb_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
329gf_boolean_t
330wb_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
353static 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 }
396out:
397 return ret;
398}
399
400
401static int
402wb_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
417out:
418 return ret;
419}
420
421
422static 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
436out:
437 return req;
438}
439
440
441wb_request_t *
442wb_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
455out:
456 return req;
457}
458
459
460gf_boolean_t
461wb_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
554out:
555 if (!req)
556 return _gf_false;
557
558 return _gf_true;
559}
560
561
562gf_boolean_t
563wb_enqueue (wb_inode_t *wb_inode, call_stub_t *stub)
564{
565 return wb_enqueue_common (wb_inode, stub, 0);
566}
567
568
569gf_boolean_t
570wb_enqueue_tempted (wb_inode_t *wb_inode, call_stub_t *stub)
571{
572 return wb_enqueue_common (wb_inode, stub, 1);
573}
574
575
576wb_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
604out:
605 return wb_inode;
606}
607
608
609wb_inode_t *
610wb_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
624out:
625 return wb_inode;
626}
627
628
629void
630wb_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);
636out:
637 return;
638}
639
640
641void
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
662void
663wb_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
682void
683wb_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
707int
708wb_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
752void
753wb_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;
803err:
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
826void
827wb_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
884void
885wb_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))
))
{
12
Within the expansion of the macro 'list_for_each_entry_safe':
893 frame = req->stub->frame;
13
Access to field 'frame' results in a dereference of a null pointer (loaded from field 'stub')
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
907void
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))))
{
9
Within the expansion of the macro 'list_for_each_entry_safe':
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
937int
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;
1001out:
1002 return ret;
1003}
1004
1005
1006void
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
1106void
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
1143void
1144wb_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
1159void
1160wb_process_queue (wb_inode_t *wb_inode)
1161{
1162 list_head_t tasks = {0, };
1163 list_head_t lies = {0, };
7
field 'stub' initialized to a null pointer value
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);
8
Calling '__wb_pick_unwinds'
10
Returning from '__wb_pick_unwinds'
1177
1178 }
1179 UNLOCK (&wb_inode->lock)pthread_spin_unlock (&wb_inode->lock);
1180
1181 wb_do_unwinds (wb_inode, &lies);
11
Calling 'wb_do_unwinds'
1182
1183 wb_do_winds (wb_inode, &tasks);
1184
1185 wb_fulfill (wb_inode, &liabilities);
1186
1187 return;
1188}
1189
1190
1191int
1192wb_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
1209int
1210wb_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
1221int
1222wb_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
1281unwind:
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
1291int
1292wb_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
1302int
1303wb_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
1325unwind:
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
1330noqueue:
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
1338int
1339wb_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
1347int
1348wb_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
1377flushbehind:
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 */
1388unwind:
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
1395int
1396wb_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
1416unwind:
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
1421noqueue:
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
1429int
1430wb_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
1439int
1440wb_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
1465unwind:
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
1470noqueue:
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
1477int
1478wb_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
1486int
1487wb_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
1508unwind:
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
1515noqueue:
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
1522int
1523wb_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
1531int
1532wb_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
1553unwind:
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
1560noqueue:
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
1567int
1568wb_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
1577int
1578wb_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
1600unwind:
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
1610int
1611wb_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
1620int
1621wb_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
1653unwind:
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
1662int
1663wb_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
1672int
1673wb_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;
1694unwind:
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
1701noqueue:
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
1708int
1709wb_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
1718int
1719wb_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)
1
Assuming 'wb_inode' is non-null
2
Taking false branch
1727 goto noqueue;
1728
1729 stub = fop_fsetattr_stub (frame, wb_fsetattr_helper, fd, stbuf,
1730 valid, xdata);
1731 if (!stub)
3
Assuming 'stub' is non-null
4
Taking false branch
1732 goto unwind;
1733
1734 if (!wb_enqueue (wb_inode, stub))
5
Taking false branch
1735 goto unwind;
1736
1737 wb_process_queue (wb_inode);
6
Calling 'wb_process_queue'
1738
1739 return 0;
1740unwind:
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
1747noqueue:
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
1754int
1755wb_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
1777int
1778wb_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
1788int
1789wb_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;
1811out:
1812 return ret;
1813}
1814
1815
1816void
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
1861int
1862wb_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;
1916out:
1917 return ret;
1918}
1919
1920
1921int
1922mem_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
1937out:
1938 return ret;
1939}
1940
1941
1942int
1943reconfigure (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;
1964out:
1965 return ret;
1966}
1967
1968
1969int32_t
1970init (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
2028out:
2029 if (ret) {
2030 GF_FREE (conf)__gf_free (conf);
2031 }
2032 return ret;
2033}
2034
2035
2036void
2037fini (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
2051out:
2052 return;
2053}
2054
2055
2056struct 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
2070struct xlator_cbks cbks = {
2071 .forget = wb_forget,
2072 .release = wb_release
2073};
2074
2075
2076struct xlator_dumpops dumpops = {
2077 .priv = wb_priv_dump,
2078 .inodectx = wb_inode_dump,
2079};
2080
2081
2082struct 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};