~ubuntu-branches/ubuntu/trusty/glusterfs/trusty

« back to all changes in this revision

Viewing changes to xlators/cluster/dht/src/dht-common.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Matthäi
  • Date: 2010-02-09 18:53:10 UTC
  • mfrom: (1.2.4 upstream) (4.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100209185310-ww8p82lsbosorg2u
* New upstream release.
* Uploading to unstable.
* Bump Standards-Version to 3.8.4 (no changes needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "defaults.h"
32
32
 
33
33
#include <sys/time.h>
 
34
#include <libgen.h>
34
35
 
35
36
/* TODO:
36
37
   - use volumename in xattr instead of "dht"
54
55
 
55
56
        if (ret == 0) {
56
57
                layout = local->selfheal.layout;
57
 
                ret = inode_ctx_put (local->inode, this, 
58
 
                                     (uint64_t)(long)layout);
 
58
                ret = dht_layout_set (this, local->inode, layout);
59
59
 
60
 
                if (ret == 0)
61
 
                        local->selfheal.layout = NULL;
62
 
                
63
60
                if (local->st_ino) {
64
61
                        local->stbuf.st_ino = local->st_ino;
65
62
                } else {
67
64
                                "could not find hashed subvolume for %s",
68
65
                                local->loc.path);
69
66
                }
 
67
 
 
68
                if (local->loc.parent)
 
69
                        local->postparent.st_ino = local->loc.parent->ino;
70
70
        }
71
71
 
72
 
        DHT_STACK_UNWIND (frame, ret, local->op_errno, local->inode,
73
 
                          &local->stbuf, local->xattr);
 
72
        DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode,
 
73
                          &local->stbuf, local->xattr, &local->postparent);
74
74
 
75
75
        return 0;
76
76
}
79
79
int
80
80
dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
81
81
                    int op_ret, int op_errno,
82
 
                    inode_t *inode, struct stat *stbuf, dict_t *xattr)
 
82
                    inode_t *inode, struct stat *stbuf, dict_t *xattr,
 
83
                    struct stat *postparent)
83
84
{
84
 
        dht_conf_t   *conf          = NULL;
85
 
        dht_local_t  *local         = NULL;
86
 
        int           this_call_cnt = 0;
87
 
        call_frame_t *prev          = NULL;
88
 
        dht_layout_t *layout        = NULL;
89
 
        int           ret           = 0;
90
 
        int           is_dir        = 0;
 
85
        dht_conf_t   *conf                    = NULL;
 
86
        dht_local_t  *local                   = NULL;
 
87
        int           this_call_cnt           = 0;
 
88
        call_frame_t *prev                    = NULL;
 
89
        dht_layout_t *layout                  = NULL;
 
90
        int           ret                     = 0;
 
91
        int           is_dir                  = 0;
91
92
 
92
93
        conf  = this->private;
93
94
        local = frame->local;
132
133
                        local->inode = inode_ref (inode);
133
134
 
134
135
                dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
 
136
                dht_stat_merge (this, &local->postparent, postparent,
 
137
                                prev->this);
135
138
 
136
 
                if (prev->this == local->hashed_subvol)
 
139
                if (prev->this == local->hashed_subvol) {
137
140
                        local->st_ino = local->stbuf.st_ino;
 
141
                        local->st_dev = local->stbuf.st_dev;
 
142
                }
138
143
 
139
144
        }
140
145
unlock:
153
158
                if (local->op_ret == 0) {
154
159
                        ret = dht_layout_normalize (this, &local->loc, layout);
155
160
 
156
 
                        local->layout = NULL;
157
 
 
158
161
                        if (ret != 0) {
159
162
                                gf_log (this->name, GF_LOG_DEBUG,
160
163
                                        "fixing assignment on %s",
162
165
                                goto selfheal;
163
166
                        }
164
167
                        
165
 
                        inode_ctx_put (local->inode, this,
166
 
                                       (uint64_t)(long)layout);
 
168
                        dht_layout_set (this, local->inode, layout);
167
169
                        
168
170
                        if (local->st_ino) {
169
171
                                local->stbuf.st_ino = local->st_ino;
 
172
                                local->stbuf.st_dev = local->st_dev;
170
173
                        } else {
171
174
                                gf_log (this->name, GF_LOG_DEBUG,
172
175
                                        "could not find hashed subvol for %s",
173
176
                                        local->loc.path);
174
177
                        }
 
178
 
 
179
                        if (local->loc.parent)
 
180
                                local->postparent.st_ino =
 
181
                                        local->loc.parent->ino;
175
182
                }
176
183
 
177
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
178
 
                                  local->inode, &local->stbuf, local->xattr);
 
184
                DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
 
185
                                  local->inode, &local->stbuf, local->xattr,
 
186
                                  &local->postparent);
179
187
        }
180
188
 
181
189
        return 0;
190
198
int
191
199
dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
192
200
                    int op_ret, int op_errno,
193
 
                    inode_t *inode, struct stat *stbuf, dict_t *xattr)
 
201
                    inode_t *inode, struct stat *stbuf, dict_t *xattr,
 
202
                    struct stat *postparent)
194
203
{
195
204
        dht_local_t  *local         = NULL;
196
205
        int           this_call_cnt = 0;
241
250
                        goto unlock;
242
251
                }
243
252
 
244
 
                layout = dht_layout_get (this, inode);
 
253
                layout = local->layout;
245
254
                
246
255
                is_dir = check_is_dir (inode, stbuf, xattr);
247
256
                is_linkfile = check_is_linkfile (inode, stbuf, xattr);
271
280
                } 
272
281
                
273
282
                dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
 
283
                dht_stat_merge (this, &local->postparent, postparent,
 
284
                                prev->this);
274
285
                
275
286
                local->op_ret = 0;
276
287
                local->stbuf.st_ino = local->st_ino;
 
288
                local->stbuf.st_dev = local->loc.inode->generation;
 
289
 
 
290
                if (local->loc.parent)
 
291
                        local->postparent.st_ino = local->loc.parent->ino;
277
292
 
278
293
                if (!local->xattr)
279
294
                        local->xattr = dict_ref (xattr);
296
311
                        local->op_errno = ESTALE;
297
312
                }
298
313
                        
299
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
300
 
                                  local->inode, &local->stbuf, local->xattr);
 
314
                DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
 
315
                                  local->inode, &local->stbuf, local->xattr,
 
316
                                  &local->postparent);
301
317
        }
302
318
 
303
319
        return 0;
308
324
dht_lookup_linkfile_create_cbk (call_frame_t *frame, void *cookie,
309
325
                                xlator_t *this,
310
326
                                int32_t op_ret, int32_t op_errno,
311
 
                                inode_t *inode, struct stat *stbuf)
 
327
                                inode_t *inode, struct stat *stbuf,
 
328
                                struct stat *preparent, struct stat *postparent)
312
329
{
313
330
        dht_local_t  *local = NULL;
314
331
        xlator_t     *cached_subvol = NULL;
319
336
        cached_subvol = local->cached_subvol;
320
337
        conf = this->private;
321
338
 
322
 
        ret = dht_layout_inode_set (this, local->cached_subvol, inode);
 
339
        ret = dht_layout_preset (this, local->cached_subvol, inode);
323
340
        if (ret < 0) {
324
341
                gf_log (this->name, GF_LOG_DEBUG,
325
342
                        "failed to set layout for subvolume %s",
335
352
                local->stbuf.st_mode |= S_ISVTX;
336
353
        }
337
354
 
 
355
        if (local->loc.parent)
 
356
                local->postparent.st_ino = local->loc.parent->ino;
 
357
 
338
358
unwind:
339
 
        DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
340
 
                          local->inode, &local->stbuf, local->xattr);
 
359
        DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
 
360
                          local->inode, &local->stbuf, local->xattr,
 
361
                          &local->postparent);
341
362
        return 0;
342
363
}
343
364
 
345
366
int
346
367
dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
347
368
                           int32_t op_ret, int32_t op_errno,
348
 
                           inode_t *inode, struct stat *buf, dict_t *xattr)
 
369
                           inode_t *inode, struct stat *buf, dict_t *xattr,
 
370
                           struct stat *postparent)
349
371
{
350
372
        dht_conf_t   *conf          = NULL;
351
373
        dht_local_t  *local         = NULL;
407
429
                                gf_log (this->name, GF_LOG_DEBUG,
408
430
                                        "found on %s file %s",
409
431
                                        subvol->name, loc->path);
 
432
                                
 
433
                                dht_stat_merge (this, &local->postparent,
 
434
                                                postparent, subvol);
410
435
                        } else {
411
436
                                gf_log (this->name, GF_LOG_DEBUG,
412
437
                                        "multiple subvolumes (%s and %s) have "
436
461
                                "and directory on another. "
437
462
                                "Please fix it manually",
438
463
                                loc->path);
439
 
                        DHT_STACK_UNWIND (frame, -1, EIO, NULL, NULL, NULL);
 
464
                        DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL,
 
465
                                          NULL);
440
466
                        return 0;
441
467
                }
442
468
 
446
472
                }
447
473
 
448
474
                if (!cached_subvol) {
449
 
                        DHT_STACK_UNWIND (frame, -1, ENOENT, NULL, NULL, NULL);
 
475
                        DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL,
 
476
                                          NULL);
450
477
                        return 0;
451
478
                }
452
479
 
459
486
                        local->op_ret = 0;
460
487
                        local->op_errno = 0;
461
488
 
462
 
                        ret = dht_layout_inode_set (frame->this, cached_subvol,
463
 
                                                    local->inode);
 
489
                        ret = dht_layout_preset (frame->this, cached_subvol,
 
490
                                                 local->inode);
464
491
                        if (ret < 0) {
465
492
                                gf_log (this->name, GF_LOG_DEBUG,
466
493
                                        "failed to set layout for subvol %s",
470
497
                                local->op_errno = EINVAL;
471
498
                        }
472
499
 
473
 
                        DHT_STACK_UNWIND (frame, local->op_ret,
 
500
                        if (local->loc.parent)
 
501
                                local->postparent.st_ino =
 
502
                                        local->loc.parent->ino;
 
503
 
 
504
                        DHT_STACK_UNWIND (lookup, frame, local->op_ret,
474
505
                                          local->op_errno, local->inode,
475
 
                                          &local->stbuf, local->xattr);
 
506
                                          &local->stbuf, local->xattr,
 
507
                                          &local->postparent);
476
508
                        return 0;
477
509
                }
478
510
 
521
553
int
522
554
dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie,
523
555
                         xlator_t *this, int op_ret, int op_errno,
524
 
                         inode_t *inode, struct stat *stbuf, dict_t *xattr)
 
556
                         inode_t *inode, struct stat *stbuf, dict_t *xattr,
 
557
                         struct stat *postparent)
525
558
{
526
 
        call_frame_t *prev = NULL;
527
 
        dht_local_t  *local = NULL;
528
 
        dht_layout_t *layout = NULL;
529
 
        xlator_t     *subvol = NULL;
530
 
        loc_t        *loc = NULL;
531
 
        dht_conf_t   *conf = NULL;
 
559
        call_frame_t *prev          = NULL;
 
560
        dht_local_t  *local         = NULL;
 
561
        xlator_t     *subvol        = NULL;
 
562
        loc_t        *loc           = NULL;
 
563
        dht_conf_t   *conf          = NULL;
 
564
        int           ret           = 0;
532
565
 
533
566
        prev   = cookie;
534
567
        subvol = prev->this;
562
595
                stbuf->st_mode |= S_ISVTX;
563
596
        }
564
597
        dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
565
 
 
566
 
        layout = dht_layout_for_subvol (this, prev->this);
567
 
        if (!layout) {
568
 
                gf_log (this->name, GF_LOG_DEBUG,
569
 
                        "no pre-set layout for subvolume %s",
570
 
                        prev->this->name);
 
598
        if (local->loc.parent)
 
599
                postparent->st_ino = local->loc.parent->ino;
 
600
        
 
601
        ret = dht_layout_preset (this, prev->this, inode);
 
602
        if (ret < 0) {
 
603
                gf_log (this->name, GF_LOG_DEBUG,
 
604
                        "failed to set layout for subvolume %s",
 
605
                        prev->this->name);
571
606
                op_ret   = -1;
572
607
                op_errno = EINVAL;
573
608
                goto out;
574
609
        }
575
610
 
576
 
        inode_ctx_put (inode, this, (uint64_t)(long)layout);
577
 
 
578
611
out:
579
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf, xattr);
 
612
        DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
 
613
                          postparent);
580
614
 
581
615
        return 0;
582
616
 
605
639
        if (!local->layout) {
606
640
                gf_log (this->name, GF_LOG_ERROR,
607
641
                        "Out of memory");
608
 
                DHT_STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL, NULL);
 
642
                DHT_STACK_UNWIND (lookup, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
609
643
                return 0;
610
644
        }
611
645
                
622
656
int
623
657
dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
624
658
                int op_ret, int op_errno,
625
 
                inode_t *inode, struct stat *stbuf, dict_t *xattr)
 
659
                inode_t *inode, struct stat *stbuf, dict_t *xattr,
 
660
                struct stat *postparent)
626
661
{
627
 
        dht_layout_t *layout      = NULL;
628
 
        char          is_linkfile = 0;
629
 
        char          is_dir      = 0;
630
 
        xlator_t     *subvol      = NULL;
631
 
        dht_conf_t   *conf        = NULL;
632
 
        dht_local_t  *local       = NULL;
633
 
        loc_t        *loc         = NULL;
634
 
        call_frame_t *prev        = NULL;
635
 
 
 
662
        char          is_linkfile   = 0;
 
663
        char          is_dir        = 0;
 
664
        xlator_t     *subvol        = NULL;
 
665
        dht_conf_t   *conf          = NULL;
 
666
        dht_local_t  *local         = NULL;
 
667
        loc_t        *loc           = NULL;
 
668
        call_frame_t *prev          = NULL;
 
669
        int           ret           = 0;
636
670
 
637
671
        conf  = this->private;
638
672
 
672
706
 
673
707
                dht_itransform (this, prev->this, stbuf->st_ino,
674
708
                                &stbuf->st_ino);
 
709
                if (loc->parent)
 
710
                        postparent->st_ino = loc->parent->ino;
675
711
 
676
 
                layout = dht_layout_for_subvol (this, prev->this);
677
 
                if (!layout) {
 
712
                ret = dht_layout_preset (this, prev->this, inode);
 
713
                if (ret < 0) {
678
714
                        gf_log (this->name, GF_LOG_DEBUG,
679
 
                                "no pre-set layout for subvolume %s",
 
715
                                "could not set pre-set layout for subvolume %s",
680
716
                                prev->this->name);
681
717
                        op_ret   = -1;
682
718
                        op_errno = EINVAL;
683
719
                        goto out;
684
720
                }
685
 
 
686
 
                inode_ctx_put (inode, this, (uint64_t)(long)layout);
687
721
                goto out; 
688
722
        }
689
723
 
706
740
        return 0;
707
741
 
708
742
out:
709
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf, xattr);
 
743
        /* 
 
744
         * FIXME: postparent->st_size and postparent->st_blocks do not have 
 
745
         * correct values. since, postparent corresponds to a directory these 
 
746
         * two members should have values equal to sum of corresponding values
 
747
         * from each of the subvolume. See dht_stat_merge for reference.
 
748
         */ 
 
749
        DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
 
750
                          postparent);
710
751
        return 0;
711
752
}
712
753
 
