2 Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
3 This file is part of GlusterFS.
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.
19 #include "glusterfs.h"
27 #include "call-stub.h"
29 #include "common-utils.h"
30 #include "compat-errno.h"
32 #include "protocol-common.h"
33 #include "byte-order.h"
34 #include "afr-transaction.h"
35 #include "afr-self-heal.h"
36 #include "afr-messages.h"
39 __afr_inode_write_finalize (call_frame_t *frame, xlator_t *this)
41 afr_local_t *local = NULL;
42 afr_private_t *priv = NULL;
50 if (local->transaction.type == AFR_METADATA_TRANSACTION)
51 read_subvol = afr_metadata_subvol_get (local->inode, this,
55 read_subvol = afr_data_subvol_get (local->inode, this,
60 local->op_errno = afr_final_errno (local, priv);
62 for (i = 0; i < priv->child_count; i++) {
63 if (!local->replies[i].valid)
65 if (local->replies[i].op_ret < 0) {
66 afr_inode_read_subvol_reset (local->inode, this);
70 /* Order of checks in the compound conditional
73 - Highest precedence: largest op_ret
74 - Next precendence: if all op_rets are equal, read subvol
75 - Least precedence: any succeeded subvol
77 if ((local->op_ret < local->replies[i].op_ret) ||
78 ((local->op_ret == local->replies[i].op_ret) &&
79 (i == read_subvol))) {
81 local->op_ret = local->replies[i].op_ret;
82 local->op_errno = local->replies[i].op_errno;
84 local->cont.inode_wfop.prebuf =
85 local->replies[i].prestat;
86 local->cont.inode_wfop.postbuf =
87 local->replies[i].poststat;
89 if (local->replies[i].xdata) {
91 dict_unref (local->xdata_rsp);
93 dict_ref (local->replies[i].xdata);
95 if (local->replies[i].xattr) {
97 dict_unref (local->xattr_rsp);
99 dict_ref (local->replies[i].xattr);
104 afr_txn_arbitrate_fop_cbk (frame, this);
109 __afr_inode_write_fill (call_frame_t *frame, xlator_t *this, int child_index,
110 int op_ret, int op_errno,
111 struct iatt *prebuf, struct iatt *postbuf,
112 dict_t *xattr, dict_t *xdata)
114 afr_local_t *local = NULL;
115 afr_private_t *priv = NULL;
117 local = frame->local;
118 priv = this->private;
120 local->replies[child_index].valid = 1;
122 if (AFR_IS_ARBITER_BRICK(priv, child_index) && op_ret == 1)
123 op_ret = iov_length (local->cont.writev.vector,
124 local->cont.writev.count);
126 local->replies[child_index].op_ret = op_ret;
127 local->replies[child_index].op_errno = op_errno;
131 local->replies[child_index].prestat = *prebuf;
133 local->replies[child_index].poststat = *postbuf;
135 local->replies[child_index].xattr = dict_ref (xattr);
137 local->replies[child_index].xdata = dict_ref (xdata);
139 afr_transaction_fop_failed (frame, this, child_index);
147 __afr_inode_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
148 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
149 struct iatt *postbuf, dict_t *xattr, dict_t *xdata)
151 afr_local_t *local = NULL;
152 int child_index = (long) cookie;
155 local = frame->local;
159 __afr_inode_write_fill (frame, this, child_index, op_ret,
160 op_errno, prebuf, postbuf, xattr,
163 UNLOCK (&frame->lock);
165 call_count = afr_frame_return (frame);
167 if (call_count == 0) {
168 __afr_inode_write_finalize (frame, this);
170 if (afr_txn_nothing_failed (frame, this))
171 local->transaction.unwind (frame, this);
173 local->transaction.resume (frame, this);
182 afr_writev_copy_outvars (call_frame_t *src_frame, call_frame_t *dst_frame)
184 afr_local_t *src_local = NULL;
185 afr_local_t *dst_local = NULL;
187 src_local = src_frame->local;
188 dst_local = dst_frame->local;
190 dst_local->op_ret = src_local->op_ret;
191 dst_local->op_errno = src_local->op_errno;
192 dst_local->cont.inode_wfop.prebuf = src_local->cont.inode_wfop.prebuf;
193 dst_local->cont.inode_wfop.postbuf = src_local->cont.inode_wfop.postbuf;
194 if (src_local->xdata_rsp)
195 dst_local->xdata_rsp = dict_ref (src_local->xdata_rsp);
199 afr_writev_unwind (call_frame_t *frame, xlator_t *this)
201 afr_local_t * local = NULL;
202 local = frame->local;
204 AFR_STACK_UNWIND (writev, frame,
205 local->op_ret, local->op_errno,
206 &local->cont.inode_wfop.prebuf,
207 &local->cont.inode_wfop.postbuf,
213 afr_transaction_writev_unwind (call_frame_t *frame, xlator_t *this)
215 call_frame_t *fop_frame = NULL;
217 fop_frame = afr_transaction_detach_fop_frame (frame);
220 afr_writev_copy_outvars (frame, fop_frame);
221 afr_writev_unwind (fop_frame, this);
227 afr_writev_handle_short_writes (call_frame_t *frame, xlator_t *this)
229 afr_local_t *local = NULL;
230 afr_private_t *priv = NULL;
233 local = frame->local;
234 priv = this->private;
236 * We already have the best case result of the writev calls staged
237 * as the return value. Any writev that returns some value less
238 * than the best case is now out of sync, so mark the fop as
239 * failed. Note that fops that have returned with errors have
240 * already been marked as failed.
242 for (i = 0; i < priv->child_count; i++) {
243 if ((!local->replies[i].valid) ||
244 (local->replies[i].op_ret == -1))
247 if (local->replies[i].op_ret < local->op_ret)
248 afr_transaction_fop_failed (frame, this, i);
253 afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
254 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
255 struct iatt *postbuf, dict_t *xdata)
257 afr_local_t * local = NULL;
258 call_frame_t *fop_frame = NULL;
259 int child_index = (long) cookie;
262 uint32_t open_fd_count = 0;
263 uint32_t write_is_append = 0;
265 local = frame->local;
269 __afr_inode_write_fill (frame, this, child_index, op_ret,
270 op_errno, prebuf, postbuf, NULL, xdata);
271 if (op_ret == -1 || !xdata)
275 ret = dict_get_uint32 (xdata, GLUSTERFS_WRITE_IS_APPEND,
277 if (ret || !write_is_append)
278 local->append_write = _gf_false;
280 ret = dict_get_uint32 (xdata, GLUSTERFS_OPEN_FD_COUNT,
284 if ((open_fd_count > local->open_fd_count)) {
285 local->open_fd_count = open_fd_count;
286 local->update_open_fd_count = _gf_true;
290 UNLOCK (&frame->lock);
292 call_count = afr_frame_return (frame);
294 if (call_count == 0) {
295 if (!local->stable_write && !local->append_write)
296 /* An appended write removes the necessity to
297 fsync() the file. This is because self-heal
298 has the logic to check for larger file when
299 the xattrs are not reliably pointing at
302 afr_fd_report_unstable_write (this, local->fd);
304 __afr_inode_write_finalize (frame, this);
306 afr_writev_handle_short_writes (frame, this);
308 if (local->update_open_fd_count)
309 afr_handle_open_fd_count (frame, this);
311 if (!afr_txn_nothing_failed (frame, this)) {
312 //Don't unwind until post-op is complete
313 local->transaction.resume (frame, this);
316 * Generally inode-write fops do transaction.unwind then
317 * transaction.resume, but writev needs to make sure that
318 * delayed post-op frame is placed in fdctx before unwind
319 * happens. This prevents the race of flush doing the
320 * changelog wakeup first in fuse thread and then this
321 * writev placing its delayed post-op frame in fdctx.
322 * This helps flush make sure all the delayed post-ops are
326 fop_frame = afr_transaction_detach_fop_frame (frame);
327 afr_writev_copy_outvars (frame, fop_frame);
328 local->transaction.resume (frame, this);
329 afr_writev_unwind (fop_frame, this);
336 afr_arbiter_writev_wind (call_frame_t *frame, xlator_t *this, int subvol)
338 afr_local_t *local = frame->local;
339 afr_private_t *priv = this->private;
340 static char byte = 0xFF;
341 static struct iovec vector = {&byte, 1};
344 STACK_WIND_COOKIE (frame, afr_writev_wind_cbk, (void *) (long) subvol,
345 priv->children[subvol],
346 priv->children[subvol]->fops->writev,
347 local->fd, &vector, count, local->cont.writev.offset,
348 local->cont.writev.flags, local->cont.writev.iobref,
355 afr_writev_wind (call_frame_t *frame, xlator_t *this, int subvol)
357 afr_local_t *local = NULL;
358 afr_private_t *priv = NULL;
360 local = frame->local;
361 priv = this->private;
363 if (AFR_IS_ARBITER_BRICK(priv, subvol)) {
364 afr_arbiter_writev_wind (frame, this, subvol);
368 STACK_WIND_COOKIE (frame, afr_writev_wind_cbk, (void *) (long) subvol,
369 priv->children[subvol],
370 priv->children[subvol]->fops->writev,
371 local->fd, local->cont.writev.vector,
372 local->cont.writev.count, local->cont.writev.offset,
373 local->cont.writev.flags, local->cont.writev.iobref,
380 afr_do_writev (call_frame_t *frame, xlator_t *this)
382 call_frame_t *transaction_frame = NULL;
383 afr_local_t *local = NULL;
384 afr_private_t *priv = NULL;
386 int op_errno = ENOMEM;
388 transaction_frame = copy_frame (frame);
389 if (!transaction_frame)
392 local = frame->local;
393 priv = this->private;
394 transaction_frame->local = local;
397 if (!AFR_FRAME_INIT (frame, op_errno))
400 local->op = GF_FOP_WRITE;
402 local->transaction.wind = afr_writev_wind;
403 local->transaction.fop = __afr_txn_write_fop;
404 local->transaction.done = __afr_txn_write_done;
405 local->transaction.unwind = afr_transaction_writev_unwind;
407 local->transaction.main_frame = frame;
409 if (local->fd->flags & O_APPEND) {
411 * Backend vfs ignores the 'offset' for append mode fd so
412 * locking just the region provided for the writev does not
413 * give consistency guarantee. The actual write may happen at a
414 * completely different range than the one provided by the
415 * offset, len in the fop. So lock the entire file.
417 local->transaction.start = 0;
418 local->transaction.len = 0;
420 local->transaction.start = local->cont.writev.offset;
421 local->transaction.len = iov_length (local->cont.writev.vector,
422 local->cont.writev.count);
424 /*Lock entire file to avoid network split brains.*/
425 if (priv->arbiter_count == 1) {
426 local->transaction.start = 0;
427 local->transaction.len = 0;
431 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
439 if (transaction_frame)
440 AFR_STACK_DESTROY (transaction_frame);
442 AFR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
448 afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
449 struct iovec *vector, int32_t count, off_t offset,
450 uint32_t flags, struct iobref *iobref, dict_t *xdata)
452 afr_local_t *local = NULL;
453 int op_errno = ENOMEM;
455 local = AFR_FRAME_INIT (frame, op_errno);
459 local->cont.writev.vector = iov_dup (vector, count);
460 if (!local->cont.writev.vector)
462 local->cont.writev.count = count;
463 local->cont.writev.offset = offset;
464 local->cont.writev.flags = flags;
465 local->cont.writev.iobref = iobref_ref (iobref);
468 local->xdata_req = dict_copy_with_ref (xdata, NULL);
470 local->xdata_req = dict_new ();
472 if (!local->xdata_req)
475 local->fd = fd_ref (fd);
476 local->inode = inode_ref (fd->inode);
478 if (dict_set_uint32 (local->xdata_req, GLUSTERFS_OPEN_FD_COUNT, 4)) {
483 if (dict_set_uint32 (local->xdata_req, GLUSTERFS_WRITE_IS_APPEND, 4)) {
488 /* Set append_write to be true speculatively. If on any
489 server it turns not be true, we unset it in the
492 local->append_write = _gf_true;
494 /* detect here, but set it in writev_wind_cbk *after* the unstable
497 local->stable_write = !!((fd->flags|flags)&(O_SYNC|O_DSYNC));
499 afr_fix_open (fd, this);
501 afr_do_writev (frame, this);
505 AFR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
516 afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
518 afr_local_t * local = NULL;
519 call_frame_t *main_frame = NULL;
521 local = frame->local;
523 main_frame = afr_transaction_detach_fop_frame (frame);
527 AFR_STACK_UNWIND (truncate, main_frame, local->op_ret, local->op_errno,
528 &local->cont.inode_wfop.prebuf,
529 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
535 afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
536 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
537 struct iatt *postbuf, dict_t *xdata)
539 afr_local_t *local = NULL;
541 local = frame->local;
543 if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size)
544 local->stable_write = _gf_false;
546 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
547 prebuf, postbuf, NULL, xdata);
552 afr_truncate_wind (call_frame_t *frame, xlator_t *this, int subvol)
554 afr_local_t *local = NULL;
555 afr_private_t *priv = NULL;
557 local = frame->local;
558 priv = this->private;
560 STACK_WIND_COOKIE (frame, afr_truncate_wind_cbk, (void *) (long) subvol,
561 priv->children[subvol],
562 priv->children[subvol]->fops->truncate,
563 &local->loc, local->cont.truncate.offset,
570 afr_truncate (call_frame_t *frame, xlator_t *this,
571 loc_t *loc, off_t offset, dict_t *xdata)
573 afr_local_t * local = NULL;
574 call_frame_t *transaction_frame = NULL;
576 int op_errno = ENOMEM;
578 transaction_frame = copy_frame (frame);
579 if (!transaction_frame)
582 local = AFR_FRAME_INIT (transaction_frame, op_errno);
586 local->cont.truncate.offset = offset;
588 local->xdata_req = dict_copy_with_ref (xdata, NULL);
590 local->xdata_req = dict_new ();
592 if (!local->xdata_req)
595 local->transaction.wind = afr_truncate_wind;
596 local->transaction.fop = __afr_txn_write_fop;
597 local->transaction.done = __afr_txn_write_done;
598 local->transaction.unwind = afr_truncate_unwind;
600 loc_copy (&local->loc, loc);
601 local->inode = inode_ref (loc->inode);
603 local->op = GF_FOP_TRUNCATE;
605 local->transaction.main_frame = frame;
606 local->transaction.start = offset;
607 local->transaction.len = 0;
609 /* Set it true speculatively, will get reset in afr_truncate_wind_cbk
610 if truncate was not a NOP */
611 local->stable_write = _gf_true;
613 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
621 if (transaction_frame)
622 AFR_STACK_DESTROY (transaction_frame);
624 AFR_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
635 afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
637 afr_local_t * local = NULL;
638 call_frame_t *main_frame = NULL;
640 local = frame->local;
642 main_frame = afr_transaction_detach_fop_frame (frame);
646 AFR_STACK_UNWIND (ftruncate, main_frame, local->op_ret, local->op_errno,
647 &local->cont.inode_wfop.prebuf,
648 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
654 afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
655 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
656 struct iatt *postbuf, dict_t *xdata)
658 afr_local_t *local = NULL;
660 local = frame->local;
662 if (op_ret == 0 && prebuf->ia_size != postbuf->ia_size)
663 local->stable_write = _gf_false;
665 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
666 prebuf, postbuf, NULL, xdata);
671 afr_ftruncate_wind (call_frame_t *frame, xlator_t *this, int subvol)
673 afr_local_t *local = NULL;
674 afr_private_t *priv = NULL;
676 local = frame->local;
677 priv = this->private;
679 STACK_WIND_COOKIE (frame, afr_ftruncate_wind_cbk, (void *) (long) subvol,
680 priv->children[subvol],
681 priv->children[subvol]->fops->ftruncate,
682 local->fd, local->cont.ftruncate.offset,
689 afr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
692 afr_local_t *local = NULL;
693 call_frame_t *transaction_frame = NULL;
695 int op_errno = ENOMEM;
697 transaction_frame = copy_frame (frame);
698 if (!transaction_frame)
701 local = AFR_FRAME_INIT (transaction_frame, op_errno);
705 local->cont.ftruncate.offset = offset;
707 local->xdata_req = dict_copy_with_ref (xdata, NULL);
709 local->xdata_req = dict_new ();
711 if (!local->xdata_req)
714 local->fd = fd_ref (fd);
715 local->inode = inode_ref (fd->inode);
717 local->op = GF_FOP_FTRUNCATE;
719 local->transaction.wind = afr_ftruncate_wind;
720 local->transaction.fop = __afr_txn_write_fop;
721 local->transaction.done = __afr_txn_write_done;
722 local->transaction.unwind = afr_ftruncate_unwind;
724 local->transaction.main_frame = frame;
726 local->transaction.start = local->cont.ftruncate.offset;
727 local->transaction.len = 0;
729 afr_fix_open (fd, this);
731 /* Set it true speculatively, will get reset in afr_ftruncate_wind_cbk
732 if truncate was not a NOP */
733 local->stable_write = _gf_true;
735 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
743 AFR_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
753 afr_setattr_unwind (call_frame_t *frame, xlator_t *this)
755 afr_local_t *local = NULL;
756 call_frame_t *main_frame = NULL;
758 local = frame->local;
760 main_frame = afr_transaction_detach_fop_frame (frame);
764 AFR_STACK_UNWIND (setattr, main_frame, local->op_ret, local->op_errno,
765 &local->cont.inode_wfop.prebuf,
766 &local->cont.inode_wfop.postbuf,
773 afr_setattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
774 int op_ret, int op_errno,
775 struct iatt *preop, struct iatt *postop, dict_t *xdata)
777 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
778 preop, postop, NULL, xdata);
783 afr_setattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
785 afr_local_t *local = NULL;
786 afr_private_t *priv = NULL;
788 local = frame->local;
789 priv = this->private;
791 STACK_WIND_COOKIE (frame, afr_setattr_wind_cbk, (void *) (long) subvol,
792 priv->children[subvol],
793 priv->children[subvol]->fops->setattr,
794 &local->loc, &local->cont.setattr.in_buf,
795 local->cont.setattr.valid, local->xdata_req);
801 afr_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf,
802 int32_t valid, dict_t *xdata)
804 afr_local_t *local = NULL;
805 call_frame_t *transaction_frame = NULL;
807 int op_errno = ENOMEM;
809 transaction_frame = copy_frame (frame);
810 if (!transaction_frame)
813 local = AFR_FRAME_INIT (transaction_frame, op_errno);
817 local->cont.setattr.in_buf = *buf;
818 local->cont.setattr.valid = valid;
820 local->xdata_req = dict_copy_with_ref (xdata, NULL);
822 local->xdata_req = dict_new ();
824 if (!local->xdata_req)
827 local->transaction.wind = afr_setattr_wind;
828 local->transaction.fop = __afr_txn_write_fop;
829 local->transaction.done = __afr_txn_write_done;
830 local->transaction.unwind = afr_setattr_unwind;
832 loc_copy (&local->loc, loc);
833 local->inode = inode_ref (loc->inode);
835 local->op = GF_FOP_SETATTR;
837 local->transaction.main_frame = frame;
838 local->transaction.start = LLONG_MAX - 1;
839 local->transaction.len = 0;
841 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
849 if (transaction_frame)
850 AFR_STACK_DESTROY (transaction_frame);
852 AFR_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
859 afr_fsetattr_unwind (call_frame_t *frame, xlator_t *this)
861 afr_local_t * local = NULL;
862 call_frame_t *main_frame = NULL;
864 local = frame->local;
866 main_frame = afr_transaction_detach_fop_frame (frame);
870 AFR_STACK_UNWIND (fsetattr, main_frame, local->op_ret, local->op_errno,
871 &local->cont.inode_wfop.prebuf,
872 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
878 afr_fsetattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
879 int32_t op_ret, int32_t op_errno,
880 struct iatt *preop, struct iatt *postop, dict_t *xdata)
882 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
883 preop, postop, NULL, xdata);
888 afr_fsetattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
890 afr_local_t *local = NULL;
891 afr_private_t *priv = NULL;
893 local = frame->local;
894 priv = this->private;
896 STACK_WIND_COOKIE (frame, afr_fsetattr_wind_cbk, (void *) (long) subvol,
897 priv->children[subvol],
898 priv->children[subvol]->fops->fsetattr,
899 local->fd, &local->cont.fsetattr.in_buf,
900 local->cont.fsetattr.valid, local->xdata_req);
906 afr_fsetattr (call_frame_t *frame, xlator_t *this,
907 fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata)
909 afr_local_t *local = NULL;
910 call_frame_t *transaction_frame = NULL;
912 int op_errno = ENOMEM;
914 transaction_frame = copy_frame (frame);
915 if (!transaction_frame)
918 local = AFR_FRAME_INIT (transaction_frame, op_errno);
922 local->cont.fsetattr.in_buf = *buf;
923 local->cont.fsetattr.valid = valid;
925 local->xdata_req = dict_copy_with_ref (xdata, NULL);
927 local->xdata_req = dict_new ();
929 if (!local->xdata_req)
932 local->transaction.wind = afr_fsetattr_wind;
933 local->transaction.fop = __afr_txn_write_fop;
934 local->transaction.done = __afr_txn_write_done;
935 local->transaction.unwind = afr_fsetattr_unwind;
937 local->fd = fd_ref (fd);
938 local->inode = inode_ref (fd->inode);
940 local->op = GF_FOP_FSETATTR;
942 afr_fix_open (fd, this);
944 local->transaction.main_frame = frame;
945 local->transaction.start = LLONG_MAX - 1;
946 local->transaction.len = 0;
948 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
956 if (transaction_frame)
957 AFR_STACK_DESTROY (transaction_frame);
959 AFR_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
968 afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
970 afr_local_t * local = NULL;
971 call_frame_t *main_frame = NULL;
973 local = frame->local;
975 main_frame = afr_transaction_detach_fop_frame (frame);
979 AFR_STACK_UNWIND (setxattr, main_frame, local->op_ret, local->op_errno,
986 afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
987 int32_t op_ret, int32_t op_errno, dict_t *xdata)
989 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
990 NULL, NULL, NULL, xdata);
995 afr_setxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
997 afr_local_t *local = NULL;
998 afr_private_t *priv = NULL;
1000 local = frame->local;
1001 priv = this->private;
1003 STACK_WIND_COOKIE (frame, afr_setxattr_wind_cbk, (void *) (long) subvol,
1004 priv->children[subvol],
1005 priv->children[subvol]->fops->setxattr,
1006 &local->loc, local->cont.setxattr.dict,
1007 local->cont.setxattr.flags, local->xdata_req);
1012 afr_rb_set_pending_changelog_cbk (call_frame_t *frame, void *cookie,
1013 xlator_t *this, int op_ret, int op_errno,
1014 dict_t *xattr, dict_t *xdata)
1017 afr_local_t *local = NULL;
1018 afr_private_t *priv = NULL;
1021 local = frame->local;
1022 priv = this->private;
1025 local->replies[i].valid = 1;
1026 local->replies[i].op_ret = op_ret;
1027 local->replies[i].op_errno = op_errno;
1028 gf_msg (this->name, op_ret ? GF_LOG_ERROR : GF_LOG_INFO,
1029 op_ret ? op_errno : 0,
1030 AFR_MSG_REPLACE_BRICK_STATUS, "Set of pending xattr %s on"
1031 " %s.", op_ret ? "failed" : "succeeded",
1032 priv->children[i]->name);
1034 syncbarrier_wake (&local->barrier);
1039 afr_rb_set_pending_changelog (call_frame_t *frame, xlator_t *this,
1040 unsigned char *locked_nodes)
1042 afr_local_t *local = NULL;
1043 afr_private_t *priv = NULL;
1046 local = frame->local;
1047 priv = this->private;
1049 AFR_ONLIST (locked_nodes, frame, afr_rb_set_pending_changelog_cbk,
1050 xattrop, &local->loc, GF_XATTROP_ADD_ARRAY,
1051 local->xdata_req, NULL);
1053 /* It is sufficient if xattrop was successful on one child */
1054 for (i = 0; i < priv->child_count; i++) {
1055 if (!local->replies[i].valid)
1058 if (local->replies[i].op_ret == 0) {
1062 ret = afr_higher_errno (ret,
1063 local->replies[i].op_errno);
1071 _afr_handle_replace_brick_type (xlator_t *this, call_frame_t *frame,
1072 loc_t *loc, int rb_index,
1073 afr_transaction_type type)
1075 afr_local_t *local = NULL;
1076 afr_private_t *priv = NULL;
1077 unsigned char *locked_nodes = NULL;
1082 priv = this->private;
1083 local = frame->local;
1085 locked_nodes = alloca0 (priv->child_count);
1087 idx = afr_index_for_transaction_type (type);
1089 local->pending = afr_matrix_create (priv->child_count,
1090 AFR_NUM_CHANGE_LOGS);
1091 if (!local->pending)
1094 local->pending[rb_index][idx] = hton32 (1);
1096 local->xdata_req = dict_new ();
1097 if (!local->xdata_req)
1100 ret = afr_set_pending_dict (priv, local->xdata_req, local->pending);
1104 if (AFR_ENTRY_TRANSACTION == type) {
1105 count = afr_selfheal_entrylk (frame, this, loc->inode,
1106 this->name, NULL, locked_nodes);
1108 count = afr_selfheal_inodelk (frame, this, loc->inode,
1109 this->name, LLONG_MAX - 1, 0,
1114 gf_log (this->name, GF_LOG_ERROR, "Couldn't acquire lock on"
1120 ret = afr_rb_set_pending_changelog (frame, this, locked_nodes);
1125 if (AFR_ENTRY_TRANSACTION == type) {
1126 afr_selfheal_unentrylk (frame, this, loc->inode, this->name,
1127 NULL, locked_nodes);
1129 afr_selfheal_uninodelk (frame, this, loc->inode, this->name,
1130 LLONG_MAX - 1, 0, locked_nodes);
1137 _afr_handle_replace_brick_cbk (int ret, call_frame_t *frame, void *opaque)
1139 afr_replace_brick_args_t *data = NULL;
1142 loc_wipe (&data->loc);
1148 _afr_handle_replace_brick (void *opaque)
1151 afr_local_t *local = NULL;
1152 afr_private_t *priv = NULL;
1155 int op_errno = ENOMEM;
1156 call_frame_t *frame = NULL;
1157 xlator_t *this = NULL;
1158 afr_replace_brick_args_t *data = NULL;
1161 frame = data->frame;
1162 rb_index = data->rb_index;
1164 priv = this->private;
1166 local = AFR_FRAME_INIT (frame, op_errno);
1170 loc_copy (&local->loc, &data->loc);
1172 gf_log (this->name, GF_LOG_DEBUG, "Child being replaced is : %s",
1173 priv->children[rb_index]->name);
1175 ret = _afr_handle_replace_brick_type (this, frame, &local->loc, rb_index,
1176 AFR_METADATA_TRANSACTION);
1183 dict_unref (local->xdata_req);
1184 afr_matrix_cleanup (local->pending, priv->child_count);
1185 local->pending = NULL;
1186 local->xdata_req = NULL;
1188 ret = _afr_handle_replace_brick_type (this, frame, &local->loc, rb_index,
1189 AFR_ENTRY_TRANSACTION);
1197 AFR_STACK_UNWIND (setxattr, frame, ret, op_errno, NULL);
1203 afr_split_brain_resolve_do (call_frame_t *frame, xlator_t *this, loc_t *loc,
1206 afr_local_t *local = NULL;
1208 int op_errno = EINVAL;
1210 local = frame->local;
1211 local->xdata_req = dict_new ();
1213 if (!local->xdata_req) {
1218 ret = dict_set_int32 (local->xdata_req, "heal-op",
1219 GF_SHD_OP_SBRAIN_HEAL_FROM_BRICK);
1225 ret = dict_set_str (local->xdata_req, "child-name", data);
1231 /* set spb choice to -1 whether heal succeeds or not:
1232 * If heal succeeds : spb-choice should be set to -1 as
1233 * it is no longer valid; file is not
1234 * in split-brain anymore.
1235 * If heal doesn't succeed:
1236 * spb-choice should be set to -1
1237 * otherwise reads will be served
1238 * from spb-choice which is misleading.
1240 ret = afr_inode_split_brain_choice_set (loc->inode, this, -1);
1242 gf_msg (this->name, GF_LOG_WARNING, 0,
1243 AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR, "Failed to set"
1244 "split-brain choice to -1");
1245 afr_heal_splitbrain_file (frame, this, loc);
1249 AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
1254 afr_get_split_brain_child_index (xlator_t *this, void *value, size_t len)
1256 int spb_child_index = -1;
1257 char *spb_child_str = NULL;
1259 spb_child_str = alloca0 (len + 1);
1260 memcpy (spb_child_str, value, len);
1262 if (!strcmp (spb_child_str, "none"))
1265 spb_child_index = afr_get_child_index_from_name (this,
1267 if (spb_child_index < 0) {
1268 gf_msg (this->name, GF_LOG_ERROR, 0,
1269 AFR_MSG_INVALID_SUBVOL, "Invalid subvol: %s",
1272 return spb_child_index;
1276 afr_can_set_split_brain_choice (void *opaque)
1278 afr_spbc_timeout_t *data = opaque;
1279 call_frame_t *frame = NULL;
1280 xlator_t *this = NULL;
1284 frame = data->frame;
1288 ret = afr_is_split_brain (frame, this, loc->inode, loc->gfid,
1289 &data->d_spb, &data->m_spb);
1292 gf_msg (this->name, GF_LOG_ERROR, 0,
1293 AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR,
1294 "Failed to determine if %s"
1295 " is in split-brain. "
1296 "Aborting split-brain-choice set.",
1297 uuid_utoa (loc->gfid));
1302 afr_handle_split_brain_commands (xlator_t *this, call_frame_t *frame,
1303 loc_t *loc, dict_t *dict)
1306 afr_private_t *priv = NULL;
1307 afr_local_t *local = NULL;
1308 afr_spbc_timeout_t *data = NULL;
1310 int spb_child_index = -1;
1312 int op_errno = EINVAL;
1314 priv = this->private;
1316 local = AFR_FRAME_INIT (frame, op_errno);
1322 local->op = GF_FOP_SETXATTR;
1324 ret = dict_get_ptr_and_len (dict, GF_AFR_SBRAIN_CHOICE, &value,
1327 spb_child_index = afr_get_split_brain_child_index (this, value,
1329 if (spb_child_index < 0) {
1330 /* Case where value was "none" */
1331 if (spb_child_index == -2)
1332 spb_child_index = -1;
1340 data = GF_CALLOC (1, sizeof (*data), gf_afr_mt_spbc_timeout_t);
1345 data->spb_child_index = spb_child_index;
1346 data->frame = frame;
1348 ret = synctask_new (this->ctx->env,
1349 afr_can_set_split_brain_choice,
1350 afr_set_split_brain_choice, NULL, data);
1352 gf_msg (this->name, GF_LOG_ERROR, 0,
1353 AFR_MSG_SPLIT_BRAIN_CHOICE_ERROR,
1355 " synctask. Aborting split-brain choice set"
1356 " for %s", loc->name);
1365 ret = dict_get_ptr_and_len (dict, GF_AFR_SBRAIN_RESOLVE, &value, &len);
1367 spb_child_index = afr_get_split_brain_child_index (this, value,
1369 if (spb_child_index < 0) {
1374 afr_split_brain_resolve_do (frame, this, loc,
1375 priv->children[spb_child_index]->name);
1379 /* key was correct but value was invalid when ret == 1 */
1381 AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
1390 afr_handle_spb_choice_timeout (xlator_t *this, call_frame_t *frame,
1395 uint64_t timeout = 0;
1396 afr_private_t *priv = NULL;
1398 priv = this->private;
1400 ret = dict_get_uint64 (dict, GF_AFR_SPB_CHOICE_TIMEOUT, &timeout);
1402 priv->spb_choice_timeout = timeout * 60;
1403 AFR_STACK_UNWIND (setxattr, frame, ret, op_errno, NULL);
1410 afr_handle_replace_brick (xlator_t *this, call_frame_t *frame, loc_t *loc,
1415 int op_errno = EPERM;
1416 char *replace_brick = NULL;
1417 afr_replace_brick_args_t *data = NULL;
1419 ret = dict_get_str (dict, GF_AFR_REPLACE_BRICK, &replace_brick);
1422 if (frame->root->pid != GF_CLIENT_PID_AFR_SELF_HEALD) {
1423 gf_log (this->name, GF_LOG_ERROR, "'%s' is an internal"
1424 " extended attribute : %s.",
1425 GF_AFR_REPLACE_BRICK, strerror (EPERM));
1429 rb_index = afr_get_child_index_from_name (this, replace_brick);
1432 /* Didn't belong to this replica pair
1435 AFR_STACK_UNWIND (setxattr, frame, 0, 0, NULL);
1438 data = GF_CALLOC (1, sizeof (*data),
1439 gf_afr_mt_replace_brick_t);
1445 data->frame = frame;
1446 loc_copy (&data->loc, loc);
1447 data->rb_index = rb_index;
1448 ret = synctask_new (this->ctx->env,
1449 _afr_handle_replace_brick,
1450 _afr_handle_replace_brick_cbk,
1453 gf_msg (this->name, GF_LOG_ERROR, 0,
1454 AFR_MSG_REPLACE_BRICK_FAILED,
1455 "Failed to create synctask. Unable to "
1456 "perform replace-brick.");
1459 loc_wipe (&data->loc);
1468 AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
1475 afr_handle_special_xattr (xlator_t *this, call_frame_t *frame, loc_t *loc,
1480 ret = afr_handle_split_brain_commands (this, frame, loc, dict);
1484 ret = afr_handle_spb_choice_timeout (this, frame, dict);
1488 ret = afr_handle_replace_brick (this, frame, loc, dict);
1494 afr_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
1495 int32_t flags, dict_t *xdata)
1497 afr_local_t *local = NULL;
1498 call_frame_t *transaction_frame = NULL;
1500 int op_errno = EINVAL;
1502 GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
1505 GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
1508 ret = afr_handle_special_xattr (this, frame, loc, dict);
1512 transaction_frame = copy_frame (frame);
1513 if (!transaction_frame)
1516 local = AFR_FRAME_INIT (transaction_frame, op_errno);
1520 local->cont.setxattr.dict = dict_ref (dict);
1521 local->cont.setxattr.flags = flags;
1523 local->xdata_req = dict_copy_with_ref (xdata, NULL);
1525 local->xdata_req = dict_new ();
1527 if (!local->xdata_req)
1530 local->transaction.wind = afr_setxattr_wind;
1531 local->transaction.fop = __afr_txn_write_fop;
1532 local->transaction.done = __afr_txn_write_done;
1533 local->transaction.unwind = afr_setxattr_unwind;
1535 loc_copy (&local->loc, loc);
1536 local->inode = inode_ref (loc->inode);
1538 local->transaction.main_frame = frame;
1539 local->transaction.start = LLONG_MAX - 1;
1540 local->transaction.len = 0;
1542 local->op = GF_FOP_SETXATTR;
1544 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
1552 if (transaction_frame)
1553 AFR_STACK_DESTROY (transaction_frame);
1555 AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
1564 afr_fsetxattr_unwind (call_frame_t *frame, xlator_t *this)
1566 afr_local_t *local = NULL;
1567 call_frame_t *main_frame = NULL;
1569 local = frame->local;
1571 main_frame = afr_transaction_detach_fop_frame (frame);
1575 AFR_STACK_UNWIND (fsetxattr, main_frame, local->op_ret, local->op_errno,
1582 afr_fsetxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1583 int32_t op_ret, int32_t op_errno, dict_t *xdata)
1585 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
1586 NULL, NULL, NULL, xdata);
1591 afr_fsetxattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
1593 afr_local_t *local = NULL;
1594 afr_private_t *priv = NULL;
1596 local = frame->local;
1597 priv = this->private;
1599 STACK_WIND_COOKIE (frame, afr_fsetxattr_wind_cbk, (void *) (long) subvol,
1600 priv->children[subvol],
1601 priv->children[subvol]->fops->fsetxattr,
1602 local->fd, local->cont.fsetxattr.dict,
1603 local->cont.fsetxattr.flags, local->xdata_req);
1609 afr_fsetxattr (call_frame_t *frame, xlator_t *this,
1610 fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata)
1612 afr_local_t *local = NULL;
1613 call_frame_t *transaction_frame = NULL;
1615 int op_errno = ENOMEM;
1617 GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
1620 GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
1623 transaction_frame = copy_frame (frame);
1624 if (!transaction_frame)
1627 local = AFR_FRAME_INIT (transaction_frame, op_errno);
1631 local->cont.fsetxattr.dict = dict_ref (dict);
1632 local->cont.fsetxattr.flags = flags;
1635 local->xdata_req = dict_copy_with_ref (xdata, NULL);
1637 local->xdata_req = dict_new ();
1639 if (!local->xdata_req)
1642 local->transaction.wind = afr_fsetxattr_wind;
1643 local->transaction.fop = __afr_txn_write_fop;
1644 local->transaction.done = __afr_txn_write_done;
1645 local->transaction.unwind = afr_fsetxattr_unwind;
1647 local->fd = fd_ref (fd);
1648 local->inode = inode_ref (fd->inode);
1650 local->op = GF_FOP_FSETXATTR;
1652 local->transaction.main_frame = frame;
1653 local->transaction.start = LLONG_MAX - 1;
1654 local->transaction.len = 0;
1656 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
1664 if (transaction_frame)
1665 AFR_STACK_DESTROY (transaction_frame);
1667 AFR_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
1674 /* {{{ removexattr */
1678 afr_removexattr_unwind (call_frame_t *frame, xlator_t *this)
1680 afr_local_t * local = NULL;
1681 call_frame_t *main_frame = NULL;
1683 local = frame->local;
1685 main_frame = afr_transaction_detach_fop_frame (frame);
1689 AFR_STACK_UNWIND (removexattr, main_frame, local->op_ret, local->op_errno,
1696 afr_removexattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1697 int32_t op_ret, int32_t op_errno, dict_t *xdata)
1699 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
1700 NULL, NULL, NULL, xdata);
1705 afr_removexattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
1707 afr_local_t *local = NULL;
1708 afr_private_t *priv = NULL;
1710 local = frame->local;
1711 priv = this->private;
1713 STACK_WIND_COOKIE (frame, afr_removexattr_wind_cbk, (void *) (long) subvol,
1714 priv->children[subvol],
1715 priv->children[subvol]->fops->removexattr,
1716 &local->loc, local->cont.removexattr.name,
1723 afr_removexattr (call_frame_t *frame, xlator_t *this,
1724 loc_t *loc, const char *name, dict_t *xdata)
1726 afr_local_t *local = NULL;
1727 call_frame_t *transaction_frame = NULL;
1729 int op_errno = ENOMEM;
1731 GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
1732 name, op_errno, out);
1734 GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
1735 name, op_errno, out);
1737 transaction_frame = copy_frame (frame);
1738 if (!transaction_frame)
1741 local = AFR_FRAME_INIT (transaction_frame, op_errno);
1745 local->cont.removexattr.name = gf_strdup (name);
1748 local->xdata_req = dict_copy_with_ref (xdata, NULL);
1750 local->xdata_req = dict_new ();
1752 if (!local->xdata_req)
1755 local->transaction.wind = afr_removexattr_wind;
1756 local->transaction.fop = __afr_txn_write_fop;
1757 local->transaction.done = __afr_txn_write_done;
1758 local->transaction.unwind = afr_removexattr_unwind;
1760 loc_copy (&local->loc, loc);
1761 local->inode = inode_ref (loc->inode);
1763 local->op = GF_FOP_REMOVEXATTR;
1765 local->transaction.main_frame = frame;
1766 local->transaction.start = LLONG_MAX - 1;
1767 local->transaction.len = 0;
1769 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
1777 if (transaction_frame)
1778 AFR_STACK_DESTROY (transaction_frame);
1780 AFR_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
1786 afr_fremovexattr_unwind (call_frame_t *frame, xlator_t *this)
1788 afr_local_t * local = NULL;
1789 call_frame_t *main_frame = NULL;
1791 local = frame->local;
1793 main_frame = afr_transaction_detach_fop_frame (frame);
1797 AFR_STACK_UNWIND (fremovexattr, main_frame, local->op_ret, local->op_errno,
1804 afr_fremovexattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1805 int32_t op_ret, int32_t op_errno, dict_t *xdata)
1807 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
1808 NULL, NULL, NULL, xdata);
1813 afr_fremovexattr_wind (call_frame_t *frame, xlator_t *this, int subvol)
1815 afr_local_t *local = NULL;
1816 afr_private_t *priv = NULL;
1818 local = frame->local;
1819 priv = this->private;
1821 STACK_WIND_COOKIE (frame, afr_fremovexattr_wind_cbk, (void *) (long) subvol,
1822 priv->children[subvol],
1823 priv->children[subvol]->fops->fremovexattr,
1824 local->fd, local->cont.removexattr.name,
1831 afr_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
1832 const char *name, dict_t *xdata)
1834 afr_local_t *local = NULL;
1835 call_frame_t *transaction_frame = NULL;
1837 int op_errno = ENOMEM;
1839 GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
1840 name, op_errno, out);
1842 GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
1843 name, op_errno, out);
1845 transaction_frame = copy_frame (frame);
1846 if (!transaction_frame)
1849 local = AFR_FRAME_INIT (transaction_frame, op_errno);
1853 local->cont.removexattr.name = gf_strdup (name);
1855 local->xdata_req = dict_copy_with_ref (xdata, NULL);
1857 local->xdata_req = dict_new ();
1859 if (!local->xdata_req)
1862 local->transaction.wind = afr_fremovexattr_wind;
1863 local->transaction.fop = __afr_txn_write_fop;
1864 local->transaction.done = __afr_txn_write_done;
1865 local->transaction.unwind = afr_fremovexattr_unwind;
1867 local->fd = fd_ref (fd);
1868 local->inode = inode_ref (fd->inode);
1870 local->op = GF_FOP_FREMOVEXATTR;
1872 local->transaction.main_frame = frame;
1873 local->transaction.start = LLONG_MAX - 1;
1874 local->transaction.len = 0;
1876 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
1884 if (transaction_frame)
1885 AFR_STACK_DESTROY (transaction_frame);
1887 AFR_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
1894 afr_fallocate_unwind (call_frame_t *frame, xlator_t *this)
1896 afr_local_t * local = NULL;
1897 call_frame_t *main_frame = NULL;
1899 local = frame->local;
1901 main_frame = afr_transaction_detach_fop_frame (frame);
1905 AFR_STACK_UNWIND (fallocate, main_frame, local->op_ret, local->op_errno,
1906 &local->cont.inode_wfop.prebuf,
1907 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
1913 afr_fallocate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1914 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
1915 struct iatt *postbuf, dict_t *xdata)
1917 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
1918 prebuf, postbuf, NULL, xdata);
1923 afr_fallocate_wind (call_frame_t *frame, xlator_t *this, int subvol)
1925 afr_local_t *local = NULL;
1926 afr_private_t *priv = NULL;
1928 local = frame->local;
1929 priv = this->private;
1931 STACK_WIND_COOKIE (frame, afr_fallocate_wind_cbk, (void *) (long) subvol,
1932 priv->children[subvol],
1933 priv->children[subvol]->fops->fallocate,
1934 local->fd, local->cont.fallocate.mode,
1935 local->cont.fallocate.offset,
1936 local->cont.fallocate.len, local->xdata_req);
1942 afr_fallocate (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode,
1943 off_t offset, size_t len, dict_t *xdata)
1945 call_frame_t *transaction_frame = NULL;
1946 afr_local_t *local = NULL;
1948 int op_errno = ENOMEM;
1950 transaction_frame = copy_frame (frame);
1951 if (!transaction_frame)
1954 local = AFR_FRAME_INIT (transaction_frame, op_errno);
1958 local->cont.fallocate.mode = mode;
1959 local->cont.fallocate.offset = offset;
1960 local->cont.fallocate.len = len;
1962 local->fd = fd_ref (fd);
1963 local->inode = inode_ref (fd->inode);
1966 local->xdata_req = dict_copy_with_ref (xdata, NULL);
1968 local->xdata_req = dict_new ();
1970 if (!local->xdata_req)
1973 local->op = GF_FOP_FALLOCATE;
1975 local->transaction.wind = afr_fallocate_wind;
1976 local->transaction.fop = __afr_txn_write_fop;
1977 local->transaction.done = __afr_txn_write_done;
1978 local->transaction.unwind = afr_fallocate_unwind;
1980 local->transaction.main_frame = frame;
1982 local->transaction.start = local->cont.fallocate.offset;
1983 local->transaction.len = 0;
1985 afr_fix_open (fd, this);
1987 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
1995 if (transaction_frame)
1996 AFR_STACK_DESTROY (transaction_frame);
1998 AFR_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL);
2008 afr_discard_unwind (call_frame_t *frame, xlator_t *this)
2010 afr_local_t * local = NULL;
2011 call_frame_t *main_frame = NULL;
2013 local = frame->local;
2015 main_frame = afr_transaction_detach_fop_frame (frame);
2019 AFR_STACK_UNWIND (discard, main_frame, local->op_ret, local->op_errno,
2020 &local->cont.inode_wfop.prebuf,
2021 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
2027 afr_discard_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2028 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
2029 struct iatt *postbuf, dict_t *xdata)
2031 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
2032 prebuf, postbuf, NULL, xdata);
2037 afr_discard_wind (call_frame_t *frame, xlator_t *this, int subvol)
2039 afr_local_t *local = NULL;
2040 afr_private_t *priv = NULL;
2042 local = frame->local;
2043 priv = this->private;
2045 STACK_WIND_COOKIE (frame, afr_discard_wind_cbk, (void *) (long) subvol,
2046 priv->children[subvol],
2047 priv->children[subvol]->fops->discard,
2048 local->fd, local->cont.discard.offset,
2049 local->cont.discard.len, local->xdata_req);
2055 afr_discard (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
2056 size_t len, dict_t *xdata)
2058 afr_local_t *local = NULL;
2059 call_frame_t *transaction_frame = NULL;
2061 int op_errno = ENOMEM;
2063 transaction_frame = copy_frame (frame);
2064 if (!transaction_frame)
2067 local = AFR_FRAME_INIT (transaction_frame, op_errno);
2071 local->cont.discard.offset = offset;
2072 local->cont.discard.len = len;
2074 local->fd = fd_ref (fd);
2075 local->inode = inode_ref (fd->inode);
2078 local->xdata_req = dict_copy_with_ref (xdata, NULL);
2080 local->xdata_req = dict_new ();
2082 if (!local->xdata_req)
2085 local->op = GF_FOP_DISCARD;
2087 local->transaction.wind = afr_discard_wind;
2088 local->transaction.fop = __afr_txn_write_fop;
2089 local->transaction.done = __afr_txn_write_done;
2090 local->transaction.unwind = afr_discard_unwind;
2092 local->transaction.main_frame = frame;
2094 local->transaction.start = local->cont.discard.offset;
2095 local->transaction.len = 0;
2097 afr_fix_open (fd, this);
2099 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
2107 if (transaction_frame)
2108 AFR_STACK_DESTROY (transaction_frame);
2110 AFR_STACK_UNWIND (discard, frame, -1, op_errno, NULL, NULL, NULL);
2118 afr_zerofill_unwind (call_frame_t *frame, xlator_t *this)
2120 afr_local_t * local = NULL;
2121 call_frame_t *main_frame = NULL;
2123 local = frame->local;
2125 main_frame = afr_transaction_detach_fop_frame (frame);
2129 AFR_STACK_UNWIND (discard, main_frame, local->op_ret, local->op_errno,
2130 &local->cont.inode_wfop.prebuf,
2131 &local->cont.inode_wfop.postbuf, local->xdata_rsp);
2137 afr_zerofill_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2138 int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
2139 struct iatt *postbuf, dict_t *xdata)
2141 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
2142 prebuf, postbuf, NULL, xdata);
2147 afr_zerofill_wind (call_frame_t *frame, xlator_t *this, int subvol)
2149 afr_local_t *local = NULL;
2150 afr_private_t *priv = NULL;
2152 local = frame->local;
2153 priv = this->private;
2155 STACK_WIND_COOKIE (frame, afr_zerofill_wind_cbk, (void *) (long) subvol,
2156 priv->children[subvol],
2157 priv->children[subvol]->fops->zerofill,
2158 local->fd, local->cont.zerofill.offset,
2159 local->cont.zerofill.len, local->xdata_req);
2164 afr_zerofill (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
2165 size_t len, dict_t *xdata)
2167 afr_local_t *local = NULL;
2168 call_frame_t *transaction_frame = NULL;
2170 int op_errno = ENOMEM;
2172 transaction_frame = copy_frame (frame);
2173 if (!transaction_frame)
2176 local = AFR_FRAME_INIT (transaction_frame, op_errno);
2180 local->cont.zerofill.offset = offset;
2181 local->cont.zerofill.len = len;
2183 local->fd = fd_ref (fd);
2184 local->inode = inode_ref (fd->inode);
2187 local->xdata_req = dict_copy_with_ref (xdata, NULL);
2189 local->xdata_req = dict_new ();
2191 if (!local->xdata_req)
2194 local->op = GF_FOP_ZEROFILL;
2196 local->transaction.wind = afr_zerofill_wind;
2197 local->transaction.fop = __afr_txn_write_fop;
2198 local->transaction.done = __afr_txn_write_done;
2199 local->transaction.unwind = afr_zerofill_unwind;
2201 local->transaction.main_frame = frame;
2203 local->transaction.start = local->cont.discard.offset;
2204 local->transaction.len = len;
2206 afr_fix_open (fd, this);
2208 ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
2216 if (transaction_frame)
2217 AFR_STACK_DESTROY (transaction_frame);
2219 AFR_STACK_UNWIND (zerofill, frame, -1, op_errno, NULL, NULL, NULL);
2226 afr_xattrop_wind_cbk (call_frame_t *frame, void *cookie,
2227 xlator_t *this, int32_t op_ret, int32_t op_errno,
2228 dict_t *xattr, dict_t *xdata)
2230 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
2231 NULL, NULL, xattr, xdata);
2235 afr_xattrop_wind (call_frame_t *frame, xlator_t *this, int subvol)
2237 afr_local_t *local = NULL;
2238 afr_private_t *priv = NULL;
2240 local = frame->local;
2241 priv = this->private;
2243 STACK_WIND_COOKIE (frame, afr_xattrop_wind_cbk, (void *) (long) subvol,
2244 priv->children[subvol],
2245 priv->children[subvol]->fops->xattrop,
2246 &local->loc, local->cont.xattrop.optype,
2247 local->cont.xattrop.xattr, local->xdata_req);
2252 afr_xattrop_unwind (call_frame_t *frame, xlator_t *this)
2254 afr_local_t *local = NULL;
2255 call_frame_t *main_frame = NULL;
2257 local = frame->local;
2259 main_frame = afr_transaction_detach_fop_frame (frame);
2263 AFR_STACK_UNWIND (xattrop, main_frame, local->op_ret, local->op_errno,
2264 local->xattr_rsp, local->xdata_rsp);
2269 afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
2270 gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
2272 afr_local_t *local = NULL;
2273 call_frame_t *transaction_frame = NULL;
2275 int op_errno = ENOMEM;
2277 transaction_frame = copy_frame (frame);
2278 if (!transaction_frame)
2281 local = AFR_FRAME_INIT (transaction_frame, op_errno);
2285 local->cont.xattrop.xattr = dict_ref (xattr);
2286 local->cont.xattrop.optype = optype;
2288 local->xdata_req = dict_ref (xdata);
2290 local->transaction.wind = afr_xattrop_wind;
2291 local->transaction.fop = __afr_txn_write_fop;
2292 local->transaction.done = __afr_txn_write_done;
2293 local->transaction.unwind = afr_xattrop_unwind;
2295 loc_copy (&local->loc, loc);
2296 local->inode = inode_ref (loc->inode);
2298 local->op = GF_FOP_XATTROP;
2300 local->transaction.main_frame = frame;
2301 local->transaction.start = LLONG_MAX - 1;
2302 local->transaction.len = 0;
2304 ret = afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
2312 if (transaction_frame)
2313 AFR_STACK_DESTROY (transaction_frame);
2315 AFR_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
2320 afr_fxattrop_wind_cbk (call_frame_t *frame, void *cookie,
2321 xlator_t *this, int32_t op_ret, int32_t op_errno,
2322 dict_t *xattr, dict_t *xdata)
2324 return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno,
2325 NULL, NULL, xattr, xdata);
2329 afr_fxattrop_wind (call_frame_t *frame, xlator_t *this, int subvol)
2331 afr_local_t *local = NULL;
2332 afr_private_t *priv = NULL;
2334 local = frame->local;
2335 priv = this->private;
2337 STACK_WIND_COOKIE (frame, afr_fxattrop_wind_cbk, (void *) (long) subvol,
2338 priv->children[subvol],
2339 priv->children[subvol]->fops->fxattrop,
2340 local->fd, local->cont.xattrop.optype,
2341 local->cont.xattrop.xattr, local->xdata_req);
2346 afr_fxattrop_unwind (call_frame_t *frame, xlator_t *this)
2348 afr_local_t *local = NULL;
2349 call_frame_t *main_frame = NULL;
2351 local = frame->local;
2353 main_frame = afr_transaction_detach_fop_frame (frame);
2357 AFR_STACK_UNWIND (fxattrop, main_frame, local->op_ret, local->op_errno,
2358 local->xattr_rsp, local->xdata_rsp);
2363 afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
2364 gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
2366 afr_local_t *local = NULL;
2367 call_frame_t *transaction_frame = NULL;
2369 int op_errno = ENOMEM;
2371 transaction_frame = copy_frame (frame);
2372 if (!transaction_frame)
2375 local = AFR_FRAME_INIT (transaction_frame, op_errno);
2379 local->cont.xattrop.xattr = dict_ref (xattr);
2380 local->cont.xattrop.optype = optype;
2382 local->xdata_req = dict_ref (xdata);
2384 local->transaction.wind = afr_fxattrop_wind;
2385 local->transaction.fop = __afr_txn_write_fop;
2386 local->transaction.done = __afr_txn_write_done;
2387 local->transaction.unwind = afr_fxattrop_unwind;
2389 local->fd = fd_ref (fd);
2390 local->inode = inode_ref (fd->inode);
2392 local->op = GF_FOP_FXATTROP;
2394 local->transaction.main_frame = frame;
2395 local->transaction.start = LLONG_MAX - 1;
2396 local->transaction.len = 0;
2398 ret = afr_transaction (transaction_frame, this,
2399 AFR_METADATA_TRANSACTION);
2407 if (transaction_frame)
2408 AFR_STACK_DESTROY (transaction_frame);
2410 AFR_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);