765
806
        local->hashed_subvol = hashed_subvol;
766
807
 
767
808
        if (is_revalidate (loc)) {
768
 
                layout = dht_layout_get (this, loc->inode);
 
809
                local->layout = layout = dht_layout_get (this, loc->inode);
769
810
 
770
811
                if (!layout) {
771
812
                        gf_log (this->name, GF_LOG_DEBUG,
779
820
                        gf_log (this->name, GF_LOG_TRACE,
780
821
                                "incomplete layout failure for path=%s",
781
822
                                loc->path);
782
 
                        op_errno = ESTALE;
783
 
                        goto err;
 
823
 
 
824
                        dht_layout_unref (this, local->layout);
 
825
                        local->layout = NULL;
 
826
                        goto do_fresh_lookup;
784
827
                }
785
828
 
786
829
                local->inode    = inode_ref (loc->inode);
806
849
                                break;
807
850
                }
808
851
        } else {
 
852
        do_fresh_lookup:
809
853
                /* TODO: remove the hard-coding */
810
854
                ret = dict_set_uint32 (local->xattr_req, 
811
855
                                       "trusted.glusterfs.dht", 4 * 4);
821
865
                        call_cnt        = conf->subvolume_cnt;
822
866
                        local->call_cnt = call_cnt;
823
867
                        
824
 
                        local->layout = dht_layout_new (this, conf->subvolume_cnt);
 
868
                        local->layout = dht_layout_new (this,
 
869
                                                        conf->subvolume_cnt);
825
870
                        if (!local->layout) {
826
871
                                op_errno = ENOMEM;
827
872
                                gf_log (this->name, GF_LOG_ERROR,
847
892
 
848
893
err:
849
894
        op_errno = (op_errno == -1) ? errno : op_errno;
850
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL);
851
 
        return 0;
852
 
}
 
895
        DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
 
896
        return 0;
 
897
}
 
898
 
 
899
 
 
900
int
 
901
dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 
902
              int op_ret, int op_errno, struct stat *prebuf,
 
903
              struct stat *postbuf)
 
904
{
 
905
        dht_local_t  *local = NULL;
 
906
        int           this_call_cnt = 0;
 
907
        call_frame_t *prev = NULL;
 
908
 
 
909
 
 
910
        local = frame->local;
 
911
        prev = cookie;
 
912
 
 
913
        LOCK (&frame->lock);
 
914
        {
 
915
                if (op_ret == -1) {
 
916
                        local->op_errno = op_errno;
 
917
                        gf_log (this->name, GF_LOG_DEBUG,
 
918
                                "subvolume %s returned -1 (%s)",
 
919
                                prev->this->name, strerror (op_errno));
 
920
                        goto unlock;
 
921
                }
 
922
 
 
923
                dht_stat_merge (this, &local->prebuf, prebuf, prev->this);
 
924
                dht_stat_merge (this, &local->stbuf, postbuf, prev->this);
 
925
 
 
926
                if (local->inode) {
 
927
                        local->stbuf.st_ino = local->inode->ino;
 
928
                        local->prebuf.st_ino = local->inode->ino;
 
929
                }
 
930
 
 
931
                local->op_ret = 0;
 
932
        }
 
933
unlock:
 
934
        UNLOCK (&frame->lock);
 
935
 
 
936
        this_call_cnt = dht_frame_return (frame);
 
937
        if (is_last_call (this_call_cnt))
 
938
                DHT_STACK_UNWIND (truncate, frame, local->op_ret, local->op_errno,
 
939
                                  &local->prebuf, &local->stbuf);
 
940
 
 
941
        return 0;
 
942
}
 
943
 
853
944
 
854
945
 
855
946
int
885
976
 
886
977
        this_call_cnt = dht_frame_return (frame);
887
978
        if (is_last_call (this_call_cnt))
888
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
 
979
                DHT_STACK_UNWIND (stat, frame, local->op_ret, local->op_errno,
889
980
                                  &local->stbuf);
890
981
 
891
982
        return 0;
909
1000
        VALIDATE_OR_GOTO (loc->inode, err);
910
1001
        VALIDATE_OR_GOTO (loc->path, err);
911
1002
 
912
 
        layout = dht_layout_get (this, loc->inode);
913
 
        if (!layout) {
914
 
                gf_log (this->name, GF_LOG_DEBUG,
915
 
                        "no layout for path=%s", loc->path);
916
 
                op_errno = EINVAL;
917
 
                goto err;
918
 
        }
919
1003
 
920
1004
        local = dht_local_init (frame);
921
1005
        if (!local) {
925
1009
                goto err;
926
1010
        }
927
1011
 
 
1012
        local->layout = layout = dht_layout_get (this, loc->inode);
 
1013
        if (!layout) {
 
1014
                gf_log (this->name, GF_LOG_DEBUG,
 
1015
                        "no layout for path=%s", loc->path);
 
1016
                op_errno = EINVAL;
 
1017
                goto err;
 
1018
        }
 
1019
 
928
1020
        local->inode = inode_ref (loc->inode);
929
1021
        local->call_cnt = layout->cnt;
930
1022
 
940
1032
 
941
1033
err:
942
1034
        op_errno = (op_errno == -1) ? errno : op_errno;
943
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1035
        DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
944
1036
 
945
1037
        return 0;
946
1038
}
961
1053
        VALIDATE_OR_GOTO (this, err);
962
1054
        VALIDATE_OR_GOTO (fd, err);
963
1055
 
964
 
        layout = dht_layout_get (this, fd->inode);
965
 
        if (!layout) {
966
 
                gf_log (this->name, GF_LOG_DEBUG,
967
 
                        "no layout for fd=%p", fd);
968
 
                op_errno = EINVAL;
969
 
                goto err;
970
 
        }
971
 
 
972
1056
        local = dht_local_init (frame);
973
1057
        if (!local) {
974
1058
                op_errno = ENOMEM;
977
1061
                goto err;
978
1062
        }
979
1063
 
 
1064
        local->layout = layout = dht_layout_get (this, fd->inode);
 
1065
        if (!layout) {
 
1066
                gf_log (this->name, GF_LOG_DEBUG,
 
1067
                        "no layout for fd=%p", fd);
 
1068
                op_errno = EINVAL;
 
1069
                goto err;
 
1070
        }
 
1071
 
980
1072
        local->inode    = inode_ref (fd->inode);
981
1073
        local->call_cnt = layout->cnt;;
982
1074
 
991
1083
 
992
1084
err:
993
1085
        op_errno = (op_errno == -1) ? errno : op_errno;
994
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
995
 
 
996
 
        return 0;
997
 
}
998
 
 
999
 
 
1000
 
int
1001
 
dht_chmod (call_frame_t *frame, xlator_t *this,
1002
 
           loc_t *loc, mode_t mode)
1003
 
{
1004
 
        dht_layout_t *layout = NULL;
1005
 
        dht_local_t  *local  = NULL;
1006
 
        int           op_errno = -1;
1007
 
        int           i = -1;
1008
 
 
1009
 
 
1010
 
        VALIDATE_OR_GOTO (frame, err);
1011
 
        VALIDATE_OR_GOTO (this, err);
1012
 
        VALIDATE_OR_GOTO (loc, err);
1013
 
        VALIDATE_OR_GOTO (loc->inode, err);
1014
 
        VALIDATE_OR_GOTO (loc->path, err);
1015
 
 
1016
 
        layout = dht_layout_get (this, loc->inode);
1017
 
 
1018
 
        if (!layout) {
1019
 
                gf_log (this->name, GF_LOG_DEBUG,
1020
 
                        "no layout for path=%s", loc->path);
1021
 
                op_errno = EINVAL;
1022
 
                goto err;
1023
 
        }
1024
 
 
1025
 
        if (!layout_is_sane (layout)) {
1026
 
                gf_log (this->name, GF_LOG_DEBUG,
1027
 
                        "layout is not sane for path=%s", loc->path);
1028
 
                op_errno = EINVAL;
1029
 
                goto err;
1030
 
        }
1031
 
 
1032
 
        local = dht_local_init (frame);
1033
 
        if (!local) {
1034
 
                op_errno = ENOMEM;
1035
 
                gf_log (this->name, GF_LOG_DEBUG,
1036
 
                        "memory allocation failed :(");
1037
 
                goto err;
1038
 
        }
1039
 
 
1040
 
        local->inode = inode_ref (loc->inode);
1041
 
        local->call_cnt = layout->cnt;
1042
 
 
1043
 
        for (i = 0; i < layout->cnt; i++) {
1044
 
                STACK_WIND (frame, dht_attr_cbk,
1045
 
                            layout->list[i].xlator,
1046
 
                            layout->list[i].xlator->fops->chmod,
1047
 
                            loc, mode);
1048
 
        }
1049
 
 
1050
 
        return 0;
1051
 
 
1052
 
err:
1053
 
        op_errno = (op_errno == -1) ? errno : op_errno;
1054
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
1055
 
 
1056
 
        return 0;
1057
 
}
1058
 
 
1059
 
 
1060
 
int
1061
 
dht_chown (call_frame_t *frame, xlator_t *this,
1062
 
           loc_t *loc, uid_t uid, gid_t gid)
1063
 
{
1064
 
        dht_layout_t *layout = NULL;
1065
 
        dht_local_t  *local  = NULL;
1066
 
        int           op_errno = -1;
1067
 
        int           i = -1;
1068
 
 
1069
 
 
1070
 
        VALIDATE_OR_GOTO (frame, err);
1071
 
        VALIDATE_OR_GOTO (this, err);
1072
 
        VALIDATE_OR_GOTO (loc, err);
1073
 
        VALIDATE_OR_GOTO (loc->inode, err);
1074
 
        VALIDATE_OR_GOTO (loc->path, err);
1075
 
 
1076
 
        layout = dht_layout_get (this, loc->inode);
1077
 
        if (!layout) {
1078
 
                gf_log (this->name, GF_LOG_DEBUG,
1079
 
                        "no layout for path=%s", loc->path);
1080
 
                op_errno = EINVAL;
1081
 
                goto err;
1082
 
        }
1083
 
 
1084
 
        if (!layout_is_sane (layout)) {
1085
 
                gf_log (this->name, GF_LOG_DEBUG,
1086
 
                        "layout is not sane for path=%s", loc->path);
1087
 
                op_errno = EINVAL;
1088
 
                goto err;
1089
 
        }
1090
 
 
1091
 
        local = dht_local_init (frame);
1092
 
        if (!local) {
1093
 
                op_errno = ENOMEM;
1094
 
                gf_log (this->name, GF_LOG_ERROR,
1095
 
                        "Out of memory");
1096
 
                goto err;
1097
 
        }
1098
 
 
1099
 
        local->inode = inode_ref (loc->inode);
1100
 
        local->call_cnt = layout->cnt;
1101
 
 
1102
 
        for (i = 0; i < layout->cnt; i++) {
1103
 
                STACK_WIND (frame, dht_attr_cbk,
1104
 
                            layout->list[i].xlator,
1105
 
                            layout->list[i].xlator->fops->chown,
1106
 
                            loc, uid, gid);
1107
 
        }
1108
 
 
1109
 
        return 0;
1110
 
 
1111
 
err:
1112
 
        op_errno = (op_errno == -1) ? errno : op_errno;
1113
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
1114
 
 
1115
 
        return 0;
1116
 
}
1117
 
 
1118
 
 
1119
 
int
1120
 
dht_fchmod (call_frame_t *frame, xlator_t *this,
1121
 
            fd_t *fd, mode_t mode)
1122
 
{
1123
 
        dht_layout_t *layout = NULL;
1124
 
        dht_local_t  *local  = NULL;
1125
 
        int           op_errno = -1;
1126
 
        int           i = -1;
1127
 
 
1128
 
 
1129
 
        VALIDATE_OR_GOTO (frame, err);
1130
 
        VALIDATE_OR_GOTO (this, err);
1131
 
        VALIDATE_OR_GOTO (fd, err);
1132
 
 
1133
 
 
1134
 
        layout = dht_layout_get (this, fd->inode);
1135
 
        if (!layout) {
1136
 
                gf_log (this->name, GF_LOG_DEBUG,
1137
 
                        "no layout for fd=%p", fd);
1138
 
                op_errno = EINVAL;
1139
 
                goto err;
1140
 
        }
1141
 
 
1142
 
        if (!layout_is_sane (layout)) {
1143
 
                gf_log (this->name, GF_LOG_DEBUG,
1144
 
                        "layout is not sane for fd=%p", fd);
1145
 
                op_errno = EINVAL;
1146
 
                goto err;
1147
 
        }
1148
 
 
1149
 
        local = dht_local_init (frame);
1150
 
        if (!local) {
1151
 
                op_errno = ENOMEM;
1152
 
                gf_log (this->name, GF_LOG_ERROR,
1153
 
                        "Out of memory");
1154
 
                goto err;
1155
 
        }
1156
 
 
1157
 
        local->inode = inode_ref (fd->inode);
1158
 
        local->call_cnt = layout->cnt;
1159
 
 
1160
 
        for (i = 0; i < layout->cnt; i++) {
1161
 
                STACK_WIND (frame, dht_attr_cbk,
1162
 
                            layout->list[i].xlator,
1163
 
                            layout->list[i].xlator->fops->fchmod,
1164
 
                            fd, mode);
1165
 
        }
1166
 
 
1167
 
        return 0;
1168
 
 
1169
 
err:
1170
 
        op_errno = (op_errno == -1) ? errno : op_errno;
1171
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
1172
 
 
1173
 
        return 0;
1174
 
}
1175
 
 
1176
 
 
1177
 
int
1178
 
dht_fchown (call_frame_t *frame, xlator_t *this,
1179
 
            fd_t *fd, uid_t uid, gid_t gid)
1180
 
{
1181
 
        dht_layout_t *layout = NULL;
1182
 
        dht_local_t  *local  = NULL;
1183
 
        int           op_errno = -1;
1184
 
        int           i = -1;
1185
 
 
1186
 
 
1187
 
        VALIDATE_OR_GOTO (frame, err);
1188
 
        VALIDATE_OR_GOTO (this, err);
1189
 
        VALIDATE_OR_GOTO (fd, err);
1190
 
 
1191
 
        layout = dht_layout_get (this, fd->inode);
1192
 
        if (!layout) {
1193
 
                gf_log (this->name, GF_LOG_DEBUG,
1194
 
                        "no layout for fd=%p", fd);
1195
 
                op_errno = EINVAL;
1196
 
                goto err;
1197
 
        }
1198
 
 
1199
 
        if (!layout_is_sane (layout)) {
1200
 
                gf_log (this->name, GF_LOG_DEBUG,
1201
 
                        "layout is not sane for fd=%p", fd);
1202
 
                op_errno = EINVAL;
1203
 
                goto err;
1204
 
        }
1205
 
 
1206
 
        local = dht_local_init (frame);
1207
 
        if (!local) {
1208
 
                op_errno = ENOMEM;
1209
 
                gf_log (this->name, GF_LOG_ERROR,
1210
 
                        "Out of memory");
1211
 
                goto err;
1212
 
        }
1213
 
 
1214
 
        local->inode = inode_ref (fd->inode);
1215
 
        local->call_cnt = layout->cnt;
1216
 
 
1217
 
        for (i = 0; i < layout->cnt; i++) {
1218
 
                STACK_WIND (frame, dht_attr_cbk,
1219
 
                            layout->list[i].xlator,
1220
 
                            layout->list[i].xlator->fops->fchown,
1221
 
                            fd, uid, gid);
1222
 
        }
1223
 
 
1224
 
        return 0;
1225
 
 
1226
 
err:
1227
 
        op_errno = (op_errno == -1) ? errno : op_errno;
1228
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
1229
 
 
1230
 
        return 0;
1231
 
}
1232
 
 
1233
 
 
1234
 
int
1235
 
dht_utimens (call_frame_t *frame, xlator_t *this,
1236
 
             loc_t *loc, struct timespec tv[2])
1237
 
{
1238
 
        dht_layout_t *layout = NULL;
1239
 
        dht_local_t  *local  = NULL;
1240
 
        int           op_errno = -1;
1241
 
        int           i = -1;
1242
 
 
1243
 
 
1244
 
        VALIDATE_OR_GOTO (frame, err);
1245
 
        VALIDATE_OR_GOTO (this, err);
1246
 
        VALIDATE_OR_GOTO (loc, err);
1247
 
        VALIDATE_OR_GOTO (loc->inode, err);
1248
 
        VALIDATE_OR_GOTO (loc->path, err);
1249
 
 
1250
 
        layout = dht_layout_get (this, loc->inode);
1251
 
        if (!layout) {
1252
 
                gf_log (this->name, GF_LOG_DEBUG,
1253
 
                        "no layout for path=%s", loc->path);
1254
 
                op_errno = EINVAL;
1255
 
                goto err;
1256
 
        }
1257
 
 
1258
 
        if (!layout_is_sane (layout)) {
1259
 
                gf_log (this->name, GF_LOG_DEBUG,
1260
 
                        "layout is not sane for path=%s", loc->path);
1261
 
                op_errno = EINVAL;
1262
 
                goto err;
1263
 
        }
1264
 
 
1265
 
        local = dht_local_init (frame);
1266
 
        if (!local) {
1267
 
                op_errno = ENOMEM;
1268
 
                gf_log (this->name, GF_LOG_ERROR,
1269
 
                        "Out of memory");
1270
 
                goto err;
1271
 
        }
1272
 
 
1273
 
        local->inode = inode_ref (loc->inode);
1274
 
        local->call_cnt = layout->cnt;
1275
 
 
1276
 
        for (i = 0; i < layout->cnt; i++) {
1277
 
                STACK_WIND (frame, dht_attr_cbk,
1278
 
                            layout->list[i].xlator,
1279
 
                            layout->list[i].xlator->fops->utimens,
1280
 
                            loc, tv);
1281
 
        }
1282
 
 
1283
 
        return 0;
1284
 
 
1285
 
err:
1286
 
        op_errno = (op_errno == -1) ? errno : op_errno;
1287
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1086
        DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL);
1288
1087
 
1289
1088
        return 0;
1290
1089
}
1324
1123
        local->inode = inode_ref (loc->inode);
1325
1124
        local->call_cnt = 1;
1326
1125
 
1327
 
        STACK_WIND (frame, dht_attr_cbk,
 
1126
        STACK_WIND (frame, dht_truncate_cbk,
1328
1127
                    subvol, subvol->fops->truncate,
1329
1128
                    loc, offset);
1330
1129
 
1332
1131
 
1333
1132
err:
1334
1133
        op_errno = (op_errno == -1) ? errno : op_errno;
1335
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1134
        DHT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
1336
1135
 
1337
1136
        return 0;
1338
1137
}
1370
1169
        local->inode = inode_ref (fd->inode);
1371
1170
        local->call_cnt = 1;
1372
1171
 
1373
 
        STACK_WIND (frame, dht_attr_cbk,
 
1172
        STACK_WIND (frame, dht_truncate_cbk,
1374
1173
                    subvol, subvol->fops->ftruncate,
1375
1174
                    fd, offset);
1376
1175
 
1378
1177
 
1379
1178
err:
1380
1179
        op_errno = (op_errno == -1) ? errno : op_errno;
1381
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1180
        DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
1382
1181
 
1383
1182
        return 0;
1384
1183
}
1385
1184
 
1386
1185
 
1387
1186
int
 
1187
dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 
1188
                int op_ret, int op_errno, struct stat *preparent,
 
1189
                struct stat *postparent)
 
1190
{
 
1191
        dht_local_t  *local = NULL;
 
1192
        int           this_call_cnt = 0;
 
1193
        call_frame_t *prev = NULL;
 
1194
 
 
1195
 
 
1196
        local = frame->local;
 
1197
        prev = cookie;
 
1198
 
 
1199
        LOCK (&frame->lock);
 
1200
        {
 
1201
                if (op_ret == -1) {
 
1202
                        local->op_errno = op_errno;
 
1203
                        gf_log (this->name, GF_LOG_DEBUG,
 
1204
                                "subvolume %s returned -1 (%s)",
 
1205
                                prev->this->name, strerror (op_errno));
 
1206
                        goto unlock;
 
1207
                }
 
1208
 
 
1209
                local->op_ret = 0;
 
1210
        }
 
1211
unlock:
 
1212
        UNLOCK (&frame->lock);
 
1213
 
 
1214
        this_call_cnt = dht_frame_return (frame);
 
1215
        if (is_last_call (this_call_cnt))
 
1216
                DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
 
1217
                                  NULL, NULL);
 
1218
 
 
1219
        return 0;
 
1220
}
 
1221
 
 
1222
 
 
1223
int
 
1224
dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
 
1225
               int op_errno, struct stat *prebuf, struct stat *postbuf)
 
1226
{
 
1227
        dht_local_t  *local = NULL;
 
1228
        int           this_call_cnt = 0;
 
1229
        call_frame_t *prev = NULL;
 
1230
 
 
1231
 
 
1232
        local = frame->local;
 
1233
        prev = cookie;
 
1234
 
 
1235
        LOCK (&frame->lock);
 
1236
        {
 
1237
                if (op_ret == -1) {
 
1238
                        local->op_errno = op_errno;
 
1239
                        gf_log (this->name, GF_LOG_DEBUG,
 
1240
                                "subvolume %s returned -1 (%s)",
 
1241
                                prev->this->name, strerror (op_errno));
 
1242
                        goto unlock;
 
1243
                }
 
1244
 
 
1245
                local->op_ret = 0;
 
1246
        }
 
1247
unlock:
 
1248
        UNLOCK (&frame->lock);
 
1249
 
 
1250
        if (local && (op_ret == 0)) {
 
1251
                prebuf->st_ino = local->st_ino;
 
1252
                postbuf->st_ino = local->st_ino;
 
1253
        }
 
1254
 
 
1255
        this_call_cnt = dht_frame_return (frame);
 
1256
        if (is_last_call (this_call_cnt))
 
1257
                DHT_STACK_UNWIND (fsync, frame, local->op_ret, local->op_errno,
 
1258
                                  prebuf, postbuf);
 
1259
 
 
1260
        return 0;
 
1261
}
 
1262
 
 
1263
 
 
1264
 
 
1265
int
1388
1266
dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1389
1267
             int op_ret, int op_errno)
1390
1268
{
1412
1290
        UNLOCK (&frame->lock);
1413
1291
 
1414
1292
        this_call_cnt = dht_frame_return (frame);
1415
 
        if (is_last_call (this_call_cnt))
1416
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno);
 
1293
        if (is_last_call (this_call_cnt)) {
 
1294
                DHT_STACK_UNWIND (setxattr, frame, local->op_ret, local->op_errno);
 
1295
        }
1417
1296
 
1418
1297
        return 0;
1419
1298
}
1460
1339
 
1461
1340
err:
1462
1341
        op_errno = (op_errno == -1) ? errno : op_errno;
1463
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
1342
        DHT_STACK_UNWIND (access, frame, -1, op_errno);
1464
1343
 
1465
1344
        return 0;
1466
1345
}
1468
1347
 
1469
1348
int
1470
1349
dht_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1471
 
                  int op_ret, int op_errno, const char *path)
 
1350
                  int op_ret, int op_errno, const char *path, struct stat *sbuf)
1472
1351
{
1473
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, path);
 
1352
        dht_local_t *local = NULL;
 
1353
 
 
1354
        local = frame->local;
 
1355
        if (op_ret == -1)
 
1356
                goto err;
 
1357
 
 
1358
        if (local) {
 
1359
                sbuf->st_ino = local->st_ino;
 
1360
        } else {
 
1361
                op_ret = -1;
 
1362
                op_errno = EINVAL;
 
1363
        }
 
1364
 
 
1365
err:
 
1366
        DHT_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, sbuf);
1474
1367
 
1475
1368
        return 0;
1476
1369
}
1482
1375
{
1483
1376
        xlator_t     *subvol = NULL;
1484
1377
        int           op_errno = -1;
1485
 
 
 
1378
        dht_local_t  *local = NULL;
1486
1379
 
1487
1380
        VALIDATE_OR_GOTO (frame, err);
1488
1381
        VALIDATE_OR_GOTO (this, err);
1498
1391
                goto err;
1499
1392
        }
1500
1393
 
 
1394
        local = dht_local_init (frame);
 
1395
        if (!local) {
 
1396
                op_errno = ENOMEM;
 
1397
                gf_log (this->name, GF_LOG_ERROR,
 
1398
                        "Out of memory");
 
1399
                goto err;
 
1400
        }
 
1401
 
 
1402
        local->st_ino = loc->inode->ino;
 
1403
 
1501
1404
        STACK_WIND (frame, dht_readlink_cbk,
1502
1405
                    subvol, subvol->fops->readlink,
1503
1406
                    loc, size);
1506
1409
 
1507
1410
err:
1508
1411
        op_errno = (op_errno == -1) ? errno : op_errno;
1509
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1412
        DHT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL);
1510
1413
 
1511
1414
        return 0;
1512
1415
}
1516
1419
dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1517
1420
                  int op_ret, int op_errno, dict_t *xattr)
1518
1421
{
1519
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, xattr);
 
1422
        DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
1520
1423
 
1521
1424
        return 0;
1522
1425
}
1552
1455
 
1553
1456
err:
1554
1457
        op_errno = (op_errno == -1) ? errno : op_errno;
1555
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1458
        DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL);
1556
1459
 
1557
1460
        return 0;
1558
1461
}
1599
1502
 
1600
1503
err:
1601
1504
        op_errno = (op_errno == -1) ? errno : op_errno;
1602
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1505
        DHT_STACK_UNWIND (setxattr, frame, -1, op_errno);
1603
1506
 
1604
1507
        return 0;
1605
1508
}
1646
1549
 
1647
1550
err:
1648
1551
        op_errno = (op_errno == -1) ? errno : op_errno;
1649
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1552
        DHT_STACK_UNWIND (removexattr, frame, -1, op_errno);
1650
1553
 
1651
1554
        return 0;
1652
1555
}
1681
1584
 
1682
1585
        this_call_cnt = dht_frame_return (frame);
1683
1586
        if (is_last_call (this_call_cnt))
1684
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
 
1587
                DHT_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
1685
1588
                                  local->fd);
1686
1589
 
1687
1590
        return 0;
1690
1593
 
1691
1594
int
1692
1595
dht_open (call_frame_t *frame, xlator_t *this,
1693
 
          loc_t *loc, int flags, fd_t *fd)
 
1596
          loc_t *loc, int flags, fd_t *fd, int wbflags)
1694
1597
{
1695
1598
        xlator_t     *subvol = NULL;
1696
1599
        int           ret = -1;
1731
1634
 
1732
1635
        STACK_WIND (frame, dht_fd_cbk,
1733
1636
                    subvol, subvol->fops->open,
1734
 
                    loc, flags, fd);
 
1637
                    loc, flags, fd, wbflags);
1735
1638
 
1736
1639
        return 0;
1737
1640
 
1738
1641
err:
1739
1642
        op_errno = (op_errno == -1) ? errno : op_errno;
1740
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1643
        DHT_STACK_UNWIND (open, frame, -1, op_errno, NULL);
1741
1644
 
1742
1645
        return 0;
1743
1646
}
1749
1652
               struct iovec *vector, int count, struct stat *stbuf,
1750
1653
               struct iobref *iobref)
1751
1654
{
1752
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf,
 
1655
        DHT_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, stbuf,
1753
1656
                          iobref);
1754
1657
 
1755
1658
        return 0;
1784
1687
 
1785
1688
err:
1786
1689
        op_errno = (op_errno == -1) ? errno : op_errno;
1787
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, 0, NULL, NULL);
 
1690
        DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
1788
1691
 
1789
1692
        return 0;
1790
1693
}
1792
1695
 
1793
1696
int
1794
1697
dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1795
 
                int op_ret, int op_errno, struct stat *stbuf)
 
1698
                int op_ret, int op_errno, struct stat *prebuf,
 
1699
                struct stat *postbuf)
1796
1700
{
1797
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, stbuf);
 
1701
        dht_local_t *local = NULL;
 
1702
 
 
1703
        if (op_ret == -1) {
 
1704
                goto out;
 
1705
        }
 
1706
 
 
1707
        local = frame->local;
 
1708
        if (!local) {
 
1709
                op_ret = -1;
 
1710
                op_errno = EINVAL;
 
1711
                goto out;
 
1712
        } 
 
1713
        
 
1714
        prebuf->st_ino = local->st_ino;
 
1715
        postbuf->st_ino = local->st_ino;
 
1716
 
 
1717
out:
 
1718
        DHT_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
1798
1719
 
1799
1720
        return 0;
1800
1721
}
1807
1728
{
1808
1729
        xlator_t     *subvol = NULL;
1809
1730
        int           op_errno = -1;
1810
 
 
 
1731
        dht_local_t  *local = NULL;
1811
1732
 
1812
1733
        VALIDATE_OR_GOTO (frame, err);
1813
1734
        VALIDATE_OR_GOTO (this, err);
1821
1742
                goto err;
1822
1743
        }
1823
1744
 
 
1745
        local = dht_local_init (frame);
 
1746
        if (!local) {
 
1747
                gf_log (this->name, GF_LOG_ERROR,
 
1748
                        "Out of memory");
 
1749
                op_errno = ENOMEM;
 
1750
                goto err;
 
1751
        }
 
1752
 
 
1753
        local->st_ino = fd->inode->ino;
 
1754
 
1824
1755
        STACK_WIND (frame, dht_writev_cbk,
1825
1756
                    subvol, subvol->fops->writev,
1826
1757
                    fd, vector, count, off, iobref);
1829
1760
 
1830
1761
err:
1831
1762
        op_errno = (op_errno == -1) ? errno : op_errno;
1832
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, 0);
 
1763
        DHT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
1833
1764
 
1834
1765
        return 0;
1835
1766
}
1873
1804
 
1874
1805
err:
1875
1806
        op_errno = (op_errno == -1) ? errno : op_errno;
1876
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
1807
        DHT_STACK_UNWIND (flush, frame, -1, op_errno);
1877
1808
 
1878
1809
        return 0;
1879
1810
}
1909
1840
        }
1910
1841
        local->call_cnt = 1;
1911
1842
 
1912
 
        STACK_WIND (frame, dht_err_cbk,
 
1843
        local->st_ino = fd->inode->ino;
 
1844
 
 
1845
        STACK_WIND (frame, dht_fsync_cbk,
1913
1846
                    subvol, subvol->fops->fsync,
1914
1847
                    fd, datasync);
1915
1848
 
1917
1850
 
1918
1851
err:
1919
1852
        op_errno = (op_errno == -1) ? errno : op_errno;
1920
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
1853
        DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
1921
1854
 
1922
1855
        return 0;
1923
1856
}
1927
1860
dht_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
1928
1861
            int op_ret, int op_errno, struct flock *flock)
1929
1862
{
1930
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, flock);
 
1863
        DHT_STACK_UNWIND (lk, frame, op_ret, op_errno, flock);
1931
1864
 
1932
1865
        return 0;
1933
1866
}
1961
1894
 
1962
1895
err:
1963
1896
        op_errno = (op_errno == -1) ? errno : op_errno;
1964
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1897
        DHT_STACK_UNWIND (lk, frame, -1, op_errno, NULL);
1965
1898
 
1966
1899
        return 0;
1967
1900
}
2006
1939
 
2007
1940
        this_call_cnt = dht_frame_return (frame);
2008
1941
        if (is_last_call (this_call_cnt))
2009
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno,
 
1942
                DHT_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
2010
1943
                                  &local->statvfs);
2011
1944
 
2012
1945
        return 0;
2043
1976
 
2044
1977
err:
2045
1978
        op_errno = (op_errno == -1) ? errno : op_errno;
2046
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
1979
        DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL);
2047
1980
 
2048
1981
        return 0;
2049
1982
}
2095
2028
 
2096
2029
err:
2097
2030
        op_errno = (op_errno == -1) ? errno : op_errno;
2098
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
2031
        DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
2099
2032
 
2100
2033
        return 0;
2101
2034
}
2102
2035
 
2103
2036
 
2104
2037
int
 
2038
dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
 
2039
                  int op_errno, gf_dirent_t *orig_entries)
 
2040
{
 
2041
        dht_local_t  *local = NULL;
 
2042
        gf_dirent_t   entries;
 
2043
        gf_dirent_t  *orig_entry = NULL;
 
2044
        gf_dirent_t  *entry = NULL;
 
2045
        call_frame_t *prev = NULL;
 
2046
        xlator_t     *next_subvol = NULL;
 
2047
        off_t         next_offset = 0;
 
2048
        int           count = 0;
 
2049
 
 
2050
 
 
2051
        INIT_LIST_HEAD (&entries.list);
 
2052
        prev = cookie;
 
2053
        local = frame->local;
 
2054
 
 
2055
        if (op_ret < 0)
 
2056
                goto done;
 
2057
 
 
2058
        list_for_each_entry (orig_entry, (&orig_entries->list), list) {
 
2059
                next_offset = orig_entry->d_off;
 
2060
 
 
2061
                if (check_is_linkfile (NULL, (&orig_entry->d_stat), NULL)
 
2062
                    || (check_is_dir (NULL, (&orig_entry->d_stat), NULL)
 
2063
                        && (prev->this != dht_first_up_subvol (this)))) {
 
2064
                        continue;
 
2065
                }
 
2066
 
 
2067
                entry = gf_dirent_for_name (orig_entry->d_name);
 
2068
                if (!entry) {
 
2069
                        gf_log (this->name, GF_LOG_ERROR,
 
2070
                                "Out of memory");
 
2071
                        goto unwind;
 
2072
                }
 
2073
 
 
2074
                entry->d_stat = orig_entry->d_stat;
 
2075
 
 
2076
                dht_itransform (this, prev->this, orig_entry->d_ino,
 
2077
                                &entry->d_ino);
 
2078
                dht_itransform (this, prev->this, orig_entry->d_off,
 
2079
                                &entry->d_off);
 
2080
 
 
2081
                entry->d_stat.st_ino = entry->d_ino;
 
2082
                entry->d_type = orig_entry->d_type;
 
2083
                entry->d_len  = orig_entry->d_len;
 
2084
 
 
2085
                list_add_tail (&entry->list, &entries.list);
 
2086
                count++;
 
2087
        }
 
2088
        op_ret = count;
 
2089
 
 
2090
done:
 
2091
        if (count == 0) {
 
2092
                /* non-zero next_offset means that
 
2093
                   EOF is not yet hit on the current subvol
 
2094
                */
 
2095
                if (next_offset == 0) {
 
2096
                        next_subvol = dht_subvol_next (this, prev->this);
 
2097
                } else {
 
2098
                        next_subvol = prev->this;
 
2099
                }
 
2100
 
 
2101
                if (!next_subvol) {
 
2102
                        goto unwind;
 
2103
                }
 
2104
 
 
2105
                STACK_WIND (frame, dht_readdirp_cbk,
 
2106
                            next_subvol, next_subvol->fops->readdirp,
 
2107
                            local->fd, local->size, next_offset);
 
2108
                return 0;
 
2109
        }
 
2110
 
 
2111
unwind:
 
2112
        if (op_ret < 0)
 
2113
                op_ret = 0;
 
2114
 
 
2115
        DHT_STACK_UNWIND (readdirp, frame, op_ret, op_errno, &entries);
 
2116
 
 
2117
        gf_dirent_free (&entries);
 
2118
 
 
2119
        return 0;
 
2120
}
 
2121
 
 
2122
 
 
2123
 
 
2124
int
2105
2125
dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2106
2126
                 int op_ret, int op_errno, gf_dirent_t *orig_entries)
2107
2127
{
2138
2158
                        goto unwind;
2139
2159
                }
2140
2160
 
2141
 
                entry->d_stat = orig_entry->d_stat;
2142
 
 
2143
2161
                dht_itransform (this, prev->this, orig_entry->d_ino,
2144
2162
                                &entry->d_ino);
2145
2163
                dht_itransform (this, prev->this, orig_entry->d_off,
2178
2196
        if (op_ret < 0)
2179
2197
                op_ret = 0;
2180
2198
 
2181
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, &entries);
 
2199
        DHT_STACK_UNWIND (readdir, frame, op_ret, op_errno, &entries);
2182
2200
 
2183
2201
        gf_dirent_free (&entries);
2184
2202
 
2187
2205
 
2188
2206
 
2189
2207
int
2190
 
dht_readdir (call_frame_t *frame, xlator_t *this,
2191
 
             fd_t *fd, size_t size, off_t yoff)
 
2208
dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
 
2209
                off_t yoff, int whichop)
2192
2210
{
2193
2211
        dht_local_t  *local  = NULL;
2194
2212
        dht_conf_t   *conf = NULL;
2217
2235
        dht_deitransform (this, yoff, &xvol, (uint64_t *)&xoff);
2218
2236
 
2219
2237
        /* TODO: do proper readdir */
2220
 
        STACK_WIND (frame, dht_readdir_cbk,
2221
 
                    xvol, xvol->fops->readdir,
2222
 
                    fd, size, xoff);
 
2238
        if (whichop == GF_FOP_READDIR)
 
2239
                STACK_WIND (frame, dht_readdir_cbk, xvol, xvol->fops->readdir,
 
2240
                            fd, size, xoff);
 
2241
        else
 
2242
                STACK_WIND (frame, dht_readdirp_cbk, xvol, xvol->fops->readdirp,
 
2243
                            fd, size, xoff);
2223
2244
 
2224
2245
        return 0;
2225
2246
 
2226
2247
err:
2227
2248
        op_errno = (op_errno == -1) ? errno : op_errno;
2228
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
2249
        DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL);
2229
2250
 
2230
2251
        return 0;
2231
2252
}
2232
2253
 
2233
2254
 
2234
2255
int
 
2256
dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
 
2257
             off_t yoff)
 
2258
{
 
2259
        dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIR);
 
2260
        return 0;
 
2261
}
 
2262
 
 
2263
int
 
2264
dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
 
2265
              off_t yoff)
 
2266
{
 
2267
        dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP);
 
2268
        return 0;
 
2269
}
 
2270
 
 
2271
 
 
2272
 
 
2273
int
2235
2274
dht_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2236
2275
                  int op_ret, int op_errno)
2237
2276
{
2253
2292
 
2254
2293
        this_call_cnt = dht_frame_return (frame);
2255
2294
        if (is_last_call (this_call_cnt))
2256
 
                DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno);
 
2295
                DHT_STACK_UNWIND (fsyncdir, frame, local->op_ret, local->op_errno);
2257
2296
 
2258
2297
        return 0;
2259
2298
}
2296
2335
 
2297
2336
err:
2298
2337
        op_errno = (op_errno == -1) ? errno : op_errno;
2299
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
2338
        DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno);
2300
2339
 
2301
2340
        return 0;
2302
2341
}
2305
2344
int
2306
2345
dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2307
2346
                 int op_ret, int op_errno,
2308
 
                 inode_t *inode, struct stat *stbuf)
 
2347
                 inode_t *inode, struct stat *stbuf, struct stat *preparent,
 
2348
                 struct stat *postparent)
2309
2349
{
2310
2350
        call_frame_t *prev = NULL;
2311
 
        dht_layout_t *layout = NULL;
2312
2351
        int           ret = -1;
 
2352
        dht_local_t  *local = NULL;
2313
2353
 
2314
2354
 
2315
2355
        if (op_ret == -1)
2316
2356
                goto out;
2317
2357
 
 
2358
        local = frame->local;
 
2359
        if (!local) {
 
2360
                op_ret = -1;
 
2361
                op_errno = EINVAL;
 
2362
                goto out;
 
2363
        }
 
2364
 
2318
2365
        prev = cookie;
2319
2366
 
2320
2367
        dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
2321
 
        layout = dht_layout_for_subvol (this, prev->this);
 
2368
        if (local->loc.parent) {
 
2369
                preparent->st_ino = local->loc.parent->ino;
 
2370
                postparent->st_ino = local->loc.parent->ino;
 
2371
        }
2322
2372
 
2323
 
        if (!layout) {
 
2373
        ret = dht_layout_preset (this, prev->this, inode);
 
2374
        if (ret < 0) {
2324
2375
                gf_log (this->name, GF_LOG_DEBUG,
2325
 
                        "no pre-set layout for subvolume %s",
 
2376
                        "could not set pre-set layout for subvolume %s",
2326
2377
                        prev->this->name);
2327
2378
                op_ret   = -1;
2328
2379
                op_errno = EINVAL;
2329
2380
                goto out;
2330
2381
        }
2331
 
 
2332
 
        ret = inode_ctx_put (inode, this, (uint64_t)(long)layout);
2333
 
        if (ret != 0) {
2334
 
                gf_log (this->name, GF_LOG_DEBUG,
2335
 
                        "could not set inode context");
2336
 
                op_ret   = -1;
2337
 
                op_errno = EINVAL;
2338
 
                goto out;
2339
 
        }
2340
 
 
2341
2382
out:
2342
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf);
 
2383
        /* 
 
2384
         * FIXME: st_size and st_blocks of preparent and postparent do not have 
 
2385
         * correct values. since, preparent and postparent buffers correspond
 
2386
         * to a directory these two members should have values equal to sum of
 
2387
         * corresponding values from each of the subvolume.
 
2388
         * See dht_stat_merge for reference.
 
2389
         */ 
 
2390
 
 
2391
        DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, stbuf, preparent,
 
2392
                          postparent);
2343
2393
        return 0;
2344
2394
}
2345
2395
 
2347
2397
dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie,
2348
2398
                               xlator_t *this,
2349
2399
                               int32_t op_ret, int32_t op_errno,
2350
 
                               inode_t *inode, struct stat *stbuf)
 
2400
                               inode_t *inode, struct stat *stbuf,
 
2401
                               struct stat *preparent, struct stat *postparent)
2351
2402
{
2352
2403
        dht_local_t  *local = NULL;
2353
2404
        xlator_t     *cached_subvol = NULL;
2364
2415
 
2365
2416
        return 0;
2366
2417
 err:
2367
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);     
 
2418
        DHT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL);  
2368
2419
        return 0;
2369
2420
}
2370
2421
 
2387
2438
 
2388
2439
        dht_get_du_info (frame, this, loc);
2389
2440
 
 
2441
        local = dht_local_init (frame);
 
2442
        if (!local) {
 
2443
                op_errno = ENOMEM;
 
2444
                gf_log (this->name, GF_LOG_ERROR,
 
2445
                        "Out of memory");
 
2446
                goto err;
 
2447
        }
 
2448
 
2390
2449
        subvol = dht_subvol_get_hashed (this, loc);
2391
2450
        if (!subvol) {
2392
2451
                gf_log (this->name, GF_LOG_DEBUG,
2396
2455
                goto err;
2397
2456
        }
2398
2457
 
 
2458
        ret = loc_dup (loc, &local->loc);
 
2459
        if (ret == -1) {
 
2460
                op_errno = ENOMEM;
 
2461
                gf_log (this->name, GF_LOG_ERROR,
 
2462
                        "Out of memory");
 
2463
                goto err;
 
2464
        }
 
2465
 
2399
2466
        if (!dht_is_subvol_filled (this, subvol)) {
2400
2467
                gf_log (this->name, GF_LOG_TRACE,
2401
2468
                        "creating %s on %s", loc->path, subvol->name);
2408
2475
                if (avail_subvol != subvol) {
2409
2476
                        /* Choose the minimum filled volume, and create the 
2410
2477
                           files there */
2411
 
                        local = dht_local_init (frame);
2412
 
                        if (!local) {
2413
 
                                op_errno = ENOMEM;
2414
 
                                gf_log (this->name, GF_LOG_ERROR,
2415
 
                                        "Out of memory");
2416
 
                                goto err;
2417
 
                        }
2418
 
                        ret = loc_dup (loc, &local->loc);
2419
 
                        if (ret == -1) {
2420
 
                                op_errno = ENOMEM;
2421
 
                                gf_log (this->name, GF_LOG_ERROR,
2422
 
                                        "Out of memory");
2423
 
                                goto err;
2424
 
                        }
2425
2478
 
2426
2479
                        local->cached_subvol = avail_subvol;
2427
2480
                        local->mode = mode; 
2444
2497
 
2445
2498
err:
2446
2499
        op_errno = (op_errno == -1) ? errno : op_errno;
2447
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
 
2500
        DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
 
2501
                          NULL, NULL, NULL, NULL);
2448
2502
 
2449
2503
        return 0;
2450
2504
}
2454
2508
dht_symlink (call_frame_t *frame, xlator_t *this,
2455
2509
             const char *linkname, loc_t *loc)
2456
2510
{
2457
 
        xlator_t  *subvol = NULL;
2458
 
        int        op_errno = -1;
 
2511
        xlator_t    *subvol = NULL;
 
2512
        int          op_errno = -1;
 
2513
        dht_local_t *local = NULL;
2459
2514
 
2460
2515
 
2461
2516
        VALIDATE_OR_GOTO (frame, err);
2462
2517
        VALIDATE_OR_GOTO (this, err);
2463
2518
        VALIDATE_OR_GOTO (loc, err);
2464
2519
 
 
2520
        local = dht_local_init (frame);
 
2521
        if (!local) {
 
2522
                op_errno = ENOMEM;
 
2523
                gf_log (this->name, GF_LOG_ERROR,
 
2524
                        "Out of memory");
 
2525
                goto err;
 
2526
        }
 
2527
 
2465
2528
        subvol = dht_subvol_get_hashed (this, loc);
2466
2529
        if (!subvol) {
2467
2530
                gf_log (this->name, GF_LOG_DEBUG,
2482
2545
 
2483
2546
err:
2484
2547
        op_errno = (op_errno == -1) ? errno : op_errno;
2485
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
 
2548
        DHT_STACK_UNWIND (link, frame, -1, op_errno,
 
2549
                          NULL, NULL, NULL, NULL);
2486
2550
 
2487
2551
        return 0;
2488
2552
}
2493
2557
{
2494
2558
        xlator_t    *cached_subvol = NULL;
2495
2559
        xlator_t    *hashed_subvol = NULL;
 
2560
        int          ret = -1;
2496
2561
        int          op_errno = -1;
2497
2562
        dht_local_t *local = NULL;
2498
2563
 
2526
2591
                goto err;
2527
2592
        }
2528
2593
 
 
2594
        ret = loc_copy (&local->loc, loc);
 
2595
        if (ret == -1) {
 
2596
                op_errno = ENOMEM;
 
2597
                gf_log (this->name, GF_LOG_ERROR,
 
2598
                        "Out of memory");
 
2599
                goto err;
 
2600
        }
 
2601
 
2529
2602
        local->call_cnt = 1;
2530
2603
        if (hashed_subvol != cached_subvol)
2531
2604
                local->call_cnt++;
2532
2605
 
2533
 
        STACK_WIND (frame, dht_err_cbk,
 
2606
        STACK_WIND (frame, dht_unlink_cbk,
2534
2607
                    cached_subvol, cached_subvol->fops->unlink, loc);
2535
2608
 
2536
2609
        if (hashed_subvol != cached_subvol)
2537
 
                STACK_WIND (frame, dht_err_cbk,
 
2610
                STACK_WIND (frame, dht_unlink_cbk,
2538
2611
                            hashed_subvol, hashed_subvol->fops->unlink, loc);
2539
2612
 
2540
2613
        return 0;
2541
2614
 
2542
2615
err:
2543
2616
        op_errno = (op_errno == -1) ? errno : op_errno;
2544
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
2617
        DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
2545
2618
 
2546
2619
        return 0;
2547
2620
}
2550
2623
int
2551
2624
dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2552
2625
              int op_ret, int op_errno,
2553
 
              inode_t *inode, struct stat *stbuf)
 
2626
              inode_t *inode, struct stat *stbuf, struct stat *preparent,
 
2627
              struct stat *postparent)
2554
2628
{
2555
2629
        call_frame_t *prev = NULL;
2556
2630
        dht_layout_t *layout = NULL;
2574
2648
 
2575
2649
        stbuf->st_ino = local->loc.inode->ino;
2576
2650
 
 
2651
        preparent->st_ino = local->loc2.parent->ino;
 
2652
        postparent->st_ino = local->loc2.parent->ino;
 
2653
 
2577
2654
out:
2578
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf);
 
2655
        DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
 
2656
                          postparent);
2579
2657
 
2580
2658
        return 0;
2581
2659
}
2584
2662
int
2585
2663
dht_link_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2586
2664
                       int op_ret, int op_errno,
2587
 
                       inode_t *inode, struct stat *stbuf)
 
2665
                       inode_t *inode, struct stat *stbuf,
 
2666
                       struct stat *preparent, struct stat *postparent)
2588
2667
{
2589
2668
        dht_local_t  *local = NULL;
2590
2669
        xlator_t     *srcvol = NULL;
2603
2682
        return 0;
2604
2683
 
2605
2684
err:
2606
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, inode, stbuf);
 
2685
        DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
 
2686
                          postparent);
2607
2687
 
2608
2688
        return 0;
2609
2689
}
2679
2759
 
2680
2760
err:
2681
2761
        op_errno = (op_errno == -1) ? errno : op_errno;
2682
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
 
2762
        DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
2683
2763
 
2684
2764
        return 0;
2685
2765
}
2688
2768
int
2689
2769
dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2690
2770
                 int op_ret, int op_errno,
2691
 
                 fd_t *fd, inode_t *inode, struct stat *stbuf)
 
2771
                 fd_t *fd, inode_t *inode, struct stat *stbuf,
 
2772
                 struct stat *preparent, struct stat *postparent)
2692
2773
{
2693
2774
        call_frame_t *prev = NULL;
2694
 
        dht_layout_t *layout = NULL;
2695
2775
        int           ret = -1;
 
2776
        dht_local_t  *local = NULL;
2696
2777
 
2697
2778
        if (op_ret == -1)
2698
2779
                goto out;
2699
2780
 
 
2781
        local = frame->local;
 
2782
        if (!local) {
 
2783
                op_ret = -1;
 
2784
                op_errno = EINVAL;
 
2785
                goto out;
 
2786
        }
 
2787
 
2700
2788
        prev = cookie;
2701
2789
 
2702
2790
        dht_itransform (this, prev->this, stbuf->st_ino, &stbuf->st_ino);
2703
 
        layout = dht_layout_for_subvol (this, prev->this);
2704
 
 
2705
 
        if (!layout) {
2706
 
                gf_log (this->name, GF_LOG_DEBUG,
2707
 
                        "no pre-set layout for subvolume %s",
2708
 
                        prev->this->name);
2709
 
                op_ret   = -1;
2710
 
                op_errno = EINVAL;
2711
 
                goto out;
2712
 
        }
2713
 
 
2714
 
        ret = inode_ctx_put (inode, this, (uint64_t)(long)layout);
 
2791
        if (local->loc.parent) {
 
2792
                preparent->st_ino = local->loc.parent->ino;
 
2793
                postparent->st_ino = local->loc.parent->ino;
 
2794
        }
 
2795
 
 
2796
        ret = dht_layout_preset (this, prev->this, inode);
2715
2797
        if (ret != 0) {
2716
2798
                gf_log (this->name, GF_LOG_DEBUG,
2717
 
                        "could not set inode context");
 
2799
                        "could not set preset layout for subvol %s",
 
2800
                        prev->this->name);
2718
2801
                op_ret   = -1;
2719
2802
                op_errno = EINVAL;
2720
2803
                goto out;
2721
2804
        }
2722
2805
 
2723
2806
out:
2724
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, fd, inode, stbuf);
 
2807
        DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, stbuf, preparent,
 
2808
                          postparent);
2725
2809
        return 0;
2726
2810
}
2727
2811
 
2730
2814
dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
2731
2815
                                xlator_t *this,
2732
2816
                                int32_t op_ret, int32_t op_errno,
2733
 
                                inode_t *inode, struct stat *stbuf)
 
2817
                                inode_t *inode, struct stat *stbuf,
 
2818
                                struct stat *preparent, struct stat *postparent)
2734
2819
{
2735
2820
        dht_local_t  *local = NULL;
2736
2821
        xlator_t     *cached_subvol = NULL;
2747
2832
 
2748
2833
        return 0;
2749
2834
 err:
2750
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL);       
 
2835
        DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
2751
2836
        return 0;
2752
2837
}
2753
2838
 
2787
2872
                goto err;
2788
2873
        }
2789
2874
 
 
2875
        ret = loc_dup (loc, &local->loc);
 
2876
        if (ret == -1) {
 
2877
                op_errno = ENOMEM;
 
2878
                gf_log (this->name, GF_LOG_ERROR,
 
2879
                        "Out of memory");
 
2880
                goto err;
 
2881
        }
 
2882
 
2790
2883
        if (!dht_is_subvol_filled (this, subvol)) {
2791
2884
                gf_log (this->name, GF_LOG_TRACE,
2792
2885
                        "creating %s on %s", loc->path, subvol->name);
2799
2892
                /* TODO */
2800
2893
                avail_subvol = dht_free_disk_available_subvol (this, subvol);
2801
2894
                if (avail_subvol != subvol) {
2802
 
                        ret = loc_dup (loc, &local->loc);
2803
 
                        if (ret == -1) {
2804
 
                                op_errno = ENOMEM;
2805
 
                                gf_log (this->name, GF_LOG_ERROR,
2806
 
                                        "Out of memory");
2807
 
                                goto err;
2808
 
                        }
2809
 
 
2810
2895
                        local->fd = fd_ref (fd);
2811
2896
                        local->flags = flags;
2812
2897
                        local->mode = mode;
2833
2918
 
2834
2919
err:
2835
2920
        op_errno = (op_errno == -1) ? errno : op_errno;
2836
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL, NULL);
 
2921
        DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
2837
2922
 
2838
2923
        return 0;
2839
2924
}
2852
2937
        layout = local->selfheal.layout;
2853
2938
 
2854
2939
        if (op_ret == 0) {
2855
 
                inode_ctx_put (local->inode, this, (uint64_t)(long)layout);
2856
 
                local->selfheal.layout = NULL;
 
2940
                dht_layout_set (this, local->inode, layout);
2857
2941
                local->stbuf.st_ino = local->st_ino;
 
2942
                local->stbuf.st_dev = local->st_dev;
 
2943
                if (local->loc.parent) {
 
2944
                        local->preparent.st_ino = local->loc.parent->ino;
 
2945
                        local->postparent.st_ino = local->loc.parent->ino;
 
2946
                }
2858
2947
        }
2859
2948
 
2860
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno,
2861
 
                          local->inode, &local->stbuf);
 
2949
        DHT_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
 
2950
                          local->inode, &local->stbuf, &local->preparent,
 
2951
                          &local->postparent);
2862
2952
 
2863
2953
        return 0;
2864
2954
}
2865
2955
 
2866
2956
int
2867
2957
dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
2868
 
               int op_ret, int op_errno, inode_t *inode, struct stat *stbuf)
 
2958
               int op_ret, int op_errno, inode_t *inode, struct stat *stbuf,
 
2959
               struct stat *preparent, struct stat *postparent)
2869
2960
{
2870
2961
        dht_local_t  *local = NULL;
2871
2962
        int           this_call_cnt = 0;
2897
2988
                        goto unlock;
2898
2989
                }
2899
2990
                dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
 
2991
                dht_stat_merge (this, &local->preparent, preparent, prev->this);
 
2992
                dht_stat_merge (this, &local->postparent, postparent,
 
2993
                                prev->this);
2900
2994
        }
2901
2995
unlock:
2902
2996
        UNLOCK (&frame->lock);
2903
2997
 
2904
2998
        this_call_cnt = dht_frame_return (frame);
2905
2999
        if (is_last_call (this_call_cnt)) {
2906
 
                local->layout = NULL;
2907
3000
                dht_selfheal_new_directory (frame, dht_mkdir_selfheal_cbk,
2908
3001
                                            layout);
2909
3002
        }
2913
3006
 
2914
3007
int
2915
3008
dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie, 
2916
 
                      xlator_t *this, int op_ret, int op_errno, 
2917
 
                      inode_t *inode, struct stat *stbuf)
 
3009
                      xlator_t *this, int op_ret, int op_errno,
 
3010
                      inode_t *inode, struct stat *stbuf,
 
3011
                      struct stat *preparent, struct stat *postparent)
2918
3012
{
2919
3013
        dht_local_t  *local = NULL;
2920
3014
        int           ret = -1;
2944
3038
        local->op_ret = 0;
2945
3039
 
2946
3040
        dht_stat_merge (this, &local->stbuf, stbuf, prev->this);
 
3041
        dht_stat_merge (this, &local->preparent, preparent, prev->this);
 
3042
        dht_stat_merge (this, &local->postparent, postparent, prev->this);
2947
3043
 
2948
3044
        local->st_ino = local->stbuf.st_ino;
 
3045
        local->st_dev = local->stbuf.st_dev;
2949
3046
 
2950
3047
        local->call_cnt = conf->subvolume_cnt - 1;
2951
3048
        
2952
3049
        if (local->call_cnt == 0) {
2953
 
                local->layout = NULL;
2954
3050
                dht_selfheal_directory (frame, dht_mkdir_selfheal_cbk,
2955
3051
                                        &local->loc, layout);
2956
3052
        }
2964
3060
        }
2965
3061
        return 0;
2966
3062
err:
2967
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
 
3063
        DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
2968
3064
        return 0;
2969
3065
}
2970
3066
 
3036
3132
 
3037
3133
err:
3038
3134
        op_errno = (op_errno == -1) ? errno : op_errno;
3039
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL, NULL);
 
3135
        DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
3040
3136
 
3041
3137
        return 0;
3042
3138
}
3049
3145
        dht_local_t  *local = NULL;
3050
3146
 
3051
3147
        local = frame->local;
3052
 
        local->layout = NULL;
3053
 
 
3054
 
        DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno);
 
3148
 
 
3149
        if (local->loc.parent) {
 
3150
                local->preparent.st_ino = local->loc.parent->ino;
 
3151
                local->postparent.st_ino = local->loc.parent->ino;
 
3152
        }
 
3153
 
 
3154
        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
 
3155
                          &local->preparent, &local->postparent);
3055
3156
 
3056
3157
        return 0;
3057
3158
}
3059
3160
 
3060
3161
int
3061
3162
dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3062
 
               int op_ret, int op_errno)
 
3163
               int op_ret, int op_errno, struct stat *preparent,
 
3164
               struct stat *postparent)
3063
3165
{
3064
 
        uint64_t      tmp_layout = 0;
3065
3166
        dht_local_t  *local = NULL;
3066
3167
        int           this_call_cnt = 0;
3067
3168
        call_frame_t *prev = NULL;
3068
 
        dht_layout_t *layout = NULL;
3069
3169
 
3070
3170
        local = frame->local;
3071
3171
        prev  = cookie;
3085
3185
                                strerror (op_errno));
3086
3186
                        goto unlock;
3087
3187
                }
 
3188
 
 
3189
                dht_stat_merge (this, &local->preparent, preparent, prev->this);
 
3190
                dht_stat_merge (this, &local->postparent, postparent,
 
3191
                                prev->this);
3088
3192
        }
3089
3193
unlock:
3090
3194
        UNLOCK (&frame->lock);
3093
3197
        this_call_cnt = dht_frame_return (frame);
3094
3198
        if (is_last_call (this_call_cnt)) {
3095
3199
                if (local->need_selfheal) {
3096
 
                        inode_ctx_get (local->loc.inode, this, 
3097
 
                                       &tmp_layout);
3098
 
                        layout = (dht_layout_t *)(long)tmp_layout;
 
3200
                        local->layout =
 
3201
                                dht_layout_get (this, local->loc.inode);
3099
3202
 
3100
3203
                        /* TODO: neater interface needed below */
3101
3204
                        local->stbuf.st_mode = local->loc.inode->st_mode;
3102
3205
 
3103
3206
                        dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
3104
 
                                              &local->loc, layout);
 
3207
                                              &local->loc, local->layout);
3105
3208
                } else {
3106
 
                        DHT_STACK_UNWIND (frame, local->op_ret,
3107
 
                                          local->op_errno);
 
3209
                        if (local->loc.parent) {
 
3210
                                local->preparent.st_ino =
 
3211
                                        local->loc.parent->ino;
 
3212
                                local->postparent.st_ino =
 
3213
                                        local->loc.parent->ino;
 
3214
                        }
 
3215
 
 
3216
                        DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
 
3217
                                          local->op_errno, &local->preparent,
 
3218
                                          &local->postparent);
3108
3219
                }
3109
3220
        }
3110
3221
 
3137
3248
        return 0;
3138
3249
 
3139
3250
err:
3140
 
        DHT_STACK_UNWIND (frame, local->op_ret, local->op_errno);
 
3251
        DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
 
3252
                          &local->preparent, &local->postparent);
3141
3253
        return 0;
3142
3254
}
3143
3255
 
3264
3376
 
3265
3377
err:
3266
3378
        op_errno = (op_errno == -1) ? errno : op_errno;
3267
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
3379
        DHT_STACK_UNWIND (rmdir, frame, -1, op_errno,
 
3380
                          NULL, NULL);
3268
3381
 
3269
3382
        return 0;
3270
3383
}
3274
3387
dht_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3275
3388
                 int32_t op_ret, int32_t op_errno, dict_t *dict)
3276
3389
{
3277
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, dict);
 
3390
        DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict);
3278
3391
        return 0;
3279
3392
}
3280
3393
 
3321
3434
 
3322
3435
err:
3323
3436
        op_errno = (op_errno == -1) ? errno : op_errno;
3324
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
3437
        DHT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
3325
3438
 
3326
3439
        return 0;
3327
3440
}
3331
3444
dht_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3332
3445
                  int32_t op_ret, int32_t op_errno, dict_t *dict)
3333
3446
{
3334
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno, dict);
 
3447
        DHT_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, dict);
3335
3448
        return 0;
3336
3449
}
3337
3450
 
3364
3477
 
3365
3478
err:
3366
3479
        op_errno = (op_errno == -1) ? errno : op_errno;
3367
 
        DHT_STACK_UNWIND (frame, -1, op_errno, NULL);
 
3480
        DHT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL);
3368
3481
 
3369
3482
        return 0;
3370
3483
}
3375
3488
                 xlator_t *this, int32_t op_ret, int32_t op_errno)
3376
3489
 
3377
3490
{
3378
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno);
 
3491
        DHT_STACK_UNWIND (inodelk, frame, op_ret, op_errno);
3379
3492
        return 0;
3380
3493
}
3381
3494
 
3423
3536
 
3424
3537
err:
3425
3538
        op_errno = (op_errno == -1) ? errno : op_errno;
3426
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
3539
        DHT_STACK_UNWIND (inodelk, frame, -1, op_errno);
3427
3540
 
3428
3541
        return 0;
3429
3542
}
3434
3547
                  xlator_t *this, int32_t op_ret, int32_t op_errno)
3435
3548
 
3436
3549
{
3437
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno);
 
3550
        DHT_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
3438
3551
        return 0;
3439
3552
}
3440
3553
 
3468
3581
 
3469
3582
err:
3470
3583
        op_errno = (op_errno == -1) ? errno : op_errno;
3471
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
3584
        DHT_STACK_UNWIND (finodelk, frame, -1, op_errno);
3472
3585
 
3473
3586
        return 0;
3474
3587
}
3479
3592
                 xlator_t *this, int32_t op_ret, int32_t op_errno)
3480
3593
 
3481
3594
{
3482
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno);
 
3595
        DHT_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
3483
3596
        return 0;
3484
3597
}
3485
3598
 
3526
3639
 
3527
3640
err:
3528
3641
        op_errno = (op_errno == -1) ? errno : op_errno;
3529
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
3642
        DHT_STACK_UNWIND (entrylk, frame, -1, op_errno);
3530
3643
 
3531
3644
        return 0;
3532
3645
}
3537
3650
                  xlator_t *this, int32_t op_ret, int32_t op_errno)
3538
3651
 
3539
3652
{
3540
 
        DHT_STACK_UNWIND (frame, op_ret, op_errno);
 
3653
        DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
3541
3654
        return 0;
3542
3655
}
3543
3656
 
3570
3683
 
3571
3684
err:
3572
3685
        op_errno = (op_errno == -1) ? errno : op_errno;
3573
 
        DHT_STACK_UNWIND (frame, -1, op_errno);
 
3686
        DHT_STACK_UNWIND (fentrylk, frame, -1, op_errno);
 
3687
 
 
3688
        return 0;
 
3689
}
 
3690
 
 
3691
 
 
3692
int
 
3693
dht_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 
3694
                 int op_ret, int op_errno, struct stat *statpre,
 
3695
                 struct stat *statpost)
 
3696
{
 
3697
        dht_local_t  *local = NULL;
 
3698
        int           this_call_cnt = 0;
 
3699
        call_frame_t *prev = NULL;
 
3700
 
 
3701
 
 
3702
        local = frame->local;
 
3703
        prev = cookie;
 
3704
 
 
3705
        LOCK (&frame->lock);
 
3706
        {
 
3707
                if (op_ret == -1) {
 
3708
                        local->op_errno = op_errno;
 
3709
                        gf_log (this->name, GF_LOG_DEBUG,
 
3710
                                "subvolume %s returned -1 (%s)",
 
3711
                                prev->this->name, strerror (op_errno));
 
3712
                        goto unlock;
 
3713
                }
 
3714
 
 
3715
                dht_stat_merge (this, &local->prebuf, statpre, prev->this);
 
3716
                dht_stat_merge (this, &local->stbuf, statpost, prev->this);
 
3717
                
 
3718
                if (local->inode) {
 
3719
                        local->prebuf.st_ino = local->inode->ino;
 
3720
                        local->stbuf.st_ino = local->inode->ino;
 
3721
                }
 
3722
 
 
3723
                local->op_ret = 0;
 
3724
        }
 
3725
unlock:
 
3726
        UNLOCK (&frame->lock);
 
3727
 
 
3728
        this_call_cnt = dht_frame_return (frame);
 
3729
        if (is_last_call (this_call_cnt))
 
3730
                DHT_STACK_UNWIND (setattr, frame, local->op_ret, local->op_errno,
 
3731
                                  &local->prebuf, &local->stbuf);
 
3732
 
 
3733
        return 0;
 
3734
}
 
3735
 
 
3736
 
 
3737
int
 
3738
dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
 
3739
             struct stat *stbuf, int32_t valid)
 
3740
{
 
3741
        dht_layout_t *layout = NULL;
 
3742
        dht_local_t  *local  = NULL;
 
3743
        int           op_errno = -1;
 
3744
        int           i = -1;
 
3745
 
 
3746
 
 
3747
        VALIDATE_OR_GOTO (frame, err);
 
3748
        VALIDATE_OR_GOTO (this, err);
 
3749
        VALIDATE_OR_GOTO (loc, err);
 
3750
        VALIDATE_OR_GOTO (loc->inode, err);
 
3751
        VALIDATE_OR_GOTO (loc->path, err);
 
3752
 
 
3753
        local = dht_local_init (frame);
 
3754
        if (!local) {
 
3755
                op_errno = ENOMEM;
 
3756
                gf_log (this->name, GF_LOG_DEBUG,
 
3757
                        "memory allocation failed :(");
 
3758
                goto err;
 
3759
        }
 
3760
 
 
3761
        local->layout = layout = dht_layout_get (this, loc->inode);
 
3762
        if (!layout) {
 
3763
                gf_log (this->name, GF_LOG_DEBUG,
 
3764
                        "no layout for path=%s", loc->path);
 
3765
                op_errno = EINVAL;
 
3766
                goto err;
 
3767
        }
 
3768
 
 
3769
        if (!layout_is_sane (layout)) {
 
3770
                gf_log (this->name, GF_LOG_DEBUG,
 
3771
                        "layout is not sane for path=%s", loc->path);
 
3772
                op_errno = EINVAL;
 
3773
                goto err;
 
3774
        }
 
3775
 
 
3776
        local->inode = inode_ref (loc->inode);
 
3777
        local->call_cnt = layout->cnt;
 
3778
 
 
3779
        for (i = 0; i < layout->cnt; i++) {
 
3780
                STACK_WIND (frame, dht_setattr_cbk,
 
3781
                            layout->list[i].xlator,
 
3782
                            layout->list[i].xlator->fops->setattr,
 
3783
                            loc, stbuf, valid);
 
3784
        }
 
3785
 
 
3786
        return 0;
 
3787
 
 
3788
err:
 
3789
        op_errno = (op_errno == -1) ? errno : op_errno;
 
3790
        DHT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL);
 
3791
 
 
3792
        return 0;
 
3793
}
 
3794
 
 
3795
 
 
3796
int
 
3797
dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct stat *stbuf,
 
3798
              int32_t valid)
 
3799
{
 
3800
        dht_layout_t *layout = NULL;
 
3801
        dht_local_t  *local  = NULL;
 
3802
        int           op_errno = -1;
 
3803
        int           i = -1;
 
3804
 
 
3805
 
 
3806
        VALIDATE_OR_GOTO (frame, err);
 
3807
        VALIDATE_OR_GOTO (this, err);
 
3808
        VALIDATE_OR_GOTO (fd, err);
 
3809
 
 
3810
        local = dht_local_init (frame);
 
3811
        if (!local) {
 
3812
                op_errno = ENOMEM;
 
3813
                gf_log (this->name, GF_LOG_ERROR,
 
3814
                        "Out of memory");
 
3815
                goto err;
 
3816
        }
 
3817
 
 
3818
        local->layout = layout = dht_layout_get (this, fd->inode);
 
3819
        if (!layout) {
 
3820
                gf_log (this->name, GF_LOG_DEBUG,
 
3821
                        "no layout for fd=%p", fd);
 
3822
                op_errno = EINVAL;
 
3823
                goto err;
 
3824
        }
 
3825
 
 
3826
        if (!layout_is_sane (layout)) {
 
3827
                gf_log (this->name, GF_LOG_DEBUG,
 
3828
                        "layout is not sane for fd=%p", fd);
 
3829
                op_errno = EINVAL;
 
3830
                goto err;
 
3831
        }
 
3832
 
 
3833
        local->inode = inode_ref (fd->inode);
 
3834
        local->call_cnt = layout->cnt;
 
3835
 
 
3836
        for (i = 0; i < layout->cnt; i++) {
 
3837
                STACK_WIND (frame, dht_setattr_cbk,
 
3838
                            layout->list[i].xlator,
 
3839
                            layout->list[i].xlator->fops->fsetattr,
 
3840
                            fd, stbuf, valid);
 
3841
        }
 
3842
 
 
3843
        return 0;
 
3844
 
 
3845
err:
 
3846
        op_errno = (op_errno == -1) ? errno : op_errno;
 
3847
        DHT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL);
3574
3848
 
3575
3849
        return 0;
3576
3850
}
3588
3862
                return 0;
3589
3863
 
3590
3864
        layout = (dht_layout_t *)(long)tmp_layout;
3591
 
        if (!layout->preset)
3592
 
                FREE (layout);
 
3865
        dht_layout_unref (this, layout);
3593
3866
 
3594
3867
        return 0;
3595
3868
}