summaryrefslogtreecommitdiffstats
path: root/tests/bugs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bugs')
0 files changed, 0 insertions, 0 deletions
lass='right'>318
-rw-r--r--xlators/cluster/afr/src/afr-dir-read.h36
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c727
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.h43
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.c1227
-rw-r--r--xlators/cluster/afr/src/afr-inode-read.h39
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c1007
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.h57
-rw-r--r--xlators/cluster/afr/src/afr-lk-common.c706
-rw-r--r--xlators/cluster/afr/src/afr-mem-types.h31
-rw-r--r--xlators/cluster/afr/src/afr-open.c696
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-algorithm.c1245
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-algorithm.h42
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c2378
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.h123
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-data.c1189
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-entry.c1390
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-metadata.c419
-rw-r--r--xlators/cluster/afr/src/afr-self-heal.h36
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c1228
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.h52
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c724
-rw-r--r--xlators/cluster/afr/src/afr-transaction.h33
-rw-r--r--xlators/cluster/afr/src/afr.c887
-rw-r--r--xlators/cluster/afr/src/afr.h661
-rw-r--r--xlators/cluster/afr/src/pump.c979
-rw-r--r--xlators/cluster/afr/src/pump.h39
-rw-r--r--xlators/cluster/dht/src/Makefile.am15
-rw-r--r--xlators/cluster/dht/src/dht-common.c3419
-rw-r--r--xlators/cluster/dht/src/dht-common.h540
-rw-r--r--xlators/cluster/dht/src/dht-diskusage.c451
-rw-r--r--xlators/cluster/dht/src/dht-hashfn.c20
-rw-r--r--xlators/cluster/dht/src/dht-helper.c499
-rw-r--r--xlators/cluster/dht/src/dht-inode-read.c1115
-rw-r--r--xlators/cluster/dht/src/dht-inode-write.c612
-rw-r--r--xlators/cluster/dht/src/dht-layout.c102
-rw-r--r--xlators/cluster/dht/src/dht-linkfile.c137
-rw-r--r--xlators/cluster/dht/src/dht-mem-types.h23
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c1684
-rw-r--r--xlators/cluster/dht/src/dht-rename.c317
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c454
-rw-r--r--xlators/cluster/dht/src/dht.c404
-rw-r--r--xlators/cluster/dht/src/nufa.c126
-rw-r--r--xlators/cluster/dht/src/switch.c160
-rw-r--r--xlators/cluster/ha/src/ha-helpers.c8
-rw-r--r--xlators/cluster/ha/src/ha-mem-types.h8
-rw-r--r--xlators/cluster/ha/src/ha.c16
-rw-r--r--xlators/cluster/ha/src/ha.h8
-rw-r--r--xlators/cluster/map/src/map-helper.c8
-rw-r--r--xlators/cluster/map/src/map-mem-types.h8
-rw-r--r--xlators/cluster/map/src/map.c11
-rw-r--r--xlators/cluster/map/src/map.h8
-rw-r--r--xlators/cluster/stripe/src/Makefile.am4
-rw-r--r--xlators/cluster/stripe/src/stripe-helpers.c588
-rw-r--r--xlators/cluster/stripe/src/stripe-mem-types.h28
-rw-r--r--xlators/cluster/stripe/src/stripe.c3006
-rw-r--r--xlators/cluster/stripe/src/stripe.h165
-rw-r--r--xlators/cluster/unify/Makefile.am3
-rw-r--r--xlators/cluster/unify/src/Makefile.am16
-rw-r--r--xlators/cluster/unify/src/unify-mem-types.h41
-rw-r--r--xlators/cluster/unify/src/unify-self-heal.c1239
-rw-r--r--xlators/cluster/unify/src/unify.c4589
-rw-r--r--xlators/cluster/unify/src/unify.h146
-rw-r--r--xlators/debug/error-gen/src/Makefile.am2
-rw-r--r--xlators/debug/error-gen/src/error-gen-mem-types.h30
-rw-r--r--xlators/debug/error-gen/src/error-gen.c786
-rw-r--r--xlators/debug/error-gen/src/error-gen.h11
-rw-r--r--xlators/debug/io-stats/src/io-stats-mem-types.h8
-rw-r--r--xlators/debug/io-stats/src/io-stats.c999
-rw-r--r--xlators/debug/trace/src/trace.c562
-rw-r--r--xlators/encryption/rot-13/src/rot-13.c34
-rw-r--r--xlators/encryption/rot-13/src/rot-13.h8
-rw-r--r--xlators/features/Makefile.am2
-rw-r--r--xlators/features/access-control/Makefile.am (renamed from xlators/features/index/Makefile.am)0
-rw-r--r--xlators/features/access-control/src/Makefile.am13
-rw-r--r--xlators/features/access-control/src/access-control.c2060
-rw-r--r--xlators/features/access-control/src/access-control.h55
-rw-r--r--xlators/features/filter/src/filter-mem-types.h8
-rw-r--r--xlators/features/filter/src/filter.c8
-rw-r--r--xlators/features/index/src/Makefile.am15
-rw-r--r--xlators/features/index/src/index-mem-types.h32
-rw-r--r--xlators/features/index/src/index.c1205
-rw-r--r--xlators/features/index/src/index.h69
-rw-r--r--xlators/features/locks/src/Makefile.am12
-rw-r--r--xlators/features/locks/src/clear.c433
-rw-r--r--xlators/features/locks/src/clear.h86
-rw-r--r--xlators/features/locks/src/common.c150
-rw-r--r--xlators/features/locks/src/common.h37
-rw-r--r--xlators/features/locks/src/entrylk.c116
-rw-r--r--xlators/features/locks/src/inodelk.c266
-rw-r--r--xlators/features/locks/src/locks-mem-types.h9
-rw-r--r--xlators/features/locks/src/locks.h36
-rw-r--r--xlators/features/locks/src/posix.c760
-rw-r--r--xlators/features/locks/src/reservelk.c35
-rw-r--r--xlators/features/locks/tests/unit-test.c8
-rw-r--r--xlators/features/mac-compat/src/mac-compat.c33
-rw-r--r--xlators/features/marker/src/marker-common.c20
-rw-r--r--xlators/features/marker/src/marker-common.h2
-rw-r--r--xlators/features/marker/src/marker-mem-types.h12
-rw-r--r--xlators/features/marker/src/marker-quota-helper.c120
-rw-r--r--xlators/features/marker/src/marker-quota-helper.h41
-rw-r--r--xlators/features/marker/src/marker-quota.c1694
-rw-r--r--xlators/features/marker/src/marker-quota.h99
-rw-r--r--xlators/features/marker/src/marker.c1130
-rw-r--r--xlators/features/marker/src/marker.h54
-rw-r--r--xlators/features/marker/utils/Makefile.am6
-rwxr-xr-xxlators/features/marker/utils/gsyncd.in55
-rw-r--r--xlators/features/marker/utils/src/Makefile.am22
-rw-r--r--xlators/features/marker/utils/src/gsyncd.c347
-rw-r--r--xlators/features/marker/utils/src/procdiggy.c131
-rw-r--r--xlators/features/marker/utils/src/procdiggy.h30
-rw-r--r--xlators/features/marker/utils/syncdaemon/Makefile.am3
-rw-r--r--xlators/features/marker/utils/syncdaemon/__codecheck.py46
-rw-r--r--xlators/features/marker/utils/syncdaemon/configinterface.py49
-rw-r--r--xlators/features/marker/utils/syncdaemon/gconf.py5
-rw-r--r--xlators/features/marker/utils/syncdaemon/gsyncd.py170
-rw-r--r--xlators/features/marker/utils/syncdaemon/libcxattr.py19
-rw-r--r--xlators/features/marker/utils/syncdaemon/master.py700
-rw-r--r--xlators/features/marker/utils/syncdaemon/monitor.py91
-rw-r--r--xlators/features/marker/utils/syncdaemon/repce.py69
-rw-r--r--xlators/features/marker/utils/syncdaemon/resource.py634
-rw-r--r--xlators/features/marker/utils/syncdaemon/syncdutils.py132
-rw-r--r--xlators/features/path-convertor/src/path-mem-types.h8
-rw-r--r--xlators/features/path-convertor/src/path.c13
-rw-r--r--xlators/features/quiesce/src/quiesce-mem-types.h8
-rw-r--r--xlators/features/quiesce/src/quiesce.c690
-rw-r--r--xlators/features/quiesce/src/quiesce.h11
-rw-r--r--xlators/features/quota/src/quota-mem-types.h11
-rw-r--r--xlators/features/quota/src/quota.c1282
-rw-r--r--xlators/features/quota/src/quota.h28
-rw-r--r--xlators/features/read-only/src/Makefile.am12
-rw-r--r--xlators/features/read-only/src/read-only-common.c249
-rw-r--r--xlators/features/read-only/src/read-only-common.h125
-rw-r--r--xlators/features/read-only/src/read-only.c229
-rw-r--r--xlators/features/read-only/src/worm.c100
-rw-r--r--xlators/features/trash/src/trash-mem-types.h11
-rw-r--r--xlators/features/trash/src/trash.c95
-rw-r--r--xlators/features/trash/src/trash.h8
-rw-r--r--xlators/lib/src/libxlator.c357
-rw-r--r--xlators/lib/src/libxlator.h30
-rw-r--r--xlators/meta/src/meta-mem-types.h8
-rw-r--r--xlators/meta/src/meta.c8
-rw-r--r--xlators/meta/src/meta.h8
-rw-r--r--xlators/meta/src/misc.c8
-rw-r--r--xlators/meta/src/misc.h8
-rw-r--r--xlators/meta/src/tree.c10
-rw-r--r--xlators/meta/src/tree.h8
-rw-r--r--xlators/meta/src/view.c8
-rw-r--r--xlators/meta/src/view.h8
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am41
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-brick-ops.c1616
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-geo-rep.c2222
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c2671
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c232
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.c525
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-hooks.h99
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-log-ops.c274
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mem-types.h21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.c703
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.h52
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c7825
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.h109
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.c91
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-pmap.h10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c842
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rebalance.c972
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-replace-brick.c1845
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c1253
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.c137
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-sm.h10
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.c1018
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h29
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.c588
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-syncop.h60
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c3118
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h197
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c2217
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.h46
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c1921
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.c684
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h252
-rw-r--r--xlators/mount/fuse/src/Makefile.am18
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c2455
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h134
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c399
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h11
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c769
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in290
-rwxr-xr-xxlators/mount/fuse/utils/mount_glusterfs.in11
-rw-r--r--xlators/nfs/lib/src/auth-null.c72
-rw-r--r--xlators/nfs/lib/src/auth-unix.c97
-rw-r--r--xlators/nfs/lib/src/msg-nfs3.c554
-rw-r--r--xlators/nfs/lib/src/msg-nfs3.h186
-rw-r--r--xlators/nfs/lib/src/rpc-socket.c361
-rw-r--r--xlators/nfs/lib/src/rpc-socket.h65
-rw-r--r--xlators/nfs/lib/src/rpcsvc-auth.c400
-rw-r--r--xlators/nfs/lib/src/rpcsvc.c2923
-rw-r--r--xlators/nfs/lib/src/rpcsvc.h728
-rw-r--r--xlators/nfs/lib/src/xdr-common.h48
-rw-r--r--xlators/nfs/lib/src/xdr-nfs3.c1897
-rw-r--r--xlators/nfs/lib/src/xdr-nfs3.h1206
-rw-r--r--xlators/nfs/lib/src/xdr-rpc.c229
-rw-r--r--xlators/nfs/lib/src/xdr-rpc.h82
-rw-r--r--xlators/nfs/server/src/Makefile.am14
-rw-r--r--xlators/nfs/server/src/mount3.c430
-rw-r--r--xlators/nfs/server/src/mount3.h13
-rw-r--r--xlators/nfs/server/src/mount3udp_svc.c198
-rw-r--r--xlators/nfs/server/src/nfs-common.c179
-rw-r--r--xlators/nfs/server/src/nfs-common.h15
-rw-r--r--xlators/nfs/server/src/nfs-fops.c410
-rw-r--r--xlators/nfs/server/src/nfs-fops.h30
-rw-r--r--xlators/nfs/server/src/nfs-generics.c37
-rw-r--r--xlators/nfs/server/src/nfs-generics.h19
-rw-r--r--xlators/nfs/server/src/nfs-inodes.c54
-rw-r--r--xlators/nfs/server/src/nfs-inodes.h10
-rw-r--r--xlators/nfs/server/src/nfs-mem-types.h18
-rw-r--r--xlators/nfs/server/src/nfs.c492
-rw-r--r--xlators/nfs/server/src/nfs.h34
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c156
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h31
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c2825
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.h29
-rw-r--r--xlators/nfs/server/src/nfs3.c1239
-rw-r--r--xlators/nfs/server/src/nfs3.h50
-rw-r--r--xlators/nfs/server/src/nlm4.c2472
-rw-r--r--xlators/nfs/server/src/nlm4.h91
-rw-r--r--xlators/nfs/server/src/nlmcbk_svc.c122
-rw-r--r--xlators/performance/Makefile.am2
-rw-r--r--xlators/performance/io-cache/src/io-cache.c1942
-rw-r--r--xlators/performance/io-cache/src/io-cache.h46
-rw-r--r--xlators/performance/io-cache/src/ioc-inode.c46
-rw-r--r--xlators/performance/io-cache/src/ioc-mem-types.h20
-rw-r--r--xlators/performance/io-cache/src/page.c250
-rw-r--r--xlators/performance/io-threads/src/io-threads.c1261
-rw-r--r--xlators/performance/io-threads/src/io-threads.h26
-rw-r--r--xlators/performance/io-threads/src/iot-mem-types.h21
-rw-r--r--xlators/performance/md-cache/src/Makefile.am23
-rw-r--r--xlators/performance/md-cache/src/md-cache-mem-types.h24
-rw-r--r--xlators/performance/md-cache/src/md-cache.c1956
-rw-r--r--xlators/performance/quick-read/src/quick-read-mem-types.h21
-rw-r--r--xlators/performance/quick-read/src/quick-read.c1590
-rw-r--r--xlators/performance/quick-read/src/quick-read.h50
-rw-r--r--xlators/performance/read-ahead/src/page.c66
-rw-r--r--xlators/performance/read-ahead/src/read-ahead-mem-types.h20
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.c449
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.h23
-rw-r--r--xlators/performance/stat-prefetch/Makefile.am (renamed from xlators/performance/md-cache/Makefile.am)0
-rw-r--r--xlators/performance/stat-prefetch/src/Makefile.am14
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch-mem-types.h36
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c4115
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.h106
-rw-r--r--xlators/performance/symlink-cache/src/symlink-cache.c56
-rw-r--r--xlators/performance/write-behind/src/write-behind-mem-types.h22
-rw-r--r--xlators/performance/write-behind/src/write-behind.c964
-rw-r--r--xlators/protocol/auth/addr/src/Makefile.am3
-rw-r--r--xlators/protocol/auth/addr/src/addr.c41
-rw-r--r--xlators/protocol/auth/login/src/login.c11
-rw-r--r--xlators/protocol/client/src/Makefile.am5
-rw-r--r--xlators/protocol/client/src/client-callback.c25
-rw-r--r--xlators/protocol/client/src/client-handshake.c882
-rw-r--r--xlators/protocol/client/src/client-helpers.c91
-rw-r--r--xlators/protocol/client/src/client-lk.c86
-rw-r--r--xlators/protocol/client/src/client-mem-types.h23
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c5867
-rw-r--r--xlators/protocol/client/src/client.c884
-rw-r--r--xlators/protocol/client/src/client.h122
-rw-r--r--xlators/protocol/client/src/client3_1-fops.c5446
-rw-r--r--xlators/protocol/legacy/Makefile.am3
-rw-r--r--xlators/protocol/legacy/client/Makefile.am3
-rw-r--r--xlators/protocol/legacy/client/src/Makefile.am21
-rw-r--r--xlators/protocol/legacy/client/src/client-mem-types.h43
-rw-r--r--xlators/protocol/legacy/client/src/client-protocol.c6683
-rw-r--r--xlators/protocol/legacy/client/src/client-protocol.h178
-rw-r--r--xlators/protocol/legacy/client/src/saved-frames.c196
-rw-r--r--xlators/protocol/legacy/client/src/saved-frames.h79
-rw-r--r--xlators/protocol/legacy/lib/Makefile.am3
-rw-r--r--xlators/protocol/legacy/lib/src/Makefile.am14
-rw-r--r--xlators/protocol/legacy/lib/src/protocol.c108
-rw-r--r--xlators/protocol/legacy/lib/src/protocol.h1118
-rw-r--r--xlators/protocol/legacy/lib/src/transport.c422
-rw-r--r--xlators/protocol/legacy/lib/src/transport.h106
-rw-r--r--xlators/protocol/legacy/server/Makefile.am3
-rw-r--r--xlators/protocol/legacy/server/src/Makefile.am27
-rw-r--r--xlators/protocol/legacy/server/src/authenticate.c249
-rw-r--r--xlators/protocol/legacy/server/src/authenticate.h60
-rw-r--r--xlators/protocol/legacy/server/src/server-helpers.c622
-rw-r--r--xlators/protocol/legacy/server/src/server-helpers.h48
-rw-r--r--xlators/protocol/legacy/server/src/server-mem-types.h39
-rw-r--r--xlators/protocol/legacy/server/src/server-protocol.c6587
-rw-r--r--xlators/protocol/legacy/server/src/server-protocol.h191
-rw-r--r--xlators/protocol/legacy/server/src/server-resolve.c658
-rw-r--r--xlators/protocol/legacy/transport/Makefile.am3
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/Makefile.am1
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am19
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h39
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c2625
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h220
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/name.c712
-rw-r--r--xlators/protocol/legacy/transport/ib-verbs/src/name.h47
-rw-r--r--xlators/protocol/legacy/transport/socket/Makefile.am1
-rw-r--r--xlators/protocol/legacy/transport/socket/src/Makefile.am19
-rw-r--r--xlators/protocol/legacy/transport/socket/src/name.c740
-rw-r--r--xlators/protocol/legacy/transport/socket/src/name.h44
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket-mem-types.h36
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket.c1625
-rw-r--r--xlators/protocol/legacy/transport/socket/src/socket.h129
-rw-r--r--xlators/protocol/server/src/Makefile.am5
-rw-r--r--xlators/protocol/server/src/authenticate.c34
-rw-r--r--xlators/protocol/server/src/authenticate.h8
-rw-r--r--xlators/protocol/server/src/server-handshake.c145
-rw-r--r--xlators/protocol/server/src/server-helpers.c596
-rw-r--r--xlators/protocol/server/src/server-helpers.h22
-rw-r--r--xlators/protocol/server/src/server-mem-types.h9
-rw-r--r--xlators/protocol/server/src/server-resolve.c417
-rw-r--r--xlators/protocol/server/src/server.c587
-rw-r--r--xlators/protocol/server/src/server.h68
-rw-r--r--xlators/protocol/server/src/server3_1-fops.c (renamed from xlators/protocol/server/src/server-rpc-fops.c)3442
-rw-r--r--xlators/storage/bdb/Makefile.am3
-rw-r--r--xlators/storage/bdb/src/Makefile.am18
-rw-r--r--xlators/storage/bdb/src/bctx.c341
-rw-r--r--xlators/storage/bdb/src/bdb-ll.c1464
-rw-r--r--xlators/storage/bdb/src/bdb-mem-types.h42
-rw-r--r--xlators/storage/bdb/src/bdb.c3603
-rw-r--r--xlators/storage/bdb/src/bdb.h530
-rw-r--r--xlators/storage/posix/src/Makefile.am8
-rw-r--r--xlators/storage/posix/src/posix-aio.c517
-rw-r--r--xlators/storage/posix/src/posix-aio.h49
-rw-r--r--xlators/storage/posix/src/posix-handle.c761
-rw-r--r--xlators/storage/posix/src/posix-handle.h153
-rw-r--r--xlators/storage/posix/src/posix-helpers.c1093
-rw-r--r--xlators/storage/posix/src/posix-mem-types.h9
-rw-r--r--xlators/storage/posix/src/posix.c2615
-rw-r--r--xlators/storage/posix/src/posix.h70
-rw-r--r--xlators/system/Makefile.am1
-rw-r--r--xlators/system/posix-acl/Makefile.am1
-rw-r--r--xlators/system/posix-acl/src/Makefile.am21
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.c190
-rw-r--r--xlators/system/posix-acl/src/posix-acl-xattr.h50
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c2133
-rw-r--r--xlators/system/posix-acl/src/posix-acl.h87
343 files changed, 93531 insertions, 86272 deletions
diff --git a/xlators/Makefile.am b/xlators/Makefile.am
index b1643d26c..4c94f5e44 100644
--- a/xlators/Makefile.am
+++ b/xlators/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt system
+SUBDIRS = cluster storage protocol performance debug features encryption mount nfs mgmt
CLEANFILES =
diff --git a/xlators/cluster/afr/src/Makefile.am b/xlators/cluster/afr/src/Makefile.am
index 95db5dd96..e192b599b 100644
--- a/xlators/cluster/afr/src/Makefile.am
+++ b/xlators/cluster/afr/src/Makefile.am
@@ -1,11 +1,7 @@
xlator_LTLIBRARIES = afr.la pump.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
-afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c \
- afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c \
- afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c \
- afr-self-heal-algorithm.c afr-lk-common.c afr-self-heald.c \
- $(top_builddir)/xlators/lib/src/libxlator.c
+afr_common_source = afr-dir-read.c afr-dir-write.c afr-inode-read.c afr-inode-write.c afr-open.c afr-transaction.c afr-self-heal-data.c afr-self-heal-common.c afr-self-heal-metadata.c afr-self-heal-entry.c afr-self-heal-algorithm.c afr-lk-common.c $(top_builddir)/xlators/lib/src/libxlator.c
afr_la_LDFLAGS = -module -avoidversion
afr_la_SOURCES = $(afr_common_source) afr.c
@@ -15,15 +11,11 @@ pump_la_LDFLAGS = -module -avoidversion
pump_la_SOURCES = $(afr_common_source) pump.c
pump_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h \
- afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h \
- afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c \
- afr-self-heald.h $(top_builddir)/xlators/lib/src/libxlator.h \
- $(top_builddir)/glusterfsd/src/glusterfsd.h
+noinst_HEADERS = afr.h afr-transaction.h afr-inode-write.h afr-inode-read.h afr-dir-read.h afr-dir-write.h afr-self-heal.h afr-self-heal-common.h afr-self-heal-algorithm.h pump.h afr-mem-types.h afr-common.c $(top_builddir)/xlators/lib/src/libxlator.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/xlators/lib/src \
- -I$(top_srcdir)/rpc/rpc-lib/src -shared -nostartfiles $(GF_CFLAGS)
+ -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/contrib/md5 -shared -nostartfiles $(GF_CFLAGS) \
+ -I$(top_srcdir)/xlators/lib/src
CLEANFILES =
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index 70a9cd354..f000aaf92 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -35,7 +44,6 @@
#include "compat.h"
#include "byte-order.h"
#include "statedump.h"
-#include "inode.h"
#include "fd.h"
@@ -46,802 +54,303 @@
#include "afr-transaction.h"
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
-#include "afr-self-heald.h"
#include "pump.h"
#define AFR_ICTX_OPENDIR_DONE_MASK 0x0000000200000000ULL
#define AFR_ICTX_SPLIT_BRAIN_MASK 0x0000000100000000ULL
#define AFR_ICTX_READ_CHILD_MASK 0x00000000FFFFFFFFULL
-int
-afr_lookup_done_success_action (call_frame_t *frame, xlator_t *this,
- gf_boolean_t fail_conflict);
-void
-afr_children_copy (int32_t *dst, int32_t *src, unsigned int child_count)
-{
- int i = 0;
-
- for (i = 0; i < child_count; i++)
- dst[i] = src[i];
-}
-
-void
-afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req, const char *path)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- int ret = 0;
-
- priv = this->private;
-
- for (i = 0; i < priv->child_count; i++) {
- ret = dict_set_uint64 (xattr_req, priv->pending_key[i],
- 3 * sizeof(int32_t));
- if (ret < 0)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- path, priv->pending_key[i]);
- /* 3 = data+metadata+entry */
- }
- ret = dict_set_int32 (xattr_req, GF_GFIDLESS_LOOKUP, 1);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "%s: failed to set gfidless "
- "lookup", path);
- }
-}
-
-int
-afr_lookup_xattr_req_prepare (afr_local_t *local, xlator_t *this,
- dict_t *xattr_req, loc_t *loc, void **gfid_req)
-{
- int ret = -ENOMEM;
-
- GF_ASSERT (gfid_req);
-
- *gfid_req = NULL;
- local->xattr_req = dict_new ();
- if (!local->xattr_req)
- goto out;
- if (xattr_req)
- dict_copy (xattr_req, local->xattr_req);
-
- afr_xattr_req_prepare (this, local->xattr_req, loc->path);
- ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_INODELK_COUNT, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, GLUSTERFS_INODELK_COUNT);
- }
- ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, GLUSTERFS_ENTRYLK_COUNT);
- }
-
- ret = dict_set_uint32 (local->xattr_req, GLUSTERFS_PARENT_ENTRYLK, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: Unable to set dict value for %s",
- loc->path, GLUSTERFS_PARENT_ENTRYLK);
- }
-
- ret = dict_get_ptr (local->xattr_req, "gfid-req", gfid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: failed to get the gfid from dict", loc->path);
- *gfid_req = NULL;
- } else {
- if (loc->parent != NULL)
- dict_del (local->xattr_req, "gfid-req");
- }
- ret = 0;
-out:
- return ret;
-}
-
-void
-afr_lookup_save_gfid (uuid_t dst, void* new, const loc_t *loc)
-{
- inode_t *inode = NULL;
-
- inode = loc->inode;
- if (inode && !uuid_is_null (inode->gfid))
- uuid_copy (dst, inode->gfid);
- else if (!uuid_is_null (loc->gfid))
- uuid_copy (dst, loc->gfid);
- else if (new && !uuid_is_null (new))
- uuid_copy (dst, new);
-}
-
-int
-afr_errno_count (int32_t *children, int *child_errno,
- unsigned int child_count, int32_t op_errno)
-{
- int i = 0;
- int errno_count = 0;
- int child = 0;
-
- for (i = 0; i < child_count; i++) {
- if (children) {
- child = children[i];
- if (child == -1)
- break;
- } else {
- child = i;
- }
- if (child_errno[child] == op_errno)
- errno_count++;
- }
- return errno_count;
-}
-
int32_t
afr_set_dict_gfid (dict_t *dict, uuid_t gfid)
{
- int ret = 0;
- uuid_t *pgfid = NULL;
+ int ret = 0;
GF_ASSERT (gfid);
- pgfid = GF_CALLOC (1, sizeof (uuid_t), gf_common_mt_char);
- if (!pgfid) {
- ret = -1;
- goto out;
- }
-
- uuid_copy (*pgfid, gfid);
-
- ret = dict_set_dynptr (dict, "gfid-req", pgfid, sizeof (uuid_t));
+ ret = dict_set_static_bin (dict, "gfid-req", gfid, 16);
if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "gfid set failed");
-
-out:
- if (ret && pgfid)
- GF_FREE (pgfid);
+ gf_log (THIS->name, GF_LOG_DEBUG, "gfid set failed");
return ret;
}
-afr_inode_ctx_t*
-afr_inode_ctx_get_from_addr (uint64_t addr, int32_t child_count)
+uint64_t
+afr_is_split_brain (xlator_t *this, inode_t *inode)
{
- int ret = -1;
- afr_inode_ctx_t *ctx = NULL;
- size_t size = 0;
-
- GF_ASSERT (child_count > 0);
-
- if (!addr) {
- ctx = GF_CALLOC (1, sizeof (*ctx),
- gf_afr_mt_inode_ctx_t);
- if (!ctx)
- goto out;
- size = sizeof (*ctx->fresh_children);
- ctx->fresh_children = GF_CALLOC (child_count, size,
- gf_afr_mt_int32_t);
- if (!ctx->fresh_children)
- goto out;
- } else {
- ctx = (afr_inode_ctx_t*) (long) addr;
- }
- ret = 0;
-out:
- if (ret && ctx) {
- GF_FREE (ctx->fresh_children);
- GF_FREE (ctx);
- ctx = NULL;
- }
- return ctx;
-}
+ int ret = 0;
-void
-afr_inode_get_ctx (xlator_t *this, inode_t *inode, afr_inode_params_t *params)
-{
- GF_ASSERT (inode);
- GF_ASSERT (params);
+ uint64_t ctx = 0;
+ uint64_t split_brain = 0;
- int ret = 0;
- afr_inode_ctx_t *ctx = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- uint64_t ctx_addr = 0;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ VALIDATE_OR_GOTO (inode, out);
- priv = this->private;
LOCK (&inode->lock);
{
- ret = __inode_ctx_get (inode, this, &ctx_addr);
+ ret = __inode_ctx_get (inode, this, &ctx);
+
if (ret < 0)
goto unlock;
- ctx = afr_inode_ctx_get_from_addr (ctx_addr, priv->child_count);
- if (!ctx)
- goto unlock;
- switch (params->op) {
- case AFR_INODE_GET_READ_CTX:
- fresh_children = params->u.read_ctx.children;
- read_child = (int32_t)(ctx->masks &
- AFR_ICTX_READ_CHILD_MASK);
- params->u.read_ctx.read_child = read_child;
- if (!fresh_children)
- goto unlock;
- for (i = 0; i < priv->child_count; i++)
- fresh_children[i] = ctx->fresh_children[i];
- break;
- case AFR_INODE_GET_OPENDIR_DONE:
- params->u.value = _gf_false;
- if (ctx->masks & AFR_ICTX_OPENDIR_DONE_MASK)
- params->u.value = _gf_true;
- break;
- case AFR_INODE_GET_SPLIT_BRAIN:
- params->u.value = _gf_false;
- if (ctx->masks & AFR_ICTX_SPLIT_BRAIN_MASK)
- params->u.value = _gf_true;
- ;
- break;
- default:
- GF_ASSERT (0);
- break;
- }
+
+ split_brain = ctx & AFR_ICTX_SPLIT_BRAIN_MASK;
}
unlock:
UNLOCK (&inode->lock);
-}
-gf_boolean_t
-afr_is_split_brain (xlator_t *this, inode_t *inode)
-{
- afr_inode_params_t params = {0};
-
- params.op = AFR_INODE_GET_SPLIT_BRAIN;
- afr_inode_get_ctx (this, inode, &params);
- return params.u.value;
-}
-
-gf_boolean_t
-afr_is_opendir_done (xlator_t *this, inode_t *inode)
-{
- afr_inode_params_t params = {0};
-
- params.op = AFR_INODE_GET_OPENDIR_DONE;
- afr_inode_get_ctx (this, inode, &params);
- return params.u.value;
+out:
+ return split_brain;
}
-int32_t
-afr_inode_get_read_ctx (xlator_t *this, inode_t *inode, int32_t *fresh_children)
-{
- afr_inode_params_t params = {0};
-
- params.op = AFR_INODE_GET_READ_CTX;
- params.u.read_ctx.children = fresh_children;
- afr_inode_get_ctx (this, inode, &params);
- return params.u.read_ctx.read_child;
-}
-
void
-afr_inode_ctx_set_read_child (afr_inode_ctx_t *ctx, int32_t read_child)
+afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set)
{
- uint64_t remaining_mask = 0;
- uint64_t mask = 0;
+ uint64_t ctx = 0;
+ int ret = 0;
- remaining_mask = (~AFR_ICTX_READ_CHILD_MASK & ctx->masks);
- mask = (AFR_ICTX_READ_CHILD_MASK & read_child);
- ctx->masks = remaining_mask | mask;
-}
+ VALIDATE_OR_GOTO (inode, out);
-void
-afr_inode_ctx_set_read_ctx (afr_inode_ctx_t *ctx, int32_t read_child,
- int32_t *fresh_children, int32_t child_count)
-{
- int i = 0;
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
- afr_inode_ctx_set_read_child (ctx, read_child);
- for (i = 0; i < child_count; i++) {
- if (fresh_children)
- ctx->fresh_children[i] = fresh_children[i];
- else
- ctx->fresh_children[i] = -1;
- }
-}
+ if (ret < 0) {
+ ctx = 0;
+ }
-void
-afr_inode_ctx_rm_stale_children (afr_inode_ctx_t *ctx, int32_t *stale_children,
- int32_t child_count)
-{
- int i = 0;
- int32_t read_child = -1;
+ if (set) {
+ ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx)
+ | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_SPLIT_BRAIN_MASK);
+ } else {
+ ctx = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx);
+ }
- GF_ASSERT (stale_children);
- for (i = 0; i < child_count; i++) {
- if (stale_children[i] == -1)
- break;
- afr_children_rm_child (ctx->fresh_children,
- stale_children[i], child_count);
+ ret = __inode_ctx_put (inode, this, ctx);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_INFO,
+ "failed to set the inode ctx (%s)",
+ uuid_utoa (inode->gfid));
+ }
}
- read_child = (int32_t)(ctx->masks & AFR_ICTX_READ_CHILD_MASK);
- if (!afr_is_child_present (ctx->fresh_children, child_count,
- read_child))
- afr_inode_ctx_set_read_child (ctx, ctx->fresh_children[0]);
-}
-
-void
-afr_inode_ctx_set_opendir_done (afr_inode_ctx_t *ctx)
-{
- uint64_t remaining_mask = 0;
- uint64_t mask = 0;
-
- remaining_mask = (~AFR_ICTX_OPENDIR_DONE_MASK & ctx->masks);
- mask = (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_OPENDIR_DONE_MASK);
- ctx->masks = remaining_mask | mask;
+ UNLOCK (&inode->lock);
+out:
+ return;
}
-void
-afr_inode_ctx_set_splitbrain (afr_inode_ctx_t *ctx, gf_boolean_t set)
-{
- uint64_t remaining_mask = 0;
- uint64_t mask = 0;
-
- if (set) {
- remaining_mask = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx->masks);
- mask = (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_SPLIT_BRAIN_MASK);
- ctx->masks = remaining_mask | mask;
- } else {
- ctx->masks = (~AFR_ICTX_SPLIT_BRAIN_MASK & ctx->masks);
- }
-}
-void
-afr_inode_set_ctx (xlator_t *this, inode_t *inode, afr_inode_params_t *params)
+uint64_t
+afr_is_opendir_done (xlator_t *this, inode_t *inode)
{
- GF_ASSERT (inode);
- GF_ASSERT (params);
+ int ret = 0;
+ uint64_t ctx = 0;
+ uint64_t opendir_done = 0;
- int ret = 0;
- afr_inode_ctx_t *ctx = NULL;
- afr_private_t *priv = NULL;
- uint64_t ctx_addr = 0;
- gf_boolean_t set = _gf_false;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
- int32_t *stale_children = NULL;
+ VALIDATE_OR_GOTO (inode, out);
- priv = this->private;
LOCK (&inode->lock);
{
- ret = __inode_ctx_get (inode, this, &ctx_addr);
+ ret = __inode_ctx_get (inode, this, &ctx);
+
if (ret < 0)
- ctx_addr = 0;
- ctx = afr_inode_ctx_get_from_addr (ctx_addr, priv->child_count);
- if (!ctx)
goto unlock;
- switch (params->op) {
- case AFR_INODE_SET_READ_CTX:
- read_child = params->u.read_ctx.read_child;
- fresh_children = params->u.read_ctx.children;
- afr_inode_ctx_set_read_ctx (ctx, read_child,
- fresh_children,
- priv->child_count);
- break;
- case AFR_INODE_RM_STALE_CHILDREN:
- stale_children = params->u.read_ctx.children;
- afr_inode_ctx_rm_stale_children (ctx,
- stale_children,
- priv->child_count);
- break;
- case AFR_INODE_SET_OPENDIR_DONE:
- afr_inode_ctx_set_opendir_done (ctx);
- break;
- case AFR_INODE_SET_SPLIT_BRAIN:
- set = params->u.value;
- afr_inode_ctx_set_splitbrain (ctx, set);
- break;
- default:
- GF_ASSERT (0);
- break;
- }
- ret = __inode_ctx_put (inode, this, (uint64_t)ctx);
- if (ret) {
- gf_log_callingfn (this->name, GF_LOG_ERROR, "failed to "
- "set the inode ctx (%s)",
- uuid_utoa (inode->gfid));
- }
+
+ opendir_done = ctx & AFR_ICTX_OPENDIR_DONE_MASK;
}
unlock:
UNLOCK (&inode->lock);
-}
-
-void
-afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set)
-{
- afr_inode_params_t params = {0};
-
- params.op = AFR_INODE_SET_SPLIT_BRAIN;
- params.u.value = set;
- afr_inode_set_ctx (this, inode, &params);
-}
-
-void
-afr_set_opendir_done (xlator_t *this, inode_t *inode)
-{
- afr_inode_params_t params = {0};
- params.op = AFR_INODE_SET_OPENDIR_DONE;
- afr_inode_set_ctx (this, inode, &params);
+out:
+ return opendir_done;
}
-void
-afr_inode_set_read_ctx (xlator_t *this, inode_t *inode, int32_t read_child,
- int32_t *fresh_children)
-{
- afr_inode_params_t params = {0};
- afr_private_t *priv = NULL;
-
- priv = this->private;
- GF_ASSERT (read_child >= 0);
- GF_ASSERT (fresh_children);
- GF_ASSERT (afr_is_child_present (fresh_children, priv->child_count,
- read_child));
-
- params.op = AFR_INODE_SET_READ_CTX;
- params.u.read_ctx.read_child = read_child;
- params.u.read_ctx.children = fresh_children;
- afr_inode_set_ctx (this, inode, &params);
-}
void
-afr_inode_rm_stale_children (xlator_t *this, inode_t *inode,
- int32_t *stale_children)
-{
- afr_inode_params_t params = {0};
-
- GF_ASSERT (stale_children);
-
- params.op = AFR_INODE_RM_STALE_CHILDREN;
- params.u.read_ctx.children = stale_children;
- afr_inode_set_ctx (this, inode, &params);
-}
-
-gf_boolean_t
-afr_is_source_child (int32_t *sources, int32_t child_count, int32_t child)
+afr_set_opendir_done (xlator_t *this, inode_t *inode)
{
- gf_boolean_t source_xattrs = _gf_false;
-
- GF_ASSERT (child < child_count);
-
- if ((child >= 0) && (child < child_count) &&
- sources[child]) {
- source_xattrs = _gf_true;
- }
- return source_xattrs;
-}
+ uint64_t ctx = 0;
+ int ret = 0;
-gf_boolean_t
-afr_is_child_present (int32_t *success_children, int32_t child_count,
- int32_t child)
-{
- gf_boolean_t success_child = _gf_false;
- int i = 0;
+ VALIDATE_OR_GOTO (inode, out);
- GF_ASSERT (child < child_count);
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
- for (i = 0; i < child_count; i++) {
- if (success_children[i] == -1)
- break;
- if (child == success_children[i]) {
- success_child = _gf_true;
- break;
+ if (ret < 0) {
+ ctx = 0;
}
- }
- return success_child;
-}
-
-gf_boolean_t
-afr_is_read_child (int32_t *success_children, int32_t *sources,
- int32_t child_count, int32_t child)
-{
- gf_boolean_t success_child = _gf_false;
- gf_boolean_t source = _gf_false;
-
- if (child < 0) {
- return _gf_false;
- }
- GF_ASSERT (success_children);
- GF_ASSERT (child_count > 0);
+ ctx = (~AFR_ICTX_OPENDIR_DONE_MASK & ctx)
+ | (0xFFFFFFFFFFFFFFFFULL & AFR_ICTX_OPENDIR_DONE_MASK);
- success_child = afr_is_child_present (success_children, child_count,
- child);
- if (!success_child)
- goto out;
- if (NULL == sources) {
- source = _gf_true;
- goto out;
+ ret = __inode_ctx_put (inode, this, ctx);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_INFO,
+ "failed to set the inode ctx (%s)",
+ uuid_utoa (inode->gfid));
+ }
}
- source = afr_is_source_child (sources, child_count, child);
+ UNLOCK (&inode->lock);
out:
- return (success_child && source);
+ return;
}
-int32_t
-afr_hash_child (int32_t *success_children, int32_t child_count,
- unsigned int hmode, uuid_t gfid)
-{
- uuid_t gfid_copy = {0,};
-
- if (!hmode) {
- return -1;
- }
-
- if (gfid) {
- uuid_copy(gfid_copy,gfid);
- }
- if (hmode > 1) {
- /*
- * Why getpid? Because it's one of the cheapest calls
- * available - faster than gethostname etc. - and returns a
- * constant-length value that's sure to be shorter than a UUID.
- * It's still very unlikely to be the same across clients, so
- * it still provides good mixing. We're not trying for
- * perfection here. All we need is a low probability that
- * multiple clients won't converge on the same subvolume.
- */
- *((pid_t *)gfid_copy) = getpid();
- }
-
- return SuperFastHash((char *)gfid_copy,
- sizeof(gfid_copy)) % child_count;
-}
-/* If sources is NULL the xattrs are assumed to be of source for all
- * success_children.
- */
-int
-afr_select_read_child_from_policy (int32_t *success_children,
- int32_t child_count, int32_t prev_read_child,
- int32_t config_read_child, int32_t *sources,
- unsigned int hmode, uuid_t gfid)
+uint64_t
+afr_read_child (xlator_t *this, inode_t *inode)
{
- int32_t read_child = -1;
- int i = 0;
+ int ret = 0;
- GF_ASSERT (success_children);
+ uint64_t ctx = 0;
+ uint64_t read_child = 0;
- read_child = config_read_child;
- if (afr_is_read_child (success_children, sources, child_count,
- read_child))
- goto out;
+ VALIDATE_OR_GOTO (inode, out);
- read_child = prev_read_child;
- if (afr_is_read_child (success_children, sources, child_count,
- read_child))
- goto out;
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
- read_child = afr_hash_child (success_children, child_count,
- hmode, gfid);
- if (afr_is_read_child (success_children, sources, child_count,
- read_child)) {
- goto out;
- }
+ if (ret < 0)
+ goto unlock;
- for (i = 0; i < child_count; i++) {
- read_child = success_children[i];
- if (read_child < 0)
- break;
- if (afr_is_read_child (success_children, sources, child_count,
- read_child))
- goto out;
+ read_child = ctx & AFR_ICTX_READ_CHILD_MASK;
}
- read_child = -1;
+unlock:
+ UNLOCK (&inode->lock);
out:
return read_child;
}
-/* This function should be used when all the success_children are sources
- */
-void
-afr_set_read_ctx_from_policy (xlator_t *this, inode_t *inode,
- int32_t *fresh_children, int32_t prev_read_child,
- int32_t config_read_child, uuid_t gfid)
-{
- int read_child = -1;
- afr_private_t *priv = NULL;
-
- priv = this->private;
- read_child = afr_select_read_child_from_policy (fresh_children,
- priv->child_count,
- prev_read_child,
- config_read_child,
- NULL,
- priv->hash_mode, gfid);
- if (read_child >= 0)
- afr_inode_set_read_ctx (this, inode, read_child,
- fresh_children);
-}
-
-/* afr_next_call_child ()
- * This is a common function used by all the read-type fops
- * This function should not be called with the inode's read_children array.
- * The fop's handler should make a copy of the inode's read_children,
- * preferred read_child into the local vars, because while this function is
- * in execution there is a chance for inode's read_ctx to change.
- */
-int32_t
-afr_next_call_child (int32_t *fresh_children, unsigned char *child_up,
- size_t child_count, int32_t *last_index,
- int32_t read_child)
-{
- int next_index = 0;
- int32_t next_call_child = -1;
-
- GF_ASSERT (last_index);
-
- next_index = *last_index;
-retry:
- next_index++;
- if ((next_index >= child_count) ||
- (fresh_children[next_index] == -1))
- goto out;
- if ((fresh_children[next_index] == read_child) ||
- (!child_up[fresh_children[next_index]]))
- goto retry;
- *last_index = next_index;
- next_call_child = fresh_children[next_index];
-out:
- return next_call_child;
-}
- /* This function should not be called with the inode's read_children array.
- * The fop's handler should make a copy of the inode's read_children,
- * preferred read_child into the local vars, because while this function is
- * in execution there is a chance for inode's read_ctx to change.
- */
-int32_t
-afr_get_call_child (xlator_t *this, unsigned char *child_up, int32_t read_child,
- int32_t *fresh_children,
- int32_t *call_child, int32_t *last_index)
+void
+afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child)
{
- int ret = 0;
- afr_private_t *priv = NULL;
- int i = 0;
+ uint64_t ctx = 0;
+ int ret = 0;
- GF_ASSERT (child_up);
- GF_ASSERT (call_child);
- GF_ASSERT (last_index);
- GF_ASSERT (fresh_children);
+ VALIDATE_OR_GOTO (inode, out);
- if (read_child < 0) {
- ret = -EIO;
- goto out;
- }
- priv = this->private;
- *call_child = -1;
- *last_index = -1;
-
- if (child_up[read_child]) {
- *call_child = read_child;
- } else {
- for (i = 0; i < priv->child_count; i++) {
- if (fresh_children[i] == -1)
- break;
- if (child_up[fresh_children[i]]) {
- *call_child = fresh_children[i];
- ret = 0;
- break;
- }
- }
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &ctx);
- if (*call_child == -1) {
- ret = -ENOTCONN;
- goto out;
+ if (ret < 0) {
+ ctx = 0;
}
- *last_index = i;
- }
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d, call_child: %d, "
- "last_index: %d", ret, *call_child, *last_index);
- return ret;
-}
-
-void
-afr_reset_xattr (dict_t **xattr, unsigned int child_count)
-{
- unsigned int i = 0;
+ ctx = (~AFR_ICTX_READ_CHILD_MASK & ctx)
+ | (AFR_ICTX_READ_CHILD_MASK & read_child);
- if (!xattr)
- goto out;
- for (i = 0; i < child_count; i++) {
- if (xattr[i]) {
- dict_unref (xattr[i]);
- xattr[i] = NULL;
+ ret = __inode_ctx_put (inode, this, ctx);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_INFO,
+ "failed to set the inode ctx (%s)",
+ uuid_utoa (inode->gfid));
}
}
+ UNLOCK (&inode->lock);
+
out:
return;
}
+
+/**
+ * afr_local_cleanup - cleanup everything in frame->local
+ */
+
void
afr_local_sh_cleanup (afr_local_t *local, xlator_t *this)
{
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
+ int i = 0;
+
sh = &local->self_heal;
priv = this->private;
- GF_FREE (sh->buf);
-
- GF_FREE (sh->parentbufs);
-
- if (sh->inode)
- inode_unref (sh->inode);
+ if (sh->buf)
+ GF_FREE (sh->buf);
if (sh->xattr) {
- afr_reset_xattr (sh->xattr, priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i]) {
+ dict_unref (sh->xattr[i]);
+ sh->xattr[i] = NULL;
+ }
+ }
GF_FREE (sh->xattr);
}
- GF_FREE (sh->child_errno);
+ if (sh->child_errno)
+ GF_FREE (sh->child_errno);
+
+ if (sh->pending_matrix) {
+ for (i = 0; i < priv->child_count; i++) {
+ GF_FREE (sh->pending_matrix[i]);
+ }
+ GF_FREE (sh->pending_matrix);
+ }
- afr_matrix_cleanup (sh->pending_matrix, priv->child_count);
- afr_matrix_cleanup (sh->delta_matrix, priv->child_count);
+ if (sh->delta_matrix) {
+ for (i = 0; i < priv->child_count; i++) {
+ GF_FREE (sh->delta_matrix[i]);
+ }
+ GF_FREE (sh->delta_matrix);
+ }
- GF_FREE (sh->sources);
+ if (sh->sources)
+ GF_FREE (sh->sources);
- GF_FREE (sh->success);
+ if (sh->success)
+ GF_FREE (sh->success);
- GF_FREE (sh->locked_nodes);
+ if (sh->locked_nodes)
+ GF_FREE (sh->locked_nodes);
- if (sh->healing_fd) {
+ if (sh->healing_fd && !sh->healing_fd_opened) {
fd_unref (sh->healing_fd);
sh->healing_fd = NULL;
}
- GF_FREE ((char *)sh->linkname);
-
- GF_FREE (sh->success_children);
-
- GF_FREE (sh->fresh_children);
-
- GF_FREE (sh->fresh_parent_dirs);
+ if (sh->linkname)
+ GF_FREE ((char *)sh->linkname);
loc_wipe (&sh->parent_loc);
- loc_wipe (&sh->lookup_loc);
-
- GF_FREE (sh->checksum);
-
- GF_FREE (sh->write_needed);
- if (sh->healing_fd)
- fd_unref (sh->healing_fd);
}
void
afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
{
+ int i = 0;
afr_private_t * priv = NULL;
priv = this->private;
- afr_matrix_cleanup (local->pending, priv->child_count);
- afr_matrix_cleanup (local->transaction.txn_changelog,
- priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->pending && local->pending[i])
+ GF_FREE (local->pending[i]);
+ }
+
+ GF_FREE (local->pending);
- GF_FREE (local->internal_lock.locked_nodes);
+ if (local->internal_lock.locked_nodes)
+ GF_FREE (local->internal_lock.locked_nodes);
- GF_FREE (local->internal_lock.inode_locked_nodes);
+ if (local->internal_lock.inode_locked_nodes)
+ GF_FREE (local->internal_lock.inode_locked_nodes);
- GF_FREE (local->internal_lock.entry_locked_nodes);
+ if (local->internal_lock.entry_locked_nodes)
+ GF_FREE (local->internal_lock.entry_locked_nodes);
- GF_FREE (local->internal_lock.lower_locked_nodes);
+ if (local->internal_lock.lower_locked_nodes)
+ GF_FREE (local->internal_lock.lower_locked_nodes);
- GF_FREE (local->transaction.pre_op);
- GF_FREE (local->transaction.eager_lock);
+ GF_FREE (local->transaction.child_errno);
+ GF_FREE (local->child_errno);
GF_FREE (local->transaction.basename);
GF_FREE (local->transaction.new_basename);
@@ -854,6 +363,7 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)
void
afr_local_cleanup (afr_local_t *local, xlator_t *this)
{
+ int i = 0;
afr_private_t * priv = NULL;
if (!local)
@@ -874,21 +384,16 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
if (local->xattr_req)
dict_unref (local->xattr_req);
- if (local->dict)
- dict_unref (local->dict);
-
GF_FREE (local->child_up);
- GF_FREE (local->child_errno);
-
- GF_FREE (local->fresh_children);
-
- GF_FREE (local->fd_open_on);
-
{ /* lookup */
if (local->cont.lookup.xattrs) {
- afr_reset_xattr (local->cont.lookup.xattrs,
- priv->child_count);
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->cont.lookup.xattrs[i]) {
+ dict_unref (local->cont.lookup.xattrs[i]);
+ local->cont.lookup.xattrs[i] = NULL;
+ }
+ }
GF_FREE (local->cont.lookup.xattrs);
local->cont.lookup.xattrs = NULL;
}
@@ -900,24 +405,16 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
if (local->cont.lookup.inode) {
inode_unref (local->cont.lookup.inode);
}
-
- GF_FREE (local->cont.lookup.postparents);
-
- GF_FREE (local->cont.lookup.bufs);
-
- GF_FREE (local->cont.lookup.success_children);
-
- GF_FREE (local->cont.lookup.sources);
- afr_matrix_cleanup (local->cont.lookup.pending_matrix,
- priv->child_count);
}
{ /* getxattr */
- GF_FREE (local->cont.getxattr.name);
+ if (local->cont.getxattr.name)
+ GF_FREE (local->cont.getxattr.name);
}
{ /* lk */
- GF_FREE (local->cont.lk.locked_nodes);
+ if (local->cont.lk.locked_nodes)
+ GF_FREE (local->cont.lk.locked_nodes);
}
{ /* create */
@@ -951,40 +448,18 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this)
dict_unref (local->cont.setxattr.dict);
}
- { /* fsetxattr */
- if (local->cont.fsetxattr.dict)
- dict_unref (local->cont.fsetxattr.dict);
- }
-
{ /* removexattr */
GF_FREE (local->cont.removexattr.name);
}
- { /* xattrop */
- if (local->cont.xattrop.xattr)
- dict_unref (local->cont.xattrop.xattr);
- }
- { /* fxattrop */
- if (local->cont.fxattrop.xattr)
- dict_unref (local->cont.fxattrop.xattr);
- }
+
{ /* symlink */
GF_FREE (local->cont.symlink.linkpath);
}
{ /* opendir */
- GF_FREE (local->cont.opendir.checksum);
+ if (local->cont.opendir.checksum)
+ GF_FREE (local->cont.opendir.checksum);
}
-
- { /* readdirp */
- if (local->cont.readdir.dict)
- dict_unref (local->cont.readdir.dict);
- }
-
- if (local->xdata_req)
- dict_unref (local->xdata_req);
-
- if (local->xdata_rsp)
- dict_unref (local->xdata_rsp);
}
@@ -1005,140 +480,106 @@ afr_frame_return (call_frame_t *frame)
return call_count;
}
+
+/**
+ * up_children_count - return the number of children that are up
+ */
+
int
-afr_set_elem_count_get (unsigned char *elems, int child_count)
+afr_up_children_count (int child_count, unsigned char *child_up)
{
int i = 0;
int ret = 0;
for (i = 0; i < child_count; i++)
- if (elems[i])
+ if (child_up[i])
ret++;
return ret;
}
-/**
- * up_children_count - return the number of children that are up
- */
-unsigned int
-afr_up_children_count (unsigned char *child_up, unsigned int child_count)
+ino64_t
+afr_itransform (ino64_t ino, int child_count, int child_index)
{
- return afr_set_elem_count_get (child_up, child_count);
-}
+ ino64_t scaled_ino = -1;
-unsigned int
-afr_locked_children_count (unsigned char *children, unsigned int child_count)
-{
- return afr_set_elem_count_get (children, child_count);
-}
+ if (ino == ((uint64_t) -1)) {
+ scaled_ino = ((uint64_t) -1);
+ goto out;
+ }
-unsigned int
-afr_pre_op_done_children_count (unsigned char *pre_op,
- unsigned int child_count)
-{
- return afr_set_elem_count_get (pre_op, child_count);
+ scaled_ino = (ino * child_count) + child_index;
+
+out:
+ return scaled_ino;
}
-gf_boolean_t
-afr_is_fresh_lookup (loc_t *loc, xlator_t *this)
+
+int
+afr_deitransform_orig (ino64_t ino, int child_count)
{
- uint64_t ctx = 0;
- int32_t ret = 0;
+ int index = -1;
- GF_ASSERT (loc);
- GF_ASSERT (this);
- GF_ASSERT (loc->inode);
+ index = ino % child_count;
- ret = inode_ctx_get (loc->inode, this, &ctx);
- if (0 == ret)
- return _gf_false;
- return _gf_true;
+ return index;
}
-void
-afr_update_loc_gfids (loc_t *loc, struct iatt *buf, struct iatt *postparent)
-{
- GF_ASSERT (loc);
- GF_ASSERT (buf);
- uuid_copy (loc->gfid, buf->ia_gfid);
- if (postparent)
- uuid_copy (loc->pargfid, postparent->ia_gfid);
+int
+afr_deitransform (ino64_t ino, int child_count)
+{
+ return 0;
}
+
int
-afr_lookup_build_response_params (afr_local_t *local, xlator_t *this)
+afr_self_heal_lookup_unwind (call_frame_t *frame, xlator_t *this)
{
- struct iatt *buf = NULL;
- struct iatt *postparent = NULL;
- dict_t **xattr = NULL;
- int32_t *success_children = NULL;
- int32_t *sources = NULL;
- afr_private_t *priv = NULL;
- int32_t read_child = -1;
- int ret = 0;
- int i = 0;
-
- GF_ASSERT (local);
+ afr_local_t *local = NULL;
- buf = &local->cont.lookup.buf;
- postparent = &local->cont.lookup.postparent;
- xattr = &local->cont.lookup.xattr;
- priv = this->private;
+ local = frame->local;
- read_child = afr_inode_get_read_ctx (this, local->cont.lookup.inode,
- local->fresh_children);
- if (read_child < 0) {
- ret = -1;
- goto out;
+ if (local->govinda_gOvinda && local->cont.lookup.inode) {
+ afr_set_split_brain (this, local->cont.lookup.inode, _gf_true);
}
- success_children = local->cont.lookup.success_children;
- sources = local->cont.lookup.sources;
- memset (sources, 0, sizeof (*sources) * priv->child_count);
- afr_children_intersection_get (local->fresh_children, success_children,
- sources, priv->child_count);
- if (!sources[read_child]) {
- read_child = -1;
- for (i = 0; i < priv->child_count; i++) {
- if (sources[i]) {
- read_child = i;
- break;
- }
- }
- }
- if (read_child < 0) {
- ret = -1;
- goto out;
- }
- gf_log (this->name, GF_LOG_DEBUG, "Building lookup response from %d",
- read_child);
- if (!*xattr)
- *xattr = dict_ref (local->cont.lookup.xattrs[read_child]);
- *buf = local->cont.lookup.bufs[read_child];
- *postparent = local->cont.lookup.postparents[read_child];
-
- if (IA_INVAL == local->cont.lookup.inode->ia_type) {
- /* fix for RT #602 */
- local->cont.lookup.inode->ia_type = buf->ia_type;
- }
-out:
- return ret;
+
+ AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->cont.lookup.inode,
+ &local->cont.lookup.buf,
+ local->cont.lookup.xattr,
+ &local->cont.lookup.postparent);
+
+ return 0;
}
+
static void
-afr_lookup_update_lk_counts (afr_local_t *local, xlator_t *this,
- int child_index, dict_t *xattr)
+afr_lookup_collect_xattr (afr_local_t *local, xlator_t *this,
+ int child_index, dict_t *xattr)
{
uint32_t inodelk_count = 0;
uint32_t entrylk_count = 0;
- int ret = -1;
- uint32_t parent_entrylk = 0;
+ int ret = 0;
- GF_ASSERT (local);
- GF_ASSERT (this);
- GF_ASSERT (xattr);
- GF_ASSERT (child_index >= 0);
+ if (afr_sh_has_metadata_pending (xattr, child_index, this)) {
+ local->self_heal.need_metadata_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_DEBUG,
+ "metadata self-heal is pending for %s.",
+ local->loc.path);
+ }
+
+ if (afr_sh_has_entry_pending (xattr, child_index, this)) {
+ local->self_heal.need_entry_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_INFO,
+ "entry self-heal is pending for %s.", local->loc.path);
+ }
+
+ if (afr_sh_has_data_pending (xattr, child_index, this)) {
+ local->self_heal.need_data_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_INFO,
+ "data self-heal is pending for %s.", local->loc.path);
+ }
ret = dict_get_uint32 (xattr, GLUSTERFS_INODELK_COUNT,
&inodelk_count);
@@ -1149,84 +590,33 @@ afr_lookup_update_lk_counts (afr_local_t *local, xlator_t *this,
&entrylk_count);
if (ret == 0)
local->entrylk_count += entrylk_count;
- ret = dict_get_uint32 (xattr, GLUSTERFS_PARENT_ENTRYLK,
- &parent_entrylk);
- if (!ret)
- local->cont.lookup.parent_entrylk += parent_entrylk;
}
+
static void
-afr_lookup_set_self_heal_params_by_xattr (afr_local_t *local, xlator_t *this,
- dict_t *xattr)
+afr_lookup_self_heal_check (xlator_t *this, afr_local_t *local,
+ struct iatt *buf, struct iatt *lookup_buf)
{
- GF_ASSERT (local);
- GF_ASSERT (this);
- GF_ASSERT (xattr);
-
- if (afr_sh_has_metadata_pending (xattr, this)) {
- local->self_heal.do_metadata_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_DEBUG,
- "metadata self-heal is pending for %s.",
- local->loc.path);
- }
+ if (FILETYPE_DIFFERS (buf, lookup_buf)) {
+ /* mismatching filetypes with same name
+ */
- if (afr_sh_has_entry_pending (xattr, this)) {
- local->self_heal.do_entry_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_DEBUG,
- "entry self-heal is pending for %s.", local->loc.path);
- }
+ gf_log (this->name, GF_LOG_INFO,
+ "filetype differs for %s ", local->loc.path);
- if (afr_sh_has_data_pending (xattr, this)) {
- local->self_heal.do_data_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_DEBUG,
- "data self-heal is pending for %s.", local->loc.path);
+ local->govinda_gOvinda = 1;
}
-}
-
-void
-afr_lookup_check_set_metadata_split_brain (afr_local_t *local, xlator_t *this)
-{
- int32_t *sources = NULL;
- afr_private_t *priv = NULL;
- int32_t subvol_status = 0;
- int32_t *success_children = NULL;
- dict_t **xattrs = NULL;
- struct iatt *bufs = NULL;
- int32_t **pending_matrix = NULL;
- priv = this->private;
-
- sources = GF_CALLOC (priv->child_count, sizeof (*sources),
- gf_afr_mt_int32_t);
- if (NULL == sources)
- goto out;
- success_children = local->cont.lookup.success_children;
- xattrs = local->cont.lookup.xattrs;
- bufs = local->cont.lookup.bufs;
- pending_matrix = local->cont.lookup.pending_matrix;
- afr_build_sources (this, xattrs, bufs, pending_matrix,
- sources, success_children, AFR_METADATA_TRANSACTION,
- &subvol_status, _gf_false);
- if (subvol_status & SPLIT_BRAIN)
- local->cont.lookup.possible_spb = _gf_true;
-out:
- GF_FREE (sources);
-}
-
-static void
-afr_detect_self_heal_by_iatt (afr_local_t *local, xlator_t *this,
- struct iatt *buf, struct iatt *lookup_buf)
-{
if (PERMISSION_DIFFERS (buf, lookup_buf)) {
/* mismatching permissions */
gf_log (this->name, GF_LOG_INFO,
"permissions differ for %s ", local->loc.path);
- local->self_heal.do_metadata_self_heal = _gf_true;
+ local->self_heal.need_metadata_self_heal = _gf_true;
}
if (OWNERSHIP_DIFFERS (buf, lookup_buf)) {
/* mismatching permissions */
- local->self_heal.do_metadata_self_heal = _gf_true;
+ local->self_heal.need_metadata_self_heal = _gf_true;
gf_log (this->name, GF_LOG_INFO,
"ownership differs for %s ", local->loc.path);
}
@@ -1235,7 +625,7 @@ afr_detect_self_heal_by_iatt (afr_local_t *local, xlator_t *this,
&& IA_ISREG (buf->ia_type)) {
gf_log (this->name, GF_LOG_INFO,
"size differs for %s ", local->loc.path);
- local->self_heal.do_data_self_heal = _gf_true;
+ local->self_heal.need_data_self_heal = _gf_true;
}
if (uuid_compare (buf->ia_gfid, lookup_buf->ia_gfid)) {
@@ -1245,707 +635,120 @@ afr_detect_self_heal_by_iatt (afr_local_t *local, xlator_t *this,
}
}
-static void
-afr_detect_self_heal_by_split_brain_status (afr_local_t *local, xlator_t *this)
-{
- gf_boolean_t split_brain = _gf_false;
- afr_self_heal_t *sh = NULL;
-
- sh = &local->self_heal;
-
- split_brain = afr_is_split_brain (this, local->cont.lookup.inode);
- split_brain = split_brain || local->cont.lookup.possible_spb;
- if ((local->success_count > 0) && split_brain &&
- IA_ISREG (local->cont.lookup.inode->ia_type)) {
- sh->force_confirm_spb = _gf_true;
- gf_log (this->name, GF_LOG_WARNING,
- "split brain detected during lookup of %s.",
- local->loc.path);
- }
-}
-
-static void
-afr_detect_self_heal_by_lookup_status (afr_local_t *local, xlator_t *this)
-{
- GF_ASSERT (local);
- GF_ASSERT (this);
-
- if ((local->success_count > 0) && (local->enoent_count > 0)) {
- local->self_heal.do_metadata_self_heal = _gf_true;
- local->self_heal.do_data_self_heal = _gf_true;
- local->self_heal.do_entry_self_heal = _gf_true;
- local->self_heal.do_gfid_self_heal = _gf_true;
- local->self_heal.do_missing_entry_self_heal = _gf_true;
- gf_log(this->name, GF_LOG_INFO,
- "entries are missing in lookup of %s.",
- local->loc.path);
- //If all self-heals are needed no need to check for other rules
- goto out;
- }
-
-out:
- return;
-}
-
-gf_boolean_t
-afr_can_self_heal_proceed (afr_self_heal_t *sh, afr_private_t *priv)
-{
- GF_ASSERT (sh);
- GF_ASSERT (priv);
-
- if (sh->force_confirm_spb)
- return _gf_true;
- return (sh->do_gfid_self_heal
- || sh->do_missing_entry_self_heal
- || (afr_data_self_heal_enabled (priv->data_self_heal) &&
- sh->do_data_self_heal)
- || (priv->metadata_self_heal && sh->do_metadata_self_heal)
- || (priv->entry_self_heal && sh->do_entry_self_heal));
-}
-
-afr_transaction_type
-afr_transaction_type_get (ia_type_t ia_type)
-{
- afr_transaction_type type = AFR_METADATA_TRANSACTION;
-
- GF_ASSERT (ia_type != IA_INVAL);
-
- if (IA_ISDIR (ia_type)) {
- type = AFR_ENTRY_TRANSACTION;
- } else if (IA_ISREG (ia_type)) {
- type = AFR_DATA_TRANSACTION;
- }
- return type;
-}
-
-int
-afr_lookup_select_read_child (afr_local_t *local, xlator_t *this,
- int32_t *read_child)
-{
- ia_type_t ia_type = IA_INVAL;
- int32_t source = -1;
- int ret = -1;
- dict_t **xattrs = NULL;
- int32_t *success_children = NULL;
- afr_transaction_type type = AFR_METADATA_TRANSACTION;
- uuid_t *gfid = NULL;
-
- GF_ASSERT (local);
- GF_ASSERT (this);
- GF_ASSERT (local->success_count > 0);
-
- success_children = local->cont.lookup.success_children;
- /*We can take the success_children[0] only because we already
- *handle the conflicting children other wise, we could select the
- *read_child based on wrong file type
- */
- ia_type = local->cont.lookup.bufs[success_children[0]].ia_type;
- type = afr_transaction_type_get (ia_type);
- xattrs = local->cont.lookup.xattrs;
- gfid = &local->cont.lookup.buf.ia_gfid;
- source = afr_lookup_select_read_child_by_txn_type (this, local, xattrs,
- type, *gfid);
- if (source < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "failed to select source "
- "for %s", local->loc.path);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Source selected as %d for %s",
- source, local->loc.path);
- *read_child = source;
- ret = 0;
-out:
- return ret;
-}
-
-static inline gf_boolean_t
-afr_is_transaction_running (afr_local_t *local)
-{
- GF_ASSERT (local->fop == GF_FOP_LOOKUP);
- return ((local->inodelk_count > 0) || (local->entrylk_count > 0));
-}
-
-void
-afr_launch_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode,
- gf_boolean_t background, ia_type_t ia_type, char *reason,
- void (*gfid_sh_success_cbk) (call_frame_t *sh_frame,
- xlator_t *this),
- int (*unwind) (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- int32_t sh_failed))
-{
- afr_local_t *local = NULL;
- char sh_type_str[256] = {0,};
- char *bg = "";
-
- GF_ASSERT (frame);
- GF_ASSERT (this);
- GF_ASSERT (inode);
- GF_ASSERT (ia_type != IA_INVAL);
-
- local = frame->local;
- local->self_heal.background = background;
- local->self_heal.type = ia_type;
- local->self_heal.unwind = unwind;
- local->self_heal.gfid_sh_success_cbk = gfid_sh_success_cbk;
-
- afr_self_heal_type_str_get (&local->self_heal,
- sh_type_str,
- sizeof (sh_type_str));
-
- if (background)
- bg = "background";
- gf_log (this->name, GF_LOG_INFO,
- "%s %s self-heal triggered. path: %s, reason: %s", bg,
- sh_type_str, local->loc.path, reason);
-
- afr_self_heal (frame, this, inode);
-}
-
-unsigned int
-afr_gfid_missing_count (const char *xlator_name, int32_t *success_children,
- struct iatt *bufs, unsigned int child_count,
- const char *path)
-{
- unsigned int gfid_miss_count = 0;
- int i = 0;
- struct iatt *child1 = NULL;
-
- for (i = 0; i < child_count; i++) {
- if (success_children[i] == -1)
- break;
- child1 = &bufs[success_children[i]];
- if (uuid_is_null (child1->ia_gfid)) {
- gf_log (xlator_name, GF_LOG_DEBUG, "%s: gfid is null"
- " on subvolume %d", path, success_children[i]);
- gfid_miss_count++;
- }
- }
-
- return gfid_miss_count;
-}
-
-static int
-afr_lookup_gfid_missing_count (afr_local_t *local, xlator_t *this)
-{
- int32_t *success_children = NULL;
- afr_private_t *priv = NULL;
- struct iatt *bufs = NULL;
- int miss_count = 0;
-
- priv = this->private;
- bufs = local->cont.lookup.bufs;
- success_children = local->cont.lookup.success_children;
-
- miss_count = afr_gfid_missing_count (this->name, success_children,
- bufs, priv->child_count,
- local->loc.path);
- return miss_count;
-}
-
-gf_boolean_t
-afr_conflicting_iattrs (struct iatt *bufs, int32_t *success_children,
- unsigned int child_count, const char *path,
- const char *xlator_name)
-{
- gf_boolean_t conflicting = _gf_false;
- int i = 0;
- struct iatt *child1 = NULL;
- struct iatt *child2 = NULL;
- uuid_t *gfid = NULL;
-
- for (i = 0; i < child_count; i++) {
- if (success_children[i] == -1)
- break;
- child1 = &bufs[success_children[i]];
- if ((!gfid) && (!uuid_is_null (child1->ia_gfid)))
- gfid = &child1->ia_gfid;
-
- if (i == 0)
- continue;
-
- child2 = &bufs[success_children[i-1]];
- if (FILETYPE_DIFFERS (child1, child2)) {
- gf_log (xlator_name, GF_LOG_WARNING, "%s: filetype "
- "differs on subvolumes (%d, %d)", path,
- success_children[i-1], success_children[i]);
- conflicting = _gf_true;
- goto out;
- }
- if (!gfid || uuid_is_null (child1->ia_gfid))
- continue;
- if (uuid_compare (*gfid, child1->ia_gfid)) {
- gf_log (xlator_name, GF_LOG_WARNING, "%s: gfid differs"
- " on subvolume %d", path, success_children[i]);
- conflicting = _gf_true;
- goto out;
- }
- }
-out:
- return conflicting;
-}
-
-/* afr_update_gfid_from_iatts: This function should be called only if the
- * iatts are not conflicting.
- */
-void
-afr_update_gfid_from_iatts (uuid_t uuid, struct iatt *bufs,
- int32_t *success_children, unsigned int child_count)
-{
- uuid_t *gfid = NULL;
- int i = 0;
- int child = 0;
-
- for (i = 0; i < child_count; i++) {
- child = success_children[i];
- if (child == -1)
- break;
- if ((!gfid) && (!uuid_is_null (bufs[child].ia_gfid))) {
- gfid = &bufs[child].ia_gfid;
- } else if (gfid && (!uuid_is_null (bufs[child].ia_gfid))) {
- if (uuid_compare (*gfid, bufs[child].ia_gfid)) {
- GF_ASSERT (0);
- goto out;
- }
- }
- }
- if (gfid && (!uuid_is_null (*gfid)))
- uuid_copy (uuid, *gfid);
-out:
- return;
-}
-
-static gf_boolean_t
-afr_lookup_conflicting_entries (afr_local_t *local, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- gf_boolean_t conflict = _gf_false;
-
- priv = this->private;
- conflict = afr_conflicting_iattrs (local->cont.lookup.bufs,
- local->cont.lookup.success_children,
- priv->child_count, local->loc.path,
- this->name);
- return conflict;
-}
-
-gf_boolean_t
-afr_open_only_data_self_heal (char *data_self_heal)
-{
- return !strcmp (data_self_heal, "open");
-}
-
-gf_boolean_t
-afr_data_self_heal_enabled (char *data_self_heal)
-{
- gf_boolean_t enabled = _gf_false;
-
- if (gf_string2boolean (data_self_heal, &enabled) == -1) {
- enabled = !strcmp (data_self_heal, "open");
- GF_ASSERT (enabled);
- }
-
- return enabled;
-}
static void
-afr_lookup_set_self_heal_params (afr_local_t *local, xlator_t *this)
+afr_lookup_done (call_frame_t *frame, xlator_t *this, struct iatt *lookup_buf)
{
- int i = 0;
- struct iatt *bufs = NULL;
- dict_t **xattr = NULL;
- afr_private_t *priv = NULL;
- int32_t child1 = -1;
- int32_t child2 = -1;
- afr_self_heal_t *sh = NULL;
+ int unwind = 1;
+ int source = -1;
+ int up_count = 0;
+ char sh_type_str[256] = {0,};
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
priv = this->private;
- sh = &local->self_heal;
-
- afr_detect_self_heal_by_lookup_status (local, this);
-
- if (afr_lookup_gfid_missing_count (local, this))
- local->self_heal.do_gfid_self_heal = _gf_true;
-
- if (_gf_true == afr_lookup_conflicting_entries (local, this))
- local->self_heal.do_missing_entry_self_heal = _gf_true;
- else
- afr_update_gfid_from_iatts (local->self_heal.sh_gfid_req,
- local->cont.lookup.bufs,
- local->cont.lookup.success_children,
- priv->child_count);
-
- bufs = local->cont.lookup.bufs;
- for (i = 1; i < local->success_count; i++) {
- child1 = local->cont.lookup.success_children[i-1];
- child2 = local->cont.lookup.success_children[i];
- afr_detect_self_heal_by_iatt (local, this,
- &bufs[child1], &bufs[child2]);
- }
-
- xattr = local->cont.lookup.xattrs;
- for (i = 0; i < local->success_count; i++) {
- child1 = local->cont.lookup.success_children[i];
- afr_lookup_set_self_heal_params_by_xattr (local, this,
- xattr[child1]);
- }
- if (afr_open_only_data_self_heal (priv->data_self_heal))
- sh->do_data_self_heal = _gf_false;
- if (sh->do_metadata_self_heal)
- afr_lookup_check_set_metadata_split_brain (local, this);
- afr_detect_self_heal_by_split_brain_status (local, this);
-}
-
-int
-afr_self_heal_lookup_unwind (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- int32_t sh_failed)
-{
- afr_local_t *local = NULL;
- int ret = -1;
- dict_t *xattr = NULL;
-
local = frame->local;
- if (op_ret == -1) {
- local->op_ret = -1;
- if (afr_error_more_important (local->op_errno, op_errno))
- local->op_errno = op_errno;
-
- goto out;
- } else {
- local->op_ret = 0;
- }
-
- afr_lookup_done_success_action (frame, this, _gf_true);
- xattr = local->cont.lookup.xattr;
- if (xattr) {
- ret = dict_set_int32 (xattr, "sh-failed", sh_failed);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "%s: Failed to set "
- "sh-failed to %d", local->loc.path, sh_failed);
- }
-out:
- AFR_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
- local->cont.lookup.inode, &local->cont.lookup.buf,
- local->cont.lookup.xattr,
- &local->cont.lookup.postparent);
-
- return 0;
-}
-
-//TODO: At the moment only lookup needs this, so not doing any checks, in the
-// future we will have to do fop specific operations
-void
-afr_post_gfid_sh_success (call_frame_t *sh_frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_local_t *sh_local = NULL;
- afr_private_t *priv = NULL;
- afr_self_heal_t *sh = NULL;
- int i = 0;
- struct iatt *lookup_bufs = NULL;
- struct iatt *lookup_parentbufs = NULL;
-
- sh_local = sh_frame->local;
- sh = &sh_local->self_heal;
- local = sh->orig_frame->local;
- lookup_bufs = local->cont.lookup.bufs;
- lookup_parentbufs = local->cont.lookup.postparents;
- priv = this->private;
-
- memcpy (lookup_bufs, sh->buf, priv->child_count * sizeof (*sh->buf));
- memcpy (lookup_parentbufs, sh->parentbufs,
- priv->child_count * sizeof (*sh->parentbufs));
+ local->cont.lookup.postparent.ia_ino = local->cont.lookup.parent_ino;
- afr_reset_xattr (local->cont.lookup.xattrs, priv->child_count);
- if (local->cont.lookup.xattr) {
- dict_unref (local->cont.lookup.xattr);
- local->cont.lookup.xattr = NULL;
+ if (local->cont.lookup.ino) {
+ local->cont.lookup.buf.ia_ino = local->cont.lookup.ino;
}
- for (i = 0; i < priv->child_count; i++) {
- if (sh->xattr[i])
- local->cont.lookup.xattrs[i] = dict_ref (sh->xattr[i]);
+ if (local->op_ret == 0) {
+ /* KLUDGE: assuming DHT will not itransform in
+ revalidate */
+ if (local->cont.lookup.inode->ino) {
+ local->cont.lookup.buf.ia_ino =
+ local->cont.lookup.inode->ino;
+ }
}
-
- afr_reset_children (local->cont.lookup.success_children,
- priv->child_count);
- afr_children_copy (local->cont.lookup.success_children,
- sh->fresh_children, priv->child_count);
-}
-
-static void
-afr_lookup_perform_self_heal (call_frame_t *frame, xlator_t *this,
- gf_boolean_t *sh_launched)
-{
- unsigned int up_count = 0;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- char *reason = NULL;
-
- GF_ASSERT (sh_launched);
- *sh_launched = _gf_false;
- priv = this->private;
- local = frame->local;
-
- up_count = afr_up_children_count (local->child_up, priv->child_count);
+ up_count = afr_up_children_count (priv->child_count, priv->child_up);
if (up_count == 1) {
gf_log (this->name, GF_LOG_DEBUG,
"Only 1 child up - do not attempt to detect self heal");
- goto out;
- }
-
- afr_lookup_set_self_heal_params (local, this);
- if (afr_can_self_heal_proceed (&local->self_heal, priv)) {
- if (afr_is_transaction_running (local))
- goto out;
-
- reason = "lookup detected pending operations";
- afr_launch_self_heal (frame, this, local->cont.lookup.inode,
- _gf_true, local->cont.lookup.buf.ia_type,
- reason, afr_post_gfid_sh_success,
- afr_self_heal_lookup_unwind);
- *sh_launched = _gf_true;
- }
-out:
- return;
-}
-
-void
-afr_get_fresh_children (int32_t *success_children, int32_t *sources,
- int32_t *fresh_children, unsigned int child_count)
-{
- unsigned int i = 0;
- unsigned int j = 0;
-
- GF_ASSERT (success_children);
- GF_ASSERT (sources);
- GF_ASSERT (fresh_children);
-
- afr_reset_children (fresh_children, child_count);
- for (i = 0; i < child_count; i++) {
- if (success_children[i] == -1)
- break;
- if (afr_is_read_child (success_children, sources, child_count,
- success_children[i])) {
- fresh_children[j] = success_children[i];
- j++;
- }
- }
-}
-
-static int
-afr_lookup_set_read_ctx (afr_local_t *local, xlator_t *this, int32_t read_child)
-{
- afr_private_t *priv = NULL;
-
- GF_ASSERT (read_child >= 0);
-
- priv = this->private;
- afr_get_fresh_children (local->cont.lookup.success_children,
- local->cont.lookup.sources,
- local->fresh_children, priv->child_count);
- afr_inode_set_read_ctx (this, local->cont.lookup.inode, read_child,
- local->fresh_children);
-
- return 0;
-}
-
-int
-afr_lookup_done_success_action (call_frame_t *frame, xlator_t *this,
- gf_boolean_t fail_conflict)
-{
- int32_t read_child = -1;
- int32_t ret = -1;
- afr_local_t *local = NULL;
- gf_boolean_t fresh_lookup = _gf_false;
-
- local = frame->local;
- fresh_lookup = local->cont.lookup.fresh_lookup;
-
- if (local->loc.parent == NULL)
- fail_conflict = _gf_true;
- if (afr_lookup_conflicting_entries (local, this)) {
- if (fail_conflict == _gf_false)
- ret = 0;
- goto out;
- }
-
- ret = afr_lookup_select_read_child (local, this, &read_child);
- if (!afr_is_transaction_running (local) || fresh_lookup) {
- if (read_child < 0)
- goto out;
-
- ret = afr_lookup_set_read_ctx (local, this, read_child);
- if (ret)
- goto out;
+ goto unwind;
}
- ret = afr_lookup_build_response_params (local, this);
- if (ret)
- goto out;
- afr_update_loc_gfids (&local->loc,
- &local->cont.lookup.buf,
- &local->cont.lookup.postparent);
-
- ret = 0;
-out:
- if (ret) {
- local->op_ret = -1;
- local->op_errno = EIO;
+ if (local->success_count && local->enoent_count) {
+ local->self_heal.need_metadata_self_heal = _gf_true;
+ local->self_heal.need_data_self_heal = _gf_true;
+ local->self_heal.need_entry_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_INFO,
+ "entries are missing in lookup of %s.",
+ local->loc.path);
}
- return ret;
-}
-
-int
-afr_lookup_get_latest_subvol (afr_local_t *local, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- int32_t *success_children = NULL;
- struct iatt *bufs = NULL;
- int i = 0;
- int child = 0;
- int lsubvol = -1;
- priv = this->private;
- success_children = local->cont.lookup.success_children;
- bufs = local->cont.lookup.bufs;
- for (i = 0; i < priv->child_count; i++) {
- child = success_children[i];
- if (child == -1)
- break;
- if (uuid_is_null (bufs[child].ia_gfid))
- continue;
- if (lsubvol < 0) {
- lsubvol = child;
- } else if (bufs[lsubvol].ia_ctime < bufs[child].ia_ctime) {
- lsubvol = child;
- } else if ((bufs[lsubvol].ia_ctime == bufs[child].ia_ctime) &&
- (bufs[lsubvol].ia_ctime_nsec < bufs[child].ia_ctime_nsec)) {
- lsubvol = child;
+ if (local->success_count) {
+ /* check for split-brain case in previous lookup */
+ if (afr_is_split_brain (this, local->cont.lookup.inode)) {
+ local->self_heal.need_data_self_heal = _gf_true;
+ gf_log(this->name, GF_LOG_WARNING,
+ "split brain detected during lookup of %s.",
+ local->loc.path);
}
}
- return lsubvol;
-}
-
-void
-afr_lookup_mark_other_entries_stale (afr_local_t *local, xlator_t *this,
- int subvol)
-{
- afr_private_t *priv = NULL;
- int32_t *success_children = NULL;
- struct iatt *bufs = NULL;
- int i = 0;
- int child = 0;
- priv = this->private;
- success_children = local->cont.lookup.success_children;
- bufs = local->cont.lookup.bufs;
- memcpy (local->fresh_children, success_children,
- sizeof (*success_children) * priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- child = local->fresh_children[i];
- if (child == -1)
- break;
- if (child == subvol)
- continue;
- if (uuid_is_null (bufs[child].ia_gfid) &&
- (bufs[child].ia_type == bufs[subvol].ia_type))
- continue;
- afr_children_rm_child (success_children, child,
- priv->child_count);
- local->success_count--;
- }
- afr_reset_children (local->fresh_children, priv->child_count);
-}
+ if ((local->self_heal.need_metadata_self_heal
+ || local->self_heal.need_data_self_heal
+ || local->self_heal.need_entry_self_heal)
+ && ((!local->cont.lookup.is_revalidate)
+ || (local->op_ret != -1))) {
-void
-afr_succeed_lookup_on_latest_iatt (afr_local_t *local, xlator_t *this)
-{
- int lsubvol = 0;
+ if (local->inodelk_count || local->entrylk_count) {
- if (!afr_lookup_conflicting_entries (local, this))
- goto out;
+ /* Someone else is doing self-heal on this file.
+ So just make a best effort to set the read-subvolume
+ and return */
- lsubvol = afr_lookup_get_latest_subvol (local, this);
- if (lsubvol < 0)
- goto out;
- afr_lookup_mark_other_entries_stale (local, this, lsubvol);
-out:
- return;
-}
+ if (IA_ISREG (local->cont.lookup.inode->ia_type)) {
+ source = afr_self_heal_get_source (this, local, local->cont.lookup.xattrs);
-static void
-afr_lookup_done (call_frame_t *frame, xlator_t *this)
-{
- int unwind = 1;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int ret = -1;
- gf_boolean_t sh_launched = _gf_false;
- gf_boolean_t fail_conflict = _gf_false;
- int gfid_miss_count = 0;
- int enotconn_count = 0;
- int up_children_count = 0;
+ if (source >= 0) {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ source);
+ }
+ }
+ goto unwind;
+ }
- priv = this->private;
- local = frame->local;
+ if (!local->cont.lookup.inode->ia_type) {
+ /* fix for RT #602 */
+ local->cont.lookup.inode->ia_type =
+ lookup_buf->ia_type;
+ }
- if (local->op_ret < 0)
- goto unwind;
+ local->self_heal.background = _gf_true;
+ local->self_heal.type = local->cont.lookup.buf.ia_type;
+ local->self_heal.unwind = afr_self_heal_lookup_unwind;
- if (local->cont.lookup.parent_entrylk && local->success_count > 1)
- afr_succeed_lookup_on_latest_iatt (local, this);
-
- gfid_miss_count = afr_lookup_gfid_missing_count (local, this);
- up_children_count = afr_up_children_count (local->child_up,
- priv->child_count);
- enotconn_count = priv->child_count - up_children_count;
- if ((gfid_miss_count == local->success_count) &&
- (enotconn_count > 0)) {
- local->op_ret = -1;
- local->op_errno = EIO;
- gf_log (this->name, GF_LOG_ERROR, "Failing lookup for %s, "
- "LOOKUP on a file without gfid is not allowed when "
- "some of the children are down", local->loc.path);
- goto unwind;
- }
+ unwind = 0;
- if ((gfid_miss_count == local->success_count) &&
- uuid_is_null (local->cont.lookup.gfid_req)) {
- local->op_ret = -1;
- local->op_errno = ENODATA;
- gf_log (this->name, GF_LOG_ERROR, "%s: No gfid present",
- local->loc.path);
- goto unwind;
- }
+ afr_self_heal_type_str_get(&local->self_heal,
+ sh_type_str,
+ sizeof(sh_type_str));
- if (gfid_miss_count && uuid_is_null (local->cont.lookup.gfid_req))
- fail_conflict = _gf_true;
- ret = afr_lookup_done_success_action (frame, this, fail_conflict);
- if (ret)
- goto unwind;
- uuid_copy (local->self_heal.sh_gfid_req, local->cont.lookup.gfid_req);
+ gf_log (this->name, GF_LOG_INFO,
+ "background %s self-heal triggered. path: %s",
+ sh_type_str, local->loc.path);
- afr_lookup_perform_self_heal (frame, this, &sh_launched);
- if (sh_launched) {
- unwind = 0;
- goto unwind;
+ afr_self_heal (frame, this);
}
- unwind:
- if (unwind) {
- AFR_STACK_UNWIND (lookup, frame, local->op_ret,
- local->op_errno, local->cont.lookup.inode,
- &local->cont.lookup.buf,
- local->cont.lookup.xattr,
- &local->cont.lookup.postparent);
+unwind:
+ if (unwind) {
+ AFR_STACK_UNWIND (lookup, frame, local->op_ret,
+ local->op_errno,
+ local->cont.lookup.inode,
+ &local->cont.lookup.buf,
+ local->cont.lookup.xattr,
+ &local->cont.lookup.postparent);
}
}
+
/*
* During a lookup, some errors are more "important" than
* others in that they must be given higher priority while
@@ -1955,8 +758,8 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this)
*
*/
-gf_boolean_t
-afr_error_more_important (int32_t old_errno, int32_t new_errno)
+static gf_boolean_t
+__error_more_important (int32_t old_errno, int32_t new_errno)
{
gf_boolean_t ret = _gf_true;
@@ -1964,339 +767,305 @@ afr_error_more_important (int32_t old_errno, int32_t new_errno)
if (old_errno == ESTALE)
ret = _gf_false;
- /* Nothing should overwrite ENOENT, except ESTALE/EIO*/
- else if ((old_errno == ENOENT) && (new_errno != ESTALE)
- && (new_errno != EIO))
+ /* Nothing should overwrite ENOENT, except ESTALE */
+ else if ((old_errno == ENOENT) && (new_errno != ESTALE))
ret = _gf_false;
return ret;
}
-int32_t
-afr_resultant_errno_get (int32_t *children,
- int *child_errno, unsigned int child_count)
+
+int
+afr_fresh_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
- int i = 0;
- int32_t op_errno = 0;
- int child = 0;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ struct iatt * lookup_buf = NULL;
+ int call_count = -1;
+ int child_index = -1;
+ int first_up_child = -1;
- for (i = 0; i < child_count; i++) {
- if (children) {
- child = children[i];
- if (child == -1)
- break;
- } else {
- child = i;
- }
- if (afr_error_more_important (op_errno, child_errno[child]))
- op_errno = child_errno[child];
- }
- return op_errno;
-}
+ child_index = (long) cookie;
+ priv = this->private;
-static void
-afr_lookup_handle_error (afr_local_t *local, int32_t op_ret, int32_t op_errno)
-{
- GF_ASSERT (local);
- if (op_errno == ENOENT)
- local->enoent_count++;
+ LOCK (&frame->lock);
+ {
+ local = frame->local;
- if (afr_error_more_important (local->op_errno, op_errno))
- local->op_errno = op_errno;
+ lookup_buf = &local->cont.lookup.buf;
- if (local->op_errno == ESTALE) {
- local->op_ret = -1;
- }
-}
+ if (op_ret == -1) {
+ if (op_errno == ENOENT)
+ local->enoent_count++;
-static void
-afr_set_root_inode_on_first_lookup (afr_local_t *local, xlator_t *this,
- inode_t *inode)
-{
- afr_private_t *priv = NULL;
- GF_ASSERT (inode);
+ if (__error_more_important (local->op_errno, op_errno))
+ local->op_errno = op_errno;
- if (!__is_root_gfid (inode->gfid))
- goto out;
- if (!afr_is_fresh_lookup (&local->loc, this))
- goto out;
- priv = this->private;
- if ((priv->first_lookup)) {
- gf_log (this->name, GF_LOG_INFO, "added root inode");
- priv->root_inode = inode_ref (inode);
- priv->first_lookup = 0;
- }
-out:
- return;
-}
+ if (local->op_errno == ESTALE) {
+ local->op_ret = -1;
+ }
-static void
-afr_lookup_cache_args (afr_local_t *local, int child_index, dict_t *xattr,
- struct iatt *buf, struct iatt *postparent)
-{
- GF_ASSERT (child_index >= 0);
- local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
- local->cont.lookup.postparents[child_index] = *postparent;
- local->cont.lookup.bufs[child_index] = *buf;
-}
+ goto unlock;
+ }
-static void
-afr_lookup_handle_first_success (afr_local_t *local, xlator_t *this,
- inode_t *inode, struct iatt *buf)
-{
- local->cont.lookup.inode = inode_ref (inode);
- local->cont.lookup.buf = *buf;
- afr_set_root_inode_on_first_lookup (local, this, inode);
-}
+ afr_lookup_collect_xattr (local, this, child_index, xattr);
-static int32_t
-afr_discovery_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
-{
- int ret = 0;
- char *pathinfo = NULL;
- gf_boolean_t is_local = _gf_false;
- afr_private_t *priv = NULL;
- int32_t child_index = -1;
+ first_up_child = afr_first_up_child (priv);
- if (op_ret != 0) {
- goto out;
- }
+ if (child_index == first_up_child) {
+ local->cont.lookup.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ first_up_child);
+ }
- ret = dict_get_str (dict, GF_XATTR_PATHINFO_KEY, &pathinfo);
- if (ret != 0) {
- goto out;
- }
+ if (local->success_count == 0) {
+ if (local->op_errno != ESTALE)
+ local->op_ret = op_ret;
- ret = afr_local_pathinfo (pathinfo, &is_local);
- if (ret) {
- goto out;
- }
+ local->cont.lookup.inode = inode_ref (inode);
+ local->cont.lookup.xattr = dict_ref (xattr);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparent = *postparent;
- priv = this->private;
- /*
- * Note that one local subvolume will override another here. The only
- * way to avoid that would be to retain extra information about whether
- * the previous read_child is local, and it's just not worth it. Even
- * the slowest local subvolume is far preferable to a remote one.
- */
- if (is_local) {
- child_index = (int32_t)(long)cookie;
- gf_log (this->name, GF_LOG_INFO,
- "selecting local read_child %s",
- priv->children[child_index]->name);
- priv->read_child = child_index;
- }
+ if (priv->first_lookup && inode->ino == 1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "added root inode");
+ priv->root_inode = inode_ref (inode);
+ priv->first_lookup = 0;
+ }
-out:
- STACK_DESTROY(frame->root);
- return 0;
-}
+ *lookup_buf = *buf;
-static void
-afr_attempt_local_discovery (xlator_t *this, int32_t child_index)
-{
- call_frame_t *newframe = NULL;
- loc_t tmploc = {0,};
- afr_private_t *priv = this->private;
+ lookup_buf->ia_ino = afr_itransform (buf->ia_ino,
+ priv->child_count,
+ child_index);
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ child_index);
+ }
- newframe = create_frame(this,this->ctx->pool);
- if (!newframe) {
- return;
- }
+ } else {
+ afr_lookup_self_heal_check (this, local, buf, lookup_buf);
- tmploc.gfid[sizeof(tmploc.gfid)-1] = 1;
- STACK_WIND_COOKIE (newframe, afr_discovery_cbk,
- (void *)(long)child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->getxattr,
- &tmploc, GF_XATTR_PATHINFO_KEY, NULL);
-}
+ if (child_index == local->read_child_index) {
+ /*
+ lookup has succeeded on the read child.
+ So use its inode number
+ */
+ if (local->cont.lookup.xattr)
+ dict_unref (local->cont.lookup.xattr);
-static void
-afr_lookup_handle_success (afr_local_t *local, xlator_t *this, int32_t child_index,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- afr_private_t *priv = this->private;
+ local->cont.lookup.xattr = dict_ref (xattr);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparent = *postparent;
+
+ *lookup_buf = *buf;
+ }
- if (local->success_count == 0) {
- if (local->op_errno != ESTALE) {
- local->op_ret = op_ret;
- local->op_errno = 0;
}
- afr_lookup_handle_first_success (local, this, inode, buf);
+
+ local->success_count++;
}
- afr_lookup_update_lk_counts (local, this,
- child_index, xattr);
+unlock:
+ UNLOCK (&frame->lock);
- afr_lookup_cache_args (local, child_index, xattr,
- buf, postparent);
+ call_count = afr_frame_return (frame);
- if (local->do_discovery && (priv->read_child == (-1))) {
- afr_attempt_local_discovery(this,child_index);
+ if (call_count == 0) {
+ afr_lookup_done (frame, this, lookup_buf);
}
- local->cont.lookup.success_children[local->success_count] = child_index;
- local->success_count++;
+ return 0;
}
+
int
-afr_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+afr_revalidate_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ struct iatt * lookup_buf = NULL;
int call_count = -1;
int child_index = -1;
+ int first_up_child = -1;
- child_index = (long) cookie;
+ child_index = (long) cookie;
+ priv = this->private;
LOCK (&frame->lock);
{
local = frame->local;
+ lookup_buf = &local->cont.lookup.buf;
+
if (op_ret == -1) {
- afr_lookup_handle_error (local, op_ret, op_errno);
+ if (op_errno == ENOENT)
+ local->enoent_count++;
+
+ if (__error_more_important (local->op_errno, op_errno))
+ local->op_errno = op_errno;
+
+ if (local->op_errno == ESTALE) {
+ local->op_ret = -1;
+ }
+
goto unlock;
}
- afr_lookup_handle_success (local, this, child_index, op_ret,
- op_errno, inode, buf, xattr,
- postparent);
- }
-unlock:
- UNLOCK (&frame->lock);
+ afr_lookup_collect_xattr (local, this, child_index, xattr);
- call_count = afr_frame_return (frame);
- if (call_count == 0) {
- afr_lookup_done (frame, this);
- }
+ first_up_child = afr_first_up_child (priv);
- return 0;
-}
+ if (child_index == first_up_child) {
+ local->cont.lookup.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ first_up_child);
+ }
-int
-afr_lookup_cont_init (afr_local_t *local, unsigned int child_count)
-{
- int ret = -ENOMEM;
- struct iatt *iatts = NULL;
- int32_t *success_children = NULL;
- int32_t *sources = NULL;
- int32_t **pending_matrix = NULL;
-
- GF_ASSERT (local);
- local->cont.lookup.xattrs = GF_CALLOC (child_count,
- sizeof (*local->cont.lookup.xattr),
- gf_afr_mt_dict_t);
- if (NULL == local->cont.lookup.xattrs)
- goto out;
+ /* in case of revalidate, we need to send stat of the
+ * child whose stat was sent during the first lookup.
+ * (so that time stamp does not vary with revalidate.
+ * in case it is down, stat of the fist success will
+ * be replied */
- iatts = GF_CALLOC (child_count, sizeof (*iatts), gf_afr_mt_iatt);
- if (NULL == iatts)
- goto out;
- local->cont.lookup.postparents = iatts;
+ /* inode number should be preserved across revalidates */
- iatts = GF_CALLOC (child_count, sizeof (*iatts), gf_afr_mt_iatt);
- if (NULL == iatts)
- goto out;
- local->cont.lookup.bufs = iatts;
+ if (local->success_count == 0) {
+ if (local->op_errno != ESTALE)
+ local->op_ret = op_ret;
- success_children = afr_children_create (child_count);
- if (NULL == success_children)
- goto out;
- local->cont.lookup.success_children = success_children;
+ local->cont.lookup.inode = inode_ref (inode);
+ local->cont.lookup.xattr = dict_ref (xattr);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparent = *postparent;
- local->fresh_children = afr_children_create (child_count);
- if (NULL == local->fresh_children)
- goto out;
+ *lookup_buf = *buf;
- sources = GF_CALLOC (sizeof (*sources), child_count, gf_afr_mt_int32_t);
- if (NULL == sources)
- goto out;
- local->cont.lookup.sources = sources;
+ lookup_buf->ia_ino = afr_itransform (buf->ia_ino,
+ priv->child_count,
+ child_index);
- pending_matrix = afr_matrix_create (child_count, child_count);
- if (NULL == pending_matrix)
- goto out;
- local->cont.lookup.pending_matrix = pending_matrix;
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this,
+ local->cont.lookup.inode,
+ child_index);
+ }
- ret = 0;
-out:
- return ret;
+ } else {
+ afr_lookup_self_heal_check (this, local, buf, lookup_buf);
+
+ if (child_index == local->read_child_index) {
+
+ /*
+ lookup has succeeded on the read child.
+ So use its inode number
+ */
+
+ if (local->cont.lookup.xattr)
+ dict_unref (local->cont.lookup.xattr);
+
+ local->cont.lookup.xattr = dict_ref (xattr);
+ local->cont.lookup.xattrs[child_index] = dict_ref (xattr);
+ local->cont.lookup.postparent = *postparent;
+
+ *lookup_buf = *buf;
+ }
+
+ }
+
+ local->success_count++;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ afr_lookup_done (frame, this, lookup_buf);
+ }
+
+ return 0;
}
+
int
afr_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- void *gfid_req = NULL;
- int ret = -1;
- int i = 0;
- int call_count = 0;
- uint64_t ctx = 0;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ int ret = -1;
+ int i = 0;
+ fop_lookup_cbk_t callback = NULL;
+ int call_count = 0;
+ uint64_t ctx = 0;
+ int32_t op_errno = 0;
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (local, out);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
local->op_ret = -1;
frame->local = local;
- local->fop = GF_FOP_LOOKUP;
- loc_copy (&local->loc, loc);
- ret = loc_path (&local->loc, NULL);
- if (ret < 0) {
- op_errno = EINVAL;
+ if (!strcmp (loc->path, "/" GF_REPLICATE_TRASH_DIR)) {
+ op_errno = ENOENT;
goto out;
}
- ret = inode_ctx_get (local->loc.inode, this, &ctx);
+ loc_copy (&local->loc, loc);
+
+ ret = inode_ctx_get (loc->inode, this, &ctx);
if (ret == 0) {
/* lookup is a revalidate */
- local->read_child_index = afr_inode_get_read_ctx (this,
- local->loc.inode,
- NULL);
+ callback = afr_revalidate_lookup_cbk;
+
+ local->cont.lookup.is_revalidate = _gf_true;
+ local->read_child_index = afr_read_child (this,
+ loc->inode);
} else {
+ callback = afr_fresh_lookup_cbk;
+
LOCK (&priv->read_child_lock);
{
- if (priv->hash_mode) {
- local->read_child_index = -1;
- }
- else {
- local->read_child_index =
- (++priv->read_child_rr) %
- (priv->child_count);
- }
+ local->read_child_index = (++priv->read_child_rr)
+ % (priv->child_count);
}
UNLOCK (&priv->read_child_lock);
- local->cont.lookup.fresh_lookup = _gf_true;
}
- local->child_up = memdup (priv->child_up,
- sizeof (*local->child_up) * priv->child_count);
- if (NULL == local->child_up) {
- op_errno = ENOMEM;
- goto out;
- }
+ if (loc->parent)
+ local->cont.lookup.parent_ino = loc->parent->ino;
- ret = afr_lookup_cont_init (local, priv->child_count);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
+ local->child_up = memdup (priv->child_up, priv->child_count);
- local->call_count = afr_up_children_count (local->child_up,
- priv->child_count);
+ local->cont.lookup.xattrs = GF_CALLOC (priv->child_count,
+ sizeof (*local->cont.lookup.xattr),
+ gf_afr_mt_dict_t);
+
+ local->call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
call_count = local->call_count;
+
if (local->call_count == 0) {
ret = -1;
op_errno = ENOTCONN;
@@ -2306,28 +1075,41 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
/* By default assume ENOTCONN. On success it will be set to 0. */
local->op_errno = ENOTCONN;
- ret = afr_lookup_xattr_req_prepare (local, this, xattr_req, &local->loc,
- &gfid_req);
- if (ret) {
- local->op_errno = -ret;
- goto out;
+ if (xattr_req == NULL)
+ local->xattr_req = dict_new ();
+ else
+ local->xattr_req = dict_ref (xattr_req);
+
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_uint64 (local->xattr_req, priv->pending_key[i],
+ 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, priv->pending_key[i]);
+ /* 3 = data+metadata+entry */
}
- afr_lookup_save_gfid (local->cont.lookup.gfid_req, gfid_req,
- &local->loc);
- local->fop = GF_FOP_LOOKUP;
- if (priv->choose_local && !priv->did_discovery) {
- if (gfid_req && __is_root_gfid(gfid_req)) {
- local->do_discovery = _gf_true;
- priv->did_discovery = _gf_true;
- }
+
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_INODELK_COUNT, 0);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, GLUSTERFS_INODELK_COUNT);
+ }
+
+ ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value for %s",
+ loc->path, GLUSTERFS_ENTRYLK_COUNT);
}
+
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_lookup_cbk,
- (void *) (long) i,
+ STACK_WIND_COOKIE (frame, callback, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->lookup,
- &local->loc, local->xattr_req);
+ loc, local->xattr_req);
if (!--call_count)
break;
}
@@ -2335,7 +1117,7 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
ret = 0;
out:
- if (ret)
+ if (ret == -1)
AFR_STACK_UNWIND (lookup, frame, -1, op_errno,
NULL, NULL, NULL, NULL);
@@ -2346,7 +1128,7 @@ out:
/* {{{ open */
int
-__afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+afr_fd_ctx_set (xlator_t *this, fd_t *fd)
{
afr_private_t * priv = NULL;
int ret = -1;
@@ -2358,93 +1140,65 @@ __afr_fd_ctx_set (xlator_t *this, fd_t *fd)
priv = this->private;
- ret = __fd_ctx_get (fd, this, &ctx);
-
- if (ret == 0)
- goto out;
-
- fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
- gf_afr_mt_afr_fd_ctx_t);
- if (!fd_ctx) {
- ret = -ENOMEM;
- goto out;
- }
-
- fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_done) {
- ret = -ENOMEM;
- goto out;
- }
-
- fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_piggyback) {
- ret = -ENOMEM;
- goto out;
- }
-
- fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
- priv->child_count,
- gf_afr_mt_int32_t);
- if (!fd_ctx->opened_on) {
- ret = -ENOMEM;
- goto out;
- }
+ LOCK (&fd->lock);
+ {
+ ret = __fd_ctx_get (fd, this, &ctx);
- fd_ctx->lock_piggyback = GF_CALLOC (sizeof (*fd_ctx->lock_piggyback),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->lock_piggyback) {
- ret = -ENOMEM;
- goto out;
- }
+ if (ret == 0)
+ goto unlock;
- fd_ctx->lock_acquired = GF_CALLOC (sizeof (*fd_ctx->lock_acquired),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->lock_acquired) {
- ret = -ENOMEM;
- goto out;
- }
+ fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
+ gf_afr_mt_afr_fd_ctx_t);
+ if (!fd_ctx) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- fd_ctx->up_count = priv->up_count;
- fd_ctx->down_count = priv->down_count;
+ fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_done) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->locked_on) {
- ret = -ENOMEM;
- goto out;
- }
+ fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_piggyback) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- pthread_mutex_init (&fd_ctx->delay_lock, NULL);
- INIT_LIST_HEAD (&fd_ctx->paused_calls);
- INIT_LIST_HEAD (&fd_ctx->entries);
+ fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->opened_on) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
- ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set fd ctx (%p)", fd);
-out:
- return ret;
-}
+ fd_ctx->up_count = priv->up_count;
+ fd_ctx->down_count = priv->down_count;
+ fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->locked_on) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
-int
-afr_fd_ctx_set (xlator_t *this, fd_t *fd)
-{
- int ret = -1;
+ ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set fd ctx (%p)", fd);
- LOCK (&fd->lock);
- {
- ret = __afr_fd_ctx_set (this, fd);
+ INIT_LIST_HEAD (&fd_ctx->entries);
}
+unlock:
UNLOCK (&fd->lock);
-
+out:
return ret;
}
@@ -2468,8 +1222,7 @@ afr_flush_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
AFR_STACK_UNWIND (flush, main_frame,
- local->op_ret, local->op_errno,
- NULL);
+ local->op_ret, local->op_errno);
}
return 0;
@@ -2478,7 +1231,7 @@ afr_flush_unwind (call_frame_t *frame, xlator_t *this)
int
afr_flush_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -2533,7 +1286,7 @@ afr_flush_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (local->child_up, priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -2548,7 +1301,7 @@ afr_flush_wind (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->flush,
- local->fd, NULL);
+ local->fd);
if (!--call_count)
break;
@@ -2575,13 +1328,15 @@ afr_flush_done (call_frame_t *frame, xlator_t *this)
int
-afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
+ int ret = -1;
+ int op_ret = -1;
+ int op_errno = 0;
+ int call_count = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -2589,18 +1344,23 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
priv = this->private;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ transaction_frame->local = local;
local->op = GF_FOP_FLUSH;
@@ -2614,21 +1374,16 @@ afr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
local->transaction.start = 0;
local->transaction.len = 0;
- ret = afr_open_fd_fix (transaction_frame, this, _gf_false);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ AFR_STACK_UNWIND (flush, frame, op_ret, op_errno);
}
return 0;
@@ -2643,8 +1398,6 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
uint64_t ctx = 0;
afr_fd_ctx_t *fd_ctx = NULL;
int ret = 0;
- afr_fd_paused_call_t *paused_call = NULL;
- afr_fd_paused_call_t *tmp = NULL;
ret = fd_ctx_get (fd, this, &ctx);
if (ret < 0)
@@ -2653,24 +1406,17 @@ afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd)
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
if (fd_ctx) {
- GF_FREE (fd_ctx->pre_op_done);
-
- GF_FREE (fd_ctx->opened_on);
-
- GF_FREE (fd_ctx->locked_on);
+ if (fd_ctx->pre_op_done)
+ GF_FREE (fd_ctx->pre_op_done);
- GF_FREE (fd_ctx->pre_op_piggyback);
- list_for_each_entry_safe (paused_call, tmp, &fd_ctx->paused_calls,
- call_list) {
- list_del_init (&paused_call->call_list);
- GF_FREE (paused_call);
- }
-
- GF_FREE (fd_ctx->lock_piggyback);
+ if (fd_ctx->opened_on)
+ GF_FREE (fd_ctx->opened_on);
- GF_FREE (fd_ctx->lock_acquired);
+ if (fd_ctx->locked_on)
+ GF_FREE (fd_ctx->locked_on);
- pthread_mutex_destroy (&fd_ctx->delay_lock);
+ if (fd_ctx->pre_op_piggyback)
+ GF_FREE (fd_ctx->pre_op_piggyback);
GF_FREE (fd_ctx);
}
@@ -2710,7 +1456,7 @@ afr_release (xlator_t *this, fd_t *fd)
int
afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -2719,7 +1465,7 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- read_child = afr_inode_get_read_ctx (this, local->fd->inode, NULL);
+ read_child = afr_read_child (this, local->fd->inode);
LOCK (&frame->lock);
{
@@ -2750,10 +1496,12 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ local->cont.fsync.prebuf.ia_ino = local->cont.fsync.ino;
+ local->cont.fsync.postbuf.ia_ino = local->cont.fsync.ino;
+
AFR_STACK_UNWIND (fsync, frame, local->op_ret, local->op_errno,
&local->cont.fsync.prebuf,
- &local->cont.fsync.postbuf,
- NULL);
+ &local->cont.fsync.postbuf);
}
return 0;
@@ -2762,13 +1510,14 @@ afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync, dict_t *xdata)
+ int32_t datasync)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -2777,16 +1526,19 @@ afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
local->fd = fd_ref (fd);
+ local->cont.fsync.ino = fd->inode->ino;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
@@ -2794,16 +1546,17 @@ afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->fsync,
- fd, datasync, xdata);
+ fd, datasync);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL);
+ }
return 0;
}
@@ -2813,8 +1566,7 @@ out:
int32_t
afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -2834,7 +1586,7 @@ afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno, xdata);
+ local->op_errno);
return 0;
}
@@ -2842,13 +1594,14 @@ afr_fsyncdir_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync, dict_t *xdata)
+ int32_t datasync)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -2857,30 +1610,33 @@ afr_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fsyncdir_cbk,
priv->children[i],
priv->children[i]->fops->fsyncdir,
- fd, datasync, xdata);
+ fd, datasync);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fsyncdir, frame, op_ret, op_errno);
+ }
return 0;
}
@@ -2891,7 +1647,7 @@ out:
int32_t
afr_xattrop_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata)
+ dict_t *xattr)
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -2900,11 +1656,8 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
LOCK (&frame->lock);
{
- if (op_ret == 0) {
- if (!local->cont.xattrop.xattr)
- local->cont.xattrop.xattr = dict_ref (xattr);
+ if (op_ret == 0)
local->op_ret = 0;
- }
local->op_errno = op_errno;
}
@@ -2914,7 +1667,7 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (xattrop, frame, local->op_ret, local->op_errno,
- local->cont.xattrop.xattr, xdata);
+ xattr);
return 0;
}
@@ -2922,13 +1675,14 @@ afr_xattrop_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -2937,30 +1691,33 @@ afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_xattrop_cbk,
priv->children[i],
priv->children[i]->fops->xattrop,
- loc, optype, xattr, xdata);
+ loc, optype, xattr);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (xattrop, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -2971,7 +1728,7 @@ out:
int32_t
afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata)
+ dict_t *xattr)
{
afr_local_t *local = NULL;
@@ -2981,12 +1738,8 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
LOCK (&frame->lock);
{
- if (op_ret == 0) {
- if (!local->cont.fxattrop.xattr)
- local->cont.fxattrop.xattr = dict_ref (xattr);
-
+ if (op_ret == 0)
local->op_ret = 0;
- }
local->op_errno = op_errno;
}
@@ -2996,7 +1749,7 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fxattrop, frame, local->op_ret, local->op_errno,
- local->cont.fxattrop.xattr, xdata);
+ xattr);
return 0;
}
@@ -3004,13 +1757,14 @@ afr_fxattrop_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -3019,30 +1773,33 @@ afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fxattrop_cbk,
priv->children[i],
priv->children[i]->fops->fxattrop,
- fd, optype, xattr, xdata);
+ fd, optype, xattr);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -3051,7 +1808,7 @@ out:
int32_t
afr_inodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
@@ -3072,7 +1829,7 @@ afr_inodelk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (inodelk, frame, local->op_ret,
- local->op_errno, xdata);
+ local->op_errno);
return 0;
}
@@ -3080,14 +1837,14 @@ afr_inodelk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock, dict_t *xdata)
+ const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -3096,39 +1853,41 @@ afr_inodelk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_inodelk_cbk,
priv->children[i],
priv->children[i]->fops->inodelk,
- volume, loc, cmd, flock, xdata);
+ volume, loc, cmd, flock);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (inodelk, frame, op_ret, op_errno);
+ }
return 0;
}
int32_t
afr_finodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
@@ -3149,7 +1908,7 @@ afr_finodelk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (finodelk, frame, local->op_ret,
- local->op_errno, xdata);
+ local->op_errno);
return 0;
}
@@ -3157,14 +1916,14 @@ afr_finodelk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock,
- dict_t *xdata)
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -3173,38 +1932,42 @@ afr_finodelk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_finodelk_cbk,
priv->children[i],
priv->children[i]->fops->finodelk,
- volume, fd, cmd, flock, xdata);
+ volume, fd, cmd, flock);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
+ }
return 0;
}
int32_t
-afr_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+afr_entrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
afr_local_t *local = NULL;
int call_count = -1;
@@ -3224,7 +1987,7 @@ afr_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (call_count == 0)
AFR_STACK_UNWIND (entrylk, frame, local->op_ret,
- local->op_errno, xdata);
+ local->op_errno);
return 0;
}
@@ -3233,14 +1996,14 @@ afr_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
afr_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc,
- const char *basename, entrylk_cmd cmd, entrylk_type type,
- dict_t *xdata)
+ const char *basename, entrylk_cmd cmd, entrylk_type type)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -3249,31 +2012,34 @@ afr_entrylk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_entrylk_cbk,
priv->children[i],
priv->children[i]->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
+ volume, loc, basename, cmd, type);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
+ }
return 0;
}
@@ -3281,7 +2047,7 @@ out:
int32_t
afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
@@ -3302,7 +2068,7 @@ afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (fentrylk, frame, local->op_ret,
- local->op_errno, xdata);
+ local->op_errno);
return 0;
}
@@ -3311,14 +2077,14 @@ afr_fentrylk_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd,
- const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
+ const char *basename, entrylk_cmd cmd, entrylk_type type)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int ret = -1;
int i = 0;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -3327,38 +2093,41 @@ afr_fentrylk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
call_count = local->call_count;
+ frame->local = local;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND (frame, afr_fentrylk_cbk,
priv->children[i],
priv->children[i]->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
+ volume, fd, basename, cmd, type);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
+ }
return 0;
}
int32_t
afr_statfs_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct statvfs *statvfs, dict_t *xdata)
+ struct statvfs *statvfs)
{
afr_local_t *local = NULL;
int call_count = 0;
@@ -3389,7 +2158,7 @@ afr_statfs_cbk (call_frame_t *frame, void *cookie,
if (call_count == 0)
AFR_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
- &local->cont.statfs.buf, xdata);
+ &local->cont.statfs.buf);
return 0;
}
@@ -3397,7 +2166,7 @@ afr_statfs_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_statfs (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc)
{
afr_private_t * priv = NULL;
int child_count = 0;
@@ -3405,6 +2174,7 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
int i = 0;
int ret = -1;
int call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (this, out);
@@ -3414,13 +2184,15 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
priv = this->private;
child_count = priv->child_count;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+ frame->local = local;
call_count = local->call_count;
for (i = 0; i < child_count; i++) {
@@ -3428,24 +2200,24 @@ afr_statfs (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, afr_statfs_cbk,
priv->children[i],
priv->children[i]->fops->statfs,
- loc, xdata);
+ loc);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (statfs, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
int32_t
afr_lk_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
afr_local_t * local = NULL;
int call_count = -1;
@@ -3455,7 +2227,7 @@ afr_lk_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (call_count == 0)
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- lock, xdata);
+ lock);
return 0;
}
@@ -3477,7 +2249,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
if (call_count == 0) {
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock, NULL);
+ &local->cont.lk.ret_flock);
return 0;
}
@@ -3491,7 +2263,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->lk,
local->fd, F_SETLK,
- &local->cont.lk.user_flock, NULL);
+ &local->cont.lk.user_flock);
if (!--call_count)
break;
@@ -3504,7 +2276,7 @@ afr_lk_unlock (call_frame_t *frame, xlator_t *this)
int32_t
afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -3539,12 +2311,12 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv->children[child_index],
priv->children[child_index]->fops->lk,
local->fd, local->cont.lk.cmd,
- &local->cont.lk.user_flock, xdata);
+ &local->cont.lk.user_flock);
} else if (local->op_ret == -1) {
/* all nodes have gone down */
AFR_STACK_UNWIND (lk, frame, -1, ENOTCONN,
- &local->cont.lk.ret_flock, NULL);
+ &local->cont.lk.ret_flock);
} else {
/* locking has succeeded on all nodes that are up */
@@ -3562,7 +2334,7 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
AFR_STACK_UNWIND (lk, frame, local->op_ret, local->op_errno,
- &local->cont.lk.ret_flock, NULL);
+ &local->cont.lk.ret_flock);
}
return 0;
@@ -3571,13 +2343,13 @@ afr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int i = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
- int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -3585,12 +2357,10 @@ afr_lk (call_frame_t *frame, xlator_t *this,
priv = this->private;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ AFR_LOCAL_INIT (local, priv);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ frame->local = local;
local->cont.lk.locked_nodes = GF_CALLOC (priv->child_count,
sizeof (*local->cont.lk.locked_nodes),
@@ -3609,30 +2379,13 @@ afr_lk (call_frame_t *frame, xlator_t *this,
STACK_WIND_COOKIE (frame, afr_lk_cbk, (void *) (long) 0,
priv->children[i],
priv->children[i]->fops->lk,
- fd, cmd, flock, xdata);
+ fd, cmd, flock);
- ret = 0;
-out:
- if (ret < 0)
- AFR_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int
-afr_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t ctx_addr = 0;
- afr_inode_ctx_t *ctx = NULL;
-
- inode_ctx_get (inode, this, &ctx_addr);
-
- if (!ctx_addr)
- goto out;
-
- ctx = (afr_inode_ctx_t *)(long)ctx_addr;
- GF_FREE (ctx->fresh_children);
- GF_FREE (ctx);
+ op_ret = 0;
out:
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (lk, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -3651,23 +2404,41 @@ afr_priv_dump (xlator_t *this)
GF_ASSERT (priv);
snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name);
gf_proc_dump_add_section(key_prefix);
- gf_proc_dump_write("child_count", "%u", priv->child_count);
- gf_proc_dump_write("read_child_rr", "%u", priv->read_child_rr);
+ gf_proc_dump_build_key(key, key_prefix, "child_count");
+ gf_proc_dump_write(key, "%u", priv->child_count);
+ gf_proc_dump_build_key(key, key_prefix, "read_child_rr");
+ gf_proc_dump_write(key, "%u", priv->read_child_rr);
for (i = 0; i < priv->child_count; i++) {
- sprintf (key, "child_up[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix, "child_up[%d]", i);
gf_proc_dump_write(key, "%d", priv->child_up[i]);
- sprintf (key, "pending_key[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix,
+ "pending_key[%d]", i);
gf_proc_dump_write(key, "%s", priv->pending_key[i]);
}
- gf_proc_dump_write("data_self_heal", "%s", priv->data_self_heal);
- gf_proc_dump_write("metadata_self_heal", "%d", priv->metadata_self_heal);
- gf_proc_dump_write("entry_self_heal", "%d", priv->entry_self_heal);
- gf_proc_dump_write("data_change_log", "%d", priv->data_change_log);
- gf_proc_dump_write("metadata_change_log", "%d", priv->metadata_change_log);
- gf_proc_dump_write("entry-change_log", "%d", priv->entry_change_log);
- gf_proc_dump_write("read_child", "%d", priv->read_child);
- gf_proc_dump_write("favorite_child", "%d", priv->favorite_child);
- gf_proc_dump_write("wait_count", "%u", priv->wait_count);
+ gf_proc_dump_build_key(key, key_prefix, "data_self_heal");
+ gf_proc_dump_write(key, "%d", priv->data_self_heal);
+ gf_proc_dump_build_key(key, key_prefix, "metadata_self_heal");
+ gf_proc_dump_write(key, "%d", priv->metadata_self_heal);
+ gf_proc_dump_build_key(key, key_prefix, "entry_self_heal");
+ gf_proc_dump_write(key, "%d", priv->entry_self_heal);
+ gf_proc_dump_build_key(key, key_prefix, "data_change_log");
+ gf_proc_dump_write(key, "%d", priv->data_change_log);
+ gf_proc_dump_build_key(key, key_prefix, "metadata_change_log");
+ gf_proc_dump_write(key, "%d", priv->metadata_change_log);
+ gf_proc_dump_build_key(key, key_prefix, "entry_change_log");
+ gf_proc_dump_write(key, "%d", priv->entry_change_log);
+ gf_proc_dump_build_key(key, key_prefix, "read_child");
+ gf_proc_dump_write(key, "%d", priv->read_child);
+ gf_proc_dump_build_key(key, key_prefix, "favorite_child");
+ gf_proc_dump_write(key, "%u", priv->favorite_child);
+ gf_proc_dump_build_key(key, key_prefix, "data_lock_server_count");
+ gf_proc_dump_write(key, "%u", priv->data_lock_server_count);
+ gf_proc_dump_build_key(key, key_prefix, "metadata_lock_server_count");
+ gf_proc_dump_write(key, "%u", priv->metadata_lock_server_count);
+ gf_proc_dump_build_key(key, key_prefix, "entry_lock_server_count");
+ gf_proc_dump_write(key, "%u", priv->entry_lock_server_count);
+ gf_proc_dump_build_key(key, key_prefix, "wait_count");
+ gf_proc_dump_write(key, "%u", priv->wait_count);
return 0;
}
@@ -3697,599 +2468,94 @@ find_child_index (xlator_t *this, xlator_t *child)
int32_t
afr_notify (xlator_t *this, int32_t event,
- void *data, void *data2)
+ void *data, ...)
{
- afr_private_t *priv = NULL;
- int i = -1;
- int up_children = 0;
- int down_children = 0;
- int propagate = 0;
- int had_heard_from_all = 0;
- int have_heard_from_all = 0;
- int idx = -1;
- int ret = -1;
- int call_psh = 0;
- int up_child = AFR_ALL_CHILDREN;
- dict_t *input = NULL;
- dict_t *output = NULL;
+ afr_private_t * priv = NULL;
+ unsigned char * child_up = NULL;
+ int i = -1;
+ int up_children = 0;
+ int down_children = 0;
priv = this->private;
if (!priv)
return 0;
- /*
- * We need to reset this in case children come up in "staggered"
- * fashion, so that we discover a late-arriving local subvolume. Note
- * that we could end up issuing N lookups to the first subvolume, and
- * O(N^2) overall, but N is small for AFR so it shouldn't be an issue.
- */
- priv->did_discovery = _gf_false;
-
- had_heard_from_all = 1;
- for (i = 0; i < priv->child_count; i++) {
- if (!priv->last_event[i]) {
- had_heard_from_all = 0;
- }
- }
-
- /* parent xlators dont need to know about every child_up, child_down
- * because of afr ha. If all subvolumes go down, child_down has
- * to be triggered. In that state when 1 subvolume comes up child_up
- * needs to be triggered. dht optimizes revalidate lookup by sending
- * it only to one of its subvolumes. When child up/down happens
- * for afr's subvolumes dht should be notified by child_modified. The
- * subsequent revalidate lookup happens on all the dht's subvolumes
- * which triggers afr self-heals if any.
- */
- idx = find_child_index (this, data);
- if (idx < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Received child_up "
- "from invalid subvolume");
- goto out;
- }
+ child_up = priv->child_up;
switch (event) {
case GF_EVENT_CHILD_UP:
- LOCK (&priv->lock);
- {
- /*
- * This only really counts if the child was never up
- * (value = -1) or had been down (value = 0). See
- * comment at GF_EVENT_CHILD_DOWN for a more detailed
- * explanation.
- */
- if (priv->child_up[idx] != 1) {
- priv->up_count++;
- }
- priv->child_up[idx] = 1;
-
- call_psh = 1;
- up_child = idx;
- for (i = 0; i < priv->child_count; i++)
- if (priv->child_up[i] == 1)
- up_children++;
- if (up_children == 1) {
- gf_log (this->name, GF_LOG_INFO,
- "Subvolume '%s' came back up; "
- "going online.", ((xlator_t *)data)->name);
- } else {
- event = GF_EVENT_CHILD_MODIFIED;
- }
+ i = find_child_index (this, data);
- priv->last_event[idx] = event;
- }
- UNLOCK (&priv->lock);
+ /* temporarily
+ afr_attempt_lock_recovery (this, i);
+ */
- break;
+ child_up[i] = 1;
- case GF_EVENT_CHILD_DOWN:
LOCK (&priv->lock);
{
- /*
- * If a brick is down when we start, we'll get a
- * CHILD_DOWN to indicate its initial state. There
- * was never a CHILD_UP in this case, so if we
- * increment "down_count" the difference between than
- * and "up_count" will no longer be the number of
- * children that are currently up. This has serious
- * implications e.g. for quorum enforcement, so we
- * don't increment these values unless the event
- * represents an actual state transition between "up"
- * (value = 1) and anything else.
- */
- if (priv->child_up[idx] == 1) {
- priv->down_count++;
- }
- priv->child_up[idx] = 0;
-
- for (i = 0; i < priv->child_count; i++)
- if (priv->child_up[i] == 0)
- down_children++;
- if (down_children == priv->child_count) {
- gf_log (this->name, GF_LOG_ERROR,
- "All subvolumes are down. Going offline "
- "until atleast one of them comes back up.");
- } else {
- event = GF_EVENT_CHILD_MODIFIED;
- }
-
- priv->last_event[idx] = event;
+ priv->up_count++;
}
UNLOCK (&priv->lock);
- break;
+ /*
+ if all the children were down, and one child came up,
+ send notify to parent
+ */
- case GF_EVENT_CHILD_CONNECTING:
- LOCK (&priv->lock);
- {
- priv->last_event[idx] = event;
- }
- UNLOCK (&priv->lock);
+ for (i = 0; i < priv->child_count; i++)
+ if (child_up[i] == 1)
+ up_children++;
- break;
+ if (up_children == 1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "Subvolume '%s' came back up; "
+ "going online.", ((xlator_t *)data)->name);
- case GF_EVENT_TRANSLATOR_OP:
- input = data;
- output = data2;
- ret = afr_xl_op (this, input, output);
- goto out;
- break;
+ default_notify (this, event, data);
+ } else {
+ default_notify (this, GF_EVENT_CHILD_MODIFIED, data);
+ }
- default:
- propagate = 1;
break;
- }
- /* have all subvolumes reported status once by now? */
- have_heard_from_all = 1;
- for (i = 0; i < priv->child_count; i++) {
- if (!priv->last_event[i])
- have_heard_from_all = 0;
- }
-
- /* if all subvols have reported status, no need to hide anything
- or wait for anything else. Just propagate blindly */
- if (have_heard_from_all)
- propagate = 1;
+ case GF_EVENT_CHILD_DOWN:
+ i = find_child_index (this, data);
- if (!had_heard_from_all && have_heard_from_all) {
- /* This is the first event which completes aggregation
- of events from all subvolumes. If at least one subvol
- had come up, propagate CHILD_UP, but only this time
- */
- event = GF_EVENT_CHILD_DOWN;
+ child_up[i] = 0;
LOCK (&priv->lock);
{
- up_children = afr_up_children_count (priv->child_up,
- priv->child_count);
- for (i = 0; i < priv->child_count; i++) {
- if (priv->last_event[i] == GF_EVENT_CHILD_UP) {
- event = GF_EVENT_CHILD_UP;
- break;
- }
-
- if (priv->last_event[i] ==
- GF_EVENT_CHILD_CONNECTING) {
- event = GF_EVENT_CHILD_CONNECTING;
- /* continue to check other events for CHILD_UP */
- }
- }
+ priv->down_count++;
}
UNLOCK (&priv->lock);
- }
-
- ret = 0;
- if (propagate)
- ret = default_notify (this, event, data);
- if (call_psh && priv->shd.iamshd)
- afr_proactive_self_heal ((void*) (long) up_child);
-
-out:
- return ret;
-}
-
-int
-afr_first_up_child (unsigned char *child_up, size_t child_count)
-{
- int ret = -1;
- int i = 0;
-
- GF_ASSERT (child_up);
-
- for (i = 0; i < child_count; i++) {
- if (child_up[i]) {
- ret = i;
- break;
- }
- }
-
- return ret;
-}
-
-int
-afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno)
-{
- int ret = -1;
-
- local->op_ret = -1;
- local->op_errno = EUCLEAN;
-
- local->child_up = GF_CALLOC (priv->child_count,
- sizeof (*local->child_up),
- gf_afr_mt_char);
- if (!local->child_up) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
-
- memcpy (local->child_up, priv->child_up,
- sizeof (*local->child_up) * priv->child_count);
- local->call_count = afr_up_children_count (local->child_up,
- priv->child_count);
- if (local->call_count == 0) {
- gf_log (THIS->name, GF_LOG_INFO, "no subvolumes up");
- if (op_errno)
- *op_errno = ENOTCONN;
- goto out;
- }
-
- local->child_errno = GF_CALLOC (priv->child_count,
- sizeof (*local->child_errno),
- gf_afr_mt_int32_t);
- if (!local->child_errno) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-afr_internal_lock_init (afr_internal_lock_t *lk, size_t child_count,
- transaction_lk_type_t lk_type)
-{
- int ret = -ENOMEM;
-
- lk->inode_locked_nodes = GF_CALLOC (sizeof (*lk->inode_locked_nodes),
- child_count, gf_afr_mt_char);
- if (NULL == lk->inode_locked_nodes)
- goto out;
-
- lk->entry_locked_nodes = GF_CALLOC (sizeof (*lk->entry_locked_nodes),
- child_count, gf_afr_mt_char);
- if (NULL == lk->entry_locked_nodes)
- goto out;
-
- lk->locked_nodes = GF_CALLOC (sizeof (*lk->locked_nodes),
- child_count, gf_afr_mt_char);
- if (NULL == lk->locked_nodes)
- goto out;
-
- lk->lower_locked_nodes = GF_CALLOC (sizeof (*lk->lower_locked_nodes),
- child_count, gf_afr_mt_char);
- if (NULL == lk->lower_locked_nodes)
- goto out;
-
- lk->lock_op_ret = -1;
- lk->lock_op_errno = EUCLEAN;
- lk->transaction_lk_type = lk_type;
-
- ret = 0;
-out:
- return ret;
-}
-
-void
-afr_matrix_cleanup (int32_t **matrix, unsigned int m)
-{
- int i = 0;
-
- if (!matrix)
- goto out;
- for (i = 0; i < m; i++) {
- GF_FREE (matrix[i]);
- }
-
- GF_FREE (matrix);
-out:
- return;
-}
-
-int32_t**
-afr_matrix_create (unsigned int m, unsigned int n)
-{
- int32_t **matrix = NULL;
- int i = 0;
-
- matrix = GF_CALLOC (sizeof (*matrix), m, gf_afr_mt_int32_t);
- if (!matrix)
- goto out;
-
- for (i = 0; i < m; i++) {
- matrix[i] = GF_CALLOC (sizeof (*matrix[i]), n,
- gf_afr_mt_int32_t);
- if (!matrix[i])
- goto out;
- }
- return matrix;
-out:
- afr_matrix_cleanup (matrix, m);
- return NULL;
-}
-
-int
-afr_transaction_local_init (afr_local_t *local, xlator_t *this)
-{
- int child_up_count = 0;
- int ret = -ENOMEM;
- afr_private_t *priv = NULL;
-
- priv = this->private;
- ret = afr_internal_lock_init (&local->internal_lock, priv->child_count,
- AFR_TRANSACTION_LK);
- if (ret < 0)
- goto out;
-
- ret = -ENOMEM;
- child_up_count = afr_up_children_count (local->child_up,
- priv->child_count);
- if (priv->optimistic_change_log && child_up_count == priv->child_count)
- local->optimistic_change_log = 1;
-
- local->first_up_child = afr_first_up_child (local->child_up,
- priv->child_count);
-
- local->transaction.eager_lock =
- GF_CALLOC (sizeof (*local->transaction.eager_lock),
- priv->child_count,
- gf_afr_mt_int32_t);
-
- if (!local->transaction.eager_lock)
- goto out;
-
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children)
- goto out;
-
- if (local->fd) {
- local->fd_open_on = GF_CALLOC (sizeof (*local->fd_open_on),
- priv->child_count,
- gf_afr_mt_char);
- if (!local->fd_open_on)
- goto out;
- }
-
- local->transaction.pre_op = GF_CALLOC (sizeof (*local->transaction.pre_op),
- priv->child_count,
- gf_afr_mt_char);
- if (!local->transaction.pre_op)
- goto out;
-
- local->pending = afr_matrix_create (priv->child_count,
- AFR_NUM_CHANGE_LOGS);
- if (!local->pending)
- goto out;
-
- local->transaction.txn_changelog = afr_matrix_create (priv->child_count,
- AFR_NUM_CHANGE_LOGS);
- if (!local->transaction.txn_changelog)
- goto out;
- ret = 0;
-out:
- return ret;
-}
-
-void
-afr_reset_children (int32_t *fresh_children, int32_t child_count)
-{
- unsigned int i = 0;
- for (i = 0; i < child_count; i++)
- fresh_children[i] = -1;
-}
-
-int32_t*
-afr_children_create (int32_t child_count)
-{
- int32_t *children = NULL;
- int i = 0;
-
- GF_ASSERT (child_count > 0);
-
- children = GF_CALLOC (child_count, sizeof (*children),
- gf_afr_mt_int32_t);
- if (NULL == children)
- goto out;
- for (i = 0; i < child_count; i++)
- children[i] = -1;
-out:
- return children;
-}
-
-void
-afr_children_add_child (int32_t *children, int32_t child,
- int32_t child_count)
-{
- gf_boolean_t child_found = _gf_false;
- int i = 0;
- for (i = 0; i < child_count; i++) {
- if (children[i] == -1)
- break;
- if (children[i] == child) {
- child_found = _gf_true;
- break;
- }
- }
-
- if (!child_found) {
- GF_ASSERT (i < child_count);
- children[i] = child;
- }
-}
-
-void
-afr_children_rm_child (int32_t *children, int32_t child, int32_t child_count)
-{
- int i = 0;
-
- GF_ASSERT ((child >= 0) && (child < child_count));
- for (i = 0; i < child_count; i++) {
- if (children[i] == -1)
- break;
- if (children[i] == child) {
- if (i != (child_count - 1))
- memmove (children + i, children + i + 1,
- sizeof (*children)*(child_count - i - 1));
- children[child_count - 1] = -1;
- break;
- }
- }
-}
-
-int
-afr_get_children_count (int32_t *children, unsigned int child_count)
-{
- int count = 0;
- int i = 0;
-
- for (i = 0; i < child_count; i++) {
- if (children[i] == -1)
- break;
- count++;
- }
- return count;
-}
-
-void
-afr_set_low_priority (call_frame_t *frame)
-{
- frame->root->pid = LOW_PRIO_PROC_PID;
-}
-
-int
-afr_child_fd_ctx_set (xlator_t *this, fd_t *fd, int32_t child,
- int flags)
-{
- int ret = 0;
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
-
- GF_ASSERT (fd && fd->inode);
- ret = afr_fd_ctx_set (this, fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not set fd ctx for fd=%p", fd);
- goto out;
- }
-
- ret = fd_ctx_get (fd, this, &ctx);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not get fd ctx for fd=%p", fd);
- goto out;
- }
-
- fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- fd_ctx->opened_on[child] = AFR_FD_OPENED;
- if (!IA_ISDIR (fd->inode->ia_type)) {
- fd_ctx->flags = flags;
- }
- ret = 0;
-out:
- return ret;
-}
-
-gf_boolean_t
-afr_have_quorum (char *logname, afr_private_t *priv)
-{
- unsigned int quorum = 0;
-
- GF_VALIDATE_OR_GOTO(logname,priv,out);
+ /*
+ if all children are down, and this was the last to go down,
+ send notify to parent
+ */
- quorum = priv->quorum_count;
- if (quorum != AFR_QUORUM_AUTO) {
- return (priv->up_count >= (priv->down_count + quorum));
- }
+ for (i = 0; i < priv->child_count; i++)
+ if (child_up[i] == 0)
+ down_children++;
- quorum = priv->child_count / 2 + 1;
- if (priv->up_count >= (priv->down_count + quorum)) {
- return _gf_true;
- }
+ if (down_children == priv->child_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "All subvolumes are down. Going offline "
+ "until atleast one of them comes back up.");
- /*
- * Special case for even numbers of nodes: if we have exactly half
- * and that includes the first ("senior-most") node, then that counts
- * as quorum even if it wouldn't otherwise. This supports e.g. N=2
- * while preserving the critical property that there can only be one
- * such group.
- */
- if ((priv->child_count % 2) == 0) {
- quorum = priv->child_count / 2;
- if (priv->up_count >= (priv->down_count + quorum)) {
- if (priv->child_up[0]) {
- return _gf_true;
- }
+ default_notify (this, event, data);
+ } else {
+ default_notify (this, GF_EVENT_CHILD_MODIFIED, data);
}
- }
-
-out:
- return _gf_false;
-}
-void
-afr_priv_destroy (afr_private_t *priv)
-{
- int i = 0;
+ break;
- if (!priv)
- goto out;
- inode_unref (priv->root_inode);
- GF_FREE (priv->shd.pos);
- GF_FREE (priv->shd.pending);
- GF_FREE (priv->shd.inprogress);
-// for (i = 0; i < priv->child_count; i++)
-// if (priv->shd.timer && priv->shd.timer[i])
-// gf_timer_call_cancel (this->ctx, priv->shd.timer[i]);
- GF_FREE (priv->shd.timer);
-
- if (priv->shd.healed)
- eh_destroy (priv->shd.healed);
-
- if (priv->shd.heal_failed)
- eh_destroy (priv->shd.heal_failed);
-
- if (priv->shd.split_brain)
- eh_destroy (priv->shd.split_brain);
-
- GF_FREE (priv->last_event);
- if (priv->pending_key) {
- for (i = 0; i < priv->child_count; i++)
- GF_FREE (priv->pending_key[i]);
+ default:
+ default_notify (this, event, data);
}
- GF_FREE (priv->pending_key);
- GF_FREE (priv->children);
- GF_FREE (priv->child_up);
- LOCK_DESTROY (&priv->lock);
- LOCK_DESTROY (&priv->read_child_lock);
- pthread_mutex_destroy (&priv->mutex);
- GF_FREE (priv);
-out:
- return;
-}
-int
-xlator_subvolume_count (xlator_t *this)
-{
- int i = 0;
- xlator_list_t *list = NULL;
+ return 0;
- for (list = this->children; list; list = list->next)
- i++;
- return i;
}
diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c
index ce91ffba7..b2a001a19 100644
--- a/xlators/cluster/afr/src/afr-dir-read.c
+++ b/xlators/cluster/afr/src/afr-dir-read.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -40,9 +49,9 @@
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
+
int
-afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this, int32_t op_ret,
- int32_t op_errno, int32_t sh_failed)
+afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
@@ -51,7 +60,7 @@ afr_examine_dir_sh_unwind (call_frame_t *frame, xlator_t *this, int32_t op_ret,
afr_set_opendir_done (this, local->fd->inode);
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
+ local->op_errno, local->fd);
return 0;
}
@@ -61,19 +70,15 @@ gf_boolean_t
__checksums_differ (uint32_t *checksum, int child_count,
unsigned char *child_up)
{
- int ret = _gf_false;
- int i = 0;
- uint32_t cksum = 0;
- gf_boolean_t activate_check = _gf_false;
+ int ret = _gf_false;
+ int i = 0;
+ uint32_t cksum = 0;
+
+ cksum = checksum[0];
for (i = 0; i < child_count; i++) {
if (!child_up[i])
continue;
- if (_gf_false == activate_check) {
- cksum = checksum[i];
- activate_check = _gf_true;
- continue;
- }
if (cksum != checksum[i]) {
ret = _gf_true;
@@ -90,24 +95,22 @@ __checksums_differ (uint32_t *checksum, int child_count,
int32_t
afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
+ gf_dirent_t *entries)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
afr_self_heal_t * sh = NULL;
gf_dirent_t * entry = NULL;
gf_dirent_t * tmp = NULL;
- char *reason = NULL;
int child_index = 0;
uint32_t entry_cksum = 0;
int call_count = 0;
off_t last_offset = 0;
- inode_t *inode = NULL;
+ char sh_type_str[256] = {0,};
priv = this->private;
local = frame->local;
sh = &local->self_heal;
- inode = local->fd->inode;
child_index = (long) cookie;
@@ -128,7 +131,7 @@ afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
}
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- entry_cksum = gf_rsync_weak_checksum ((unsigned char *)entry->d_name,
+ entry_cksum = gf_rsync_weak_checksum (entry->d_name,
strlen (entry->d_name));
local->cont.opendir.checksum[child_index] ^= entry_cksum;
}
@@ -143,7 +146,7 @@ afr_examine_dir_readdir_cbk (call_frame_t *frame, void *cookie,
(void *) (long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->readdir,
- local->fd, 131072, last_offset, NULL);
+ local->fd, 131072, last_offset);
return 0;
@@ -155,18 +158,27 @@ out:
priv->child_count,
local->child_up)) {
- sh->do_entry_self_heal = _gf_true;
+ sh->need_entry_self_heal = _gf_true;
sh->forced_merge = _gf_true;
+ sh->type = local->fd->inode->ia_type;
+ sh->background = _gf_false;
+ sh->unwind = afr_examine_dir_sh_unwind;
+
+ afr_self_heal_type_str_get(&local->self_heal,
+ sh_type_str,
+ sizeof(sh_type_str));
+ gf_log (this->name, GF_LOG_INFO,
+ "%s self-heal triggered. path: %s, "
+ "reason: checksums of directory differ,"
+ " forced merge option set",
+ sh_type_str, local->loc.path);
- reason = "checksums of directory differ";
- afr_launch_self_heal (frame, this, inode, _gf_false,
- inode->ia_type, reason, NULL,
- afr_examine_dir_sh_unwind);
+ afr_self_heal (frame, this);
} else {
- afr_set_opendir_done (this, inode);
+ afr_set_opendir_done (this, local->fd->inode);
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
+ local->op_errno, local->fd);
}
}
@@ -189,7 +201,7 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
sizeof (*local->cont.opendir.checksum),
gf_afr_mt_int32_t);
- call_count = afr_up_children_count (local->child_up, priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
local->call_count = call_count;
@@ -199,7 +211,7 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->readdir,
- local->fd, 131072, 0, NULL);
+ local->fd, 131072, 0);
if (!--call_count)
break;
@@ -213,37 +225,27 @@ afr_examine_dir (call_frame_t *frame, xlator_t *this)
int32_t
afr_opendir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
int32_t up_children_count = 0;
int ret = -1;
int call_count = -1;
- int32_t child_index = 0;
priv = this->private;
local = frame->local;
- child_index = (long) cookie;
- up_children_count = afr_up_children_count (local->child_up,
- priv->child_count);
+ up_children_count = afr_up_children_count (priv->child_count,
+ local->child_up);
LOCK (&frame->lock);
{
- if (op_ret >= 0) {
+ if (op_ret >= 0)
local->op_ret = op_ret;
- ret = afr_child_fd_ctx_set (this, fd, child_index, 0);
- if (ret) {
- local->op_ret = -1;
- local->op_errno = -ret;
- goto unlock;
- }
- }
local->op_errno = op_errno;
}
-unlock:
UNLOCK (&frame->lock);
call_count = afr_frame_return (frame);
@@ -252,6 +254,15 @@ unlock:
if (local->op_ret != 0)
goto out;
+ ret = afr_fd_ctx_set (this, local->fd);
+ if (ret) {
+ local->op_ret = -1;
+ local->op_errno = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to set fd ctx for fd %p",
+ local->fd);
+ goto out;
+ }
if (!afr_is_opendir_done (this, local->fd->inode) &&
up_children_count > 1) {
@@ -262,7 +273,7 @@ unlock:
* to regular entry self-heal because the readdir
* call is sent only to the first subvolume, and
* thus files that exist only there will never be healed
- * otherwise (assuming changelog shows no anomalies).
+ * otherwise (assuming changelog shows no anamolies).
*/
gf_log (this->name, GF_LOG_TRACE,
@@ -281,7 +292,7 @@ unlock:
out:
AFR_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
+ local->op_errno, local->fd);
return 0;
}
@@ -297,6 +308,7 @@ afr_opendir (call_frame_t *frame, xlator_t *this,
int i = 0;
int ret = -1;
int call_count = -1;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -307,36 +319,37 @@ afr_opendir (call_frame_t *frame, xlator_t *this,
child_count = priv->child_count;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
loc_copy (&local->loc, loc);
+ frame->local = local;
local->fd = fd_ref (fd);
call_count = local->call_count;
for (i = 0; i < child_count; i++) {
if (local->child_up[i]) {
- STACK_WIND_COOKIE (frame, afr_opendir_cbk,
- (void*) (long) i,
- priv->children[i],
- priv->children[i]->fops->opendir,
- loc, fd, NULL);
+ STACK_WIND (frame, afr_opendir_cbk,
+ priv->children[i],
+ priv->children[i]->fops->opendir,
+ loc, fd);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (opendir, frame, -1, op_errno, fd, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (opendir, frame, op_ret, op_errno, fd);
+ }
return 0;
}
@@ -466,9 +479,35 @@ afr_forget_entries (fd_t *fd)
int32_t
afr_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
+ gf_dirent_t *entries)
{
- AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries, NULL);
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ gf_dirent_t * entry = NULL;
+ gf_dirent_t * tmp = NULL;
+ int child_index = -1;
+
+ priv = this->private;
+ local = frame->local;
+ child_index = (long) cookie;
+
+ if (op_ret == -1)
+ goto out;
+
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ entry->d_ino = afr_itransform (entry->d_ino,
+ priv->child_count,
+ child_index);
+
+ if ((local->fd->inode == local->fd->inode->table->root)
+ && !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
+ list_del_init (&entry->list);
+ GF_FREE (entry);
+ }
+ }
+
+out:
+ AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries);
return 0;
}
@@ -476,39 +515,27 @@ afr_readdir_cbk (call_frame_t *frame, void *cookie,
int32_t
afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int32_t next_call_child = -1;
- int ret = 0;
- int32_t *last_index = NULL;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- off_t offset = 0;
- int32_t call_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ ino_t inum = 0;
+ int call_child = 0;
+ int ret = 0;
+ gf_dirent_t * entry = NULL;
+ gf_dirent_t * tmp = NULL;
+ int child_index = -1;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ off_t offset = 0;
priv = this->private;
children = priv->children;
local = frame->local;
- read_child = (long) cookie;
- last_index = &local->cont.readdir.last_index;
- fresh_children = local->fresh_children;
-
- /* the value of the last_index changes if afr_next_call_child is
- * called. So to find the call_child of this callback use last_index
- * before the next_call_child call.
- */
- if (*last_index == -1)
- call_child = read_child;
- else
- call_child = fresh_children[*last_index];
+ child_index = (long) cookie;
if (priv->strict_readdir) {
ret = fd_ctx_get (local->fd, this, &ctx);
@@ -522,31 +549,47 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- if (op_ret == -1) {
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index,
- read_child);
- if (next_call_child < 0)
+ if (child_went_down (op_ret, op_errno)) {
+ if (all_tried (child_index, priv->child_count)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "all options tried going out");
goto out;
+ }
+
+ call_child = ++child_index;
+
gf_log (this->name, GF_LOG_TRACE,
"starting readdir afresh on child %d, offset %"PRId64,
- next_call_child, (uint64_t) 0);
+ call_child, (uint64_t) 0);
fd_ctx->failed_over = _gf_true;
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
- (void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->readdirp,
- local->fd,
- local->cont.readdir.size, 0,
- local->cont.readdir.dict);
+ (void *) (long) call_child,
+ children[call_child],
+ children[call_child]->fops->readdirp, local->fd,
+ local->cont.readdir.size, 0);
return 0;
}
}
+ if (op_ret != -1) {
+ list_for_each_entry_safe (entry, tmp, &entries->list, list) {
+ inum = afr_itransform (entry->d_ino, priv->child_count,
+ child_index);
+ entry->d_ino = inum;
+ inum = afr_itransform (entry->d_stat.ia_ino,
+ priv->child_count, child_index);
+ entry->d_stat.ia_ino = inum;
+
+ if ((local->fd->inode == local->fd->inode->table->root)
+ && !strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)) {
+ list_del_init (&entry->list);
+ GF_FREE (entry);
+ }
+ }
+ }
+
if (priv->strict_readdir) {
if (fd_ctx->failed_over) {
if (list_empty (&entries->list)) {
@@ -562,20 +605,19 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (list_empty (&entries->list)) {
/* All the entries we got were duplicate. We
shouldn't send an empty list now, because
- that will make the application stop reading. So
+ that'll make the application stop reading. So
try to get more entries */
gf_log (this->name, GF_LOG_TRACE,
"trying to fetch non-duplicate entries "
"from offset %"PRId64", child %s",
- offset, children[call_child]->name);
+ offset, children[child_index]->name);
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
- (void *) (long) read_child,
- children[call_child],
- children[call_child]->fops->readdirp,
- local->fd, local->cont.readdir.size, offset,
- local->cont.readdir.dict);
+ (void *) (long) child_index,
+ children[child_index],
+ children[child_index]->fops->readdirp,
+ local->fd, local->cont.readdir.size, offset);
return 0;
}
} else {
@@ -584,14 +626,15 @@ afr_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
out:
- AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, NULL);
+ AFR_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries);
return 0;
}
+
int32_t
afr_do_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, int whichop, dict_t *dict)
+ fd_t *fd, size_t size, off_t offset, int whichop)
{
afr_private_t * priv = NULL;
xlator_t ** children = NULL;
@@ -600,8 +643,8 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
uint64_t ctx = 0;
afr_fd_ctx_t *fd_ctx = NULL;
int ret = -1;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
- uint64_t read_child = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -610,33 +653,25 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
-
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
}
- read_child = afr_inode_get_read_ctx (this, fd->inode,
- local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.readdir.last_index);
- if (ret < 0) {
- op_errno = -ret;
+ frame->local = local;
+
+ call_child = afr_first_up_child (priv);
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "no child is up");
goto out;
}
local->fd = fd_ref (fd);
local->cont.readdir.size = size;
- local->cont.readdir.dict = (dict)? dict_ref (dict) : NULL;
if (priv->strict_readdir) {
ret = fd_ctx_get (fd, this, &ctx);
@@ -667,36 +702,37 @@ afr_do_readdir (call_frame_t *frame, xlator_t *this,
(void *) (long) call_child,
children[call_child],
children[call_child]->fops->readdir, fd,
- size, offset, dict);
+ size, offset);
else
STACK_WIND_COOKIE (frame, afr_readdirp_cbk,
(void *) (long) call_child,
children[call_child],
children[call_child]->fops->readdirp, fd,
- size, offset, dict);
+ size, offset);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (readdir, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
int32_t
afr_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
- afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR, xdata);
+ afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIR);
return 0;
}
int32_t
afr_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
+ off_t offset)
{
- afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP, dict);
+ afr_do_readdir (frame, this, fd, size, offset, GF_FOP_READDIRP);
return 0;
}
diff --git a/xlators/cluster/afr/src/afr-dir-read.h b/xlators/cluster/afr/src/afr-dir-read.h
index 09456d159..40c7b6aef 100644
--- a/xlators/cluster/afr/src/afr-dir-read.h
+++ b/xlators/cluster/afr/src/afr-dir-read.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __DIR_READ_H__
@@ -14,23 +23,28 @@
int32_t
afr_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata);
+ loc_t *loc, fd_t *fd);
int32_t
afr_releasedir (xlator_t *this, fd_t *fd);
int32_t
afr_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, dict_t *xdata);
+ fd_t *fd, size_t size, off_t offset);
int32_t
afr_readdirp (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, dict_t *dict);
+ fd_t *fd, size_t size, off_t offset);
+
+int32_t
+afr_getdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset, int32_t flag);
+
int32_t
afr_checksum (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, dict_t *xdata);
+ loc_t *loc, int32_t flags);
#endif /* __DIR_READ_H__ */
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index fb4617d79..06559ede0 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -38,38 +47,28 @@
#include "afr.h"
#include "afr-transaction.h"
-int
-afr_build_parent_loc (loc_t *parent, loc_t *child, int32_t *op_errno)
+
+void
+afr_build_parent_loc (loc_t *parent, loc_t *child)
{
- int ret = -1;
- char *child_path = NULL;
+ char *tmp = NULL;
if (!child->parent) {
- if (op_errno)
- *op_errno = EINVAL;
- goto out;
+ loc_copy (parent, child);
+ return;
}
- child_path = gf_strdup (child->path);
- if (!child_path) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
- parent->path = gf_strdup( dirname (child_path) );
- if (!parent->path) {
- if (op_errno)
- *op_errno = ENOMEM;
- goto out;
- }
- parent->inode = inode_ref (child->parent);
- uuid_copy (parent->gfid, child->pargfid);
+ tmp = gf_strdup (child->path);
+ parent->path = gf_strdup (dirname (tmp));
+ GF_FREE (tmp);
- ret = 0;
-out:
- GF_FREE(child_path);
+ parent->name = strrchr (parent->path, '/');
+ if (parent->name)
+ parent->name++;
- return ret;
+ parent->inode = inode_ref (child->parent);
+ parent->parent = inode_parent (parent->inode, 0, NULL);
+ parent->ino = parent->inode->ino;
}
/* {{{ create */
@@ -99,13 +98,17 @@ afr_create_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.create.buf;
}
+ unwind_buf->ia_ino = local->cont.create.ino;
+
+ local->cont.create.preparent.ia_ino = local->cont.create.parent_ino;
+ local->cont.create.postparent.ia_ino = local->cont.create.parent_ino;
+
AFR_STACK_UNWIND (create, main_frame,
local->op_ret, local->op_errno,
local->cont.create.fd,
local->cont.create.inode,
unwind_buf, &local->cont.create.preparent,
- &local->cont.create.postparent,
- local->xdata_rsp);
+ &local->cont.create.postparent);
}
return 0;
@@ -116,17 +119,15 @@ int
afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
fd_t *fd, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- int ret = 0;
- int call_count = -1;
- int child_index = -1;
- int32_t *fresh_children = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int ret = 0;
+ int call_count = -1;
+ int child_index = -1;
local = frame->local;
priv = this->private;
@@ -138,7 +139,7 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if (op_ret > -1) {
+ if (op_ret != -1) {
local->op_ret = op_ret;
ret = afr_fd_ctx_set (this, fd);
@@ -164,14 +165,32 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
+ fd_ctx->opened_on[child_index] = 1;
fd_ctx->flags = local->cont.create.flags;
if (local->success_count == 0) {
local->cont.create.buf = *buf;
- if (xdata)
- local->xdata_rsp = dict_ref(xdata);
- }
+
+ local->cont.create.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ child_index);
+
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this, inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this, inode,
+ local->read_child_index);
+ }
+ }
+
+ if (child_index == local->first_up_child) {
+ local->cont.create.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ local->first_up_child);
+ }
if (child_index == local->read_child_index) {
local->cont.create.read_child_buf = *buf;
@@ -181,8 +200,6 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.create.inode = inode;
- fresh_children = local->fresh_children;
- fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -195,14 +212,6 @@ unlock:
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (local->op_ret > -1) {
- afr_set_read_ctx_from_policy (this,
- local->cont.create.inode,
- local->fresh_children,
- local->read_child_index,
- priv->read_child,
- local->cont.create.buf.ia_gfid);
- }
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -223,8 +232,7 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -234,7 +242,7 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_create_wind_cbk,
(void *) (long) i,
priv->children[i],
@@ -242,9 +250,8 @@ afr_create_wind (call_frame_t *frame, xlator_t *this)
&local->loc,
local->cont.create.flags,
local->cont.create.mode,
- local->umask,
local->cont.create.fd,
- local->xdata_req);
+ local->cont.create.params);
if (!--call_count)
break;
}
@@ -272,13 +279,14 @@ afr_create_done (call_frame_t *frame, xlator_t *this)
int
afr_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *params)
+ fd_t *fd, dict_t *params)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ call_frame_t * transaction_frame = NULL;
+ int ret = -1;
+ int op_ret = -1;
+ int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -286,20 +294,20 @@ afr_create (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(create,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -313,31 +321,30 @@ afr_create (call_frame_t *frame, xlator_t *this,
local->cont.create.flags = flags;
local->cont.create.mode = mode;
local->cont.create.fd = fd_ref (fd);
- local->umask = umask;
if (params)
- local->xdata_req = dict_ref (params);
+ local->cont.create.params = dict_ref (params);
+
+ if (loc->parent)
+ local->cont.create.parent_ino = loc->parent->ino;
local->transaction.fop = afr_create_wind;
local->transaction.done = afr_create_done;
local->transaction.unwind = afr_create_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (create, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -372,12 +379,16 @@ afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.mknod.buf;
}
+ unwind_buf->ia_ino = local->cont.mknod.ino;
+
+ local->cont.mknod.preparent.ia_ino = local->cont.mknod.parent_ino;
+ local->cont.mknod.postparent.ia_ino = local->cont.mknod.parent_ino;
+
AFR_STACK_UNWIND (mknod, main_frame,
local->op_ret, local->op_errno,
local->cont.mknod.inode,
unwind_buf, &local->cont.mknod.preparent,
- &local->cont.mknod.postparent,
- NULL);
+ &local->cont.mknod.postparent);
}
return 0;
@@ -388,13 +399,12 @@ int
afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int child_index = -1;
- int32_t *fresh_children = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
local = frame->local;
priv = this->private;
@@ -406,11 +416,31 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if (op_ret > -1) {
+ if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0)
+ if (local->success_count == 0){
local->cont.mknod.buf = *buf;
+ local->cont.mknod.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ child_index);
+
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this, inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this, inode,
+ local->read_child_index);
+ }
+ }
+
+ if (child_index == local->first_up_child) {
+ local->cont.mknod.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ local->first_up_child);
+ }
if (child_index == local->read_child_index) {
local->cont.mknod.read_child_buf = *buf;
@@ -420,8 +450,6 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.mknod.inode = inode;
- fresh_children = local->fresh_children;
- fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -432,14 +460,6 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (local->op_ret > -1) {
- afr_set_read_ctx_from_policy (this,
- local->cont.mknod.inode,
- local->fresh_children,
- local->read_child_index,
- priv->read_child,
- local->cont.mknod.buf.ia_gfid);
- }
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -460,8 +480,7 @@ afr_mknod_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -471,14 +490,13 @@ afr_mknod_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_mknod_wind_cbk, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->mknod,
&local->loc, local->cont.mknod.mode,
local->cont.mknod.dev,
- local->umask,
- local->xdata_req);
+ local->cont.mknod.params);
if (!--call_count)
break;
}
@@ -503,13 +521,14 @@ afr_mknod_done (call_frame_t *frame, xlator_t *this)
int
-afr_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t dev, mode_t umask, dict_t *params)
+afr_mknod (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dev_t dev, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -518,20 +537,20 @@ afr_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
priv = this->private;
- QUORUM_CHECK(mknod,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -544,31 +563,30 @@ afr_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
local->cont.mknod.mode = mode;
local->cont.mknod.dev = dev;
- local->umask = umask;
if (params)
- local->xdata_req = dict_ref (params);
+ local->cont.mknod.params = dict_ref (params);
+
+ if (loc->parent)
+ local->cont.mknod.parent_ino = loc->parent->ino;
local->transaction.fop = afr_mknod_wind;
local->transaction.done = afr_mknod_done;
local->transaction.unwind = afr_mknod_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (mknod, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
}
return 0;
@@ -604,12 +622,16 @@ afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.mkdir.buf;
}
+ unwind_buf->ia_ino = local->cont.mkdir.ino;
+
+ local->cont.mkdir.preparent.ia_ino = local->cont.mkdir.parent_ino;
+ local->cont.mkdir.postparent.ia_ino = local->cont.mkdir.parent_ino;
+
AFR_STACK_UNWIND (mkdir, main_frame,
local->op_ret, local->op_errno,
local->cont.mkdir.inode,
unwind_buf, &local->cont.mkdir.preparent,
- &local->cont.mkdir.postparent,
- NULL);
+ &local->cont.mkdir.postparent);
}
return 0;
@@ -620,13 +642,12 @@ int
afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int child_index = -1;
- int32_t *fresh_children = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
local = frame->local;
priv = this->private;
@@ -638,12 +659,33 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if (op_ret > -1) {
+ if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0)
+ if (local->success_count == 0) {
local->cont.mkdir.buf = *buf;
+ local->cont.mkdir.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ child_index);
+
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this, inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this, inode,
+ local->read_child_index);
+ }
+ }
+
+ if (child_index == local->first_up_child) {
+ local->cont.mkdir.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ local->first_up_child);
+ }
+
if (child_index == local->read_child_index) {
local->cont.mkdir.read_child_buf = *buf;
local->cont.mkdir.preparent = *preparent;
@@ -652,8 +694,6 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.mkdir.inode = inode;
- fresh_children = local->fresh_children;
- fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -664,14 +704,6 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (local->op_ret > -1) {
- afr_set_read_ctx_from_policy (this,
- local->cont.mkdir.inode,
- local->fresh_children,
- local->read_child_index,
- priv->read_child,
- local->cont.mkdir.buf.ia_gfid);
- }
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -692,8 +724,7 @@ afr_mkdir_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -703,14 +734,13 @@ afr_mkdir_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_mkdir_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->mkdir,
&local->loc, local->cont.mkdir.mode,
- local->umask,
- local->xdata_req);
+ local->cont.mkdir.params);
if (!--call_count)
break;
}
@@ -737,12 +767,13 @@ afr_mkdir_done (call_frame_t *frame, xlator_t *this)
int
afr_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *params)
+ loc_t *loc, mode_t mode, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -751,20 +782,20 @@ afr_mkdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(mkdir,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -776,32 +807,31 @@ afr_mkdir (call_frame_t *frame, xlator_t *this,
UNLOCK (&priv->read_child_lock);
local->cont.mkdir.mode = mode;
- local->umask = umask;
if (params)
- local->xdata_req = dict_ref (params);
+ local->cont.mkdir.params = dict_ref (params);
+
+ if (loc->parent)
+ local->cont.mkdir.parent_ino = loc->parent->ino;
local->transaction.fop = afr_mkdir_wind;
local->transaction.done = afr_mkdir_done;
local->transaction.unwind = afr_mkdir_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (mkdir, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
}
return 0;
@@ -837,12 +867,16 @@ afr_link_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.link.buf;
}
+ unwind_buf->ia_ino = local->cont.link.ino;
+
+ local->cont.link.preparent.ia_ino = local->cont.link.parent_ino;
+ local->cont.link.postparent.ia_ino = local->cont.link.parent_ino;
+
AFR_STACK_UNWIND (link, main_frame,
local->op_ret, local->op_errno,
local->cont.link.inode,
unwind_buf, &local->cont.link.preparent,
- &local->cont.link.postparent,
- NULL);
+ &local->cont.link.postparent);
}
return 0;
@@ -853,13 +887,12 @@ int
afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int child_index = -1;
- int32_t *fresh_children = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
local = frame->local;
priv = this->private;
@@ -871,11 +904,19 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if (op_ret > -1) {
+ if (op_ret != -1) {
local->op_ret = op_ret;
if (local->success_count == 0) {
local->cont.link.buf = *buf;
+
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this, inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this, inode,
+ local->read_child_index);
+ }
}
if (child_index == local->read_child_index) {
@@ -884,9 +925,8 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.link.postparent = *postparent;
}
- fresh_children = local->fresh_children;
- fresh_children[local->success_count] = child_index;
- local->cont.link.inode = inode;
+ local->cont.link.inode = inode;
+
local->success_count++;
}
@@ -897,14 +937,6 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (local->op_ret > -1) {
- afr_set_read_ctx_from_policy (this,
- local->cont.link.inode,
- local->fresh_children,
- local->read_child_index,
- priv->read_child,
- local->cont.link.buf.ia_gfid);
- }
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -925,8 +957,7 @@ afr_link_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -936,12 +967,12 @@ afr_link_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_link_wind_cbk, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->link,
&local->loc,
- &local->newloc, local->xdata_req);
+ &local->newloc);
if (!--call_count)
break;
@@ -967,12 +998,13 @@ afr_link_done (call_frame_t *frame, xlator_t *this)
int
afr_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -981,25 +1013,23 @@ afr_link (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(link,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, oldloc);
loc_copy (&local->newloc, newloc);
- if (xdata)
- local->xdata_req = dict_ref (xdata);
LOCK (&priv->read_child_lock);
{
@@ -1008,27 +1038,30 @@ afr_link (call_frame_t *frame, xlator_t *this,
}
UNLOCK (&priv->read_child_lock);
+ local->cont.link.ino = oldloc->inode->ino;
+
+ if (oldloc->parent)
+ local->cont.link.parent_ino = newloc->parent->ino;
+
local->transaction.fop = afr_link_wind;
local->transaction.done = afr_link_done;
local->transaction.unwind = afr_link_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, newloc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (newloc->path);
+ local->transaction.basename = AFR_BASENAME (oldloc->path);
+ local->transaction.new_basename = AFR_BASENAME (newloc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (link, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (link, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
}
return 0;
@@ -1064,12 +1097,16 @@ afr_symlink_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.symlink.buf;
}
+ unwind_buf->ia_ino = local->cont.symlink.ino;
+
+ local->cont.symlink.preparent.ia_ino = local->cont.symlink.parent_ino;
+ local->cont.symlink.postparent.ia_ino = local->cont.symlink.parent_ino;
+
AFR_STACK_UNWIND (symlink, main_frame,
local->op_ret, local->op_errno,
local->cont.symlink.inode,
unwind_buf, &local->cont.symlink.preparent,
- &local->cont.symlink.postparent,
- NULL);
+ &local->cont.symlink.postparent);
}
return 0;
@@ -1080,13 +1117,12 @@ int
afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int child_index = -1;
- int32_t *fresh_children = NULL;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int call_count = -1;
+ int child_index = -1;
local = frame->local;
priv = this->private;
@@ -1098,11 +1134,30 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if (op_ret > -1) {
+ if (op_ret != -1) {
local->op_ret = op_ret;
- if (local->success_count == 0)
+ if (local->success_count == 0) {
local->cont.symlink.buf = *buf;
+ local->cont.symlink.ino =
+ afr_itransform (buf->ia_ino, priv->child_count,
+ child_index);
+
+ if (priv->read_child >= 0) {
+ afr_set_read_child (this, inode,
+ priv->read_child);
+ } else {
+ afr_set_read_child (this, inode,
+ local->read_child_index);
+ }
+ }
+
+ if (child_index == local->first_up_child) {
+ local->cont.symlink.ino =
+ afr_itransform (buf->ia_ino,
+ priv->child_count,
+ local->first_up_child);
+ }
if (child_index == local->read_child_index) {
local->cont.symlink.read_child_buf = *buf;
@@ -1112,8 +1167,6 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cont.symlink.inode = inode;
- fresh_children = local->fresh_children;
- fresh_children[local->success_count] = child_index;
local->success_count++;
}
@@ -1124,14 +1177,6 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (local->op_ret > -1) {
- afr_set_read_ctx_from_policy (this,
- local->cont.symlink.inode,
- local->fresh_children,
- local->read_child_index,
- priv->read_child,
- local->cont.symlink.buf.ia_gfid);
- }
local->transaction.unwind (frame, this);
local->transaction.resume (frame, this);
@@ -1152,8 +1197,7 @@ afr_symlink_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1163,15 +1207,14 @@ afr_symlink_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_symlink_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->symlink,
local->cont.symlink.linkpath,
&local->loc,
- local->umask,
- local->xdata_req);
+ local->cont.symlink.params);
if (!--call_count)
break;
@@ -1198,12 +1241,13 @@ afr_symlink_done (call_frame_t *frame, xlator_t *this)
int
afr_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask, dict_t *params)
+ const char *linkpath, loc_t *loc, dict_t *params)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1212,20 +1256,20 @@ afr_symlink (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(symlink,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, loc);
@@ -1237,31 +1281,30 @@ afr_symlink (call_frame_t *frame, xlator_t *this,
UNLOCK (&priv->read_child_lock);
local->cont.symlink.linkpath = gf_strdup (linkpath);
- local->umask = umask;
if (params)
- local->xdata_req = dict_ref (params);
+ local->cont.symlink.params = dict_ref (params);
+
+ if (loc->parent)
+ local->cont.symlink.parent_ino = loc->parent->ino;
local->transaction.fop = afr_symlink_wind;
local->transaction.done = afr_symlink_done;
local->transaction.unwind = afr_symlink_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (symlink, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (symlink, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
}
return 0;
@@ -1296,14 +1339,20 @@ afr_rename_unwind (call_frame_t *frame, xlator_t *this)
unwind_buf = &local->cont.rename.buf;
}
+ unwind_buf->ia_ino = local->cont.rename.ino;
+
+ local->cont.rename.preoldparent.ia_ino = local->cont.rename.oldparent_ino;
+ local->cont.rename.postoldparent.ia_ino = local->cont.rename.oldparent_ino;
+ local->cont.rename.prenewparent.ia_ino = local->cont.rename.newparent_ino;
+ local->cont.rename.postnewparent.ia_ino = local->cont.rename.newparent_ino;
+
AFR_STACK_UNWIND (rename, main_frame,
local->op_ret, local->op_errno,
unwind_buf,
&local->cont.rename.preoldparent,
&local->cont.rename.postoldparent,
&local->cont.rename.prenewparent,
- &local->cont.rename.postnewparent,
- NULL);
+ &local->cont.rename.postnewparent);
}
return 0;
@@ -1314,8 +1363,7 @@ int
afr_rename_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
afr_local_t * local = NULL;
int call_count = -1;
@@ -1377,8 +1425,7 @@ afr_rename_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1388,13 +1435,13 @@ afr_rename_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_rename_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->rename,
&local->loc,
- &local->newloc, NULL);
+ &local->newloc);
if (!--call_count)
break;
}
@@ -1419,12 +1466,13 @@ afr_rename_done (call_frame_t *frame, xlator_t *this)
int
afr_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1433,38 +1481,39 @@ afr_rename (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(rename,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, oldloc);
loc_copy (&local->newloc, newloc);
- local->read_child_index = afr_inode_get_read_ctx (this, oldloc->inode, NULL);
+ local->read_child_index = afr_read_child (this, oldloc->inode);
+
+ local->cont.rename.ino = oldloc->inode->ino;
+
+ if (oldloc->parent)
+ local->cont.rename.oldparent_ino = oldloc->parent->ino;
+ if (newloc->parent)
+ local->cont.rename.newparent_ino = newloc->parent->ino;
local->transaction.fop = afr_rename_wind;
local->transaction.done = afr_rename_done;
local->transaction.unwind = afr_rename_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, oldloc,
- &op_errno);
- if (ret)
- goto out;
- ret = afr_build_parent_loc (&local->transaction.new_parent_loc, newloc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
+ afr_build_parent_loc (&local->transaction.new_parent_loc, newloc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (oldloc->path);
@@ -1472,14 +1521,14 @@ afr_rename (call_frame_t *frame, xlator_t *this,
afr_transaction (transaction_frame, this, AFR_ENTRY_RENAME_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (rename, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (rename, frame, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
}
return 0;
@@ -1507,11 +1556,13 @@ afr_unlink_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.unlink.preparent.ia_ino = local->cont.unlink.parent_ino;
+ local->cont.unlink.postparent.ia_ino = local->cont.unlink.parent_ino;
+
AFR_STACK_UNWIND (unlink, main_frame,
local->op_ret, local->op_errno,
&local->cont.unlink.preparent,
- &local->cont.unlink.postparent,
- NULL);
+ &local->cont.unlink.postparent);
}
return 0;
@@ -1521,13 +1572,15 @@ afr_unlink_unwind (call_frame_t *frame, xlator_t *this)
int
afr_unlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
int call_count = -1;
int child_index = (long) cookie;
local = frame->local;
+ priv = this->private;
LOCK (&frame->lock);
{
@@ -1580,8 +1633,7 @@ afr_unlink_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1591,13 +1643,12 @@ afr_unlink_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_unlink_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->unlink,
- &local->loc, local->xflag,
- local->xdata_req);
+ &local->loc);
if (!--call_count)
break;
@@ -1623,12 +1674,13 @@ afr_unlink_done (call_frame_t *frame, xlator_t *this)
int32_t
afr_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
+ loc_t *loc)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1637,47 +1689,44 @@ afr_unlink (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(unlink,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
loc_copy (&local->loc, loc);
- local->xflag = xflag;
- if (xdata)
- local->xdata_req = dict_ref (xdata);
+
+ if (loc->parent)
+ local->cont.unlink.parent_ino = loc->parent->ino;
local->transaction.fop = afr_unlink_wind;
local->transaction.done = afr_unlink_done;
local->transaction.unwind = afr_unlink_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (unlink, frame, -1, op_errno,
- NULL, NULL, NULL);
+ AFR_STACK_UNWIND (unlink, frame, op_ret, op_errno,
+ NULL, NULL);
}
return 0;
@@ -1707,11 +1756,13 @@ afr_rmdir_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.rmdir.preparent.ia_ino = local->cont.rmdir.parent_ino;
+ local->cont.rmdir.postparent.ia_ino = local->cont.rmdir.parent_ino;
+
AFR_STACK_UNWIND (rmdir, main_frame,
local->op_ret, local->op_errno,
&local->cont.rmdir.preparent,
- &local->cont.rmdir.postparent,
- NULL);
+ &local->cont.rmdir.postparent);
}
return 0;
@@ -1721,14 +1772,16 @@ afr_rmdir_unwind (call_frame_t *frame, xlator_t *this)
int
afr_rmdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
int call_count = -1;
int child_index = (long) cookie;
int read_child = 0;
local = frame->local;
+ priv = this->private;
LOCK (&frame->lock);
{
@@ -1781,8 +1834,7 @@ afr_rmdir_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1792,13 +1844,12 @@ afr_rmdir_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_rmdir_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->rmdir,
- &local->loc, local->cont.rmdir.flags,
- NULL);
+ &local->loc, local->cont.rmdir.flags);
if (!--call_count)
break;
@@ -1824,12 +1875,13 @@ afr_rmdir_done (call_frame_t *frame, xlator_t *this)
int
afr_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
+ loc_t *loc, int flags)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t * transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1838,44 +1890,45 @@ afr_rmdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(rmdir,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
local->cont.rmdir.flags = flags;
loc_copy (&local->loc, loc);
+ if (loc->parent)
+ local->cont.rmdir.parent_ino = loc->parent->ino;
+
local->transaction.fop = afr_rmdir_wind;
local->transaction.done = afr_rmdir_done;
local->transaction.unwind = afr_rmdir_unwind;
- ret = afr_build_parent_loc (&local->transaction.parent_loc, loc,
- &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&local->transaction.parent_loc, loc);
local->transaction.main_frame = frame;
local->transaction.basename = AFR_BASENAME (loc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
+ NULL, NULL);
}
return 0;
diff --git a/xlators/cluster/afr/src/afr-dir-write.h b/xlators/cluster/afr/src/afr-dir-write.h
index 02f0a3682..e589efa37 100644
--- a/xlators/cluster/afr/src/afr-dir-write.h
+++ b/xlators/cluster/afr/src/afr-dir-write.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __DIR_WRITE_H__
@@ -14,34 +23,38 @@
int32_t
afr_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata);
+ fd_t *fd, dict_t *params);
int32_t
afr_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata);
+ loc_t *loc, mode_t mode, dev_t dev, dict_t *params);
int32_t
afr_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata);
+ loc_t *loc, mode_t mode, dict_t *params);
int32_t
afr_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata);
+ loc_t *loc);
int32_t
afr_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata);
+ loc_t *loc, int flags);
int32_t
afr_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata);
+ loc_t *oldloc, loc_t *newloc);
int32_t
afr_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata);
+ loc_t *oldloc, loc_t *newloc);
int
afr_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *oldloc, mode_t umask, dict_t *params);
+ const char *linkpath, loc_t *oldloc, dict_t *params);
+
+int32_t
+afr_setdents (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int32_t flags, dir_entry_t *entries, int32_t count);
#endif /* __DIR_WRITE_H__ */
diff --git a/xlators/cluster/afr/src/afr-inode-read.c b/xlators/cluster/afr/src/afr-inode-read.c
index 40e5abd3a..dd832ffe7 100644
--- a/xlators/cluster/afr/src/afr-inode-read.c
+++ b/xlators/cluster/afr/src/afr-inode-read.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -35,6 +44,9 @@
#include "compat-errno.h"
#include "compat.h"
+#include "afr.h"
+
+
/**
* Common algorithm for inode read calls:
*
@@ -49,16 +61,15 @@
int32_t
afr_access_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -68,28 +79,33 @@ afr_access_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.access.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.access.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: all subvolumes tried, going out",
+ local->loc.path);
goto out;
+ }
+ this_try = ++local->cont.access.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_access_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->access,
- &local->loc, local->cont.access.mask,
- NULL);
+ children[this_try],
+ children[this_try]->fops->access,
+ &local->loc, local->cont.access.mask);
}
out:
if (unwind) {
- AFR_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);
+ AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
}
return 0;
@@ -97,16 +113,15 @@ out:
int32_t
-afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
+afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
{
- afr_private_t *priv = NULL;
- xlator_t **children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- int32_t op_errno = 0;
- int32_t read_child = -1;
- int ret = -1;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+ int32_t read_child = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -117,29 +132,25 @@ afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ read_child = afr_read_child (this, loc->inode);
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
+
+ local->cont.access.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: no child is up", loc->path);
+ goto out;
+ }
- read_child = afr_inode_get_read_ctx (this, loc->inode,
- local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.access.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ local->cont.access.last_tried = call_child;
}
loc_copy (&local->loc, loc);
@@ -147,14 +158,14 @@ afr_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
STACK_WIND_COOKIE (frame, afr_access_cbk,
(void *) (long) call_child,
- children[call_child],
- children[call_child]->fops->access,
- loc, mask, xdata);
+ children[call_child], children[call_child]->fops->access,
+ loc, mask);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (access, frame, -1, op_errno, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (access, frame, op_ret, op_errno);
+ }
return 0;
}
@@ -166,16 +177,15 @@ out:
int32_t
afr_stat_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -185,27 +195,36 @@ afr_stat_cbk (call_frame_t *frame, void *cookie,
local = frame->local;
if (op_ret == -1) {
- last_index = &local->cont.stat.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.stat.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: all subvolumes tried, going out",
+ local->loc.path);
goto out;
+ }
+ this_try = ++local->cont.stat.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_stat_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->stat,
- &local->loc, NULL);
+ children[this_try],
+ children[this_try]->fops->stat,
+ &local->loc);
}
out:
if (unwind) {
- AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
+ if (buf)
+ buf->ia_ino = local->cont.stat.ino;
+
+ AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, buf);
}
return 0;
@@ -213,15 +232,15 @@ out:
int32_t
-afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int32_t read_child = -1;
int call_child = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
- int32_t read_child = -1;
- int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -232,40 +251,43 @@ afr_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ frame->local = local;
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
+ read_child = afr_read_child (this, loc->inode);
+
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
+
+ local->cont.stat.last_tried = -1;
+
+ } else {
+ call_child = afr_first_up_child (priv);
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: no child is up", loc->path);
+ goto out;
+ }
- read_child = afr_inode_get_read_ctx (this, loc->inode,
- local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.stat.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ local->cont.stat.last_tried = call_child;
}
+
loc_copy (&local->loc, loc);
+ local->cont.stat.ino = loc->inode->ino;
+
STACK_WIND_COOKIE (frame, afr_stat_cbk, (void *) (long) call_child,
children[call_child],
children[call_child]->fops->stat,
- loc, xdata);
+ loc);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (stat, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -277,17 +299,15 @@ out:
int32_t
afr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -297,27 +317,36 @@ afr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.fstat.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.fstat.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%p: all subvolumes tried, going out",
+ local->fd);
goto out;
+ }
+ this_try = ++local->cont.fstat.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_fstat_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->fstat,
- local->fd, NULL);
+ children[this_try],
+ children[this_try]->fops->fstat,
+ local->fd);
}
out:
if (unwind) {
- AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
+ if (buf)
+ buf->ia_ino = local->cont.fstat.ino;
+
+ AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
}
return 0;
@@ -326,15 +355,15 @@ out:
int32_t
afr_fstat (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
int call_child = 0;
+ int32_t read_child = -1;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
- int32_t read_child = 0;
- int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -346,51 +375,44 @@ afr_fstat (call_frame_t *frame, xlator_t *this,
children = priv->children;
- VALIDATE_OR_GOTO (fd->inode, out);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ frame->local = local;
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ VALIDATE_OR_GOTO (fd->inode, out);
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
+ read_child = afr_read_child (this, fd->inode);
- read_child = afr_inode_get_read_ctx (this, fd->inode,
- local->fresh_children);
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
+ local->cont.fstat.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "%p: no child is up", fd);
+ goto out;
+ }
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.fstat.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ local->cont.fstat.last_tried = call_child;
}
+ local->cont.fstat.ino = fd->inode->ino;
local->fd = fd_ref (fd);
- ret = afr_open_fd_fix (frame, this, _gf_false);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
STACK_WIND_COOKIE (frame, afr_fstat_cbk, (void *) (long) call_child,
children[call_child],
children[call_child]->fops->fstat,
- fd, xdata);
+ fd);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -402,16 +424,15 @@ out:
int32_t
afr_readlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- const char *buf, struct iatt *sbuf, dict_t *xdata)
+ const char *buf, struct iatt *sbuf)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -421,28 +442,36 @@ afr_readlink_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.readlink.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.readlink.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: all subvolumes tried, going out",
+ local->loc.path);
goto out;
+ }
+ this_try = ++local->cont.readlink.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_readlink_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->readlink,
+ children[this_try],
+ children[this_try]->fops->readlink,
&local->loc,
- local->cont.readlink.size, NULL);
+ local->cont.readlink.size);
}
out:
if (unwind) {
- AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, sbuf,
- xdata);
+ if (sbuf)
+ sbuf->ia_ino = local->cont.readlink.ino;
+
+ AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, buf, sbuf);
}
return 0;
@@ -451,15 +480,15 @@ out:
int32_t
afr_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
+ loc_t *loc, size_t size)
{
- afr_private_t *priv = NULL;
- xlator_t **children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- int32_t op_errno = 0;
- int32_t read_child = -1;
- int ret = -1;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t *local = NULL;
+ int32_t read_child = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -470,43 +499,45 @@ afr_readlink (call_frame_t *frame, xlator_t *this,
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ frame->local = local;
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
- read_child = afr_inode_get_read_ctx (this, loc->inode,
- local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.readlink.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ read_child = afr_read_child (this, loc->inode);
+
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
+
+ local->cont.readlink.last_tried = -1;
+
+ } else {
+ call_child = afr_first_up_child (priv);
+
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: no child is up", loc->path);
+ goto out;
+ }
+
+ local->cont.readlink.last_tried = call_child;
}
loc_copy (&local->loc, loc);
local->cont.readlink.size = size;
+ local->cont.readlink.ino = loc->inode->ino;
STACK_WIND_COOKIE (frame, afr_readlink_cbk,
(void *) (long) call_child,
- children[call_child],
- children[call_child]->fops->readlink,
- loc, size, xdata);
+ children[call_child], children[call_child]->fops->readlink,
+ loc, size);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (readlink, frame, op_ret, op_errno, NULL, NULL);
+ }
return 0;
}
@@ -569,16 +600,15 @@ __filter_xattrs (dict_t *dict)
int32_t
afr_getxattr_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -588,23 +618,28 @@ afr_getxattr_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.getxattr.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.getxattr.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: all subvolumes tried, going out",
+ local->loc.path);
goto out;
+ }
+ this_try = ++local->cont.getxattr.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->getxattr,
+ children[this_try],
+ children[this_try]->fops->getxattr,
&local->loc,
- local->cont.getxattr.name,
- NULL);
+ local->cont.getxattr.name);
}
out:
@@ -612,336 +647,35 @@ out:
if (op_ret >= 0 && dict)
__filter_xattrs (dict);
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
}
return 0;
}
int32_t
-afr_getxattr_unwind (call_frame_t *frame, int op_ret, int op_errno,
- dict_t *dict, dict_t *xdata)
-
-{
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-int32_t
-afr_getxattr_clrlk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- xlator_t **children = NULL;
- dict_t *xattr = NULL;
- char *tmp_report = NULL;
- char lk_summary[1024] = {0,};
- int serz_len = 0;
- int32_t callcnt = 0;
- long int cky = 0;
- int ret = 0;
-
- priv = this->private;
- children = priv->children;
-
- local = frame->local;
- cky = (long) cookie;
-
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
- if (op_ret == -1)
- local->child_errno[cky] = op_errno;
-
- if (!local->dict)
- local->dict = dict_new ();
- if (local->dict) {
- ret = dict_get_str (dict, local->cont.getxattr.name,
- &tmp_report);
- if (ret)
- goto unlock;
- ret = dict_set_dynstr (local->dict,
- children[cky]->name,
- gf_strdup (tmp_report));
- if (ret)
- goto unlock;
- }
- }
-unlock:
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- xattr = dict_new ();
- if (!xattr) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
- ret = dict_serialize_value_with_delim (local->dict,
- lk_summary,
- &serz_len, '\n');
- if (ret) {
- op_ret = -1;
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR,
- "Error serializing dictionary");
- goto unwind;
- }
- if (serz_len == -1)
- snprintf (lk_summary, sizeof (lk_summary),
- "No locks cleared.");
- ret = dict_set_dynstr (xattr, local->cont.getxattr.name,
- gf_strdup (lk_summary));
- if (ret) {
- op_ret = -1;
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting dictionary");
- goto unwind;
- }
-
- unwind:
- // Updating child_errno with more recent 'events'
- local->child_errno[cky] = op_errno;
- op_errno = afr_resultant_errno_get (NULL, local->child_errno,
- priv->child_count);
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
+afr_getxattr_unwind (call_frame_t *frame,
+ int op_ret, int op_errno, dict_t *dict)
- if (xattr)
- dict_unref (xattr);
- }
-
- return ret;
-}
-
-/**
- * node-uuid cbk uses next child querying mechanism
- */
-int32_t
-afr_getxattr_node_uuid_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
- int unwind = 1;
- int curr_call_child = 0;
-
- priv = this->private;
- children = priv->children;
-
- local = frame->local;
-
- if (op_ret == -1) { /** query the _next_ child */
-
- /**
- * _current_ becomes _next_
- * If done with all childs and yet no success; give up !
- */
- curr_call_child = (int) ((long)cookie);
- if (++curr_call_child == priv->child_count)
- goto unwind;
-
- gf_log (this->name, GF_LOG_WARNING,
- "op_ret (-1): Re-querying afr-child (%d/%d)",
- curr_call_child, priv->child_count);
-
- unwind = 0;
- STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
- (void *) (long) curr_call_child,
- children[curr_call_child],
- children[curr_call_child]->fops->getxattr,
- &local->loc,
- local->cont.getxattr.name,
- NULL);
- }
-
- unwind:
- if (unwind)
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
-
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int32_t
-afr_getxattr_pathinfo_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- int32_t callcnt = 0;
- int ret = 0;
- char *xattr = NULL;
- char *xattr_serz = NULL;
- char xattr_cky[1024] = {0,};
- dict_t *nxattr = NULL;
- long cky = 0;
- int32_t padding = 0;
- int32_t tlen = 0;
-
- if (!frame || !frame->local || !this) {
- gf_log ("", GF_LOG_ERROR, "possible NULL deref");
- goto out;
- }
-
- local = frame->local;
- cky = (long) cookie;
-
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
-
- if (!dict || (op_ret < 0))
- goto out;
-
- if (!local->dict)
- local->dict = dict_new ();
-
- if (local->dict) {
- ret = dict_get_str (dict,
- local->cont.getxattr.name,
- &xattr);
- if (ret)
- goto out;
-
- xattr = gf_strdup (xattr);
-
- (void)snprintf (xattr_cky, 1024, "%s-%ld",
- local->cont.getxattr.name, cky);
- ret = dict_set_dynstr (local->dict,
- xattr_cky, xattr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot set xattr cookie key");
- goto out;
- }
-
- local->cont.getxattr.xattr_len += strlen (xattr) + 1;
- }
- }
- out:
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (!local->cont.getxattr.xattr_len)
- goto unwind;
-
- nxattr = dict_new ();
- if (!nxattr)
- goto unwind;
-
- /* extra bytes for decorations (brackets and <>'s) */
- padding += strlen (this->name) + strlen (AFR_PATHINFO_HEADER) + 4;
- local->cont.getxattr.xattr_len += (padding + 2);
-
- xattr_serz = GF_CALLOC (local->cont.getxattr.xattr_len,
- sizeof (char), gf_common_mt_char);
-
- if (!xattr_serz)
- goto unwind;
-
- /* the xlator info */
- (void) sprintf (xattr_serz, "(<"AFR_PATHINFO_HEADER"%s> ",
- this->name);
-
- /* actual series of pathinfo */
- ret = dict_serialize_value_with_delim (local->dict,
- xattr_serz + strlen (xattr_serz),
- &tlen, ' ');
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Error serializing"
- " dictionary");
- goto unwind;
- }
-
- /* closing part */
- *(xattr_serz + padding + tlen) = ')';
- *(xattr_serz + padding + tlen + 1) = '\0';
-
- ret = dict_set_dynstr (nxattr, local->cont.getxattr.name,
- xattr_serz);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Cannot set pathinfo"
- " key in dict");
-
- unwind:
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, nxattr,
- xdata);
-
- if (nxattr)
- dict_unref (nxattr);
- }
-
- return ret;
-}
-
-static gf_boolean_t
-afr_is_special_xattr (const char *name, fop_getxattr_cbk_t *cbk)
-{
- gf_boolean_t is_spl = _gf_true;
-
- GF_ASSERT (cbk);
- if (!cbk) {
- is_spl = _gf_false;
- goto out;
- }
-
- if (!strcmp (name, GF_XATTR_PATHINFO_KEY))
- *cbk = afr_getxattr_pathinfo_cbk;
-
- else if (!strncmp (name, GF_XATTR_CLRLK_CMD,
- strlen (GF_XATTR_CLRLK_CMD)))
- *cbk = afr_getxattr_clrlk_cbk;
- else
- is_spl = _gf_false;
-
-out:
- return is_spl;
-}
-
-static void
-afr_getxattr_frm_all_children (xlator_t *this, call_frame_t *frame,
- const char *name, loc_t *loc,
- fop_getxattr_cbk_t cbk)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
- int i = 0;
-
- priv = this->private;
- children = priv->children;
-
- local = frame->local;
- local->call_count = priv->child_count;
-
- for (i = 0; i < priv->child_count; i++) {
- STACK_WIND_COOKIE (frame, cbk,
- (void *) (long) i,
- children[i], children[i]->fops->getxattr,
- loc, name, NULL);
- }
- return;
-}
-
-int32_t
afr_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
- afr_private_t *priv = NULL;
- xlator_t **children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- xlator_list_t *trav = NULL;
- xlator_t **sub_volumes = NULL;
- int i = 0;
- int32_t op_errno = 0;
- int32_t read_child = -1;
- int ret = -1;
- fop_getxattr_cbk_t cbk = NULL;
+ afr_private_t * priv = NULL;
+ xlator_t ** children = NULL;
+ int call_child = 0;
+ afr_local_t * local = NULL;
+ xlator_list_t * trav = NULL;
+ xlator_t ** sub_volumes = NULL;
+ int read_child = -1;
+ int i = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -953,79 +687,26 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ frame->local = local;
loc_copy (&local->loc, loc);
- if (!name)
- goto no_name;
-
- local->cont.getxattr.name = gf_strdup (name);
-
- if (!strncmp (name, AFR_XATTR_PREFIX,
- strlen (AFR_XATTR_PREFIX))) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: no data present for key %s",
- loc->path, name);
- op_errno = ENODATA;
- goto out;
- }
- if ((strcmp (GF_XATTR_MARKER_KEY, name) == 0)
- && (-1 == frame->root->pid)) {
-
- local->marker.call_count = priv->child_count;
-
- sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *));
- for (i = 0, trav = this->children; trav ;
- trav = trav->next, i++) {
-
- *(sub_volumes + i) = trav->xlator;
- }
+ if (name)
+ local->cont.getxattr.name = gf_strdup (name);
- if (cluster_getmarkerattr (frame, this, loc, name,
- local, afr_getxattr_unwind,
- sub_volumes,
- priv->child_count,
- MARKER_UUID_TYPE,
- priv->vol_uuid)) {
+ if (name) {
+ if (!strncmp (name, AFR_XATTR_PREFIX,
+ strlen (AFR_XATTR_PREFIX))) {
gf_log (this->name, GF_LOG_INFO,
- "%s: failed to get marker attr (%s)",
+ "%s: no data present for key %s",
loc->path, name);
- op_errno = EINVAL;
+ op_errno = ENODATA;
goto out;
}
-
- return 0;
- }
-
- /*
- * if we are doing getxattr with pathinfo as the key then we
- * collect information from all childs
- */
- if (afr_is_special_xattr (name, &cbk)) {
- afr_getxattr_frm_all_children (this, frame, name,
- loc, cbk);
- return 0;
- }
-
- if (XATTR_IS_NODE_UUID (name)) {
- i = 0;
- STACK_WIND_COOKIE (frame, afr_getxattr_node_uuid_cbk,
- (void *) (long) i,
- children[i],
- children[i]->fops->getxattr,
- loc, name, xdata);
- return 0;
- }
-
- if (*priv->vol_uuid) {
- if ((match_uuid_local (name, priv->vol_uuid) == 0)
+ if ((strcmp (GF_XATTR_MARKER_KEY, name) == 0)
&& (-1 == frame->root->pid)) {
+
local->marker.call_count = priv->child_count;
sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *));
@@ -1033,16 +714,15 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
trav = trav->next, i++) {
*(sub_volumes + i) = trav->xlator;
-
}
- if (cluster_getmarkerattr (frame, this, loc,
- name, local,
- afr_getxattr_unwind,
+ if (cluster_getmarkerattr (frame, this, loc, name,
+ local, afr_getxattr_unwind,
sub_volumes,
priv->child_count,
- MARKER_XTIME_TYPE,
+ MARKER_UUID_TYPE,
priv->vol_uuid)) {
+
gf_log (this->name, GF_LOG_INFO,
"%s: failed to get marker attr (%s)",
loc->path, name);
@@ -1052,167 +732,69 @@ afr_getxattr (call_frame_t *frame, xlator_t *this,
return 0;
}
- }
-
-no_name:
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
-
- read_child = afr_inode_get_read_ctx (this, loc->inode, local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.getxattr.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
- }
-
- STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
- (void *) (long) call_child,
- children[call_child],
- children[call_child]->fops->getxattr,
- loc, name, xdata);
-
- ret = 0;
-out:
- if (ret < 0)
- AFR_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-/* {{{ fgetxattr */
+ if (*priv->vol_uuid) {
+ if ((match_uuid_local (name, priv->vol_uuid) == 0)
+ && (-1 == frame->root->pid)) {
+ local->marker.call_count = priv->child_count;
-int32_t
-afr_fgetxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
-
- priv = this->private;
- children = priv->children;
+ sub_volumes = alloca ( priv->child_count * sizeof (xlator_t *));
+ for (i = 0, trav = this->children; trav ;
+ trav = trav->next, i++) {
- local = frame->local;
-
- read_child = (long) cookie;
+ *(sub_volumes + i) = trav->xlator;
- if (op_ret == -1) {
- last_index = &local->cont.getxattr.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
- goto out;
-
- unwind = 0;
- STACK_WIND_COOKIE (frame, afr_fgetxattr_cbk,
- (void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->fgetxattr,
- local->fd,
- local->cont.getxattr.name,
- NULL);
- }
+ }
-out:
- if (unwind) {
- if (op_ret >= 0 && dict)
- __filter_xattrs (dict);
+ if (cluster_getmarkerattr (frame, this, loc,
+ name, local,
+ afr_getxattr_unwind,
+ sub_volumes,
+ priv->child_count,
+ MARKER_XTIME_TYPE,
+ priv->vol_uuid)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: failed to get marker attr (%s)",
+ loc->path, name);
+ op_errno = EINVAL;
+ goto out;
+ }
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict,
- xdata);
+ return 0;
+ }
+ }
}
- return 0;
-}
-
-int32_t
-afr_fgetxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
-
-{
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-int32_t
-afr_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- xlator_t **children = NULL;
- int call_child = 0;
- afr_local_t *local = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t read_child = -1;
-
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (this->private, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv->children, out);
-
- children = priv->children;
+ read_child = afr_read_child (this, loc->inode);
- AFR_LOCAL_ALLOC_OR_GOTO (local, out);
- frame->local = local;
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
- op_ret = afr_local_init (local, priv, &op_errno);
- if (op_ret < 0) {
- op_errno = -op_ret;
- goto out;
- }
+ local->cont.getxattr.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
- local->fd = fd_ref (fd);
- if (name)
- local->cont.getxattr.name = gf_strdup (name);
-
- /* pathinfo gets handled only in getxattr() */
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: no child is up", loc->path);
+ goto out;
+ }
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
+ local->cont.getxattr.last_tried = call_child;
}
- read_child = afr_inode_get_read_ctx (this, fd->inode, local->fresh_children);
- op_ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.getxattr.last_index);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
- STACK_WIND_COOKIE (frame, afr_fgetxattr_cbk,
+ STACK_WIND_COOKIE (frame, afr_getxattr_cbk,
(void *) (long) call_child,
- children[call_child],
- children[call_child]->fops->fgetxattr,
- fd, name, xdata);
+ children[call_child], children[call_child]->fops->getxattr,
+ loc, name);
op_ret = 0;
out:
if (op_ret == -1) {
- AFR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, NULL, NULL);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, NULL);
}
return 0;
}
@@ -1238,16 +820,15 @@ int32_t
afr_readv_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count, struct iatt *buf,
- struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
- afr_private_t * priv = NULL;
- afr_local_t * local = NULL;
- xlator_t ** children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t *fresh_children = NULL;
- int32_t read_child = -1;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -1263,31 +844,42 @@ afr_readv_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.readv.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
+ retry:
+ last_tried = local->cont.readv.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%p: all subvolumes tried, going out",
+ local->fd);
goto out;
+ }
+ this_try = ++local->cont.readv.last_tried;
+
+ if (this_try == read_child) {
+ /*
+ skip the read child since if we are here
+ we must have already tried that child
+ */
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, afr_readv_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->readv,
+ children[this_try],
+ children[this_try]->fops->readv,
local->fd, local->cont.readv.size,
- local->cont.readv.offset,
- local->cont.readv.flags,
- NULL);
+ local->cont.readv.offset);
}
out:
if (unwind) {
+ if (buf && local)
+ buf->ia_ino = local->cont.readv.ino;
+
AFR_STACK_UNWIND (readv, frame, op_ret, op_errno,
- vector, count, buf, iobref, xdata);
+ vector, count, buf, iobref);
}
return 0;
@@ -1296,15 +888,15 @@ out:
int32_t
afr_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ fd_t *fd, size_t size, off_t offset)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
xlator_t ** children = NULL;
+ int32_t read_child = -1;
int call_child = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
- int32_t read_child = -1;
- int ret = -1;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -1314,51 +906,50 @@ afr_readv (call_frame_t *frame, xlator_t *this,
priv = this->private;
children = priv->children;
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ frame->local = local;
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ read_child = afr_read_child (this, fd->inode);
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children) {
- op_errno = ENOMEM;
- goto out;
- }
+ if ((read_child >= 0) && (priv->child_up[read_child])) {
+ call_child = read_child;
+
+ /*
+ if read fails from the read child, we try
+ all children starting with the first one
+ */
+ local->cont.readv.last_tried = -1;
- read_child = afr_inode_get_read_ctx (this, fd->inode, local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.readv.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ } else {
+ call_child = afr_first_up_child (priv);
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%p: no child is up", fd);
+ goto out;
+ }
+
+ local->cont.readv.last_tried = call_child;
}
local->fd = fd_ref (fd);
+ local->cont.readv.ino = fd->inode->ino;
local->cont.readv.size = size;
local->cont.readv.offset = offset;
- local->cont.readv.flags = flags;
- ret = afr_open_fd_fix (frame, this, _gf_false);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
STACK_WIND_COOKIE (frame, afr_readv_cbk,
(void *) (long) call_child,
children[call_child],
children[call_child]->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
- AFR_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL,
- NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (readv, frame, op_ret, op_errno, NULL, 0, NULL,
+ NULL);
}
return 0;
}
diff --git a/xlators/cluster/afr/src/afr-inode-read.h b/xlators/cluster/afr/src/afr-inode-read.h
index e4091a793..acc814fb7 100644
--- a/xlators/cluster/afr/src/afr-inode-read.h
+++ b/xlators/cluster/afr/src/afr-inode-read.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __INODE_READ_H__
@@ -13,30 +22,26 @@
int32_t
afr_access (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t mask, dict_t *xdata);
+ loc_t *loc, int32_t mask);
int32_t
afr_stat (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata);
+ loc_t *loc);
int32_t
afr_fstat (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata);
+ fd_t *fd);
int32_t
afr_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata);
+ loc_t *loc, size_t size);
int32_t
afr_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata);
+ fd_t *fd, size_t size, off_t offset);
int32_t
afr_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata);
-
-int32_t
-afr_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata);
+ loc_t *loc, const char *name);
#endif /* __INODE_READ_H__ */
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
index 6ea288a5e..a369da6de 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -37,7 +46,6 @@
#include "afr.h"
#include "afr-transaction.h"
-#include "afr-self-heal-common.h"
/* {{{ writev */
@@ -58,11 +66,13 @@ afr_writev_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.writev.prebuf.ia_ino = local->cont.writev.ino;
+ local->cont.writev.postbuf.ia_ino = local->cont.writev.ino;
+
AFR_STACK_UNWIND (writev, main_frame,
local->op_ret, local->op_errno,
&local->cont.writev.prebuf,
- &local->cont.writev.postbuf,
- NULL);
+ &local->cont.writev.postbuf);
}
return 0;
}
@@ -71,7 +81,7 @@ afr_writev_unwind (call_frame_t *frame, xlator_t *this)
int
afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_local_t * local = NULL;
int child_index = (long) cookie;
@@ -80,7 +90,7 @@ afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- read_child = afr_inode_get_read_ctx (this, local->fd->inode, NULL);
+ read_child = afr_read_child (this, local->fd->inode);
LOCK (&frame->lock);
{
@@ -118,6 +128,7 @@ afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
+
int
afr_writev_wind (call_frame_t *frame, xlator_t *this)
{
@@ -129,8 +140,7 @@ afr_writev_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -140,7 +150,7 @@ afr_writev_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_writev_wind_cbk,
(void *) (long) i,
priv->children[i],
@@ -149,9 +159,7 @@ afr_writev_wind (call_frame_t *frame, xlator_t *this)
local->cont.writev.vector,
local->cont.writev.count,
local->cont.writev.offset,
- local->cont.writev.flags,
- local->cont.writev.iobref,
- NULL);
+ local->cont.writev.iobref);
if (!--call_count)
break;
@@ -183,10 +191,10 @@ afr_writev_done (call_frame_t *frame, xlator_t *this)
int
afr_do_writev (call_frame_t *frame, xlator_t *this)
{
- call_frame_t *transaction_frame = NULL;
- afr_local_t *local = NULL;
- int op_ret = -1;
- int op_errno = 0;
+ call_frame_t * transaction_frame = NULL;
+ afr_local_t * local = NULL;
+ int op_ret = -1;
+ int op_errno = 0;
local = frame->local;
@@ -224,226 +232,25 @@ out:
if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL, NULL);
- }
-
- return 0;
-}
-
-static int
-afr_prepare_loc (call_frame_t *frame, fd_t *fd)
-{
- afr_local_t *local = NULL;
- char *name = NULL;
- char *path = NULL;
- int ret = 0;
-
- if ((!fd) || (!fd->inode))
- return -1;
-
- local = frame->local;
- ret = inode_path (fd->inode, NULL, (char **)&path);
- if (ret <= 0) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "Unable to get path for gfid: %s",
- uuid_utoa (fd->inode->gfid));
- return -1;
- }
-
- if (local->loc.path) {
- if (strcmp (path, local->loc.path))
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "overwriting old loc->path %s with %s",
- local->loc.path, path);
- GF_FREE ((char *)local->loc.path);
- }
- local->loc.path = path;
-
- name = strrchr (local->loc.path, '/');
- if (name)
- name++;
- local->loc.name = name;
-
- if (local->loc.inode) {
- inode_unref (local->loc.inode);
- }
- local->loc.inode = inode_ref (fd->inode);
-
- if (local->loc.parent) {
- inode_unref (local->loc.parent);
+ AFR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL);
}
- local->loc.parent = inode_parent (local->loc.inode, 0, NULL);
-
return 0;
}
-afr_fd_paused_call_t*
-afr_paused_call_create (call_frame_t *frame)
-{
- afr_local_t *local = NULL;
- afr_fd_paused_call_t *paused_call = NULL;
-
- local = frame->local;
- GF_ASSERT (local->fop_call_continue);
-
- paused_call = GF_CALLOC (1, sizeof (*paused_call),
- gf_afr_fd_paused_call_t);
- if (paused_call) {
- INIT_LIST_HEAD (&paused_call->call_list);
- paused_call->frame = frame;
- }
-
- return paused_call;
-}
-
-static int
-afr_pause_fd_fop (call_frame_t *frame, xlator_t *this, afr_fd_ctx_t *fd_ctx)
-{
- afr_fd_paused_call_t *paused_call = NULL;
- int ret = 0;
-
- paused_call = afr_paused_call_create (frame);
- if (paused_call)
- list_add (&paused_call->call_list, &fd_ctx->paused_calls);
- else
- ret = -ENOMEM;
-
- return ret;
-}
-
-static void
-afr_trigger_open_fd_self_heal (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- inode_t *inode = NULL;
- char *reason = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
- inode = local->fd->inode;
-
- sh->do_missing_entry_self_heal = _gf_true;
- sh->do_gfid_self_heal = _gf_true;
- sh->do_data_self_heal = _gf_true;
-
- reason = "subvolume came online";
- afr_launch_self_heal (frame, this, inode, _gf_true, inode->ia_type,
- reason, NULL, NULL);
-}
-
-int
-afr_open_fd_fix (call_frame_t *frame, xlator_t *this, gf_boolean_t pause_fop)
-{
- int ret = 0;
- int i = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
- inode_t *inode = NULL;
- gf_boolean_t need_self_heal = _gf_false;
- int *need_open = NULL;
- int need_open_count = 0;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- gf_boolean_t fop_continue = _gf_true;
-
- local = frame->local;
- priv = this->private;
-
- GF_ASSERT (local->fd);
-
- inode = local->fd->inode;
- //gfid is not set in rebalance, that case needs to be handled.
- if (fd_is_anonymous (local->fd) ||
- !inode || uuid_is_null (inode->gfid)) {
- fop_continue = _gf_true;
- goto out;
- }
-
- if (pause_fop)
- GF_ASSERT (local->fop_call_continue);
-
- ret = afr_prepare_loc (frame, local->fd);
- if (ret < 0) {
- //File does not exist we cant open it.
- ret = 0;
- goto out;
- }
-
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx) {
- ret = -EINVAL;
- goto out;
- }
-
- LOCK (&local->fd->lock);
- {
- if (fd_ctx->up_count < priv->up_count) {
- need_self_heal = _gf_true;
- fd_ctx->up_count = priv->up_count;
- fd_ctx->down_count = priv->down_count;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if ((fd_ctx->opened_on[i] == AFR_FD_NOT_OPENED) &&
- local->child_up[i]) {
- fd_ctx->opened_on[i] = AFR_FD_OPENING;
- if (!need_open)
- need_open = GF_CALLOC (priv->child_count,
- sizeof (*need_open),
- gf_afr_mt_int32_t);
- need_open[i] = 1;
- need_open_count++;
- } else if (pause_fop && local->child_up[i] &&
- (fd_ctx->opened_on[i] == AFR_FD_OPENING)) {
- local->fop_paused = _gf_true;
- }
- }
-
- if (local->fop_paused) {
- GF_ASSERT (pause_fop);
- gf_log (this->name, GF_LOG_INFO, "Pause fd %p",
- local->fd);
- ret = afr_pause_fd_fop (frame, this, fd_ctx);
- if (ret)
- goto unlock;
- fop_continue = _gf_false;
- }
- }
-unlock:
- UNLOCK (&local->fd->lock);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to fix fd for %s",
- local->loc.path);
- fop_continue = _gf_false;
- goto out;
- }
-
- if (need_self_heal)
- afr_trigger_open_fd_self_heal (frame, this);
-
- if (!need_open_count)
- goto out;
-
- gf_log (this->name, GF_LOG_INFO, "Opening fd %p", local->fd);
- afr_fix_open (frame, this, fd_ctx, need_open_count, need_open);
- fop_continue = _gf_false;
-out:
- GF_FREE (need_open);
- if (fop_continue && local->fop_call_continue)
- local->fop_call_continue (frame, this);
- return ret;
-}
int
afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -451,34 +258,43 @@ afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
- QUORUM_CHECK(writev,out);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ frame->local = local;
local->cont.writev.vector = iov_dup (vector, count);
local->cont.writev.count = count;
local->cont.writev.offset = offset;
- local->cont.writev.flags = flags;
+ local->cont.writev.ino = fd->inode->ino;
local->cont.writev.iobref = iobref_ref (iobref);
local->fd = fd_ref (fd);
- local->fop_call_continue = afr_do_writev;
- ret = afr_open_fd_fix (frame, this, _gf_true);
- if (ret) {
- op_errno = -ret;
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
goto out;
}
- ret = 0;
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (fd_ctx->up_count < priv->up_count) {
+ local->openfd_flush_cbk = afr_do_writev;
+ afr_openfd_flush (frame, this, fd);
+ } else {
+ afr_do_writev (frame, this);
+ }
+
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL);
+ }
return 0;
}
@@ -505,11 +321,13 @@ afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.truncate.prebuf.ia_ino = local->cont.truncate.ino;
+ local->cont.truncate.postbuf.ia_ino = local->cont.truncate.ino;
+
AFR_STACK_UNWIND (truncate, main_frame, local->op_ret,
local->op_errno,
&local->cont.truncate.prebuf,
- &local->cont.truncate.postbuf,
- NULL);
+ &local->cont.truncate.postbuf);
}
return 0;
@@ -519,7 +337,7 @@ afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
int
afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -531,7 +349,7 @@ afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
priv = this->private;
- read_child = afr_inode_get_read_ctx (this, local->loc.inode, NULL);
+ read_child = afr_read_child (this, local->loc.inode);
LOCK (&frame->lock);
{
@@ -589,8 +407,7 @@ afr_truncate_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -600,14 +417,13 @@ afr_truncate_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_truncate_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->truncate,
&local->loc,
- local->cont.truncate.offset,
- NULL);
+ local->cont.truncate.offset);
if (!--call_count)
break;
@@ -635,12 +451,13 @@ afr_truncate_done (call_frame_t *frame, xlator_t *this)
int
afr_truncate (call_frame_t *frame, xlator_t *this,
- loc_t *loc, off_t offset, dict_t *xdata)
+ loc_t *loc, off_t offset)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -649,22 +466,25 @@ afr_truncate (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(truncate,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
+
+ local->op_ret = -1;
local->cont.truncate.offset = offset;
+ local->cont.truncate.ino = loc->inode->ino;
local->transaction.fop = afr_truncate_wind;
local->transaction.done = afr_truncate_done;
@@ -673,17 +493,17 @@ afr_truncate (call_frame_t *frame, xlator_t *this,
loc_copy (&local->loc, loc);
local->transaction.main_frame = frame;
- local->transaction.start = offset;
- local->transaction.len = 0;
+ local->transaction.start = 0;
+ local->transaction.len = offset;
afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (truncate, frame, op_ret, op_errno, NULL, NULL);
}
return 0;
@@ -712,11 +532,13 @@ afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.ftruncate.prebuf.ia_ino = local->cont.ftruncate.ino;
+ local->cont.ftruncate.postbuf.ia_ino = local->cont.ftruncate.ino;
+
AFR_STACK_UNWIND (ftruncate, main_frame, local->op_ret,
local->op_errno,
&local->cont.ftruncate.prebuf,
- &local->cont.ftruncate.postbuf,
- NULL);
+ &local->cont.ftruncate.postbuf);
}
return 0;
}
@@ -725,7 +547,7 @@ afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
int
afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -737,7 +559,7 @@ afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
priv = this->private;
- read_child = afr_inode_get_read_ctx (this, local->fd->inode, NULL);
+ read_child = afr_read_child (this, local->fd->inode);
LOCK (&frame->lock);
{
@@ -795,8 +617,7 @@ afr_ftruncate_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -806,14 +627,12 @@ afr_ftruncate_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_ftruncate_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->ftruncate,
- local->fd,
- local->cont.ftruncate.offset,
- NULL);
+ local->fd, local->cont.ftruncate.offset);
if (!--call_count)
break;
@@ -865,8 +684,8 @@ afr_do_ftruncate (call_frame_t *frame, xlator_t *this)
local->transaction.main_frame = frame;
- local->transaction.start = local->cont.ftruncate.offset;
- local->transaction.len = 0;
+ local->transaction.start = 0;
+ local->transaction.len = local->cont.ftruncate.offset;
afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION);
@@ -875,8 +694,7 @@ out:
if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL,
- NULL, NULL);
+ AFR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL, NULL);
}
return 0;
@@ -885,13 +703,16 @@ out:
int
afr_ftruncate (call_frame_t *frame, xlator_t *this,
- fd_t *fd, off_t offset, dict_t *xdata)
+ fd_t *fd, off_t offset)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -899,32 +720,41 @@ afr_ftruncate (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(ftruncate,out);
-
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ frame->local = local;
local->cont.ftruncate.offset = offset;
+ local->cont.ftruncate.ino = fd->inode->ino;
local->fd = fd_ref (fd);
- local->fop_call_continue = afr_do_ftruncate;
- ret = afr_open_fd_fix (frame, this, _gf_true);
- if (ret) {
- op_errno = -ret;
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
goto out;
}
- ret = 0;
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ if (fd_ctx->up_count < priv->up_count) {
+ local->openfd_flush_cbk = afr_do_ftruncate;
+ afr_openfd_flush (frame, this, fd);
+ } else {
+ afr_do_ftruncate (frame, this);
+ }
+
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL, NULL);
}
return 0;
@@ -951,11 +781,13 @@ afr_setattr_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.setattr.preop_buf.ia_ino = local->cont.setattr.ino;
+ local->cont.setattr.postop_buf.ia_ino = local->cont.setattr.ino;
+
AFR_STACK_UNWIND (setattr, main_frame, local->op_ret,
local->op_errno,
&local->cont.setattr.preop_buf,
- &local->cont.setattr.postop_buf,
- NULL);
+ &local->cont.setattr.postop_buf);
}
return 0;
@@ -965,7 +797,7 @@ afr_setattr_unwind (call_frame_t *frame, xlator_t *this)
int
afr_setattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -977,7 +809,7 @@ afr_setattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
priv = this->private;
- read_child = afr_inode_get_read_ctx (this, local->loc.inode, NULL);
+ read_child = afr_read_child (this, local->loc.inode);
LOCK (&frame->lock);
{
@@ -1035,8 +867,7 @@ afr_setattr_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1046,15 +877,14 @@ afr_setattr_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_setattr_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->setattr,
&local->loc,
&local->cont.setattr.in_buf,
- local->cont.setattr.valid,
- NULL);
+ local->cont.setattr.valid);
if (!--call_count)
break;
@@ -1082,12 +912,13 @@ afr_setattr_done (call_frame_t *frame, xlator_t *this)
int
afr_setattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, struct iatt *buf, int32_t valid, dict_t *xdata)
+ loc_t *loc, struct iatt *buf, int32_t valid)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1096,20 +927,24 @@ afr_setattr (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(setattr,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
+
+ local->op_ret = -1;
+
+ local->cont.setattr.ino = loc->inode->ino;
local->cont.setattr.in_buf = *buf;
local->cont.setattr.valid = valid;
@@ -1126,12 +961,12 @@ afr_setattr (call_frame_t *frame, xlator_t *this,
afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (setattr, frame, op_ret, op_errno, NULL, NULL);
}
return 0;
@@ -1156,11 +991,15 @@ afr_fsetattr_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ local->cont.fsetattr.preop_buf.ia_ino =
+ local->cont.fsetattr.ino;
+ local->cont.fsetattr.postop_buf.ia_ino =
+ local->cont.fsetattr.ino;
+
AFR_STACK_UNWIND (fsetattr, main_frame, local->op_ret,
local->op_errno,
&local->cont.fsetattr.preop_buf,
- &local->cont.fsetattr.postop_buf,
- NULL);
+ &local->cont.fsetattr.postop_buf);
}
return 0;
@@ -1170,7 +1009,7 @@ afr_fsetattr_unwind (call_frame_t *frame, xlator_t *this)
int
afr_fsetattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -1182,7 +1021,7 @@ afr_fsetattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
priv = this->private;
- read_child = afr_inode_get_read_ctx (this, local->fd->inode, NULL);
+ read_child = afr_read_child (this, local->fd->inode);
LOCK (&frame->lock);
{
@@ -1240,8 +1079,7 @@ afr_fsetattr_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1251,15 +1089,14 @@ afr_fsetattr_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_fsetattr_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->fsetattr,
local->fd,
&local->cont.fsetattr.in_buf,
- local->cont.fsetattr.valid,
- NULL);
+ local->cont.fsetattr.valid);
if (!--call_count)
break;
@@ -1284,14 +1121,16 @@ afr_fsetattr_done (call_frame_t *frame, xlator_t *this)
return 0;
}
+
int
afr_fsetattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata)
+ fd_t *fd, struct iatt *buf, int32_t valid)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
int ret = -1;
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1300,20 +1139,24 @@ afr_fsetattr (call_frame_t *frame, xlator_t *this,
priv = this->private;
- QUORUM_CHECK(fsetattr,out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+
+ transaction_frame->local = local;
+
+ local->op_ret = -1;
+
+ local->cont.fsetattr.ino = fd->inode->ino;
local->cont.fsetattr.in_buf = *buf;
local->cont.fsetattr.valid = valid;
@@ -1324,24 +1167,18 @@ afr_fsetattr (call_frame_t *frame, xlator_t *this,
local->fd = fd_ref (fd);
- ret = afr_open_fd_fix (transaction_frame, this, _gf_false);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
-
local->transaction.main_frame = frame;
local->transaction.start = LLONG_MAX - 1;
local->transaction.len = 0;
afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
+ AFR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, NULL, NULL);
}
return 0;
@@ -1369,21 +1206,20 @@ afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
AFR_STACK_UNWIND (setxattr, main_frame,
- local->op_ret, local->op_errno,
- NULL);
- }
+ local->op_ret, local->op_errno)
+ }
return 0;
}
int
afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int need_unwind = 0;
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ int call_count = -1;
+ int need_unwind = 0;
local = frame->local;
priv = this->private;
@@ -1421,16 +1257,15 @@ afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int i = 0;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = -1;
+ int i = 0;
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1440,15 +1275,14 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_setxattr_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->setxattr,
&local->loc,
local->cont.setxattr.dict,
- local->cont.setxattr.flags,
- NULL);
+ local->cont.setxattr.flags);
if (!--call_count)
break;
@@ -1462,7 +1296,7 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
int
afr_setxattr_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = frame->local;
+ afr_local_t * local = frame->local;
local->transaction.unwind (frame, this);
@@ -1473,41 +1307,37 @@ afr_setxattr_done (call_frame_t *frame, xlator_t *this)
int
afr_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata)
+ loc_t *loc, dict_t *dict, int32_t flags)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
- data_pair_t *trav = NULL;
- int ret = -1;
- int op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (this, out);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
- trav, op_errno, out);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
- trav, op_errno, out);
+ int ret = -1;
+ int op_ret = -1;
+ int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (this->private, out);
priv = this->private;
- QUORUM_CHECK(setxattr,out);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
+ goto out;
+ }
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
+ transaction_frame->local = local;
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ local->op_ret = -1;
local->cont.setxattr.dict = dict_ref (dict);
local->cont.setxattr.flags = flags;
@@ -1524,204 +1354,12 @@ afr_setxattr (call_frame_t *frame, xlator_t *this,
afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- ret = 0;
-out:
- if (ret < 0) {
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
- }
-
- return 0;
-}
-
-/* {{{ fsetxattr */
-
-
-int
-afr_fsetxattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (local->transaction.main_frame)
- main_frame = local->transaction.main_frame;
- local->transaction.main_frame = NULL;
- }
- UNLOCK (&frame->lock);
-
- if (main_frame) {
- AFR_STACK_UNWIND (fsetxattr, main_frame,
- local->op_ret, local->op_errno,
- NULL);
- }
- return 0;
-}
-
-
-int
-afr_fsetxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int need_unwind = 0;
-
- local = frame->local;
- priv = this->private;
-
- LOCK (&frame->lock);
- {
- if (op_ret != -1) {
- if (local->success_count == 0) {
- local->op_ret = op_ret;
- }
- local->success_count++;
-
- if (local->success_count == priv->child_count) {
- need_unwind = 1;
- }
- }
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- if (need_unwind)
- local->transaction.unwind (frame, this);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- local->transaction.resume (frame, this);
- }
-
- return 0;
-}
-
-
-int
-afr_fsetxattr_wind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int i = 0;
-
- local = frame->local;
- priv = this->private;
-
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
-
- if (call_count == 0) {
- local->transaction.resume (frame, this);
- return 0;
- }
-
- local->call_count = call_count;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
- STACK_WIND_COOKIE (frame, afr_fsetxattr_wind_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fsetxattr,
- local->fd,
- local->cont.fsetxattr.dict,
- local->cont.fsetxattr.flags,
- NULL);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-}
-
-
-int
-afr_fsetxattr_done (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = frame->local;
-
- local->transaction.unwind (frame, this);
-
- AFR_STACK_DESTROY (frame);
-
- return 0;
-}
-
-int
-afr_fsetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = EINVAL;
- data_pair_t *trav = NULL;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (this->private, out);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict,
- trav, op_errno, out);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict,
- trav, op_errno, out);
-
- if (ret)
- goto out;
-
- priv = this->private;
-
- QUORUM_CHECK(fsetxattr,out);
-
- AFR_LOCAL_ALLOC_OR_GOTO (local, out);
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
-
- transaction_frame = copy_frame (frame);
- if (!transaction_frame) {
- goto out;
- }
-
- transaction_frame->local = local;
-
- local->op_ret = -1;
-
- local->cont.fsetxattr.dict = dict_ref (dict);
- local->cont.fsetxattr.flags = flags;
-
- local->transaction.fop = afr_fsetxattr_wind;
- local->transaction.done = afr_fsetxattr_done;
- local->transaction.unwind = afr_fsetxattr_unwind;
-
- local->fd = fd_ref (fd);
-
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
-
- afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
-
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
+ AFR_STACK_UNWIND (setxattr, frame, op_ret, op_errno);
}
return 0;
@@ -1729,7 +1367,6 @@ out:
/* }}} */
-
/* {{{ removexattr */
@@ -1751,16 +1388,15 @@ afr_removexattr_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
AFR_STACK_UNWIND (removexattr, main_frame,
- local->op_ret, local->op_errno,
- NULL);
- }
+ local->op_ret, local->op_errno)
+ }
return 0;
}
int
afr_removexattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -1811,8 +1447,7 @@ afr_removexattr_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1822,14 +1457,13 @@ afr_removexattr_wind (call_frame_t *frame, xlator_t *this)
local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
+ if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_removexattr_wind_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->removexattr,
&local->loc,
- local->cont.removexattr.name,
- NULL);
+ local->cont.removexattr.name);
if (!--call_count)
break;
@@ -1855,192 +1489,7 @@ afr_removexattr_done (call_frame_t *frame, xlator_t *this)
int
afr_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *transaction_frame = NULL;
- int ret = -1;
- int op_errno = 0;
-
- VALIDATE_OR_GOTO (this, out);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
- name, op_errno, out);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
- name, op_errno, out);
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this->private, out);
- VALIDATE_OR_GOTO (loc, out);
-
- priv = this->private;
-
- QUORUM_CHECK(removexattr,out);
-
- transaction_frame = copy_frame (frame);
- if (!transaction_frame) {
- op_errno = ENOMEM;
- goto out;
- }
-
- AFR_LOCAL_ALLOC_OR_GOTO (transaction_frame->local, out);
- local = transaction_frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
-
- local->cont.removexattr.name = gf_strdup (name);
-
- local->transaction.fop = afr_removexattr_wind;
- local->transaction.done = afr_removexattr_done;
- local->transaction.unwind = afr_removexattr_unwind;
-
- loc_copy (&local->loc, loc);
-
- local->transaction.main_frame = frame;
- local->transaction.start = LLONG_MAX - 1;
- local->transaction.len = 0;
-
- afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
-
- ret = 0;
-out:
- if (ret < 0) {
- if (transaction_frame)
- AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- }
-
- return 0;
-}
-
-/* ffremovexattr */
-int
-afr_fremovexattr_unwind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = NULL;
- call_frame_t *main_frame = NULL;
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- if (local->transaction.main_frame)
- main_frame = local->transaction.main_frame;
- local->transaction.main_frame = NULL;
- }
- UNLOCK (&frame->lock);
-
- if (main_frame) {
- AFR_STACK_UNWIND (fremovexattr, main_frame,
- local->op_ret, local->op_errno,
- NULL);
- }
- return 0;
-}
-
-
-int
-afr_fremovexattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- afr_local_t * local = NULL;
- afr_private_t * priv = NULL;
- int call_count = -1;
- int need_unwind = 0;
-
- local = frame->local;
- priv = this->private;
-
- LOCK (&frame->lock);
- {
- if (op_ret != -1) {
- if (local->success_count == 0) {
- local->op_ret = op_ret;
- }
- local->success_count++;
-
- if (local->success_count == priv->wait_count) {
- need_unwind = 1;
- }
- }
-
- local->op_errno = op_errno;
- }
- UNLOCK (&frame->lock);
-
- if (need_unwind)
- local->transaction.unwind (frame, this);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- local->transaction.resume (frame, this);
- }
-
- return 0;
-}
-
-
-int32_t
-afr_fremovexattr_wind (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = -1;
- int i = 0;
-
- local = frame->local;
- priv = this->private;
-
- call_count = afr_pre_op_done_children_count (local->transaction.pre_op,
- priv->child_count);
-
- if (call_count == 0) {
- local->transaction.resume (frame, this);
- return 0;
- }
-
- local->call_count = call_count;
-
- for (i = 0; i < priv->child_count; i++) {
- if (local->transaction.pre_op[i]) {
- STACK_WIND_COOKIE (frame, afr_fremovexattr_wind_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fremovexattr,
- local->fd,
- local->cont.removexattr.name,
- NULL);
-
- if (!--call_count)
- break;
- }
- }
-
- return 0;
-}
-
-
-int
-afr_fremovexattr_done (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t * local = frame->local;
-
- local->transaction.unwind (frame, this);
-
- AFR_STACK_DESTROY (frame);
-
- return 0;
-}
-
-
-int
-afr_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
@@ -2049,29 +1498,21 @@ afr_fremovexattr (call_frame_t *frame, xlator_t *this,
int op_ret = -1;
int op_errno = 0;
- VALIDATE_OR_GOTO (this, out);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.afr.*",
- name, op_errno, out);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.afr.*",
- name, op_errno, out);
-
VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (loc, out);
priv = this->private;
- QUORUM_CHECK(fremovexattr, out);
-
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (local, out);
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
+ ret = AFR_LOCAL_INIT (local, priv);
if (ret < 0) {
op_errno = -ret;
goto out;
@@ -2083,11 +1524,11 @@ afr_fremovexattr (call_frame_t *frame, xlator_t *this,
local->cont.removexattr.name = gf_strdup (name);
- local->transaction.fop = afr_fremovexattr_wind;
- local->transaction.done = afr_fremovexattr_done;
- local->transaction.unwind = afr_fremovexattr_unwind;
+ local->transaction.fop = afr_removexattr_wind;
+ local->transaction.done = afr_removexattr_done;
+ local->transaction.unwind = afr_removexattr_unwind;
- local->fd = fd_ref (fd);
+ loc_copy (&local->loc, loc);
local->transaction.main_frame = frame;
local->transaction.start = LLONG_MAX - 1;
@@ -2100,7 +1541,7 @@ out:
if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, NULL);
+ AFR_STACK_UNWIND (removexattr, frame, op_ret, op_errno);
}
return 0;
diff --git a/xlators/cluster/afr/src/afr-inode-write.h b/xlators/cluster/afr/src/afr-inode-write.h
index ed11079fd..475898722 100644
--- a/xlators/cluster/afr/src/afr-inode-write.h
+++ b/xlators/cluster/afr/src/afr-inode-write.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __INODE_WRITE_H__
@@ -13,59 +22,51 @@
int32_t
afr_chmod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dict_t *xdata);
+ loc_t *loc, mode_t mode);
int32_t
afr_chown (call_frame_t *frame, xlator_t *this,
- loc_t *loc, uid_t uid, gid_t gid, dict_t *xdata);
+ loc_t *loc, uid_t uid, gid_t gid);
int
afr_fchown (call_frame_t *frame, xlator_t *this,
- fd_t *fd, uid_t uid, gid_t gid, dict_t *xdata);
+ fd_t *fd, uid_t uid, gid_t gid);
int32_t
afr_fchmod (call_frame_t *frame, xlator_t *this,
- fd_t *fd, mode_t mode, dict_t *xdata);
+ fd_t *fd, mode_t mode);
int32_t
-afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
+afr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata);
+ struct iobref *iobref);
int32_t
afr_truncate (call_frame_t *frame, xlator_t *this,
- loc_t *loc, off_t offset, dict_t *xdata);
+ loc_t *loc, off_t offset);
int32_t
afr_ftruncate (call_frame_t *frame, xlator_t *this,
- fd_t *fd, off_t offset, dict_t *xdata);
+ fd_t *fd, off_t offset);
int32_t
afr_utimens (call_frame_t *frame, xlator_t *this,
- loc_t *loc, struct timespec tv[2], dict_t *xdata);
+ loc_t *loc, struct timespec tv[2]);
int
afr_setattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, struct iatt *buf, int32_t valid, dict_t *xdata);
+ loc_t *loc, struct iatt *buf, int32_t valid);
int
afr_fsetattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *buf, int32_t valid, dict_t *xdata);
+ fd_t *fd, struct iatt *buf, int32_t valid);
int32_t
afr_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata);
-
-int32_t
-afr_fsetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata);
+ loc_t *loc, dict_t *dict, int32_t flags);
int32_t
afr_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata);
-
-int32_t
-afr_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata);
+ loc_t *loc, const char *name);
#endif /* __INODE_WRITE_H__ */
diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c
index 5e61be4d4..81d8c9d69 100644
--- a/xlators/cluster/afr/src/afr-lk-common.c
+++ b/xlators/cluster/afr/src/afr-lk-common.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include "dict.h"
@@ -22,44 +31,9 @@
#define LOCKED_YES 0x1 /* for DATA, METADATA, ENTRY and higher_path */
#define LOCKED_LOWER 0x2 /* for lower path */
-#define AFR_TRACE_INODELK_IN(frame, this, params ...) \
- do { \
- afr_private_t *_priv = this->private; \
- if (!_priv->inodelk_trace) \
- break; \
- afr_trace_inodelk_in (frame, this, params); \
- } while (0);
-
-#define AFR_TRACE_INODELK_OUT(frame, this, params ...) \
- do { \
- afr_private_t *_priv = this->private; \
- if (!_priv->inodelk_trace) \
- break; \
- afr_trace_inodelk_out (frame, this, params); \
- } while (0);
-
-#define AFR_TRACE_ENTRYLK_IN(frame, this, params ...) \
- do { \
- afr_private_t *_priv = this->private; \
- if (!_priv->entrylk_trace) \
- break; \
- afr_trace_entrylk_in (frame, this, params); \
- } while (0);
-
-#define AFR_TRACE_ENTRYLK_OUT(frame, this, params ...) \
- do { \
- afr_private_t *_priv = this->private; \
- if (!_priv->entrylk_trace) \
- break; \
- afr_trace_entrylk_out (frame, this, params); \
- } while (0);
-
int
afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index);
-static int
-afr_copy_locked_nodes (call_frame_t *frame, xlator_t *this);
-
static uint64_t afr_lock_number = 1;
static uint64_t
@@ -83,13 +57,14 @@ afr_set_lock_number (call_frame_t *frame, xlator_t *this)
}
void
-afr_set_lk_owner (call_frame_t *frame, xlator_t *this, void *lk_owner)
+afr_set_lk_owner (call_frame_t *frame, xlator_t *this)
{
- gf_log (this->name, GF_LOG_TRACE,
- "Setting lk-owner=%llu",
- (unsigned long long) (unsigned long)lk_owner);
-
- set_lk_owner_from_ptr (&frame->root->lk_owner, lk_owner);
+ if (!frame->root->lk_owner) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "Setting lk-owner=%llu",
+ (unsigned long long) (unsigned long)frame->root);
+ frame->root->lk_owner = (uint64_t) (unsigned long)frame->root;
+ }
}
static int
@@ -115,7 +90,8 @@ is_afr_lock_selfheal (afr_local_t *local)
}
int32_t
-internal_lock_count (call_frame_t *frame, xlator_t *this)
+internal_lock_count (call_frame_t *frame, xlator_t *this,
+ afr_fd_ctx_t *fd_ctx)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -125,9 +101,10 @@ internal_lock_count (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- if (local->fd) {
+ if (fd_ctx) {
+ GF_ASSERT (local->fd);
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i] && local->fd_open_on[i])
+ if (local->child_up[i] && fd_ctx->opened_on[i])
++call_count;
}
} else {
@@ -142,7 +119,7 @@ internal_lock_count (call_frame_t *frame, xlator_t *this)
static void
afr_print_inodelk (char *str, int size, int cmd,
- struct gf_flock *flock, gf_lkowner_t *owner)
+ struct gf_flock *flock, uint64_t owner)
{
char *cmd_str = NULL;
char *type_str = NULL;
@@ -190,11 +167,11 @@ afr_print_inodelk (char *str, int size, int cmd,
}
snprintf (str, size, "lock=INODELK, cmd=%s, type=%s, "
- "start=%llu, len=%llu, pid=%llu, lk-owner=%s",
+ "start=%llu, len=%llu, pid=%llu, lk-owner=%llu",
cmd_str, type_str, (unsigned long long) flock->l_start,
(unsigned long long) flock->l_len,
(unsigned long long) flock->l_pid,
- lkowner_utoa (owner));
+ (unsigned long long) owner);
}
@@ -210,11 +187,11 @@ afr_print_lockee (char *str, int size, loc_t *loc, fd_t *fd,
void
afr_print_entrylk (char *str, int size, const char *basename,
- gf_lkowner_t *owner)
+ uint64_t owner)
{
- snprintf (str, size, "Basename=%s, lk-owner=%s",
+ snprintf (str, size, "Basename=%s, lk-owner=%llu",
basename ? basename : "<nul>",
- lkowner_utoa (owner));
+ (unsigned long long)owner);
}
static void
@@ -268,20 +245,27 @@ afr_set_lock_call_type (afr_lock_call_type_t lock_call_type,
}
static void
-afr_trace_inodelk_out (call_frame_t *frame, xlator_t *this,
- afr_lock_call_type_t lock_call_type,
+afr_trace_inodelk_out (call_frame_t *frame, afr_lock_call_type_t lock_call_type,
afr_lock_op_type_t lk_op_type, struct gf_flock *flock,
int op_ret, int op_errno, int32_t child_index)
{
+ xlator_t *this = NULL;
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
char lockee[256];
char lock_call_type_str[256];
char verdict[16];
+ this = THIS;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
+
+ if (!priv->inodelk_trace) {
+ return;
+ }
afr_print_lockee (lockee, 256, &local->loc, local->fd, child_index);
@@ -290,31 +274,39 @@ afr_trace_inodelk_out (call_frame_t *frame, xlator_t *this,
afr_print_verdict (op_ret, op_errno, verdict);
gf_log (this->name, GF_LOG_INFO,
- "[%s %s] [%s] lk-owner=%s Lockee={%s} Number={%llu}",
+ "[%s %s] [%s] Lockee={%s} Number={%llu}",
lock_call_type_str,
lk_op_type == AFR_LOCK_OP ? "LOCK REPLY" : "UNLOCK REPLY",
- verdict, lkowner_utoa (&frame->root->lk_owner), lockee,
+ verdict,
+ lockee,
(unsigned long long) int_lock->lock_number);
}
static void
-afr_trace_inodelk_in (call_frame_t *frame, xlator_t *this,
- afr_lock_call_type_t lock_call_type,
+afr_trace_inodelk_in (call_frame_t *frame, afr_lock_call_type_t lock_call_type,
afr_lock_op_type_t lk_op_type, struct gf_flock *flock,
int32_t cmd, int32_t child_index)
{
+ xlator_t *this = NULL;
afr_local_t *local = NULL;
afr_internal_lock_t *int_lock = NULL;
+ afr_private_t *priv = NULL;
char lock[256];
char lockee[256];
char lock_call_type_str[256];
+ this = THIS;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
- afr_print_inodelk (lock, 256, cmd, flock, &frame->root->lk_owner);
+ if (!priv->inodelk_trace) {
+ return;
+ }
+
+ afr_print_inodelk (lock, 256, cmd, flock, frame->root->lk_owner);
afr_print_lockee (lockee, 256, &local->loc, local->fd, child_index);
afr_set_lock_call_type (lock_call_type, lock_call_type_str, int_lock);
@@ -329,22 +321,29 @@ afr_trace_inodelk_in (call_frame_t *frame, xlator_t *this,
}
static void
-afr_trace_entrylk_in (call_frame_t *frame, xlator_t *this,
- afr_lock_call_type_t lock_call_type,
+afr_trace_entrylk_in (call_frame_t *frame, afr_lock_call_type_t lock_call_type,
afr_lock_op_type_t lk_op_type, const char *basename,
int32_t child_index)
{
+ xlator_t *this = NULL;
afr_local_t *local = NULL;
afr_internal_lock_t *int_lock = NULL;
+ afr_private_t *priv = NULL;
char lock[256];
char lockee[256];
char lock_call_type_str[256];
+ this = THIS;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
+
+ if (!priv->entrylk_trace) {
+ return;
+ }
- afr_print_entrylk (lock, 256, basename, &frame->root->lk_owner);
+ afr_print_entrylk (lock, 256, basename, frame->root->lk_owner);
afr_print_lockee (lockee, 256, &local->loc, local->fd, child_index);
afr_set_lock_call_type (lock_call_type, lock_call_type_str, int_lock);
@@ -358,21 +357,28 @@ afr_trace_entrylk_in (call_frame_t *frame, xlator_t *this,
}
static void
-afr_trace_entrylk_out (call_frame_t *frame, xlator_t *this,
- afr_lock_call_type_t lock_call_type,
- afr_lock_op_type_t lk_op_type, const char *basename,
- int op_ret, int op_errno, int32_t child_index)
+afr_trace_entrylk_out (call_frame_t *frame, afr_lock_call_type_t lock_call_type,
+ afr_lock_op_type_t lk_op_type, const char *basename, int op_ret,
+ int op_errno, int32_t child_index)
{
+ xlator_t *this = NULL;
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
char lock[256];
char lockee[256];
char lock_call_type_str[256];
char verdict[16];
+ this = THIS;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
+
+ if (!priv->entrylk_trace) {
+ return;
+ }
afr_print_lockee (lockee, 256, &local->loc, local->fd, child_index);
@@ -491,7 +497,7 @@ lower_path (loc_t *l1, const char *b1, loc_t *l2, const char *b2)
{
int ret = 0;
- ret = uuid_compare (l1->inode->gfid, l2->inode->gfid);
+ ret = strcmp (l1->path, l2->path);
if (ret == 0)
ret = strcmp (b1, b2);
@@ -520,7 +526,7 @@ afr_locked_nodes_count (unsigned char *locked_nodes, int child_count)
/* FIXME: What if UNLOCK fails */
static int32_t
afr_unlock_common_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_internal_lock_t *int_lock = NULL;
@@ -546,31 +552,23 @@ afr_unlock_common_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int32_t
afr_unlock_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- afr_internal_lock_t *int_lock = NULL;
- int32_t child_index = (long)cookie;
+ afr_local_t *local = NULL;
local = frame->local;
- int_lock = &local->internal_lock;
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_TRANSACTION,
+ afr_trace_inodelk_out (frame, AFR_INODELK_TRANSACTION,
AFR_UNLOCK_OP, NULL, op_ret,
- op_errno, child_index);
+ op_errno, (long) cookie);
if (op_ret < 0 && op_errno != ENOTCONN && op_errno != EBADFD) {
- gf_log (this->name, GF_LOG_INFO, "%s: unlock failed on %d "
- "unlock by %s", local->loc.path, child_index,
- lkowner_utoa (&frame->root->lk_owner));
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: unlock failed %s",
+ local->loc.path, strerror (op_errno));
}
-
- int_lock->inode_locked_nodes[child_index] &= LOCKED_NO;
- if (local->transaction.eager_lock)
- local->transaction.eager_lock[child_index] = 0;
-
- afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
@@ -583,13 +581,8 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
struct gf_flock flock = {0,};
- struct gf_flock full_flock = {0,};
- struct gf_flock *flock_use = NULL;
int call_count = 0;
int i = 0;
- int piggyback = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
-
local = frame->local;
int_lock = &local->internal_lock;
@@ -599,7 +592,6 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)
flock.l_len = int_lock->lk_flock.l_len;
flock.l_type = F_UNLCK;
- full_flock.l_type = F_UNLCK;
call_count = afr_locked_nodes_count (int_lock->inode_locked_nodes,
priv->child_count);
@@ -612,98 +604,55 @@ afr_unlock_inodelk (call_frame_t *frame, xlator_t *this)
goto out;
}
- if (local->fd)
- fd_ctx = afr_fd_ctx_get (local->fd, this);
-
for (i = 0; i < priv->child_count; i++) {
- if ((int_lock->inode_locked_nodes[i] & LOCKED_YES)
- != LOCKED_YES)
- continue;
+ if (int_lock->inode_locked_nodes[i] & LOCKED_YES) {
+ if (local->fd) {
+ afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION,
+ AFR_UNLOCK_OP, &flock, F_SETLK, i);
- if (local->fd) {
- flock_use = &flock;
- if (!local->transaction.eager_lock[i]) {
- goto wind;
- }
-
- piggyback = 0;
-
- LOCK (&local->fd->lock);
- {
- if (fd_ctx->lock_piggyback[i]) {
- fd_ctx->lock_piggyback[i]--;
- piggyback = 1;
- } else {
- fd_ctx->lock_acquired[i]--;
- }
- }
- UNLOCK (&local->fd->lock);
+ STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk,
+ (void *) (long)i,
+ priv->children[i],
+ priv->children[i]->fops->finodelk,
+ this->name, local->fd,
+ F_SETLK, &flock);
- if (piggyback) {
- afr_unlock_inodelk_cbk (frame, (void *) (long) i,
- this, 1, 0, NULL);
if (!--call_count)
break;
- continue;
- }
-
- flock_use = &full_flock;
- wind:
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
- AFR_UNLOCK_OP, flock_use, F_SETLK,
- i);
- STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk,
- (void *) (long)i,
- priv->children[i],
- priv->children[i]->fops->finodelk,
- this->name, local->fd,
- F_SETLK, flock_use, NULL);
+ } else {
+ afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION,
+ AFR_UNLOCK_OP, &flock, F_SETLK, i);
- if (!--call_count)
- break;
+ STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk,
+ (void *) (long)i,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name, &local->loc,
+ F_SETLK, &flock);
- } else {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
- AFR_UNLOCK_OP, &flock, F_SETLK, i);
+ if (!--call_count)
+ break;
- STACK_WIND_COOKIE (frame, afr_unlock_inodelk_cbk,
- (void *) (long)i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- this->name, &local->loc,
- F_SETLK, &flock, NULL);
+ }
- if (!--call_count)
- break;
}
+
}
+
out:
return 0;
}
static int32_t
afr_unlock_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- int32_t child_index = (long)cookie;
-
- local = frame->local;
-
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_out (frame, AFR_ENTRYLK_TRANSACTION,
AFR_UNLOCK_OP, NULL, op_ret,
- op_errno, child_index);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: unlock failed on %d, reason: %s",
- local->loc.path, child_index, strerror (op_errno));
- }
+ op_errno, (long) cookie);
- afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno, NULL);
+ afr_unlock_common_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
@@ -740,8 +689,7 @@ afr_unlock_entrylk (call_frame_t *frame, xlator_t *this)
for (i = 0; i < priv->child_count; i++) {
if (int_lock->entry_locked_nodes[i] & LOCKED_YES) {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_NB_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_NB_TRANSACTION,
AFR_UNLOCK_OP, basename, i);
STACK_WIND_COOKIE (frame, afr_unlock_entrylk_cbk,
@@ -750,7 +698,7 @@ afr_unlock_entrylk (call_frame_t *frame, xlator_t *this)
priv->children[i]->fops->entrylk,
this->name,
loc, basename,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
if (!--call_count)
break;
@@ -764,14 +712,17 @@ out:
static int32_t
afr_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int done = 0;
int child_index = (long) cookie;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
LOCK (&frame->lock);
{
@@ -783,8 +734,10 @@ afr_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"please load features/locks xlator on server");
local->op_ret = op_ret;
int_lock->lock_op_ret = op_ret;
+ done = 1;
}
+ local->child_up[child_index] = 0;
local->op_errno = op_errno;
int_lock->lock_op_errno = op_errno;
}
@@ -796,7 +749,8 @@ afr_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
afr_unlock (frame, this);
} else {
if (op_ret == 0) {
- int_lock->locked_nodes[child_index] |= LOCKED_YES;
+ int_lock->locked_nodes[child_index]
+ |= LOCKED_YES;
int_lock->lock_count++;
}
afr_lock_blocking (frame, this, child_index + 1);
@@ -807,26 +761,27 @@ afr_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int32_t
afr_blocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_TRANSACTION,
+ afr_trace_inodelk_out (frame, AFR_INODELK_TRANSACTION,
AFR_LOCK_OP, NULL, op_ret,
op_errno, (long) cookie);
- afr_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ afr_lock_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
static int32_t
afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_internal_lock_t *int_lock = NULL;
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
loc_t *lower = NULL;
loc_t *higher = NULL;
+ const char *lower_name = NULL;
const char *higher_name = NULL;
int child_index = (long) cookie;
@@ -847,13 +802,13 @@ afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
}
+ local->child_up[child_index] = 0;
local->op_errno = op_errno;
}
}
UNLOCK (&frame->lock);
if (op_ret != 0) {
- afr_copy_locked_nodes (frame, this);
afr_unlock (frame, this);
goto out;
} else {
@@ -868,6 +823,10 @@ afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&local->transaction.new_parent_loc,
local->transaction.new_basename);
+ lower_name = (lower == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
higher = (lower == &local->transaction.parent_loc ?
&local->transaction.new_parent_loc :
&local->transaction.parent_loc);
@@ -876,7 +835,7 @@ afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->transaction.basename :
local->transaction.new_basename);
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, higher_name, child_index);
@@ -885,7 +844,7 @@ afr_lock_lower_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv->children[child_index],
priv->children[child_index]->fops->entrylk,
this->name, higher, higher_name,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
out:
return 0;
@@ -893,13 +852,13 @@ out:
static int32_t
afr_blocking_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_out (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, NULL, op_ret,
op_errno, (long)cookie);
- afr_lock_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ afr_lock_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
@@ -942,8 +901,11 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
+ afr_fd_ctx_t *fd_ctx = NULL;
loc_t *lower = NULL;
+ loc_t *higher = NULL;
const char *lower_name = NULL;
+ const char *higher_name = NULL;
struct gf_flock flock = {0,};
uint64_t ctx = 0;
int ret = 0;
@@ -966,6 +928,8 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
local->op_ret = -1;
int_lock->lock_op_ret = -1;
+ local->op_errno = EINVAL;
+ int_lock->lock_op_errno = EINVAL;
afr_copy_locked_nodes (frame, this);
@@ -974,12 +938,14 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
return 0;
}
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
/* skip over children that or down
or don't have the fd open */
while ((child_index < priv->child_count)
- && (!local->child_up[child_index] ||
- !local->fd_open_on[child_index]))
+ && (!local->child_up[child_index]
+ || !fd_ctx->opened_on[child_index]))
child_index++;
} else {
@@ -997,6 +963,8 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
local->op_ret = -1;
int_lock->lock_op_ret = -1;
+ local->op_errno = EAGAIN;
+ int_lock->lock_op_errno = EAGAIN;
afr_copy_locked_nodes (frame, this);
@@ -1007,7 +975,9 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
}
if ((child_index == priv->child_count)
- || (int_lock->lock_count == int_lock->lk_expected_count)) {
+ || (int_lock->lock_count ==
+ afr_up_children_count (priv->child_count,
+ local->child_up))) {
/* we're done locking */
@@ -1026,8 +996,7 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
case AFR_METADATA_TRANSACTION:
if (local->fd) {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
+ afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION,
AFR_LOCK_OP, &flock, F_SETLKW,
child_index);
@@ -1036,11 +1005,10 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
priv->children[child_index],
priv->children[child_index]->fops->finodelk,
this->name, local->fd,
- F_SETLKW, &flock, NULL);
+ F_SETLKW, &flock);
} else {
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_TRANSACTION,
+ afr_trace_inodelk_in (frame, AFR_INODELK_TRANSACTION,
AFR_LOCK_OP, &flock, F_SETLKW,
child_index);
@@ -1049,7 +1017,7 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
priv->children[child_index],
priv->children[child_index]->fops->inodelk,
this->name, &local->loc,
- F_SETLKW, &flock, NULL);
+ F_SETLKW, &flock);
}
break;
@@ -1065,7 +1033,15 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
local->transaction.basename :
local->transaction.new_basename);
- AFR_TRACE_ENTRYLK_IN (frame, this, AFR_ENTRYLK_TRANSACTION,
+ higher = (lower == &local->transaction.parent_loc ?
+ &local->transaction.new_parent_loc :
+ &local->transaction.parent_loc);
+
+ higher_name = (higher == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, lower_name, child_index);
@@ -1074,15 +1050,14 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
priv->children[child_index],
priv->children[child_index]->fops->entrylk,
this->name, lower, lower_name,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
break;
}
case AFR_ENTRY_TRANSACTION:
if (local->fd) {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, local->transaction.basename,
child_index);
@@ -1092,10 +1067,9 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
priv->children[child_index]->fops->fentrylk,
this->name, local->fd,
local->transaction.basename,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
} else {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, local->transaction.basename,
child_index);
@@ -1106,13 +1080,15 @@ afr_lock_blocking (call_frame_t *frame, xlator_t *this, int child_index)
this->name,
&local->transaction.parent_loc,
local->transaction.basename,
- ENTRYLK_LOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
}
break;
}
return 0;
+
+
}
int32_t
@@ -1121,7 +1097,6 @@ afr_blocking_lock (call_frame_t *frame, xlator_t *this)
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
- int up_count = 0;
priv = this->private;
local = frame->local;
@@ -1134,10 +1109,6 @@ afr_blocking_lock (call_frame_t *frame, xlator_t *this)
break;
case AFR_ENTRY_RENAME_TRANSACTION:
- up_count = afr_up_children_count (local->child_up,
- priv->child_count);
- int_lock->lk_expected_count = 2 * up_count;
- //fallthrough
case AFR_ENTRY_TRANSACTION:
initialize_entrylk_variables (frame, this);
break;
@@ -1150,20 +1121,28 @@ afr_blocking_lock (call_frame_t *frame, xlator_t *this)
static int32_t
afr_nonblocking_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
- int call_count = 0;
- int child_index = (long) cookie;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
- AFR_TRACE_ENTRYLK_OUT (frame, this, AFR_ENTRYLK_TRANSACTION,
+ afr_trace_entrylk_out (frame, AFR_ENTRYLK_TRANSACTION,
AFR_LOCK_OP, NULL, op_ret,
op_errno, (long) cookie);
+ LOCK (&frame->lock);
+ {
+ call_count = --int_lock->lk_call_count;
+ }
+ UNLOCK (&frame->lock);
+
if (op_ret < 0 ) {
if (op_errno == ENOSYS) {
/* return ENOTSUP */
@@ -1173,32 +1152,28 @@ afr_nonblocking_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
int_lock->lock_op_ret = op_ret;
+ local->child_up[child_index] = 0;
int_lock->lock_op_errno = op_errno;
local->op_errno = op_errno;
}
} else if (op_ret == 0) {
- int_lock->entry_locked_nodes[child_index] |= LOCKED_YES;
+ int_lock->entry_locked_nodes[child_index]
+ |= LOCKED_YES;
int_lock->entrylk_lock_count++;
}
- LOCK (&frame->lock);
- {
- call_count = --int_lock->lk_call_count;
- }
- UNLOCK (&frame->lock);
-
if (call_count == 0) {
gf_log (this->name, GF_LOG_TRACE,
"Last locking reply received");
- /* all locks successful. Proceed to call FOP */
+ /* all locks successfull. Proceed to call FOP */
if (int_lock->entrylk_lock_count ==
- int_lock->lk_expected_count) {
+ afr_up_children_count (priv->child_count, local->child_up)) {
gf_log (this->name, GF_LOG_TRACE,
"All servers locked. Calling the cbk");
int_lock->lock_op_ret = 0;
int_lock->lock_cbk (frame, this);
}
- /* Not all locks were successful. Unlock and try locking
+ /* Not all locks were successfull. Unlock and try locking
again, this time with serially blocking locks */
else {
gf_log (this->name, GF_LOG_TRACE,
@@ -1212,20 +1187,6 @@ afr_nonblocking_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-void
-afr_mark_fd_open_on (afr_local_t *local, afr_fd_ctx_t *fd_ctx,
- size_t child_count)
-{
- int i = 0;
-
- GF_ASSERT (local->fd_open_on);
-
- memset (local->fd_open_on, 0, sizeof (*local->fd_open_on)*child_count);
- for (i = 0; i < child_count; i++)
- if (fd_ctx->opened_on[i] == AFR_FD_OPENED)
- local->fd_open_on[i] = 1;
-}
-
int
afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
{
@@ -1237,6 +1198,8 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
loc_t *loc = NULL;
int32_t call_count = 0;
int i = 0;
+ uint64_t ctx = 0;
+ int ret = 0;
local = frame->local;
int_lock = &local->internal_lock;
@@ -1249,8 +1212,9 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
loc = int_lock->lk_loc;
if (local->fd) {
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx) {
+ ret = fd_ctx_get (local->fd, this, &ctx);
+
+ if (ret < 0) {
gf_log (this->name, GF_LOG_INFO,
"unable to get fd ctx for fd=%p",
local->fd);
@@ -1263,10 +1227,10 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
return -1;
}
- afr_mark_fd_open_on (local, fd_ctx, priv->child_count);
- call_count = internal_lock_count (frame, this);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ call_count = internal_lock_count (frame, this, fd_ctx);
int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
if (!call_count) {
gf_log (this->name, GF_LOG_INFO,
@@ -1278,9 +1242,8 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
/* Send non-blocking entrylk calls only on up children
and where the fd has been opened */
for (i = 0; i < priv->child_count; i++) {
- if (local->child_up[i] && local->fd_open_on[i]) {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_NB_TRANSACTION,
+ if (local->child_up[i] && fd_ctx->opened_on[i]) {
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_NB_TRANSACTION,
AFR_LOCK_OP, basename, i);
STACK_WIND_COOKIE (frame, afr_nonblocking_entrylk_cbk,
@@ -1289,21 +1252,18 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
priv->children[i]->fops->fentrylk,
this->name, local->fd,
basename,
- ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
+ ENTRYLK_LOCK_NB, ENTRYLK_WRLCK);
}
}
} else {
GF_ASSERT (loc);
- call_count = internal_lock_count (frame, this);
+ call_count = internal_lock_count (frame, this, NULL);
int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_NB_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_NB_TRANSACTION,
AFR_LOCK_OP, basename, i);
STACK_WIND_COOKIE (frame, afr_nonblocking_entrylk_cbk,
@@ -1311,8 +1271,7 @@ afr_nonblocking_entrylk (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->entrylk,
this->name, loc, basename,
- ENTRYLK_LOCK_NB, ENTRYLK_WRLCK,
- NULL);
+ ENTRYLK_LOCK, ENTRYLK_WRLCK);
if (!--call_count)
break;
@@ -1326,23 +1285,29 @@ out:
int32_t
afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
int call_count = 0;
int child_index = (long) cookie;
- afr_fd_ctx_t *fd_ctx = NULL;
-
local = frame->local;
int_lock = &local->internal_lock;
+ priv = this->private;
- AFR_TRACE_INODELK_OUT (frame, this, AFR_INODELK_NB_TRANSACTION,
+ afr_trace_inodelk_out (frame, AFR_INODELK_NB_TRANSACTION,
AFR_LOCK_OP, NULL, op_ret,
op_errno, (long) cookie);
- if (op_ret < 0) {
+ LOCK (&frame->lock);
+ {
+ call_count = --int_lock->lk_call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (op_ret < 0 ) {
if (op_errno == ENOSYS) {
/* return ENOTSUP */
gf_log (this->name, GF_LOG_ERROR,
@@ -1350,51 +1315,28 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"please load features/locks xlator on server");
local->op_ret = op_ret;
int_lock->lock_op_ret = op_ret;
+ local->child_up[child_index] = 0;
int_lock->lock_op_errno = op_errno;
local->op_errno = op_errno;
}
- if (local->transaction.eager_lock)
- local->transaction.eager_lock[child_index] = 0;
- } else {
+ } else if (op_ret == 0) {
int_lock->inode_locked_nodes[child_index]
|= LOCKED_YES;
int_lock->inodelk_lock_count++;
-
- if (local->transaction.eager_lock &&
- local->transaction.eager_lock[child_index] && local->fd) {
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- /* piggybacked */
-
- if (op_ret == 1) {
- /* piggybacked */
- } else if (op_ret == 0) {
- /* lock acquired from server */
- LOCK (&local->fd->lock);
- {
- fd_ctx->lock_acquired[child_index]++;
- }
- UNLOCK (&local->fd->lock);
- }
- }
}
- LOCK (&frame->lock);
- {
- call_count = --int_lock->lk_call_count;
- }
- UNLOCK (&frame->lock);
if (call_count == 0) {
gf_log (this->name, GF_LOG_TRACE,
"Last inode locking reply received");
- /* all locks successful. Proceed to call FOP */
+ /* all locks successfull. Proceed to call FOP */
if (int_lock->inodelk_lock_count ==
- int_lock->lk_expected_count) {
+ afr_up_children_count (priv->child_count, local->child_up)) {
gf_log (this->name, GF_LOG_TRACE,
"All servers locked. Calling the cbk");
int_lock->lock_op_ret = 0;
int_lock->lock_cbk (frame, this);
}
- /* Not all locks were successful. Unlock and try locking
+ /* Not all locks were successfull. Unlock and try locking
again, this time with serially blocking locks */
else {
gf_log (this->name, GF_LOG_TRACE,
@@ -1415,13 +1357,11 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
afr_fd_ctx_t *fd_ctx = NULL;
- int32_t call_count = 0;
- int i = 0;
- int ret = 0;
- struct gf_flock flock = {0,};
- struct gf_flock full_flock = {0,};
- struct gf_flock *flock_use = NULL;
- int piggyback = 0;
+ int32_t call_count = 0;
+ uint64_t ctx = 0;
+ int i = 0;
+ int ret = 0;
+ struct gf_flock flock = {0,};
local = frame->local;
int_lock = &local->internal_lock;
@@ -1431,13 +1371,12 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)
flock.l_len = int_lock->lk_flock.l_len;
flock.l_type = int_lock->lk_flock.l_type;
- full_flock.l_type = int_lock->lk_flock.l_type;
-
initialize_inodelk_variables (frame, this);
if (local->fd) {
- fd_ctx = afr_fd_ctx_get (local->fd, this);
- if (!fd_ctx) {
+ ret = fd_ctx_get (local->fd, this, &ctx);
+
+ if (ret < 0) {
gf_log (this->name, GF_LOG_INFO,
"unable to get fd ctx for fd=%p",
local->fd);
@@ -1451,10 +1390,10 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)
goto out;
}
- afr_mark_fd_open_on (local, fd_ctx, priv->child_count);
- call_count = internal_lock_count (frame, this);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ call_count = internal_lock_count (frame, this, fd_ctx);
int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
if (!call_count) {
gf_log (this->name, GF_LOG_INFO,
@@ -1466,75 +1405,46 @@ afr_nonblocking_inodelk (call_frame_t *frame, xlator_t *this)
/* Send non-blocking inodelk calls only on up children
and where the fd has been opened */
for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i] || !local->fd_open_on[i])
- continue;
-
- flock_use = &flock;
- if (!priv->eager_lock) {
- goto wind;
- }
-
- piggyback = 0;
- local->transaction.eager_lock[i] = 1;
+ if (local->child_up[i] && fd_ctx->opened_on[i]) {
+ afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION,
+ AFR_LOCK_OP, &flock, F_SETLK, i);
- afr_set_delayed_post_op (frame, this);
-
- LOCK (&local->fd->lock);
- {
- if (fd_ctx->lock_acquired[i]) {
- fd_ctx->lock_piggyback[i]++;
- piggyback = 1;
- }
- }
- UNLOCK (&local->fd->lock);
+ STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->finodelk,
+ this->name, local->fd,
+ F_SETLK, &flock);
- if (piggyback) {
- /* (op_ret == 1) => indicate piggybacked lock */
- afr_nonblocking_inodelk_cbk (frame, (void *) (long) i,
- this, 1, 0, NULL);
if (!--call_count)
break;
- continue;
- }
- flock_use = &full_flock;
- wind:
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_NB_TRANSACTION,
- AFR_LOCK_OP, flock_use, F_SETLK, i);
- STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->finodelk,
- this->name, local->fd,
- F_SETLK, flock_use, NULL);
+ }
- if (!--call_count)
- break;
}
} else {
- call_count = internal_lock_count (frame, this);
+ call_count = internal_lock_count (frame, this, NULL);
int_lock->lk_call_count = call_count;
- int_lock->lk_expected_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i])
- continue;
- AFR_TRACE_INODELK_IN (frame, this,
- AFR_INODELK_NB_TRANSACTION,
- AFR_LOCK_OP, &flock, F_SETLK, i);
+ if (local->child_up[i]) {
+ afr_trace_inodelk_in (frame, AFR_INODELK_NB_TRANSACTION,
+ AFR_LOCK_OP, &flock, F_SETLK, i);
- STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->inodelk,
- this->name, &local->loc,
- F_SETLK, &flock, NULL);
+ STACK_WIND_COOKIE (frame, afr_nonblocking_inodelk_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->inodelk,
+ this->name, &local->loc,
+ F_SETLK, &flock);
- if (!--call_count)
- break;
+ if (!--call_count)
+ break;
+
+ }
}
}
+
out:
return ret;
}
@@ -1614,8 +1524,7 @@ afr_unlock_lower_entrylk (call_frame_t *frame, xlator_t *this)
for (i = 0; i < priv->child_count; i++) {
if (int_lock->lower_locked_nodes[i] & LOCKED_LOWER) {
- AFR_TRACE_ENTRYLK_IN (frame, this,
- AFR_ENTRYLK_NB_TRANSACTION,
+ afr_trace_entrylk_in (frame, AFR_ENTRYLK_NB_TRANSACTION,
AFR_UNLOCK_OP, basename, i);
STACK_WIND_COOKIE (frame, afr_unlock_entrylk_cbk,
@@ -1624,7 +1533,7 @@ afr_unlock_lower_entrylk (call_frame_t *frame, xlator_t *this)
priv->children[i]->fops->entrylk,
this->name,
loc, basename,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
if (!--call_count)
break;
@@ -1656,6 +1565,7 @@ afr_post_unlock_lower_cbk (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
loc_t *lower = NULL;
loc_t *higher = NULL;
+ const char *lower_name = NULL;
const char *higher_name = NULL;
local = frame->local;
@@ -1666,6 +1576,10 @@ afr_post_unlock_lower_cbk (call_frame_t *frame, xlator_t *this)
&local->transaction.new_parent_loc,
local->transaction.new_basename);
+ lower_name = (lower == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
higher = (lower == &local->transaction.parent_loc ?
&local->transaction.new_parent_loc :
&local->transaction.parent_loc);
@@ -1694,7 +1608,9 @@ afr_rename_unlock (call_frame_t *frame, xlator_t *this)
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
loc_t *lower = NULL;
+ loc_t *higher = NULL;
const char *lower_name = NULL;
+ const char *higher_name = NULL;
local = frame->local;
int_lock = &local->internal_lock;
@@ -1708,6 +1624,15 @@ afr_rename_unlock (call_frame_t *frame, xlator_t *this)
local->transaction.basename :
local->transaction.new_basename);
+ higher = (lower == &local->transaction.parent_loc ?
+ &local->transaction.new_parent_loc :
+ &local->transaction.parent_loc);
+
+ higher_name = (higher == &local->transaction.parent_loc ?
+ local->transaction.basename :
+ local->transaction.new_basename);
+
+
if (__is_lower_locked (frame, this)) {
gf_log (this->name, GF_LOG_DEBUG,
"unlocking lower");
@@ -1917,12 +1842,10 @@ out:
int32_t
afr_get_locks_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata);
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock);
int32_t
afr_recover_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -1946,7 +1869,7 @@ afr_recover_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
(void *) (long) source_child,
priv->children[source_child],
priv->children[source_child]->fops->lk,
- local->fd, F_GETLK_FD, &flock, NULL);
+ local->fd, F_GETLK_FD, &flock);
return 0;
@@ -1974,7 +1897,7 @@ afr_recover_lock (call_frame_t *frame, xlator_t *this,
(void *) (long) lock_recovery_child,
priv->children[lock_recovery_child],
priv->children[lock_recovery_child]->fops->lk,
- local->fd, F_SETLK, flock, NULL);
+ local->fd, F_SETLK, flock);
return 0;
}
@@ -1992,8 +1915,7 @@ is_afr_lock_eol (struct gf_flock *lock)
int32_t
afr_get_locks_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
if (op_ret) {
gf_log (this->name, GF_LOG_INFO,
@@ -2053,7 +1975,7 @@ afr_lock_recovery (call_frame_t *frame, xlator_t *this)
(void *) (long) source_child,
priv->children[source_child],
priv->children[source_child]->fops->lk,
- local->fd, F_GETLK_FD, &flock, NULL);
+ local->fd, F_GETLK_FD, &flock);
out:
return ret;
@@ -2073,7 +1995,7 @@ afr_mark_fd_opened (xlator_t *this, fd_t *fd, int32_t child_index)
fdctx = (afr_fd_ctx_t *) (long) tmp;
- fdctx->opened_on[child_index] = AFR_FD_OPENED;
+ fdctx->opened_on[child_index] = 1;
out:
return ret;
@@ -2081,8 +2003,7 @@ out:
int32_t
afr_lock_recovery_preopen_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
int32_t child_index = (long )cookie;
int ret = 0;
@@ -2134,12 +2055,7 @@ afr_lock_recovery_preopen (call_frame_t *frame, xlator_t *this)
GF_ASSERT (local && local->fd);
ret = fd_ctx_get (local->fd, this, &tmp);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to get the context of fd",
- uuid_utoa (local->fd->inode->gfid));
fdctx = (afr_fd_ctx_t *) (long) tmp;
- /* TODO: instead we should return from the function */
GF_ASSERT (fdctx);
child_index = local->lock_recovery_child;
@@ -2154,7 +2070,8 @@ afr_lock_recovery_preopen (call_frame_t *frame, xlator_t *this)
(void *)(long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->open,
- &loc, fdctx->flags, local->fd, NULL);
+ &loc, fdctx->flags, local->fd,
+ fdctx->wbflags);
return 0;
}
@@ -2172,7 +2089,7 @@ is_fd_opened (fd_t *fd, int32_t child_index)
fdctx = (afr_fd_ctx_t *) (long) tmp;
- if (fdctx->opened_on[child_index] == AFR_FD_OPENED)
+ if (fdctx->opened_on[child_index])
ret = 1;
out:
@@ -2182,14 +2099,13 @@ out:
int
afr_attempt_lock_recovery (xlator_t *this, int32_t child_index)
{
- call_frame_t *frame = NULL;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_locked_fd_t *locked_fd = NULL;
+ call_frame_t *frame = NULL;
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+ afr_locked_fd_t *locked_fd = NULL;
afr_locked_fd_t *tmp = NULL;
- int ret = -1;
+ int ret = 0;
struct list_head locks_list = {0,};
- int32_t op_errno = 0;
priv = this->private;
@@ -2203,10 +2119,15 @@ afr_attempt_lock_recovery (xlator_t *this, int32_t child_index)
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0) {
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_afr_mt_afr_local_t);
+ if (!local) {
+ ret = -1;
+ goto out;
+ }
+
+ AFR_LOCAL_INIT (local, priv);
+ if (!local) {
ret = -1;
goto out;
}
@@ -2244,34 +2165,5 @@ afr_attempt_lock_recovery (xlator_t *this, int32_t child_index)
}
out:
- if ((ret < 0) && frame)
- AFR_STACK_DESTROY (frame);
return ret;
}
-
-void
-afr_lk_transfer_datalock (call_frame_t *dst, call_frame_t *src,
- unsigned int child_count)
-{
- afr_local_t *dst_local = NULL;
- afr_local_t *src_local = NULL;
- afr_internal_lock_t *dst_lock = NULL;
- afr_internal_lock_t *src_lock = NULL;
-
- dst_local = dst->local;
- dst_lock = &dst_local->internal_lock;
- src_local = src->local;
- src_lock = &src_local->internal_lock;
- if (src_lock->inode_locked_nodes) {
- memcpy (dst_lock->inode_locked_nodes,
- src_lock->inode_locked_nodes,
- sizeof (*dst_lock->inode_locked_nodes) * child_count);
- memset (src_lock->inode_locked_nodes, 0,
- sizeof (*src_lock->inode_locked_nodes) * child_count);
- }
-
- dst_lock->transaction_lk_type = src_lock->transaction_lk_type;
- dst_lock->selfheal_lk_type = src_lock->selfheal_lk_type;
- dst_lock->inodelk_lock_count = src_lock->inodelk_lock_count;
- src_lock->inodelk_lock_count = 0;
-}
diff --git a/xlators/cluster/afr/src/afr-mem-types.h b/xlators/cluster/afr/src/afr-mem-types.h
index 7e684801f..14064ebcd 100644
--- a/xlators/cluster/afr/src/afr-mem-types.h
+++ b/xlators/cluster/afr/src/afr-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -17,6 +26,7 @@
enum gf_afr_mem_types_ {
gf_afr_mt_iovec = gf_common_mt_end + 1,
gf_afr_mt_afr_fd_ctx_t,
+ gf_afr_mt_afr_local_t,
gf_afr_mt_afr_private_t,
gf_afr_mt_int32_t,
gf_afr_mt_char,
@@ -32,15 +42,6 @@ enum gf_afr_mem_types_ {
gf_afr_mt_entry_name,
gf_afr_mt_pump_priv,
gf_afr_mt_locked_fd,
- gf_afr_mt_inode_ctx_t,
- gf_afr_fd_paused_call_t,
- gf_afr_mt_crawl_data_t,
- gf_afr_mt_brick_pos_t,
- gf_afr_mt_shd_bool_t,
- gf_afr_mt_shd_timer_t,
- gf_afr_mt_shd_event_t,
- gf_afr_mt_time_t,
- gf_afr_mt_pos_data_t,
gf_afr_mt_end
};
#endif
diff --git a/xlators/cluster/afr/src/afr-open.c b/xlators/cluster/afr/src/afr-open.c
index c0be197f2..e6304a5ea 100644
--- a/xlators/cluster/afr/src/afr-open.c
+++ b/xlators/cluster/afr/src/afr-open.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -46,84 +55,16 @@
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
-int
-afr_stale_child_up (afr_local_t *local, xlator_t *this)
-{
- int i = 0;
- afr_private_t *priv = NULL;
- int up = -1;
-
- priv = this->private;
-
- if (!local->fresh_children)
- local->fresh_children = afr_children_create (priv->child_count);
- if (!local->fresh_children)
- goto out;
-
- afr_inode_get_read_ctx (this, local->fd->inode, local->fresh_children);
- if (priv->child_count == afr_get_children_count (local->fresh_children,
- priv->child_count))
- goto out;
-
- for (i = 0; i < priv->child_count; i++) {
- if (!local->child_up[i])
- continue;
- if (afr_is_child_present (local->fresh_children,
- priv->child_count, i))
- continue;
- up = i;
- break;
- }
-out:
- return up;
-}
-
-void
-afr_perform_data_self_heal (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- inode_t *inode = NULL;
- int st_child = -1;
- char reason[64] = {0};
-
- local = frame->local;
- sh = &local->self_heal;
- inode = local->fd->inode;
-
- if (!IA_ISREG (inode->ia_type))
- goto out;
-
- st_child = afr_stale_child_up (local, this);
- if (st_child < 0)
- goto out;
-
- sh->do_data_self_heal = _gf_true;
- sh->do_metadata_self_heal = _gf_true;
- sh->do_gfid_self_heal = _gf_true;
- sh->do_missing_entry_self_heal = _gf_true;
-
- snprintf (reason, sizeof (reason), "stale subvolume %d detected",
- st_child);
- afr_launch_self_heal (frame, this, inode, _gf_true, inode->ia_type,
- reason, NULL, NULL);
-out:
- return;
-}
int
afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_local_t * local = frame->local;
- afr_private_t *priv = NULL;
- priv = this->private;
- if (afr_open_only_data_self_heal (priv->data_self_heal))
- afr_perform_data_self_heal (frame, this);
AFR_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
- local->fd, xdata);
+ local->fd);
return 0;
}
@@ -131,15 +72,15 @@ afr_open_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_open_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
afr_local_t * local = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
int ret = 0;
int call_count = -1;
int child_index = (long) cookie;
- afr_private_t *priv = NULL;
- priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -152,13 +93,32 @@ afr_open_cbk (call_frame_t *frame, void *cookie,
local->op_ret = op_ret;
local->success_count++;
- ret = afr_child_fd_ctx_set (this, fd, child_index,
- local->cont.open.flags);
- if (ret) {
- local->op_ret = -1;
+ ret = afr_fd_ctx_set (this, fd);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not set fd ctx for fd=%p", fd);
+
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ goto unlock;
+ }
+
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not get fd ctx for fd=%p", fd);
+ local->op_ret = -1;
local->op_errno = -ret;
goto unlock;
}
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ fd_ctx->opened_on[child_index] = 1;
+ fd_ctx->flags = local->cont.open.flags;
+ fd_ctx->wbflags = local->cont.open.wbflags;
}
}
unlock:
@@ -171,30 +131,29 @@ unlock:
&& (local->op_ret >= 0)) {
STACK_WIND (frame, afr_open_ftruncate_cbk,
this, this->fops->ftruncate,
- fd, 0, NULL);
+ fd, 0);
} else {
- if (afr_open_only_data_self_heal (priv->data_self_heal))
- afr_perform_data_self_heal (frame, this);
AFR_STACK_UNWIND (open, frame, local->op_ret,
- local->op_errno, local->fd, xdata);
+ local->op_errno, local->fd);
}
}
return 0;
}
+
int
afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
int i = 0;
int ret = -1;
int32_t call_count = 0;
+ int32_t op_ret = -1;
int32_t op_errno = 0;
int32_t wind_flags = flags & (~O_TRUNC);
- //We can't let truncation to happen outside transaction.
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -203,10 +162,6 @@ afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
priv = this->private;
- if (flags & (O_CREAT|O_TRUNC)) {
- QUORUM_CHECK(open,out);
- }
-
if (afr_is_split_brain (this, loc->inode)) {
/* self-heal failed */
gf_log (this->name, GF_LOG_WARNING,
@@ -215,17 +170,21 @@ afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
+ ret = AFR_LOCAL_INIT (local, priv);
+ if (ret < 0) {
+ op_errno = -ret;
goto out;
+ }
+ frame->local = local;
call_count = local->call_count;
+
loc_copy (&local->loc, loc);
local->cont.open.flags = flags;
+ local->cont.open.wbflags = wbflags;
local->fd = fd_ref (fd);
@@ -234,213 +193,462 @@ afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
STACK_WIND_COOKIE (frame, afr_open_cbk, (void *) (long) i,
priv->children[i],
priv->children[i]->fops->open,
- loc, wind_flags, fd, xdata);
+ loc, wind_flags, fd, wbflags);
if (!--call_count)
break;
}
}
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (open, frame, -1, op_errno, fd, xdata);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
+ }
return 0;
}
-//NOTE: this function should be called with holding the lock on
-//fd to which fd_ctx belongs
-void
-afr_get_resumable_calls (xlator_t *this, afr_fd_ctx_t *fd_ctx,
- struct list_head *list)
+
+int
+afr_openfd_sh_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- afr_fd_paused_call_t *paused_call = NULL;
- afr_fd_paused_call_t *tmp = NULL;
- afr_local_t *call_local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- gf_boolean_t call = _gf_false;
+ afr_internal_lock_t *int_lock = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ uint64_t ctx = 0;
+ int ret = 0;
+ int call_count = 0;
+ int child_index = (long) cookie;
- priv = this->private;
- list_for_each_entry_safe (paused_call, tmp, &fd_ctx->paused_calls,
- call_list) {
- call = _gf_true;
- call_local = paused_call->frame->local;
- for (i = 0; i < priv->child_count; i++) {
- if (call_local->child_up[i] &&
- (fd_ctx->opened_on[i] == AFR_FD_OPENING))
- call = _gf_false;
- }
+ priv = this->private;
+ local = frame->local;
+ int_lock = &local->internal_lock;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret >= 0) {
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get fd context, %p", fd);
+ goto out;
+ }
- if (call) {
- list_del_init (&paused_call->call_list);
- list_add (&paused_call->call_list, list);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ fd_ctx->opened_on[child_index] = 1;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "fd for %s opened successfully on subvolume %s",
+ local->loc.path, priv->children[child_index]->name);
}
}
+out:
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ int_lock->lock_cbk = local->transaction.done;
+ local->transaction.resume (frame, this);
+ }
+
+ return 0;
}
-void
-afr_resume_calls (xlator_t *this, struct list_head *list)
+
+static int
+__unopened_count (int child_count, unsigned int *opened_on, unsigned char *child_up)
{
- afr_fd_paused_call_t *paused_call = NULL;
- afr_fd_paused_call_t *tmp = NULL;
- afr_local_t *call_local = NULL;
-
- list_for_each_entry_safe (paused_call, tmp, list, call_list) {
- list_del_init (&paused_call->call_list);
- call_local = paused_call->frame->local;
- call_local->fop_call_continue (paused_call->frame, this);
- GF_FREE (paused_call);
+ int i = 0;
+ int count = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (!opened_on[i] && child_up[i])
+ count++;
}
+
+ return count;
}
+
int
-afr_openfd_fix_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+afr_openfd_sh_unwind (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_fd_ctx_t *fd_ctx = NULL;
- int call_count = 0;
- int child_index = (long) cookie;
- struct list_head paused_calls = {0};
- gf_boolean_t fop_paused = _gf_false;
- fd_t *local_fd = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int abandon = 0;
+ int ret = 0;
+ int i = 0;
+ int call_count = 0;
- priv = this->private;
- local = frame->local;
- fop_paused = local->fop_paused;
-
- if (op_ret >= 0) {
- gf_log (this->name, GF_LOG_INFO, "fd for %s opened "
- "successfully on subvolume %s", local->loc.path,
- priv->children[child_index]->name);
- }
+ priv = this->private;
+ local = frame->local;
- local_fd = fd_ref (local->fd);
- call_count = afr_frame_return (frame);
- //Note: Do not access any thing using the frame outside call_count 0
+ /*
+ * Some subvolumes might have come up on which we never
+ * opened this fd in the first place. Re-open fd's on those
+ * subvolumes now.
+ */
- //Note: No frame locking needed for this block of code
- fd_ctx = afr_fd_ctx_get (local_fd, this);
- if (!fd_ctx) {
+ ret = fd_ctx_get (local->fd, this, &ctx);
+ if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
- "failed to get fd context, %p", local_fd);
+ "failed to get fd context %p (%s)",
+ local->fd, local->loc.path);
+ abandon = 1;
goto out;
}
- LOCK (&local_fd->lock);
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ LOCK (&local->fd->lock);
{
- if (op_ret >= 0) {
- fd_ctx->opened_on[child_index] = AFR_FD_OPENED;
- } else {
- fd_ctx->opened_on[child_index] = AFR_FD_NOT_OPENED;
+ call_count = __unopened_count (priv->child_count,
+ fd_ctx->opened_on,
+ local->child_up);
+ for (i = 0; i < priv->child_count; i++) {
+ fd_ctx->pre_op_done[i] = 0;
+ fd_ctx->pre_op_piggyback[i] = 0;
}
- if (call_count == 0) {
- INIT_LIST_HEAD (&paused_calls);
- afr_get_resumable_calls (this, fd_ctx, &paused_calls);
+ }
+ UNLOCK (&local->fd->lock);
+
+ if (call_count == 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "fd not open on any subvolume %p (%s)",
+ local->fd, local->loc.path);
+ abandon = 1;
+ goto out;
+ }
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (!fd_ctx->opened_on[i] && local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "opening fd for %s on subvolume %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_openfd_sh_open_cbk,
+ (void *)(long) i,
+ priv->children[i],
+ priv->children[i]->fops->open,
+ &local->loc, fd_ctx->flags, local->fd,
+ fd_ctx->wbflags);
+
+ if (!--call_count)
+ break;
}
}
- UNLOCK (&local_fd->lock);
+
out:
- if (call_count == 0) {
- afr_resume_calls (this, &paused_calls);
- //If the fop is paused then resume_calls will continue the fop
- if (fop_paused)
- goto done;
-
- if (local->fop_call_continue)
- local->fop_call_continue (frame, this);
- else
- AFR_STACK_DESTROY (frame);
+ if (abandon)
+ local->transaction.resume (frame, this);
+
+ return 0;
+}
+
+
+static int
+afr_prepare_loc (call_frame_t *frame, fd_t *fd)
+{
+ afr_local_t *local = NULL;
+ char *name = NULL;
+ char *path = NULL;
+ int ret = 0;
+
+ if ((!fd) || (!fd->inode))
+ return -1;
+
+ local = frame->local;
+ ret = inode_path (fd->inode, NULL, (char **)&path);
+ if (ret <= 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "Unable to get path for gfid: %s",
+ uuid_utoa (fd->inode->gfid));
+ return -1;
+ }
+
+ if (local->loc.path) {
+ if (strcmp (path, local->loc.path))
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "overwriting old loc->path %s with %s",
+ local->loc.path, path);
+ GF_FREE ((char *)local->loc.path);
+ }
+ local->loc.path = path;
+
+ name = strrchr (local->loc.path, '/');
+ if (name)
+ name++;
+ local->loc.name = name;
+
+ if (local->loc.inode) {
+ inode_unref (local->loc.inode);
}
+ local->loc.inode = inode_ref (fd->inode);
+
+ if (local->loc.parent) {
+ inode_unref (local->loc.parent);
+ }
+
+ local->loc.parent = inode_parent (local->loc.inode, 0, NULL);
-done:
- fd_unref (local_fd);
return 0;
}
+
int
-afr_fix_open (call_frame_t *frame, xlator_t *this, afr_fd_ctx_t *fd_ctx,
- int need_open_count, int *need_open)
+afr_openfd_sh (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int i = 0;
- call_frame_t *open_frame = NULL;
- afr_local_t *open_local = NULL;
- int ret = -1;
- ia_type_t ia_type = IA_INVAL;
- int32_t op_errno = 0;
-
- GF_ASSERT (fd_ctx);
- GF_ASSERT (need_open_count > 0);
- GF_ASSERT (need_open);
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ char sh_type_str[256] = {0,};
local = frame->local;
+ sh = &local->self_heal;
+
+ GF_ASSERT (local->loc.path);
+ /* forcibly trigger missing-entries self-heal */
+
+ local->success_count = 1;
+ local->enoent_count = 1;
+
+ sh->data_lock_held = _gf_true;
+ sh->need_data_self_heal = _gf_true;
+ sh->type = local->fd->inode->ia_type;
+ sh->background = _gf_false;
+ sh->unwind = afr_openfd_sh_unwind;
+
+ afr_self_heal_type_str_get(&local->self_heal,
+ sh_type_str,
+ sizeof(sh_type_str));
+ gf_log (this->name, GF_LOG_INFO, "%s self-heal triggered. "
+ "path: %s, reason: Replicate up down flush, data lock is held",
+ sh_type_str, local->loc.path);
+
+ afr_self_heal (frame, this);
+
+ return 0;
+}
+
+
+int
+afr_openfd_flush_done (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t *priv = NULL;
+ afr_local_t *local = NULL;
+
+ uint64_t ctx;
+ afr_fd_ctx_t * fd_ctx = NULL;
+
+ int _ret = -1;
+
priv = this->private;
- if (!local->fop_call_continue) {
- open_frame = copy_frame (frame);
- if (!open_frame) {
- ret = -ENOMEM;
+ local = frame->local;
+
+ LOCK (&local->fd->lock);
+ {
+ _ret = __fd_ctx_get (local->fd, this, &ctx);
+ if (_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get fd context %p (%s)",
+ local->fd, local->loc.path);
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (open_frame->local, out);
- open_local = open_frame->local;
- ret = afr_local_init (open_local, priv, &op_errno);
- if (ret < 0)
- goto out;
- loc_copy (&open_local->loc, &local->loc);
- open_local->fd = fd_ref (local->fd);
- } else {
- ret = 0;
- open_frame = frame;
- open_local = local;
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ fd_ctx->down_count = priv->down_count;
+ fd_ctx->up_count = priv->up_count;
}
+out:
+ UNLOCK (&local->fd->lock);
- open_local->call_count = need_open_count;
+ afr_local_transaction_cleanup (local, this);
- gf_log (this->name, GF_LOG_DEBUG, "need open count: %d",
- need_open_count);
+ gf_log (this->name, GF_LOG_TRACE,
+ "The up/down flush is over");
- ia_type = open_local->fd->inode->ia_type;
- GF_ASSERT (ia_type != IA_INVAL);
- for (i = 0; i < priv->child_count; i++) {
- if (!need_open[i])
- continue;
- if (IA_IFDIR == ia_type) {
- gf_log (this->name, GF_LOG_DEBUG,
- "opening fd for dir %s on subvolume %s",
- local->loc.path, priv->children[i]->name);
+ fd_unref (local->fd);
+ local->openfd_flush_cbk (frame, this);
- STACK_WIND_COOKIE (open_frame, afr_openfd_fix_open_cbk,
- (void*) (long) i,
- priv->children[i],
- priv->children[i]->fops->opendir,
- &open_local->loc, open_local->fd,
- NULL);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "opening fd for file %s on subvolume %s",
+ return 0;
+}
+
+
+
+int
+afr_openfd_xaction (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ afr_local_t * local = NULL;
+
+ VALIDATE_OR_GOTO (frame, out);
+ VALIDATE_OR_GOTO (this, out);
+ VALIDATE_OR_GOTO (this->private, out);
+
+ local = frame->local;
+
+ local->op = GF_FOP_FLUSH;
+
+ local->transaction.fop = afr_openfd_sh;
+ local->transaction.done = afr_openfd_flush_done;
+
+ local->transaction.start = 0;
+ local->transaction.len = 0;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "doing up/down flush on fd=%p", fd);
+
+ afr_transaction (frame, this, AFR_DATA_TRANSACTION);
+
+out:
+ return 0;
+}
+
+
+
+int
+afr_openfd_xaction_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
+{
+ afr_internal_lock_t *int_lock = NULL;
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int ret = 0;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
+
+ priv = this->private;
+ local = frame->local;
+ int_lock = &local->internal_lock;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret >= 0) {
+ ret = fd_ctx_get (fd, this, &ctx);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get fd context %p (%s)",
+ fd, local->loc.path);
+ goto out;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ fd_ctx->opened_on[child_index] = 1;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "fd for %s opened successfully on subvolume %s",
+ local->loc.path, priv->children[child_index]->name);
+ }
+ }
+out:
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ afr_openfd_xaction (frame, this, local->fd);
+ }
+
+ return 0;
+}
+
+
+int
+afr_openfd_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ uint64_t ctx = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int no_open = 0;
+ int ret = 0;
+ int i = 0;
+ int call_count = 0;
+
+ priv = this->private;
+ local = frame->local;
+
+ /*
+ * If the file is already deleted while the fd is open, no need to
+ * perform the openfd flush, call the flush_cbk and get out.
+ */
+ ret = afr_prepare_loc (frame, fd);
+ if (ret < 0) {
+ local->openfd_flush_cbk (frame, this);
+ goto out;
+ }
+
+ /*
+ * Some subvolumes might have come up on which we never
+ * opened this fd in the first place. Re-open fd's on those
+ * subvolumes now.
+ */
+
+ local->fd = fd_ref (fd);
+
+ ret = fd_ctx_get (fd, this, &ctx);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get fd context %p (%s)",
+ fd, local->loc.path);
+ no_open = 1;
+ goto out;
+ }
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+
+ LOCK (&local->fd->lock);
+ {
+ call_count = __unopened_count (priv->child_count,
+ fd_ctx->opened_on,
+ local->child_up);
+ }
+ UNLOCK (&local->fd->lock);
+
+ if (call_count == 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "fd not open on any subvolume %p (%s)",
+ fd, local->loc.path);
+ no_open = 1;
+ goto out;
+ }
+
+ local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (!fd_ctx->opened_on[i] && local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "opening fd for %s on subvolume %s",
local->loc.path, priv->children[i]->name);
- STACK_WIND_COOKIE (open_frame, afr_openfd_fix_open_cbk,
+ STACK_WIND_COOKIE (frame, afr_openfd_xaction_open_cbk,
(void *)(long) i,
priv->children[i],
priv->children[i]->fops->open,
- &open_local->loc,
- fd_ctx->flags & (~O_TRUNC),
- open_local->fd, NULL);
- }
+ &local->loc, fd_ctx->flags, fd,
+ fd_ctx->wbflags);
+ if (!--call_count)
+ break;
+ }
}
- op_errno = 0;
- ret = 0;
+
out:
- if (op_errno)
- ret = -op_errno;
- if (ret && open_frame)
- AFR_STACK_DESTROY (open_frame);
- return ret;
+ if (no_open)
+ afr_openfd_xaction (frame, this, fd);
+
+ return 0;
}
diff --git a/xlators/cluster/afr/src/afr-self-heal-algorithm.c b/xlators/cluster/afr/src/afr-self-heal-algorithm.c
index 201e12c52..b28889fbd 100644
--- a/xlators/cluster/afr/src/afr-self-heal-algorithm.c
+++ b/xlators/cluster/afr/src/afr-self-heal-algorithm.c
@@ -1,15 +1,23 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
-#include <openssl/md5.h>
#include "glusterfs.h"
#include "afr.h"
#include "xlator.h"
@@ -25,6 +33,7 @@
#include "compat-errno.h"
#include "compat.h"
#include "byte-order.h"
+#include "md5.h"
#include "afr-transaction.h"
#include "afr-self-heal.h"
@@ -35,288 +44,303 @@
This file contains the various self-heal algorithms
*/
-static int
-sh_loop_driver (call_frame_t *sh_frame, xlator_t *this,
- gf_boolean_t is_first_call, call_frame_t *old_loop_frame);
-static int
-sh_loop_return (call_frame_t *sh_frame, xlator_t *this, call_frame_t *loop_frame,
- int32_t op_ret, int32_t op_errno);
-static int
-sh_destroy_frame (call_frame_t *frame, xlator_t *this)
-{
- if (!frame)
- goto out;
- AFR_STACK_DESTROY (frame);
-out:
- return 0;
-}
+/*
+ The "full" algorithm. Copies the entire file from
+ source to sinks.
+*/
+
static void
-sh_private_cleanup (call_frame_t *frame, xlator_t *this)
+sh_full_private_cleanup (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_sh_algo_private_t *sh_priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_full_private_t *sh_priv = NULL;
local = frame->local;
sh = &local->self_heal;
sh_priv = sh->private;
- GF_FREE (sh_priv);
-}
-static int
-sh_number_of_writes_needed (unsigned char *write_needed, int child_count)
-{
- int writes = 0;
- int i = 0;
-
- for (i = 0; i < child_count; i++) {
- if (write_needed[i])
- writes++;
- }
-
- return writes;
+ if (sh_priv)
+ GF_FREE (sh_priv);
}
static int
-sh_loop_driver_done (call_frame_t *sh_frame, xlator_t *this,
- call_frame_t *last_loop_frame)
+sh_full_loop_driver (call_frame_t *frame, xlator_t *this, gf_boolean_t is_first_call);
+
+static int
+sh_full_loop_driver_done (call_frame_t *frame, xlator_t *this)
{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_sh_algo_private_t *sh_priv = NULL;
- int32_t total_blocks = 0;
- int32_t diff_blocks = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_sh_algo_full_private_t *sh_priv = NULL;
- local = sh_frame->local;
- sh = &local->self_heal;
- sh_priv = sh->private;
- if (sh_priv) {
- total_blocks = sh_priv->total_blocks;
- diff_blocks = sh_priv->diff_blocks;
- }
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ sh_priv = sh->private;
- sh_private_cleanup (sh_frame, this);
+ sh_full_private_cleanup (frame, this);
if (sh->op_failed) {
- GF_ASSERT (!last_loop_frame);
- //loop_finish should have happened and the old_loop should be NULL
gf_log (this->name, GF_LOG_INFO,
- "self-heal aborting on %s",
+ "full self-heal aborting on %s",
local->loc.path);
- local->self_heal.algo_abort_cbk (sh_frame, this);
+ local->self_heal.algo_abort_cbk (frame, this);
} else {
- GF_ASSERT (last_loop_frame);
- if (diff_blocks == total_blocks) {
- gf_log (this->name, GF_LOG_INFO, "full self-heal "
- "completed on %s",local->loc.path);
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "diff self-heal on %s: completed. "
- "(%d blocks of %d were different (%.2f%%))",
- local->loc.path, diff_blocks, total_blocks,
- ((diff_blocks * 1.0)/total_blocks) * 100);
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "full self-heal completed on %s",
+ local->loc.path);
- sh->old_loop_frame = last_loop_frame;
- local->self_heal.algo_completion_cbk (sh_frame, this);
+ local->self_heal.algo_completion_cbk (frame, this);
}
-
return 0;
}
-int
-sh_loop_finish (call_frame_t *loop_frame, xlator_t *this)
+static int
+sh_full_loop_return (call_frame_t *rw_frame, xlator_t *this, off_t offset)
{
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * rw_sh = NULL;
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_sh_algo_full_private_t *sh_priv = NULL;
- if (!loop_frame)
- goto out;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
- loop_local = loop_frame->local;
- if (loop_local) {
- loop_sh = &loop_local->self_heal;
- }
+ sh_frame = rw_sh->sh_frame;
+ sh_local = sh_frame->local;
+ sh = &sh_local->self_heal;
+ sh_priv = sh->private;
+
+ AFR_STACK_DESTROY (rw_frame);
+
+ sh_full_loop_driver (sh_frame, this, _gf_false);
- if (loop_sh && loop_sh->data_lock_held) {
- afr_sh_data_unlock (loop_frame, this,
- sh_destroy_frame);
- } else {
- sh_destroy_frame (loop_frame, this);
- }
-out:
return 0;
}
+
static int
-sh_loop_lock_success (call_frame_t *loop_frame, xlator_t *this)
+sh_full_write_cbk (call_frame_t *rw_frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t *rw_sh = NULL;
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int child_index = (long) cookie;
+ int call_count = 0;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ priv = this->private;
- sh_loop_finish (loop_sh->old_loop_frame, this);
- loop_sh->old_loop_frame = NULL;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
+
+ sh_frame = rw_sh->sh_frame;
+ sh_local = sh_frame->local;
+ sh = &sh_local->self_heal;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "wrote %d bytes of data from %s to child %d, offset %"PRId64"",
+ op_ret, sh_local->loc.path, child_index,
+ rw_sh->offset - op_ret);
+
+ LOCK (&sh_frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "write to %s failed on subvolume %s (%s)",
+ sh_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+
+ sh->op_failed = 1;
+ }
+ }
+ UNLOCK (&sh_frame->lock);
+
+ call_count = afr_frame_return (rw_frame);
+
+ if (call_count == 0) {
+ sh_full_loop_return (rw_frame, this, rw_sh->offset - op_ret);
+ }
- gf_log (this->name, GF_LOG_DEBUG, "Acquired lock for range %"PRIu64
- " %"PRIu64, loop_sh->offset, loop_sh->block_size);
- loop_sh->data_lock_held = _gf_true;
- loop_sh->sh_data_algo_start (loop_frame, this);
return 0;
}
+
static int
-sh_loop_lock_failure (call_frame_t *loop_frame, xlator_t *this)
+sh_full_read_cbk (call_frame_t *rw_frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count, struct iatt *buf,
+ struct iobref *iobref)
{
- call_frame_t *sh_frame = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
-
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
- sh_frame = loop_sh->sh_frame;
-
- gf_log (this->name, GF_LOG_ERROR, "failed lock for range %"PRIu64
- " %"PRIu64, loop_sh->offset, loop_sh->block_size);
- sh_loop_finish (loop_sh->old_loop_frame, this);
- loop_sh->old_loop_frame = NULL;
- sh_loop_return (sh_frame, this, loop_frame, -1, ENOTCONN);
+ afr_private_t * priv = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t *rw_sh = NULL;
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int i = 0;
+ int call_count = 0;
+ off_t offset = (long) cookie;
+
+ priv = this->private;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
+
+ sh_frame = rw_sh->sh_frame;
+ sh_local = sh_frame->local;
+ sh = &sh_local->self_heal;
+
+ call_count = sh->active_sinks;
+
+ rw_local->call_count = call_count;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "read %d bytes of data from %s, offset %"PRId64"",
+ op_ret, sh_local->loc.path, offset);
+
+ if (op_ret <= 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "read from %s failed on subvolume %s (%s)",
+ sh_local->loc.path,
+ priv->children[sh->source]->name,
+ strerror (op_errno));
+ sh->op_failed = 1;
+ sh_full_loop_return (rw_frame, this, offset);
+ return 0;
+ }
+
+ rw_sh->offset += op_ret;
+
+ if (sh->file_has_holes) {
+ if (iov_0filled (vector, count) == 0) {
+ /* the iter function depends on the
+ sh->offset already being updated
+ above
+ */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "block has all 0 filled");
+ sh_full_loop_return (rw_frame, this, offset);
+ goto out;
+ }
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->sources[i] || !sh_local->child_up[i])
+ continue;
+
+ /* this is a sink, so write to it */
+
+ STACK_WIND_COOKIE (rw_frame, sh_full_write_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->writev,
+ sh->healing_fd, vector, count, offset,
+ iobref);
+
+ if (!--call_count)
+ break;
+ }
+
+out:
return 0;
}
+
static int
-sh_loop_frame_create (call_frame_t *sh_frame, xlator_t *this,
- call_frame_t *old_loop_frame, call_frame_t **loop_frame)
+sh_full_read_write (call_frame_t *frame, xlator_t *this, off_t offset)
{
- call_frame_t *new_loop_frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_local_t *new_loop_local = NULL;
- afr_self_heal_t *new_loop_sh = NULL;
- afr_private_t *priv = NULL;
-
- GF_ASSERT (sh_frame);
- GF_ASSERT (loop_frame);
-
- *loop_frame = NULL;
- local = sh_frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t *rw_sh = NULL;
+ afr_self_heal_t *sh = NULL;
+ call_frame_t *rw_frame = NULL;
+ int32_t op_errno = 0;
- new_loop_frame = copy_frame (sh_frame);
- if (!new_loop_frame)
- goto out;
- //We want the frame to have same lk_owner as sh_frame
- //so that locks translator allows conflicting locks
- new_loop_local = afr_local_copy (local, this);
- if (!new_loop_local)
- goto out;
- new_loop_frame->local = new_loop_local;
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
- new_loop_sh = &new_loop_local->self_heal;
- new_loop_sh->sources = memdup (sh->sources,
- priv->child_count * sizeof (*sh->sources));
- if (!new_loop_sh->sources)
- goto out;
- new_loop_sh->write_needed = GF_CALLOC (priv->child_count,
- sizeof (*new_loop_sh->write_needed),
- gf_afr_mt_char);
- if (!new_loop_sh->write_needed)
- goto out;
- new_loop_sh->checksum = GF_CALLOC (priv->child_count, MD5_DIGEST_LENGTH,
- gf_afr_mt_uint8_t);
- if (!new_loop_sh->checksum)
+ rw_frame = copy_frame (frame);
+ if (!rw_frame)
goto out;
- new_loop_sh->inode = inode_ref (sh->inode);
- new_loop_sh->sh_data_algo_start = sh->sh_data_algo_start;
- new_loop_sh->source = sh->source;
- new_loop_sh->active_sinks = sh->active_sinks;
- new_loop_sh->healing_fd = fd_ref (sh->healing_fd);
- new_loop_sh->file_has_holes = sh->file_has_holes;
- new_loop_sh->old_loop_frame = old_loop_frame;
- new_loop_sh->sh_frame = sh_frame;
- *loop_frame = new_loop_frame;
- return 0;
-out:
- sh_destroy_frame (new_loop_frame, this);
- return -ENOMEM;
-}
-static int
-sh_loop_start (call_frame_t *sh_frame, xlator_t *this, off_t offset,
- call_frame_t *old_loop_frame)
-{
- call_frame_t *new_loop_frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_local_t *new_loop_local = NULL;
- afr_self_heal_t *new_loop_sh = NULL;
- int ret = 0;
+ ALLOC_OR_GOTO (rw_local, afr_local_t, out);
- GF_ASSERT (sh_frame);
+ rw_frame->local = rw_local;
+ rw_sh = &rw_local->self_heal;
- local = sh_frame->local;
- sh = &local->self_heal;
+ rw_sh->offset = offset;
+ rw_sh->sh_frame = frame;
- ret = sh_loop_frame_create (sh_frame, this, old_loop_frame,
- &new_loop_frame);
- if (ret)
- goto out;
- new_loop_local = new_loop_frame->local;
- new_loop_sh = &new_loop_local->self_heal;
- new_loop_sh->offset = offset;
- new_loop_sh->block_size = sh->block_size;
- afr_sh_data_lock (new_loop_frame, this, offset, new_loop_sh->block_size,
- sh_loop_lock_success, sh_loop_lock_failure);
+ STACK_WIND_COOKIE (rw_frame, sh_full_read_cbk,
+ (void *) (long) offset,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->readv,
+ sh->healing_fd, sh->block_size,
+ offset);
return 0;
+
out:
sh->op_failed = 1;
- if (old_loop_frame)
- sh_loop_finish (old_loop_frame, this);
- sh_loop_return (sh_frame, this, new_loop_frame, -1, ENOMEM);
+
+ sh_full_loop_driver (frame, this, _gf_false);
+
return 0;
}
+
static int
-sh_loop_driver (call_frame_t *sh_frame, xlator_t *this,
- gf_boolean_t is_first_call, call_frame_t *old_loop_frame)
+sh_full_loop_driver (call_frame_t *frame, xlator_t *this, gf_boolean_t is_first_call)
{
+ afr_private_t * priv = NULL;
afr_local_t * local = NULL;
- afr_self_heal_t * sh = NULL;
- afr_sh_algo_private_t *sh_priv = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_sh_algo_full_private_t *sh_priv = NULL;
gf_boolean_t is_driver_done = _gf_false;
blksize_t block_size = 0;
- int loop = 0;
off_t offset = 0;
- afr_private_t *priv = NULL;
+ int loop = 0;
priv = this->private;
- local = sh_frame->local;
+ local = frame->local;
sh = &local->self_heal;
sh_priv = sh->private;
LOCK (&sh_priv->lock);
{
- if (!is_first_call)
+ if (_gf_false == is_first_call)
sh_priv->loops_running--;
- offset = sh_priv->offset;
- block_size = sh->block_size;
- while ((!sh->eof_reached) && (0 == sh->op_failed) &&
+ offset = sh_priv->offset;
+ block_size = sh->block_size;
+ while ((sh->op_failed == 0) &&
(sh_priv->loops_running < priv->data_self_heal_window_size)
&& (sh_priv->offset < sh->file_size)) {
loop++;
- sh_priv->offset += block_size;
+ gf_log (this->name, GF_LOG_TRACE,
+ "spawning a loop for offset %"PRId64,
+ sh_priv->offset);
+
+ sh_priv->offset += sh->block_size;
sh_priv->loops_running++;
- if (!is_first_call)
+ if (_gf_false == is_first_call)
break;
+
}
if (0 == sh_priv->loops_running) {
is_driver_done = _gf_true;
@@ -324,223 +348,349 @@ sh_loop_driver (call_frame_t *sh_frame, xlator_t *this,
}
UNLOCK (&sh_priv->lock);
- if (0 == loop) {
- //loop finish does unlock, but the erasing of the pending
- //xattrs needs to happen before that so do not finish the loop
- if (is_driver_done && !sh->op_failed)
- goto driver_done;
- if (old_loop_frame) {
- sh_loop_finish (old_loop_frame, this);
- old_loop_frame = NULL;
- }
- }
-
- //If we have more loops to form we should finish previous loop after
- //the next loop lock
while (loop--) {
if (sh->op_failed) {
// op failed in other loop, stop spawning more loops
- if (old_loop_frame) {
- sh_loop_finish (old_loop_frame, this);
- old_loop_frame = NULL;
- }
- sh_loop_driver (sh_frame, this, _gf_false, NULL);
+ sh_full_loop_driver (frame, this, _gf_false);
} else {
- gf_log (this->name, GF_LOG_TRACE, "spawning a loop "
- "for offset %"PRId64, offset);
-
- sh_loop_start (sh_frame, this, offset, old_loop_frame);
- old_loop_frame = NULL;
+ sh_full_read_write (frame, this, offset);
offset += block_size;
}
}
-driver_done:
if (is_driver_done) {
- sh_loop_driver_done (sh_frame, this, old_loop_frame);
+ sh_full_loop_driver_done (frame, this);
+ }
+
+ return 0;
+}
+
+
+int
+afr_sh_algo_full (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_full_private_t *sh_priv = NULL;
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = GF_CALLOC (1, sizeof (*sh_priv),
+ gf_afr_mt_afr_private_t);
+ if (!sh_priv)
+ goto out;
+
+ LOCK_INIT (&sh_priv->lock);
+
+ sh->private = sh_priv;
+
+ local->call_count = 0;
+
+ sh_full_loop_driver (frame, this, _gf_true);
+out:
+ return 0;
+}
+
+
+/*
+ * The "diff" algorithm. Copies only those blocks whose checksums
+ * don't match with those of source.
+ */
+
+
+static void
+sh_diff_private_cleanup (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = sh->private;
+
+ for (i = 0; i < priv->data_self_heal_window_size; i++) {
+ if (sh_priv->loops[i]) {
+ if (sh_priv->loops[i]->write_needed)
+ GF_FREE (sh_priv->loops[i]->write_needed);
+
+ if (sh_priv->loops[i]->checksum)
+ GF_FREE (sh_priv->loops[i]->checksum);
+
+ GF_FREE (sh_priv->loops[i]);
+ }
+ }
+
+ if (sh_priv) {
+ if (sh_priv->loops)
+ GF_FREE (sh_priv->loops);
+
+ GF_FREE (sh_priv);
+ }
+
+
+}
+
+
+static uint32_t
+__make_cookie (int loop_index, int child_index)
+{
+ uint32_t ret = ((loop_index << 16) | child_index);
+ return ret;
+}
+
+
+static int
+__loop_index (uint32_t cookie)
+{
+ return ((cookie & 0xFFFF0000) >> 16);
+}
+
+
+static int
+__child_index (uint32_t cookie)
+{
+ return (cookie & 0x0000FFFF);
+}
+
+
+static void
+sh_diff_loop_state_reset (struct sh_diff_loop_state *loop_state, int child_count)
+{
+ loop_state->active = _gf_false;
+// loop_state->offset = 0;
+
+ memset (loop_state->write_needed,
+ 0, sizeof (*loop_state->write_needed) * child_count);
+
+ memset (loop_state->checksum,
+ 0, MD5_DIGEST_LEN * child_count);
+}
+
+
+static int
+sh_diff_number_of_writes_needed (unsigned char *write_needed, int child_count)
+{
+ int writes = 0;
+ int i = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (write_needed[i])
+ writes++;
}
+
+ return writes;
+}
+
+
+static int
+sh_diff_loop_driver_done (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ int32_t total_blocks = 0;
+ int32_t diff_blocks = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ sh_priv = sh->private;
+ total_blocks = sh_priv->total_blocks;
+ diff_blocks = sh_priv->diff_blocks;
+
+ sh_diff_private_cleanup (frame, this);
+ if (sh->op_failed) {
+ gf_log (this->name, GF_LOG_INFO,
+ "diff self-heal aborting on %s",
+ local->loc.path);
+
+ local->self_heal.algo_abort_cbk (frame, this);
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "diff self-heal on %s: completed. "
+ "(%d blocks of %d were different (%.2f%%))",
+ local->loc.path, diff_blocks, total_blocks,
+ ((diff_blocks * 1.0)/total_blocks) * 100);
+
+ local->self_heal.algo_completion_cbk (frame, this);
+ }
+
return 0;
}
static int
-sh_loop_return (call_frame_t *sh_frame, xlator_t *this, call_frame_t *loop_frame,
- int32_t op_ret, int32_t op_errno)
+sh_diff_loop_driver (call_frame_t *frame, xlator_t *this,
+ gf_boolean_t is_first_call,
+ struct sh_diff_loop_state *loop_state);
+
+static int
+sh_diff_loop_return (call_frame_t *rw_frame, xlator_t *this,
+ struct sh_diff_loop_state *loop_state)
{
- afr_local_t * loop_local = NULL;
- afr_self_heal_t * loop_sh = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * rw_sh = NULL;
+ call_frame_t *sh_frame = NULL;
afr_local_t * sh_local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ priv = this->private;
+
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
+
+ sh_frame = rw_sh->sh_frame;
sh_local = sh_frame->local;
sh = &sh_local->self_heal;
+ sh_priv = sh->private;
- if (loop_frame) {
- loop_local = loop_frame->local;
- if (loop_local)
- loop_sh = &loop_local->self_heal;
- if (loop_sh)
- gf_log (this->name, GF_LOG_TRACE, "loop for offset "
- "%"PRId64" returned", loop_sh->offset);
- }
+ gf_log (this->name, GF_LOG_TRACE,
+ "loop for offset %"PRId64" returned", loop_state->offset);
- if (op_ret == -1) {
- sh->op_failed = 1;
- afr_sh_set_error (sh, op_errno);
- if (loop_frame) {
- sh_loop_finish (loop_frame, this);
- loop_frame = NULL;
- }
- }
+ AFR_STACK_DESTROY (rw_frame);
- sh_loop_driver (sh_frame, this, _gf_false, loop_frame);
+ sh_diff_loop_driver (sh_frame, this, _gf_false, loop_state);
return 0;
}
+
static int
-sh_loop_write_cbk (call_frame_t *loop_frame, void *cookie, xlator_t *this,
+sh_diff_write_cbk (call_frame_t *rw_frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
afr_private_t * priv = NULL;
- afr_local_t * loop_local = NULL;
- afr_self_heal_t * loop_sh = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * rw_sh = NULL;
call_frame_t *sh_frame = NULL;
afr_local_t * sh_local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ struct sh_diff_loop_state *loop_state = NULL;
int call_count = 0;
int child_index = 0;
+ int loop_index = 0;
priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
- sh_frame = loop_sh->sh_frame;
+ sh_frame = rw_sh->sh_frame;
sh_local = sh_frame->local;
sh = &sh_local->self_heal;
+ sh_priv = sh->private;
- child_index = (long) cookie;
+ child_index = __child_index ((uint32_t) (long) cookie);
+ loop_index = __loop_index ((uint32_t) (long) cookie);
+ loop_state = sh_priv->loops[loop_index];
gf_log (this->name, GF_LOG_TRACE,
"wrote %d bytes of data from %s to child %d, offset %"PRId64"",
- op_ret, sh_local->loc.path, child_index, loop_sh->offset);
+ op_ret, sh_local->loc.path, child_index,
+ loop_state->offset);
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "write to %s failed on subvolume %s (%s)",
- sh_local->loc.path,
- priv->children[child_index]->name,
- strerror (op_errno));
+ LOCK (&sh_frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "write to %s failed on subvolume %s (%s)",
+ sh_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
- sh->op_failed = 1;
- afr_sh_set_error (loop_sh, op_errno);
+ sh->op_failed = 1;
+ }
}
+ UNLOCK (&sh_frame->lock);
- call_count = afr_frame_return (loop_frame);
+ call_count = afr_frame_return (rw_frame);
if (call_count == 0) {
- sh_loop_return (sh_frame, this, loop_frame,
- loop_sh->op_ret, loop_sh->op_errno);
+ sh_diff_loop_return (rw_frame, this, loop_state);
}
return 0;
}
-static void
-sh_prune_writes_needed (call_frame_t *sh_frame, call_frame_t *loop_frame,
- afr_private_t *priv)
-{
- afr_local_t *sh_local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
- int i = 0;
-
- sh_local = sh_frame->local;
- sh = &sh_local->self_heal;
-
- if (!strcmp (sh->algo->name, "diff"))
- return;
-
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
-
- /* full self-heal guarantees there exists atleast 1 file with size 0
- * That means for other files we can preserve holes that come after
- * its size before 'trim'
- */
- for (i = 0; i < priv->child_count; i++) {
- if (loop_sh->write_needed[i] &&
- ((loop_sh->offset + 1) > sh->buf[i].ia_size))
- loop_sh->write_needed[i] = 0;
- }
-}
static int
-sh_loop_read_cbk (call_frame_t *loop_frame, void *cookie,
+sh_diff_read_cbk (call_frame_t *rw_frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count, struct iatt *buf,
- struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
afr_private_t * priv = NULL;
- afr_local_t * loop_local = NULL;
- afr_self_heal_t * loop_sh = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * rw_sh = NULL;
+ afr_sh_algo_diff_private_t * sh_priv = NULL;
call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ int loop_index = 0;
+ struct sh_diff_loop_state *loop_state = NULL;
+ uint32_t wcookie = 0;
int i = 0;
int call_count = 0;
- afr_local_t * sh_local = NULL;
- afr_self_heal_t * sh = NULL;
- priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ priv = this->private;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
- sh_frame = loop_sh->sh_frame;
+ sh_frame = rw_sh->sh_frame;
sh_local = sh_frame->local;
sh = &sh_local->self_heal;
+ sh_priv = sh->private;
+
+ loop_index = __loop_index ((uint32_t) (long) cookie);
+ loop_state = sh_priv->loops[loop_index];
+
+ call_count = sh_diff_number_of_writes_needed (loop_state->write_needed,
+ priv->child_count);
+
+ rw_local->call_count = call_count;
gf_log (this->name, GF_LOG_TRACE,
"read %d bytes of data from %s, offset %"PRId64"",
- op_ret, loop_local->loc.path, loop_sh->offset);
+ op_ret, sh_local->loc.path, loop_state->offset);
- if (op_ret <= 0) {
- if (op_ret < 0) {
- sh->op_failed = 1;
- gf_log (this->name, GF_LOG_ERROR, "read failed on %d "
- "for %s reason :%s", sh->source,
- sh_local->loc.path, strerror (errno));
- } else {
- sh->eof_reached = _gf_true;
- gf_log (this->name, GF_LOG_DEBUG, "Eof reached for %s",
- sh_local->loc.path);
- }
- sh_loop_return (sh_frame, this, loop_frame, op_ret, op_errno);
- goto out;
- }
+ if ((op_ret <= 0) ||
+ (call_count == 0)) {
+ sh_diff_loop_return (rw_frame, this, loop_state);
- if (loop_sh->file_has_holes && iov_0filled (vector, count) == 0)
- sh_prune_writes_needed (sh_frame, loop_frame, priv);
+ return 0;
+ }
- call_count = sh_number_of_writes_needed (loop_sh->write_needed,
- priv->child_count);
- if (call_count == 0) {
- sh_loop_return (sh_frame, this, loop_frame, 0, 0);
- goto out;
+ if (sh->file_has_holes) {
+ if (iov_0filled (vector, count) == 0) {
+ gf_log (this->name, GF_LOG_DEBUG, "0 filled block");
+ sh_diff_loop_return (rw_frame, this, loop_state);
+ goto out;
+ }
}
- loop_local->call_count = call_count;
for (i = 0; i < priv->child_count; i++) {
- if (!loop_sh->write_needed[i])
- continue;
- STACK_WIND_COOKIE (loop_frame, sh_loop_write_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->writev,
- loop_sh->healing_fd, vector, count,
- loop_sh->offset, 0, iobref, NULL);
+ if (loop_state->write_needed[i]) {
+ wcookie = __make_cookie (loop_index, i);
- if (!--call_count)
- break;
+ STACK_WIND_COOKIE (rw_frame, sh_diff_write_cbk,
+ (void *) (long) wcookie,
+ priv->children[i],
+ priv->children[i]->fops->writev,
+ sh->healing_fd, vector, count,
+ loop_state->offset, iobref);
+
+ if (!--call_count)
+ break;
+ }
}
out:
@@ -549,79 +699,101 @@ out:
static int
-sh_loop_read (call_frame_t *loop_frame, xlator_t *this)
+sh_diff_read (call_frame_t *rw_frame, xlator_t *this,
+ int loop_index)
{
- afr_private_t *priv = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * rw_sh = NULL;
+ afr_sh_algo_diff_private_t * sh_priv = NULL;
+ struct sh_diff_loop_state *loop_state = NULL;
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ uint32_t cookie = 0;
priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
- STACK_WIND_COOKIE (loop_frame, sh_loop_read_cbk,
- (void *) (long) loop_sh->source,
- priv->children[loop_sh->source],
- priv->children[loop_sh->source]->fops->readv,
- loop_sh->healing_fd, loop_sh->block_size,
- loop_sh->offset, 0, NULL);
+ sh_frame = rw_sh->sh_frame;
+ sh_local = sh_frame->local;
+ sh = &sh_local->self_heal;
+ sh_priv = sh->private;
+
+ loop_state = sh_priv->loops[loop_index];
+
+ cookie = __make_cookie (loop_index, sh->source);
+
+ STACK_WIND_COOKIE (rw_frame, sh_diff_read_cbk,
+ (void *) (long) cookie,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->readv,
+ sh->healing_fd, sh_priv->block_size,
+ loop_state->offset);
return 0;
}
static int
-sh_diff_checksum_cbk (call_frame_t *loop_frame, void *cookie, xlator_t *this,
+sh_diff_checksum_cbk (call_frame_t *rw_frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum,
- dict_t *xdata)
+ uint32_t weak_checksum, uint8_t *strong_checksum)
{
- afr_private_t *priv = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
- call_frame_t *sh_frame = NULL;
- afr_local_t *sh_local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_sh_algo_private_t *sh_priv = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t *rw_sh = NULL;
+ call_frame_t *sh_frame = NULL;
+ afr_local_t * sh_local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_sh_algo_diff_private_t * sh_priv = NULL;
+ int loop_index = 0;
int child_index = 0;
+ struct sh_diff_loop_state *loop_state = NULL;
int call_count = 0;
int i = 0;
int write_needed = 0;
priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ rw_local = rw_frame->local;
+ rw_sh = &rw_local->self_heal;
- sh_frame = loop_sh->sh_frame;
+ sh_frame = rw_sh->sh_frame;
sh_local = sh_frame->local;
sh = &sh_local->self_heal;
sh_priv = sh->private;
- child_index = (long) cookie;
+ child_index = __child_index ((uint32_t) (long) cookie);
+ loop_index = __loop_index ((uint32_t) (long) cookie);
+
+ loop_state = sh_priv->loops[loop_index];
if (op_ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"checksum on %s failed on subvolume %s (%s)",
sh_local->loc.path, priv->children[child_index]->name,
strerror (op_errno));
+
sh->op_failed = 1;
} else {
- memcpy (loop_sh->checksum + child_index * MD5_DIGEST_LENGTH,
- strong_checksum, MD5_DIGEST_LENGTH);
+ memcpy (loop_state->checksum + child_index * MD5_DIGEST_LEN,
+ strong_checksum,
+ MD5_DIGEST_LEN);
}
- call_count = afr_frame_return (loop_frame);
+ call_count = afr_frame_return (rw_frame);
if (call_count == 0) {
for (i = 0; i < priv->child_count; i++) {
if (sh->sources[i] || !sh_local->child_up[i])
continue;
- if (memcmp (loop_sh->checksum + (i * MD5_DIGEST_LENGTH),
- loop_sh->checksum + (sh->source * MD5_DIGEST_LENGTH),
- MD5_DIGEST_LENGTH)) {
+ if (memcmp (loop_state->checksum + (i * MD5_DIGEST_LEN),
+ loop_state->checksum + (sh->source * MD5_DIGEST_LEN),
+ MD5_DIGEST_LEN)) {
/*
Checksums differ, so this block
must be written to this sink
@@ -630,9 +802,9 @@ sh_diff_checksum_cbk (call_frame_t *loop_frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_DEBUG,
"checksum on subvolume %s at offset %"
PRId64" differs from that on source",
- priv->children[i]->name, loop_sh->offset);
+ priv->children[i]->name, loop_state->offset);
- write_needed = loop_sh->write_needed[i] = 1;
+ write_needed = loop_state->write_needed[i] = 1;
}
}
@@ -645,163 +817,272 @@ sh_diff_checksum_cbk (call_frame_t *loop_frame, void *cookie, xlator_t *this,
UNLOCK (&sh_priv->lock);
if (write_needed && !sh->op_failed) {
- sh_loop_read (loop_frame, this);
+ sh_diff_read (rw_frame, this, loop_index);
} else {
- sh_loop_return (sh_frame, this, loop_frame,
- op_ret, op_errno);
+ sh->offset += sh_priv->block_size;
+
+ sh_diff_loop_return (rw_frame, this, loop_state);
}
}
return 0;
}
+
static int
-sh_diff_checksum (call_frame_t *loop_frame, xlator_t *this)
+sh_diff_find_unused_loop (afr_sh_algo_diff_private_t *sh_priv, int max)
{
- afr_private_t *priv = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
- int call_count = 0;
- int i = 0;
+ int i = 0;
- priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ LOCK (&sh_priv->lock);
+ {
+ for (i = 0; i < max; i++) {
+ if (sh_priv->loops[i]->active == _gf_false) {
+ sh_priv->loops[i]->active = _gf_true;
+ break;
+ }
+ }
+ }
+ UNLOCK (&sh_priv->lock);
- call_count = loop_sh->active_sinks + 1; /* sinks and source */
+ if (i == max) {
+ gf_log ("[sh-diff]", GF_LOG_ERROR,
+ "no free loops found! This shouldn't happen. Please"
+ " report this to gluster-devel@nongnu.org");
+ }
- loop_local->call_count = call_count;
+ return i;
+}
- STACK_WIND_COOKIE (loop_frame, sh_diff_checksum_cbk,
- (void *) (long) loop_sh->source,
- priv->children[loop_sh->source],
- priv->children[loop_sh->source]->fops->rchecksum,
- loop_sh->healing_fd,
- loop_sh->offset, loop_sh->block_size, NULL);
+
+static int
+sh_diff_checksum (call_frame_t *frame, xlator_t *this, off_t offset)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_local_t * rw_local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_self_heal_t * rw_sh = NULL;
+ afr_sh_algo_diff_private_t * sh_priv = NULL;
+ call_frame_t *rw_frame = NULL;
+ uint32_t cookie = 0;
+ int loop_index = 0;
+ struct sh_diff_loop_state *loop_state = NULL;
+ int32_t op_errno = 0;
+ int call_count = 0;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+
+ sh_priv = sh->private;
+
+ rw_frame = copy_frame (frame);
+ if (!rw_frame)
+ goto out;
+
+ ALLOC_OR_GOTO (rw_local, afr_local_t, out);
+
+ rw_frame->local = rw_local;
+ rw_sh = &rw_local->self_heal;
+
+ rw_sh->offset = sh->offset;
+ rw_sh->sh_frame = frame;
+
+ call_count = sh->active_sinks + 1; /* sinks and source */
+
+ rw_local->call_count = call_count;
+
+ loop_index = sh_diff_find_unused_loop (sh_priv, priv->data_self_heal_window_size);
+
+ loop_state = sh_priv->loops[loop_index];
+ loop_state->offset = offset;
+
+ /* we need to send both the loop index and child index,
+ so squeeze them both into a 32-bit number */
+
+ cookie = __make_cookie (loop_index, sh->source);
+
+ STACK_WIND_COOKIE (rw_frame, sh_diff_checksum_cbk,
+ (void *) (long) cookie,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->rchecksum,
+ sh->healing_fd,
+ offset, sh_priv->block_size);
for (i = 0; i < priv->child_count; i++) {
- if (loop_sh->sources[i] || !loop_local->child_up[i])
+ if (sh->sources[i] || !local->child_up[i])
continue;
- STACK_WIND_COOKIE (loop_frame, sh_diff_checksum_cbk,
- (void *) (long) i,
+ cookie = __make_cookie (loop_index, i);
+
+ STACK_WIND_COOKIE (rw_frame, sh_diff_checksum_cbk,
+ (void *) (long) cookie,
priv->children[i],
priv->children[i]->fops->rchecksum,
- loop_sh->healing_fd,
- loop_sh->offset, loop_sh->block_size, NULL);
+ sh->healing_fd,
+ offset, sh_priv->block_size);
if (!--call_count)
break;
}
return 0;
+
+out:
+ sh->op_failed = 1;
+
+ sh_diff_loop_driver (frame, this, _gf_false, loop_state);
+
+ return 0;
}
+
static int
-sh_full_read_write_to_sinks (call_frame_t *loop_frame, xlator_t *this)
+sh_diff_loop_driver (call_frame_t *frame, xlator_t *this,
+ gf_boolean_t is_first_call,
+ struct sh_diff_loop_state *loop_state)
{
- afr_private_t *priv = NULL;
- afr_local_t *loop_local = NULL;
- afr_self_heal_t *loop_sh = NULL;
- int i = 0;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ gf_boolean_t is_driver_done = _gf_false;
+ blksize_t block_size = 0;
+ int loop = 0;
+ off_t offset = 0;
+ char sh_type_str[256] = {0,};
- priv = this->private;
- loop_local = loop_frame->local;
- loop_sh = &loop_local->self_heal;
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ sh_priv = sh->private;
- for (i = 0; i < priv->child_count; i++) {
- if (loop_sh->sources[i] || !loop_local->child_up[i])
- continue;
- loop_sh->write_needed[i] = 1;
+ afr_self_heal_type_str_get(sh, sh_type_str, sizeof(sh_type_str));
+
+ LOCK (&sh_priv->lock);
+ {
+ if (loop_state)
+ sh_diff_loop_state_reset (loop_state, priv->child_count);
+ if (_gf_false == is_first_call)
+ sh_priv->loops_running--;
+ offset = sh_priv->offset;
+ block_size = sh_priv->block_size;
+ while ((0 == sh->op_failed) &&
+ (sh_priv->loops_running < priv->data_self_heal_window_size)
+ && (sh_priv->offset < sh->file_size)) {
+
+ loop++;
+ gf_log (this->name, GF_LOG_TRACE,
+ "spawning a loop for offset %"PRId64,
+ sh_priv->offset);
+
+ sh_priv->offset += sh_priv->block_size;
+ sh_priv->loops_running++;
+
+ if (_gf_false == is_first_call)
+ break;
+
+ }
+ if (0 == sh_priv->loops_running) {
+ is_driver_done = _gf_true;
+ }
+ }
+ UNLOCK (&sh_priv->lock);
+
+ while (loop--) {
+ if (sh->op_failed) {
+ // op failed in other loop, stop spawning more loops
+ sh_diff_loop_driver (frame, this, _gf_false, NULL);
+ } else {
+ sh_diff_checksum (frame, this, offset);
+ offset += block_size;
+ }
+ }
+
+ if (is_driver_done) {
+ sh_diff_loop_driver_done (frame, this);
}
- sh_loop_read (loop_frame, this);
return 0;
}
-afr_sh_algo_private_t*
-afr_sh_priv_init ()
+
+int
+afr_sh_algo_diff (call_frame_t *frame, xlator_t *this)
{
- afr_sh_algo_private_t *sh_priv = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+ afr_sh_algo_diff_private_t *sh_priv = NULL;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
sh_priv = GF_CALLOC (1, sizeof (*sh_priv),
gf_afr_mt_afr_private_t);
if (!sh_priv)
- goto out;
+ goto err;
- LOCK_INIT (&sh_priv->lock);
-out:
- return sh_priv;
-}
+ sh_priv->block_size = this->ctx->page_size;
-void
-afr_sh_transfer_lock (call_frame_t *dst, call_frame_t *src,
- unsigned int child_count)
-{
- afr_local_t *dst_local = NULL;
- afr_self_heal_t *dst_sh = NULL;
- afr_local_t *src_local = NULL;
- afr_self_heal_t *src_sh = NULL;
-
- dst_local = dst->local;
- dst_sh = &dst_local->self_heal;
- src_local = src->local;
- src_sh = &src_local->self_heal;
- GF_ASSERT (src_sh->data_lock_held);
- GF_ASSERT (!dst_sh->data_lock_held);
- afr_lk_transfer_datalock (dst, src, child_count);
- src_sh->data_lock_held = _gf_false;
- dst_sh->data_lock_held = _gf_true;
-}
+ sh->private = sh_priv;
-int
-afr_sh_start_loops (call_frame_t *sh_frame, xlator_t *this,
- afr_sh_algo_fn sh_data_algo_start)
-{
- call_frame_t *first_loop_frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int ret = 0;
- afr_private_t *priv = NULL;
-
- local = sh_frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ LOCK_INIT (&sh_priv->lock);
- sh->sh_data_algo_start = sh_data_algo_start;
local->call_count = 0;
- ret = sh_loop_frame_create (sh_frame, this, NULL, &first_loop_frame);
- if (ret)
- goto out;
- afr_sh_transfer_lock (first_loop_frame, sh_frame, priv->child_count);
- sh->private = afr_sh_priv_init ();
- if (!sh->private) {
- ret = -1;
- goto out;
- }
- sh_loop_driver (sh_frame, this, _gf_true, first_loop_frame);
- ret = 0;
-out:
- if (ret) {
- sh->op_failed = 1;
- sh_loop_driver_done (sh_frame, this, NULL);
+
+ sh_priv->loops = GF_CALLOC (priv->data_self_heal_window_size,
+ sizeof (*sh_priv->loops),
+ gf_afr_mt_sh_diff_loop_state);
+ if (!sh_priv->loops)
+ goto err;
+
+ for (i = 0; i < priv->data_self_heal_window_size; i++) {
+ sh_priv->loops[i] = GF_CALLOC (1, sizeof (*sh_priv->loops[i]),
+ gf_afr_mt_sh_diff_loop_state);
+ if (!sh_priv->loops[i])
+ goto err;
+
+ sh_priv->loops[i]->checksum = GF_CALLOC (priv->child_count,
+ MD5_DIGEST_LEN, gf_afr_mt_uint8_t);
+ if (!sh_priv->loops[i]->checksum)
+ goto err;
+
+ sh_priv->loops[i]->write_needed = GF_CALLOC (priv->child_count,
+ sizeof (*sh_priv->loops[i]->write_needed),
+ gf_afr_mt_char);
+ if (!sh_priv->loops[i]->write_needed)
+ goto err;
+
}
- return 0;
-}
-int
-afr_sh_algo_diff (call_frame_t *sh_frame, xlator_t *this)
-{
- afr_sh_start_loops (sh_frame, this, sh_diff_checksum);
+ sh_diff_loop_driver (frame, this, _gf_true, NULL);
+
return 0;
-}
+err:
+ if (sh_priv) {
+ if (sh_priv->loops) {
+ for (i = 0; i < priv->data_self_heal_window_size; i++) {
+ if (sh_priv->loops[i]->write_needed)
+ GF_FREE (sh_priv->loops[i]->write_needed);
+ if (sh_priv->loops[i]->checksum)
+ GF_FREE (sh_priv->loops[i]->checksum);
+ if (sh_priv->loops[i])
+ GF_FREE (sh_priv->loops[i]);
+ }
-int
-afr_sh_algo_full (call_frame_t *sh_frame, xlator_t *this)
-{
- afr_sh_start_loops (sh_frame, this, sh_full_read_write_to_sinks);
+ GF_FREE (sh_priv->loops);
+ }
+
+ GF_FREE (sh_priv);
+ }
return 0;
}
+
struct afr_sh_algorithm afr_self_heal_algorithms[] = {
{.name = "full", .fn = afr_sh_algo_full},
{.name = "diff", .fn = afr_sh_algo_diff},
diff --git a/xlators/cluster/afr/src/afr-self-heal-algorithm.h b/xlators/cluster/afr/src/afr-self-heal-algorithm.h
index 6b20789b1..e45621b0e 100644
--- a/xlators/cluster/afr/src/afr-self-heal-algorithm.h
+++ b/xlators/cluster/afr/src/afr-self-heal-algorithm.h
@@ -1,16 +1,26 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __AFR_SELF_HEAL_ALGORITHM_H__
#define __AFR_SELF_HEAL_ALGORITHM_H__
+
typedef int (*afr_sh_algo_fn) (call_frame_t *frame,
xlator_t *this);
@@ -20,13 +30,31 @@ struct afr_sh_algorithm {
};
extern struct afr_sh_algorithm afr_self_heal_algorithms[3];
+
typedef struct {
gf_lock_t lock;
unsigned int loops_running;
off_t offset;
+} afr_sh_algo_full_private_t;
+
+struct sh_diff_loop_state {
+ off_t offset;
+ unsigned char *write_needed;
+ uint8_t *checksum;
+ gf_boolean_t active;
+};
+
+typedef struct {
+ size_t block_size;
+
+ gf_lock_t lock;
+ unsigned int loops_running;
+ off_t offset;
int32_t total_blocks;
int32_t diff_blocks;
-} afr_sh_algo_private_t;
+
+ struct sh_diff_loop_state **loops;
+} afr_sh_algo_diff_private_t;
#endif /* __AFR_SELF_HEAL_ALGORITHM_H__ */
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 48fa31d86..2e046614d 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include "glusterfs.h"
@@ -18,45 +27,6 @@
#include "afr-self-heal.h"
#include "pump.h"
-void
-afr_sh_reset (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
-
- memset (sh->child_errno, 0,
- sizeof (*sh->child_errno) * priv->child_count);
- memset (sh->buf, 0, sizeof (*sh->buf) * priv->child_count);
- memset (sh->parentbufs, 0,
- sizeof (*sh->parentbufs) * priv->child_count);
- memset (sh->success, 0, sizeof (*sh->success) * priv->child_count);
- memset (sh->locked_nodes, 0,
- sizeof (*sh->locked_nodes) * priv->child_count);
- sh->active_sinks = 0;
-
- afr_reset_xattr (sh->xattr, priv->child_count);
-}
-
-//Intersection[child]=1 if child is part of intersection
-void
-afr_children_intersection_get (int32_t *set1, int32_t *set2,
- int *intersection, unsigned int child_count)
-{
- int i = 0;
-
- memset (intersection, 0, sizeof (*intersection) * child_count);
- for (i = 0; i < child_count; i++) {
- intersection[i] = afr_is_child_present (set1, child_count, i)
- && afr_is_child_present (set2, child_count,
- i);
- }
-}
-
/**
* select_source - select a source and return it
*/
@@ -72,28 +42,20 @@ afr_sh_select_source (int sources[], int child_count)
return -1;
}
-void
-afr_sh_mark_source_sinks (call_frame_t *frame, xlator_t *this)
-{
- int i = 0;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- int active_sinks = 0;
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
+/**
+ * sink_count - return number of sinks in sources array
+ */
- for (i = 0; i < priv->child_count; i++) {
- if (sh->sources[i] == 0 && local->child_up[i] == 1) {
- active_sinks++;
- sh->success[i] = 1;
- } else if (sh->sources[i] == 1 && local->child_up[i] == 1) {
- sh->success[i] = 1;
- }
- }
- sh->active_sinks = active_sinks;
+int
+afr_sh_sink_count (int sources[], int child_count)
+{
+ int i = 0;
+ int sinks = 0;
+ for (i = 0; i < child_count; i++)
+ if (!sources[i])
+ sinks++;
+ return sinks;
}
int
@@ -108,14 +70,23 @@ afr_sh_source_count (int sources[], int child_count)
return nsource;
}
-void
-afr_sh_set_error (afr_self_heal_t *sh, int32_t op_errno)
+
+int
+afr_sh_supress_errenous_children (int sources[], int child_errno[],
+ int child_count)
{
- sh->op_ret = -1;
- if (afr_error_more_important (sh->op_errno, op_errno))
- sh->op_errno = op_errno;
+ int i = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (child_errno[i] && sources[i]) {
+ sources[i] = 0;
+ }
+ }
+
+ return 0;
}
+
void
afr_sh_print_pending_matrix (int32_t *pending_matrix[], xlator_t *this)
{
@@ -135,53 +106,18 @@ afr_sh_print_pending_matrix (int32_t *pending_matrix[], xlator_t *this)
ptr += sprintf (ptr, "%d ", pending_matrix[i][j]);
}
sprintf (ptr, "]");
- gf_log (this->name, GF_LOG_DEBUG, "pending_matrix: %s", buf);
+ gf_log (this->name, GF_LOG_TRACE,
+ "pending_matrix: %s", buf);
}
GF_FREE (buf);
}
-void
-afr_init_pending_matrix (int32_t **pending_matrix, size_t child_count)
-{
- int i = 0;
- int j = 0;
-
- GF_ASSERT (pending_matrix);
-
- for (i = 0; i < child_count; i++) {
- for (j = 0; j < child_count; j++) {
- pending_matrix[i][j] = 0;
- }
- }
-}
void
-afr_mark_ignorant_subvols_as_pending (int32_t **pending_matrix,
- unsigned char *ignorant_subvols,
- size_t child_count)
-{
- int i = 0;
- int j = 0;
-
- GF_ASSERT (pending_matrix);
- GF_ASSERT (ignorant_subvols);
-
- for (i = 0; i < child_count; i++) {
- if (ignorant_subvols[i]) {
- for (j = 0; j < child_count; j++) {
- if (!ignorant_subvols[j])
- pending_matrix[j][i] += 1;
- }
- }
- }
-}
-
-int
-afr_build_pending_matrix (char **pending_key, int32_t **pending_matrix,
- unsigned char *ignorant_subvols,
- dict_t *xattr[], afr_transaction_type type,
- size_t child_count)
+afr_sh_build_pending_matrix (afr_private_t *priv,
+ int32_t *pending_matrix[], dict_t *xattr[],
+ int child_count, afr_transaction_type type)
{
/* Indexable by result of afr_index_for_transaction_type(): 0 -- 2. */
int32_t pending[3] = {0,};
@@ -190,14 +126,23 @@ afr_build_pending_matrix (char **pending_key, int32_t **pending_matrix,
int i = 0;
int j = 0;
int k = 0;
+ unsigned char *ignorant_subvols = NULL;
- afr_init_pending_matrix (pending_matrix, child_count);
+ ignorant_subvols = GF_CALLOC (sizeof (*ignorant_subvols), child_count,
+ gf_afr_mt_char);
+
+ /* start clean */
+ for (i = 0; i < child_count; i++) {
+ for (j = 0; j < child_count; j++) {
+ pending_matrix[i][j] = 0;
+ }
+ }
for (i = 0; i < child_count; i++) {
pending_raw = NULL;
for (j = 0; j < child_count; j++) {
- ret = dict_get_ptr (xattr[i], pending_key[j],
+ ret = dict_get_ptr (xattr[i], priv->pending_key[j],
&pending_raw);
if (ret != 0) {
@@ -207,8 +152,7 @@ afr_build_pending_matrix (char **pending_key, int32_t **pending_matrix,
* subvolume.
*/
- if (ignorant_subvols)
- ignorant_subvols[i] = 1;
+ ignorant_subvols[i] = 1;
continue;
}
@@ -219,14 +163,52 @@ afr_build_pending_matrix (char **pending_key, int32_t **pending_matrix,
}
}
- return ret;
+ /*
+ * Make all non-ignorant subvols point towards the ignorant
+ * subvolumes.
+ */
+
+ for (i = 0; i < child_count; i++) {
+ if (ignorant_subvols[i]) {
+ for (j = 0; j < child_count; j++) {
+ if (!ignorant_subvols[j])
+ pending_matrix[j][i] += 1;
+ }
+ }
+ }
+
+ GF_FREE (ignorant_subvols);
}
+
+/**
+ * mark_sources: Mark all 'source' nodes and return number of source
+ * nodes found
+ *
+ * A node (a row in the pending matrix) belongs to one of
+ * three categories:
+ *
+ * M is the pending matrix.
+ *
+ * 'innocent' - M[i] is all zeroes
+ * 'fool' - M[i] has i'th element = 1 (self-reference)
+ * 'wise' - M[i] has i'th element = 0, others are 1 or 0.
+ *
+ * All 'innocent' nodes are sinks. If all nodes are innocent, no self-heal is
+ * needed.
+ *
+ * A 'wise' node can be a source. If two 'wise' nodes conflict, it is
+ * a split-brain. If one wise node refers to the other but the other doesn't
+ * refer back, the referrer is a source.
+ *
+ * All fools are sinks, unless there are no 'wise' nodes. In that case,
+ * one of the fools is made a source.
+ */
+
typedef enum {
- AFR_NODE_INVALID,
AFR_NODE_INNOCENT,
AFR_NODE_FOOL,
- AFR_NODE_WISE,
+ AFR_NODE_WISE
} afr_node_type;
typedef struct {
@@ -306,7 +288,7 @@ afr_sh_wise_nodes_exist (afr_node_character *characters, int child_count)
* It is 1 if no other wise node accuses it.
* Only wise nodes with wisdom 1 are sources.
*
- * If no nodes with wisdom 1 exist, a split-brain has occurred.
+ * If no nodes with wisdom 1 exist, a split-brain has occured.
*/
static void
@@ -371,498 +353,271 @@ afr_sh_mark_wisest_as_sources (int sources[],
return nsources;
}
-static void
-afr_compute_witness_of_fools (int32_t *witnesses, int32_t **pending_matrix,
- afr_node_character *characters,
- int32_t child_count)
+
+static int
+afr_sh_mark_if_size_differs (afr_self_heal_t *sh, int child_count)
{
- int i = 0;
- int j = 0;
- int witness = 0;
+ int32_t ** pending_matrix = NULL;
+ int i = 0;
+ int j = 0;
+ int size_differs = 0;
- GF_ASSERT (witnesses);
- GF_ASSERT (pending_matrix);
- GF_ASSERT (characters);
- GF_ASSERT (child_count > 0);
+ pending_matrix = sh->pending_matrix;
for (i = 0; i < child_count; i++) {
- if (characters[i].type != AFR_NODE_FOOL)
- continue;
-
- witness = 0;
for (j = 0; j < child_count; j++) {
- if (i == j)
- continue;
- witness += pending_matrix[i][j];
- }
- witnesses[i] = witness;
- }
-}
-
-static int32_t
-afr_find_biggest_witness_among_fools (int32_t *witnesses,
- afr_node_character *characters,
- int32_t child_count)
-{
- int i = 0;
- int biggest_witness = -1;
+ if (!sh->buf)
+ break;
- GF_ASSERT (witnesses);
- GF_ASSERT (characters);
- GF_ASSERT (child_count > 0);
+ if (SIZE_DIFFERS (&sh->buf[i], &sh->buf[j])
+ && (pending_matrix[i][j] == 0)
+ && (pending_matrix[j][i] == 0)) {
- for (i = 0; i < child_count; i++) {
- if (characters[i].type != AFR_NODE_FOOL)
- continue;
+ pending_matrix[i][j] = 1;
+ pending_matrix[j][i] = 1;
- if (biggest_witness < witnesses[i])
- biggest_witness = witnesses[i];
+ size_differs = 1;
+ }
+ }
}
- return biggest_witness;
+
+ return size_differs;
}
-int
-afr_mark_fool_as_source_by_witness (int32_t *sources, int32_t *witnesses,
+
+static int
+afr_sh_mark_biggest_fool_as_source (afr_self_heal_t *sh,
afr_node_character *characters,
- int32_t child_count, int32_t witness)
+ int child_count)
{
- int i = 0;
- int nsources = 0;
+ int i = 0;
+ int biggest = 0;
- GF_ASSERT (sources);
- GF_ASSERT (witnesses);
- GF_ASSERT (characters);
- GF_ASSERT (child_count > 0);
+ for (i = 0; i < child_count; i++) {
+ if (characters[i].type == AFR_NODE_FOOL) {
+ biggest = i;
+ break;
+ }
+ }
for (i = 0; i < child_count; i++) {
if (characters[i].type != AFR_NODE_FOOL)
continue;
- if (witness == witnesses[i]) {
- sources[i] = 1;
- nsources++;
+ if (!sh->buf)
+ break;
+
+ if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) {
+ biggest = i;
}
}
- return nsources;
-}
-static int
-afr_mark_biggest_of_fools_as_source (int32_t *sources, int32_t **pending_matrix,
- afr_node_character *characters,
- int child_count)
-{
- int32_t biggest_witness = 0;
- int nsources = 0;
- int32_t *witnesses = NULL;
+ sh->sources[biggest] = 1;
- GF_ASSERT (child_count > 0);
-
- witnesses = GF_CALLOC (child_count, sizeof (*witnesses),
- gf_afr_mt_int32_t);
- if (NULL == witnesses) {
- nsources = -1;
- goto out;
- }
-
- afr_compute_witness_of_fools (witnesses, pending_matrix, characters,
- child_count);
- biggest_witness = afr_find_biggest_witness_among_fools (witnesses,
- characters,
- child_count);
- nsources = afr_mark_fool_as_source_by_witness (sources, witnesses,
- characters, child_count,
- biggest_witness);
-out:
- GF_FREE (witnesses);
- return nsources;
+ return 1;
}
-int
-afr_mark_child_as_source_by_uid (int32_t *sources, struct iatt *bufs,
- int32_t *success_children,
- unsigned int child_count, uint32_t uid)
-{
- int i = 0;
- int nsources = 0;
- int child = 0;
-
- for (i = 0; i < child_count; i++) {
- if (-1 == success_children[i])
- break;
-
- child = success_children[i];
- if (uid == bufs[child].ia_uid) {
- sources[child] = 1;
- nsources++;
- }
- }
- return nsources;
-}
-int
-afr_get_child_with_lowest_uid (struct iatt *bufs, int32_t *success_children,
- unsigned int child_count)
+static int
+afr_sh_mark_biggest_as_source (afr_self_heal_t *sh, int child_count)
{
- int i = 0;
- int smallest = -1;
- int child = 0;
+ int biggest = 0;
+ int i = 0;
for (i = 0; i < child_count; i++) {
- if (-1 == success_children[i])
+ if (!sh->buf)
break;
- child = success_children[i];
- if ((smallest == -1) ||
- (bufs[child].ia_uid < bufs[smallest].ia_uid)) {
- smallest = child;
+
+ if (SIZE_GREATER (&sh->buf[i], &sh->buf[biggest])) {
+ biggest = i;
}
}
- return smallest;
-}
-static int
-afr_sh_mark_lowest_uid_as_source (struct iatt *bufs, int32_t *success_children,
- int child_count, int32_t *sources)
-{
- int nsources = 0;
- int smallest = 0;
+ sh->sources[biggest] = 1;
- smallest = afr_get_child_with_lowest_uid (bufs, success_children,
- child_count);
- if (smallest < 0) {
- nsources = -1;
- goto out;
- }
- nsources = afr_mark_child_as_source_by_uid (sources, bufs,
- success_children, child_count,
- bufs[smallest].ia_uid);
-out:
- return nsources;
+ return 1;
}
-int
-afr_get_no_xattr_dir_read_child (xlator_t *this, int32_t *success_children,
- struct iatt *bufs)
-{
- afr_private_t *priv = NULL;
- int i = 0;
- int child = -1;
- int read_child = -1;
- priv = this->private;
- for (i = 0; i < priv->child_count; i++) {
- child = success_children[i];
- if (child < 0)
- break;
- if (read_child < 0)
- read_child = child;
- else if (bufs[read_child].ia_size < bufs[child].ia_size)
- read_child = child;
- }
- return read_child;
-}
-
-int
-afr_sh_mark_zero_size_file_as_sink (struct iatt *bufs, int32_t *success_children,
- int child_count, int32_t *sources)
+static int
+afr_sh_mark_loweia_uid_as_source (afr_self_heal_t *sh, int child_count)
{
- int nsources = 0;
- int i = 0;
- int child = 0;
- gf_boolean_t sink_exists = _gf_false;
- gf_boolean_t source_exists = _gf_false;
- int source = -1;
+ uid_t smallest = 0;
+ int i = 0;
for (i = 0; i < child_count; i++) {
- child = success_children[i];
- if (child < 0)
+ if (!sh->buf)
break;
- if (!bufs[child].ia_size) {
- sink_exists = _gf_true;
- continue;
- }
- if (!source_exists) {
- source_exists = _gf_true;
- source = child;
- continue;
- }
- if (bufs[source].ia_size != bufs[child].ia_size) {
- nsources = -1;
- goto out;
- }
- }
- if (!source_exists && !sink_exists) {
- nsources = -1;
- goto out;
- }
-
- if (!source_exists || !sink_exists)
- goto out;
- for (i = 0; i < child_count; i++) {
- child = success_children[i];
- if (child < 0)
- break;
- if (bufs[child].ia_size) {
- sources[child] = 1;
- nsources++;
+ if (sh->buf[i].ia_uid < sh->buf[smallest].ia_uid) {
+ smallest = i;
}
}
-out:
- return nsources;
-}
-char *
-afr_get_character_str (afr_node_type type)
-{
- char *character = NULL;
+ sh->sources[smallest] = 1;
- switch (type) {
- case AFR_NODE_INNOCENT:
- character = "innocent";
- break;
- case AFR_NODE_FOOL:
- character = "fool";
- break;
- case AFR_NODE_WISE:
- character = "wise";
- break;
- default:
- character = "invalid";
- break;
- }
- return character;
+ return 1;
}
-afr_node_type
-afr_find_child_character_type (int32_t *pending_row, int32_t child,
- unsigned int child_count)
-{
- afr_node_type type = AFR_NODE_INVALID;
-
- GF_ASSERT ((child >= 0) && (child < child_count));
-
- if (afr_sh_is_innocent (pending_row, child_count))
- type = AFR_NODE_INNOCENT;
- else if (afr_sh_is_fool (pending_row, child, child_count))
- type = AFR_NODE_FOOL;
- else if (afr_sh_is_wise (pending_row, child, child_count))
- type = AFR_NODE_WISE;
- return type;
-}
int
-afr_build_sources (xlator_t *this, dict_t **xattr, struct iatt *bufs,
- int32_t **pending_matrix, int32_t *sources,
- int32_t *success_children, afr_transaction_type type,
- int32_t *subvol_status, gf_boolean_t ignore_ignorant)
+afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
+ afr_self_heal_type type)
{
- afr_private_t *priv = NULL;
- afr_self_heal_type sh_type = AFR_SELF_HEAL_INVALID;
- int nsources = -1;
- unsigned char *ignorant_subvols = NULL;
- unsigned int child_count = 0;
+ /* stores the 'characters' (innocent, fool, wise) of the nodes */
+ afr_node_character *characters = NULL;
- priv = this->private;
- child_count = priv->child_count;
+ int i = 0;
+ int32_t ** pending_matrix = NULL;
+ int * sources = NULL;
+ int size_differs = 0;
+ int nsources = 0;
+ xlator_t *this = NULL;
+ afr_private_t *priv = NULL;
- if (afr_get_children_count (success_children, priv->child_count) == 0)
+ characters = GF_CALLOC (sizeof (afr_node_character),
+ child_count,
+ gf_afr_mt_afr_node_character) ;
+ if (!characters)
goto out;
- if (!ignore_ignorant) {
- ignorant_subvols = GF_CALLOC (sizeof (*ignorant_subvols),
- child_count, gf_afr_mt_char);
- if (NULL == ignorant_subvols)
- goto out;
- }
-
- afr_build_pending_matrix (priv->pending_key, pending_matrix,
- ignorant_subvols, xattr, type,
- priv->child_count);
+ this = THIS;
+ priv = this->private;
+ pending_matrix = sh->pending_matrix;
+ sources = sh->sources;
- if (!ignore_ignorant)
- afr_mark_ignorant_subvols_as_pending (pending_matrix,
- ignorant_subvols,
- priv->child_count);
- sh_type = afr_self_heal_type_for_transaction (type);
- if (AFR_SELF_HEAL_INVALID == sh_type)
- goto out;
+ /* start clean */
+ for (i = 0; i < child_count; i++) {
+ sources[i] = 0;
+ }
- afr_sh_print_pending_matrix (pending_matrix, this);
+ for (i = 0; i < child_count; i++) {
+ if (afr_sh_is_innocent (pending_matrix[i], child_count)) {
+ characters[i].type = AFR_NODE_INNOCENT;
- nsources = afr_mark_sources (this, sources, pending_matrix, bufs,
- sh_type, success_children, subvol_status);
-out:
- GF_FREE (ignorant_subvols);
- return nsources;
-}
+ } else if (afr_sh_is_fool (pending_matrix[i], i, child_count)) {
+ characters[i].type = AFR_NODE_FOOL;
-void
-afr_find_character_types (afr_node_character *characters,
- int32_t **pending_matrix, int32_t *success_children,
- unsigned int child_count)
-{
- afr_node_type type = AFR_NODE_INVALID;
- int child = 0;
- int i = 0;
+ } else if (afr_sh_is_wise (pending_matrix[i], i, child_count)) {
+ characters[i].type = AFR_NODE_WISE;
- for (i = 0; i < child_count; i++) {
- child = success_children[i];
- if (child == -1)
- break;
- type = afr_find_child_character_type (pending_matrix[child],
- child, child_count);
- characters[child].type = type;
+ } else {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Could not determine the state of subvolume %s!"
+ " (This message should never appear."
+ " Please file a bug report to "
+ "<gluster-devel@nongnu.org>.)",
+ priv->children[i]->name);
+ }
}
-}
-void
-afr_mark_success_children_sources (int32_t *sources, int32_t *success_children,
- unsigned int child_count)
-{
- int i = 0;
- for (i = 0; i < child_count; i++) {
- if (success_children[i] == -1)
- break;
- sources[success_children[i]] = 1;
+ if (type == AFR_SELF_HEAL_DATA) {
+ size_differs = afr_sh_mark_if_size_differs (sh, child_count);
}
-}
-/**
- * mark_sources: Mark all 'source' nodes and return number of source
- * nodes found
- *
- * A node (a row in the pending matrix) belongs to one of
- * three categories:
- *
- * M is the pending matrix.
- *
- * 'innocent' - M[i] is all zeroes
- * 'fool' - M[i] has i'th element = 1 (self-reference)
- * 'wise' - M[i] has i'th element = 0, others are 1 or 0.
- *
- * All 'innocent' nodes are sinks. If all nodes are innocent, no self-heal is
- * needed.
- *
- * A 'wise' node can be a source. If two 'wise' nodes conflict, it is
- * a split-brain. If one wise node refers to the other but the other doesn't
- * refer back, the referrer is a source.
- *
- * All fools are sinks, unless there are no 'wise' nodes. In that case,
- * one of the fools is made a source.
- */
-int
-afr_mark_sources (xlator_t *this, int32_t *sources, int32_t **pending_matrix,
- struct iatt *bufs, afr_self_heal_type type,
- int32_t *success_children, int32_t *subvol_status)
-{
- /* stores the 'characters' (innocent, fool, wise) of the nodes */
- afr_node_character *characters = NULL;
- int nsources = -1;
- unsigned int child_count = 0;
- afr_private_t *priv = NULL;
+ if ((type == AFR_SELF_HEAL_METADATA)
+ && afr_sh_all_nodes_innocent (characters, child_count)) {
- priv = this->private;
- child_count = priv->child_count;
- characters = GF_CALLOC (sizeof (afr_node_character),
- child_count, gf_afr_mt_afr_node_character);
- if (!characters)
+ nsources = afr_sh_mark_loweia_uid_as_source (sh, child_count);
goto out;
+ }
- this = THIS;
-
- /* start clean */
- memset (sources, 0, sizeof (*sources) * child_count);
- nsources = 0;
- afr_find_character_types (characters, pending_matrix, success_children,
- child_count);
if (afr_sh_all_nodes_innocent (characters, child_count)) {
- switch (type) {
- case AFR_SELF_HEAL_METADATA:
- nsources = afr_sh_mark_lowest_uid_as_source (bufs,
- success_children,
- child_count,
- sources);
- break;
- case AFR_SELF_HEAL_DATA:
- nsources = afr_sh_mark_zero_size_file_as_sink (bufs,
- success_children,
- child_count,
- sources);
- if ((nsources < 0) && subvol_status)
- *subvol_status |= SPLIT_BRAIN;
- break;
- default:
- break;
+ if (size_differs) {
+ nsources = afr_sh_mark_biggest_as_source (sh,
+ child_count);
}
- goto out;
- }
- if (afr_sh_wise_nodes_exist (characters, child_count)) {
+ } else if (afr_sh_wise_nodes_exist (characters, child_count)) {
afr_sh_compute_wisdom (pending_matrix, characters, child_count);
if (afr_sh_wise_nodes_conflict (characters, child_count)) {
- if (subvol_status)
- *subvol_status |= SPLIT_BRAIN;
+ /* split-brain */
+ gf_log (this->name, GF_LOG_INFO,
+ "split-brain possible, no source detected");
nsources = -1;
+ goto out;
+
} else {
nsources = afr_sh_mark_wisest_as_sources (sources,
characters,
child_count);
}
} else {
- if (subvol_status)
- *subvol_status |= ALL_FOOLS;
- nsources = afr_mark_biggest_of_fools_as_source (sources,
- pending_matrix,
- characters,
- child_count);
+ nsources = afr_sh_mark_biggest_fool_as_source (sh, characters,
+ child_count);
}
out:
- if (nsources == 0)
- afr_mark_success_children_sources (sources, success_children,
- child_count);
- GF_FREE (characters);
+ if (characters)
+ GF_FREE (characters);
- gf_log (this->name, GF_LOG_DEBUG, "Number of sources: %d", nsources);
return nsources;
}
+
void
afr_sh_pending_to_delta (afr_private_t *priv, dict_t **xattr,
- int32_t *delta_matrix[], unsigned char success[],
+ int32_t *delta_matrix[], int success[],
int child_count, afr_transaction_type type)
{
- int i = 0;
- int j = 0;
+ /* Indexable by result of afr_index_for_transaction_type(): 0 -- 2. */
+ int32_t pending[3] = {0,};
+ void *pending_raw = NULL;
+ int ret = 0;
+ int i = 0;
+ int j = 0;
+ int k = 0;
- afr_build_pending_matrix (priv->pending_key, delta_matrix, NULL,
- xattr, type, priv->child_count);
- for (i = 0; i < priv->child_count; i++)
- for (j = 0; j < priv->child_count; j++)
- delta_matrix[i][j] = -delta_matrix[i][j];
+ /* start clean */
+ for (i = 0; i < child_count; i++) {
+ for (j = 0; j < child_count; j++) {
+ delta_matrix[i][j] = 0;
+ }
+ }
+
+ for (i = 0; i < child_count; i++) {
+ if (pending_raw)
+ pending_raw = NULL;
+
+ for (j = 0; j < child_count; j++) {
+ ret = dict_get_ptr (xattr[i], priv->pending_key[j],
+ &pending_raw);
+ if (ret < 0)
+ gf_log (THIS->name, GF_LOG_DEBUG,
+ "Unable to get dict value.");
+ if (!success[j])
+ continue;
+
+ k = afr_index_for_transaction_type (type);
+
+ if (pending_raw != NULL) {
+ memcpy (pending, pending_raw, sizeof(pending));
+ delta_matrix[i][j] = -(ntoh32 (pending[k]));
+ } else {
+ delta_matrix[i][j] = 0;
+ }
+
+ }
+ }
}
int
-afr_sh_delta_to_xattr (xlator_t *this,
+afr_sh_delta_to_xattr (afr_private_t *priv,
int32_t *delta_matrix[], dict_t *xattr[],
int child_count, afr_transaction_type type)
{
- int i = 0;
- int j = 0;
- int k = 0;
- int ret = 0;
- int32_t *pending = NULL;
- int32_t *local_pending = NULL;
- afr_private_t *priv = NULL;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int ret = 0;
+ int32_t *pending = NULL;
- priv = this->private;
for (i = 0; i < child_count; i++) {
if (!xattr[i])
continue;
- local_pending = NULL;
for (j = 0; j < child_count; j++) {
pending = GF_CALLOC (sizeof (int32_t), 3,
gf_afr_mt_int32_t);
@@ -875,28 +630,12 @@ afr_sh_delta_to_xattr (xlator_t *this,
pending[k] = hton32 (delta_matrix[i][j]);
- if (j == i) {
- local_pending = pending;
- continue;
- }
ret = dict_set_bin (xattr[i], priv->pending_key[j],
pending,
- AFR_NUM_CHANGE_LOGS * sizeof (int32_t));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
+ 3 * sizeof (int32_t));
+ if (ret < 0)
+ gf_log (THIS->name, GF_LOG_WARNING,
"Unable to set dict value.");
- GF_FREE (pending);
- }
- }
- if (local_pending) {
- ret = dict_set_bin (xattr[i], priv->pending_key[i],
- local_pending,
- AFR_NUM_CHANGE_LOGS * sizeof (int32_t));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to set dict value.");
- GF_FREE (local_pending);
- }
}
}
return 0;
@@ -904,7 +643,7 @@ afr_sh_delta_to_xattr (xlator_t *this,
int
-afr_sh_has_metadata_pending (dict_t *xattr, xlator_t *this)
+afr_sh_has_metadata_pending (dict_t *xattr, int child_count, xlator_t *this)
{
/* Indexable by result of afr_index_for_transaction_type(): 0 -- 2. */
int32_t pending[3] = {0,};
@@ -935,7 +674,7 @@ afr_sh_has_metadata_pending (dict_t *xattr, xlator_t *this)
int
-afr_sh_has_data_pending (dict_t *xattr, xlator_t *this)
+afr_sh_has_data_pending (dict_t *xattr, int child_count, xlator_t *this)
{
/* Indexable by result of afr_index_for_transaction_type(): 0 -- 2. */
int32_t pending[3] = {0,};
@@ -966,7 +705,7 @@ afr_sh_has_data_pending (dict_t *xattr, xlator_t *this)
int
-afr_sh_has_entry_pending (dict_t *xattr, xlator_t *this)
+afr_sh_has_entry_pending (dict_t *xattr, int child_count, xlator_t *this)
{
/* Indexable by result of afr_index_for_transaction_type(): 0 -- 2. */
int32_t pending[3] = {0,};
@@ -995,25 +734,54 @@ afr_sh_has_entry_pending (dict_t *xattr, xlator_t *this)
return 0;
}
+
+/**
+ * is_matrix_zero - return true if pending matrix is all zeroes
+ */
+
+int
+afr_sh_is_matrix_zero (int32_t *pending_matrix[], int child_count)
+{
+ int i = 0;
+ int j = 0;
+
+ for (i = 0; i < child_count; i++)
+ for (j = 0; j < child_count; j++)
+ if (pending_matrix[i][j])
+ return 0;
+ return 1;
+}
+
+
int
afr_sh_missing_entries_done (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
- afr_sh_reset (frame, this);
+// memset (sh->child_errno, 0, sizeof (int) * priv->child_count);
+ memset (sh->buf, 0, sizeof (struct iatt) * priv->child_count);
+
+ for (i = 0; i < priv->child_count; i++) {
+ sh->locked_nodes[i] = 0;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i])
+ dict_unref (sh->xattr[i]);
+ sh->xattr[i] = NULL;
+ }
if (local->govinda_gOvinda) {
gf_log (this->name, GF_LOG_INFO,
- "split brain found, aborting selfheal of %s",
+ "split brain found: aborting selfheal of %s",
local->loc.path);
- sh->op_failed = 1;
- }
-
- if (sh->op_failed) {
sh->completion_cbk (frame, this);
} else {
gf_log (this->name, GF_LOG_TRACE,
@@ -1027,7 +795,7 @@ afr_sh_missing_entries_done (call_frame_t *frame, xlator_t *this)
static int
-afr_sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
+sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
@@ -1041,894 +809,556 @@ afr_sh_missing_entries_finish (call_frame_t *frame, xlator_t *this)
return 0;
}
-int
-afr_sh_common_create (afr_self_heal_t *sh, unsigned int child_count)
-{
- int ret = -ENOMEM;
- sh->buf = GF_CALLOC (child_count, sizeof (*sh->buf),
- gf_afr_mt_iatt);
- if (!sh->buf)
- goto out;
- sh->parentbufs = GF_CALLOC (child_count, sizeof (*sh->parentbufs),
- gf_afr_mt_iatt);
- if (!sh->parentbufs)
- goto out;
- sh->child_errno = GF_CALLOC (child_count, sizeof (*sh->child_errno),
- gf_afr_mt_int);
- if (!sh->child_errno)
- goto out;
- sh->success_children = afr_children_create (child_count);
- if (!sh->success_children)
- goto out;
- sh->fresh_children = afr_children_create (child_count);
- if (!sh->fresh_children)
- goto out;
- sh->xattr = GF_CALLOC (child_count, sizeof (*sh->xattr),
- gf_afr_mt_dict_t);
- if (!sh->xattr)
- goto out;
- ret = 0;
-out:
- return ret;
-}
-void
-afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent,
- loc_t *loc)
+static int
+sh_destroy_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int op_errno,
+ struct iatt *preop, struct iatt *postop)
{
- int child_index = 0;
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_self_heal_t *sh = NULL;
+ afr_local_t *local = NULL;
+ loc_t *parent_loc = cookie;
+ int call_count = 0;
local = frame->local;
- priv = this->private;
- sh = &local->self_heal;
- child_index = (long) cookie;
- LOCK (&frame->lock);
- {
- if (op_ret == 0) {
- sh->buf[child_index] = *buf;
- sh->parentbufs[child_index] = *postparent;
- sh->success_children[sh->success_count] = child_index;
- sh->success_count++;
- sh->xattr[child_index] = dict_ref (xattr);
- } else {
- gf_log (this->name, GF_LOG_ERROR, "path %s on subvolume"
- " %s => -1 (%s)", loc->path,
- priv->children[child_index]->name,
- strerror (op_errno));
- local->self_heal.child_errno[child_index] = op_errno;
- }
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "setattr on %s failed: %s",
+ local->loc.path, strerror (op_errno));
}
- UNLOCK (&frame->lock);
- return;
-}
-gf_boolean_t
-afr_valid_ia_type (ia_type_t ia_type)
-{
- switch (ia_type) {
- case IA_IFSOCK:
- case IA_IFREG:
- case IA_IFBLK:
- case IA_IFCHR:
- case IA_IFIFO:
- case IA_IFLNK:
- case IA_IFDIR:
- return _gf_true;
- default:
- return _gf_false;
+ if (parent_loc) {
+ loc_wipe (parent_loc);
+ GF_FREE (parent_loc);
}
- return _gf_false;
-}
-int
-afr_impunge_frame_create (call_frame_t *frame, xlator_t *this,
- int active_source, call_frame_t **impunge_frame)
-{
- afr_local_t *local = NULL;
- afr_local_t *impunge_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- int32_t op_errno = 0;
- afr_private_t *priv = NULL;
- int ret = 0;
- call_frame_t *new_frame = NULL;
+ call_count = afr_frame_return (frame);
- op_errno = ENOMEM;
- priv = this->private;
- new_frame = copy_frame (frame);
- if (!new_frame) {
- goto out;
+ if (call_count == 0) {
+ STACK_DESTROY (frame->root);
}
- AFR_LOCAL_ALLOC_OR_GOTO (impunge_local, out);
-
- local = frame->local;
- new_frame->local = impunge_local;
- impunge_sh = &impunge_local->self_heal;
- impunge_sh->sh_frame = frame;
- impunge_sh->active_source = active_source;
- impunge_local->child_up = memdup (local->child_up,
- sizeof (*local->child_up) *
- priv->child_count);
- if (!impunge_local->child_up)
- goto out;
-
- impunge_local->pending = afr_matrix_create (priv->child_count,
- AFR_NUM_CHANGE_LOGS);
- if (!impunge_local->pending)
- goto out;
-
- ret = afr_sh_common_create (impunge_sh, priv->child_count);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
- op_errno = 0;
- *impunge_frame = new_frame;
-out:
- if (op_errno && new_frame)
- AFR_STACK_DESTROY (new_frame);
- return -op_errno;
+ return 0;
}
-void
-afr_sh_missing_entry_call_impunge_recreate (call_frame_t *frame, xlator_t *this,
- struct iatt *buf,
- struct iatt *postparent,
- afr_impunge_done_cbk_t impunge_done)
+
+static int
+sh_missing_entries_newentry_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
{
- call_frame_t *impunge_frame = NULL;
- afr_local_t *local = NULL;
- afr_local_t *impunge_local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- int ret = 0;
- unsigned int enoent_count = 0;
- afr_private_t *priv = NULL;
- int i = 0;
- int32_t op_errno = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ call_frame_t *setattr_frame = NULL;
+ int call_count = 0;
+ int child_index = 0;
+ loc_t *parent_loc = NULL;
+ struct iatt stbuf = {0,};
+ int32_t valid = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- enoent_count = afr_errno_count (NULL, sh->child_errno,
- priv->child_count, ENOENT);
- if (!enoent_count) {
+ child_index = (long) cookie;
+
+ stbuf.ia_atime = sh->buf[sh->source].ia_atime;
+ stbuf.ia_atime_nsec = sh->buf[sh->source].ia_atime_nsec;
+ stbuf.ia_mtime = sh->buf[sh->source].ia_mtime;
+ stbuf.ia_mtime_nsec = sh->buf[sh->source].ia_mtime_nsec;
+
+ stbuf.ia_uid = sh->buf[sh->source].ia_uid;
+ stbuf.ia_gid = sh->buf[sh->source].ia_gid;
+
+ valid = GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+
+ if (op_ret == -1) {
gf_log (this->name, GF_LOG_INFO,
- "no missing files - %s. proceeding to metadata check",
- local->loc.path);
- goto out;
- }
- sh->impunge_done = impunge_done;
- ret = afr_impunge_frame_create (frame, this, sh->source, &impunge_frame);
- if (ret)
- goto out;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
- loc_copy (&impunge_local->loc, &local->loc);
- ret = afr_build_parent_loc (&impunge_sh->parent_loc,
- &impunge_local->loc, &op_errno);
- if (ret) {
- ret = -op_errno;
- goto out;
- }
- impunge_local->call_count = enoent_count;
- impunge_sh->entrybuf = sh->buf[sh->source];
- impunge_sh->parentbuf = sh->parentbufs[sh->source];
- for (i = 0; i < priv->child_count; i++) {
- if (!impunge_local->child_up[i]) {
- impunge_sh->child_errno[i] = ENOTCONN;
- continue;
- }
- if (sh->child_errno[i] != ENOENT) {
- impunge_sh->child_errno[i] = EEXIST;
- continue;
- }
- }
- for (i = 0; i < priv->child_count; i++) {
- if (sh->child_errno[i] != ENOENT)
- continue;
- afr_sh_entry_impunge_create (impunge_frame, this, i);
- enoent_count--;
- }
- GF_ASSERT (!enoent_count);
- return;
-out:
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "impunge of %s failed, "
- "reason: %s", local->loc.path, strerror (-ret));
- sh->op_failed = 1;
+ "%s: failed to mknod on %s (%s)",
+ local->loc.path, priv->children[child_index]->name,
+ strerror (op_errno));
}
- afr_sh_missing_entries_finish (frame, this);
-}
-int
-afr_sh_create_entry_cbk (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
+ if (op_ret == 0) {
+ setattr_frame = copy_frame (frame);
- local = frame->local;
- sh = &local->self_heal;
- if (op_ret < 0)
- sh->op_failed = 1;
- afr_sh_missing_entries_finish (frame, this);
- return 0;
-}
+ setattr_frame->local = GF_CALLOC (1, sizeof (afr_local_t),
+ gf_afr_mt_afr_local_t);
-static int
-sh_missing_entries_create (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int type = 0;
- struct iatt *buf = NULL;
- struct iatt *postparent = NULL;
+ ((afr_local_t *)setattr_frame->local)->call_count = 2;
- local = frame->local;
- sh = &local->self_heal;
+ gf_log (this->name, GF_LOG_TRACE,
+ "setattr (%s) on subvolume %s",
+ local->loc.path, priv->children[child_index]->name);
- buf = &sh->buf[sh->source];
- postparent = &sh->parentbufs[sh->source];
+ STACK_WIND_COOKIE (setattr_frame, sh_destroy_cbk,
+ (void *) (long) 0,
+ priv->children[child_index],
+ priv->children[child_index]->fops->setattr,
+ &local->loc, &stbuf, valid);
- type = buf->ia_type;
- if (!afr_valid_ia_type (type)) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: unknown file type: 0%o", local->loc.path, type);
- local->govinda_gOvinda = 1;
- afr_sh_missing_entries_finish (frame, this);
- goto out;
+ valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+ parent_loc = GF_CALLOC (1, sizeof (*parent_loc),
+ gf_afr_mt_loc_t);
+ afr_build_parent_loc (parent_loc, &local->loc);
+
+ STACK_WIND_COOKIE (setattr_frame, sh_destroy_cbk,
+ (void *) (long) parent_loc,
+ priv->children[child_index],
+ priv->children[child_index]->fops->setattr,
+ parent_loc, &sh->parentbuf, valid);
+ }
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ sh_missing_entries_finish (frame, this);
}
- afr_sh_missing_entry_call_impunge_recreate (frame, this,
- buf, postparent,
- afr_sh_create_entry_cbk);
-out:
return 0;
}
-void
-afr_sh_missing_entries_lookup_done (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+
+static int
+sh_missing_entries_mknod (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- ia_type_t ia_type = IA_INVAL;
- int32_t nsources = 0;
- loc_t *loc = NULL;
- int32_t subvol_status = 0;
- afr_transaction_type txn_type = AFR_DATA_TRANSACTION;
- gf_boolean_t split_brain = _gf_false;
- int read_child = -1;
+ int i = 0;
+ int ret = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+ mode_t st_mode = 0;
+ dev_t ia_rdev = 0;
+ dict_t *dict = NULL;
+ dev_t st_rdev = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- loc = &local->loc;
-
- if (op_ret < 0) {
- if (op_errno == EIO)
- local->govinda_gOvinda = 1;
- // EIO can happen if finding the fresh parent dir failed
- goto out;
- }
- //now No chance for the ia_type to conflict
- ia_type = sh->buf[sh->success_children[0]].ia_type;
- txn_type = afr_transaction_type_get (ia_type);
- nsources = afr_build_sources (this, sh->xattr, sh->buf,
- sh->pending_matrix, sh->sources,
- sh->success_children, txn_type,
- &subvol_status, _gf_false);
- if (nsources < 0) {
- gf_log (this->name, GF_LOG_INFO, "No sources for dir of %s,"
- " in missing entry self-heal, continuing with the rest"
- " of the self-heals", local->loc.path);
- if (subvol_status & SPLIT_BRAIN) {
- split_brain = _gf_true;
- switch (txn_type) {
- case AFR_DATA_TRANSACTION:
- nsources = 1;
- sh->sources[sh->success_children[0]] = 1;
- break;
- case AFR_ENTRY_TRANSACTION:
- read_child = afr_get_no_xattr_dir_read_child
- (this,
- sh->success_children,
- sh->buf);
- sh->sources[read_child] = 1;
- nsources = 1;
- break;
- default:
- op_errno = EIO;
- goto out;
- }
- } else {
- op_errno = EIO;
- goto out;
- }
- }
-
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, priv->child_count);
- sh->source = sh->fresh_children[0];
- if (sh->source == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "No active sources found.");
- op_errno = EIO;
- goto out;
- }
+ for (i = 0; i < priv->child_count; i++)
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
- if (sh->gfid_sh_success_cbk)
- sh->gfid_sh_success_cbk (frame, this);
- sh->type = sh->buf[sh->source].ia_type;
- if (uuid_is_null (loc->inode->gfid))
- uuid_copy (loc->gfid, sh->buf[sh->source].ia_gfid);
- if (split_brain) {
- afr_sh_missing_entries_finish (frame, this);
- } else {
- sh_missing_entries_create (frame, this);
- }
- return;
-out:
- sh->op_failed = 1;
- afr_sh_set_error (sh, op_errno);
- afr_sh_missing_entries_finish (frame, this);
- return;
-}
+ call_count = enoent_count;
+ local->call_count = call_count;
-static int
-afr_sh_common_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- int call_count = 0;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
+ st_mode = st_mode_from_ia (sh->buf[sh->source].ia_prot,
+ sh->buf[sh->source].ia_type);
+ ia_rdev = sh->buf[sh->source].ia_rdev;
+ st_rdev = makedev (ia_major (ia_rdev), ia_minor (ia_rdev));
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ gf_log (this->name, GF_LOG_TRACE,
+ "mknod %s mode 0%o device type %"PRId64" on %d subvolumes",
+ local->loc.path, st_mode, (uint64_t)st_rdev, enoent_count);
- afr_sh_common_lookup_resp_handler (frame, cookie, this, op_ret,
- op_errno, inode, buf, xattr,
- postparent, &sh->lookup_loc);
- call_count = afr_frame_return (frame);
+ dict = dict_new ();
+ if (!dict)
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
- if (call_count)
- goto out;
- op_ret = -1;
- if (!sh->success_count) {
- op_errno = afr_resultant_errno_get (NULL, sh->child_errno,
- priv->child_count);
- gf_log (this->name, GF_LOG_ERROR, "Failed to lookup %s, "
- "reason %s", sh->lookup_loc.path,
- strerror (op_errno));
- goto done;
- }
+ ret = afr_set_dict_gfid (dict, sh->buf[sh->source].ia_gfid);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed",
+ local->loc.path);
- if ((sh->lookup_flags & AFR_LOOKUP_FAIL_CONFLICTS) &&
- (afr_conflicting_iattrs (sh->buf, sh->success_children,
- priv->child_count,
- sh->lookup_loc.path, this->name))) {
- op_errno = EIO;
- gf_log (this->name, GF_LOG_ERROR, "Conflicting entries "
- "for %s", sh->lookup_loc.path);
- goto done;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->child_errno[i] == ENOENT) {
+ STACK_WIND_COOKIE (frame,
+ sh_missing_entries_newentry_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->mknod,
+ &local->loc, st_mode, st_rdev, dict);
+ if (!--call_count)
+ break;
+ }
}
- if ((sh->lookup_flags & AFR_LOOKUP_FAIL_MISSING_GFIDS) &&
- (afr_gfid_missing_count (this->name, sh->success_children,
- sh->buf, priv->child_count,
- sh->lookup_loc.path))) {
- op_errno = ENODATA;
- gf_log (this->name, GF_LOG_ERROR, "Missing Gfids "
- "for %s", sh->lookup_loc.path);
- goto done;
- }
- op_ret = 0;
+ if (dict)
+ dict_unref (dict);
-done:
- sh->lookup_done (frame, this, op_ret, op_errno);
-out:
return 0;
}
-int
-afr_sh_remove_entry_cbk (call_frame_t *frame, xlator_t *this, int child,
- int32_t op_ret, int32_t op_errno)
+
+static int
+sh_missing_entries_mkdir (call_frame_t *frame, xlator_t *this)
{
- int call_count = 0;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ dict_t *dict = NULL;
+ int i = 0;
+ int ret = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+ mode_t st_mode = 0;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
+
+ for (i = 0; i < priv->child_count; i++)
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
+
+ call_count = enoent_count;
+ local->call_count = call_count;
- GF_ASSERT (sh->post_remove_call);
- if ((op_ret == -1) && (op_errno != ENOENT)) {
+ st_mode = st_mode_from_ia (sh->buf[sh->source].ia_prot,
+ sh->buf[sh->source].ia_type);
+
+ dict = dict_new ();
+ if (!dict) {
gf_log (this->name, GF_LOG_ERROR,
- "purge entry %s failed, on child %d reason, %s",
- local->loc.path, child, strerror (op_errno));
- LOCK (&frame->lock);
- {
- afr_sh_set_error (sh, EIO);
- sh->op_failed = 1;
- }
- UNLOCK (&frame->lock);
+ "Out of memory");
+ sh_missing_entries_finish (frame, this);
+ return 0;
}
- call_count = afr_frame_return (frame);
- if (call_count == 0)
- sh->post_remove_call (frame, this);
- return 0;
-}
-void
-afr_sh_call_entry_expunge_remove (call_frame_t *frame, xlator_t *this,
- int child_index, struct iatt *buf,
- struct iatt *parentbuf,
- afr_expunge_done_cbk_t expunge_done)
-{
- call_frame_t *expunge_frame = NULL;
- afr_local_t *local = NULL;
- afr_local_t *expunge_local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_self_heal_t *expunge_sh = NULL;
- int32_t op_errno = 0;
- int ret = 0;
+ ret = afr_set_dict_gfid (dict, sh->buf[sh->source].ia_gfid);
+ if (ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: inode gfid set failed", local->loc.path);
- expunge_frame = copy_frame (frame);
- if (!expunge_frame) {
- goto out;
- }
- AFR_LOCAL_ALLOC_OR_GOTO (expunge_local, out);
+ gf_log (this->name, GF_LOG_TRACE,
+ "mkdir %s mode 0%o on %d subvolumes",
+ local->loc.path, st_mode, enoent_count);
- local = frame->local;
- sh = &local->self_heal;
- expunge_frame->local = expunge_local;
- expunge_sh = &expunge_local->self_heal;
- expunge_sh->sh_frame = frame;
- loc_copy (&expunge_local->loc, &local->loc);
- ret = afr_build_parent_loc (&expunge_sh->parent_loc,
- &expunge_local->loc, &op_errno);
- if (ret) {
- ret = -op_errno;
- goto out;
- }
- sh->expunge_done = expunge_done;
- afr_sh_entry_expunge_remove (expunge_frame, this, child_index, buf,
- parentbuf);
- return;
-out:
- gf_log (this->name, GF_LOG_ERROR, "Expunge of %s failed, reason: %s",
- local->loc.path, strerror (op_errno));
- expunge_done (frame, this, child_index, -1, op_errno);
-}
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->child_errno[i] == ENOENT) {
+ if (!strcmp (local->loc.path, "/")) {
+ /* We shouldn't try to create "/" */
-void
-afr_sh_remove_stale_lookup_info (afr_self_heal_t *sh, int32_t *success_children,
- int32_t *fresh_children,
- unsigned int child_count)
-{
- int i = 0;
+ sh_missing_entries_finish (frame, this);
- for (i = 0; i < child_count; i++) {
- if (afr_is_child_present (success_children, child_count, i) &&
- !afr_is_child_present (fresh_children, child_count, i)) {
- sh->child_errno[i] = ENOENT;
- GF_ASSERT (sh->xattr[i]);
- dict_unref (sh->xattr[i]);
- sh->xattr[i] = NULL;
+ return 0;
+ } else {
+ STACK_WIND_COOKIE (frame,
+ sh_missing_entries_newentry_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->mkdir,
+ &local->loc, st_mode, dict);
+ if (!--call_count)
+ break;
+ }
}
}
-}
-int
-afr_sh_purge_stale_entries_done (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ if (dict)
+ dict_unref (dict);
- if (sh->op_failed) {
- afr_sh_missing_entries_finish (frame, this);
- } else {
- if (afr_gfid_missing_count (this->name, sh->fresh_children,
- sh->buf, priv->child_count,
- local->loc.path)) {
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_missing_entries_lookup_done,
- sh->sh_gfid_req,
- AFR_LOOKUP_FAIL_CONFLICTS|
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
- } else {
- //No need to set gfid so goto missing entries lookup done
- //Behave as if you have done the lookup
- afr_sh_remove_stale_lookup_info (sh,
- sh->success_children,
- sh->fresh_children,
- priv->child_count);
- afr_children_copy (sh->success_children,
- sh->fresh_children,
- priv->child_count);
- afr_sh_missing_entries_lookup_done (frame, this, 0, 0);
- }
- }
return 0;
}
-gf_boolean_t
-afr_sh_purge_entry_condition (afr_local_t *local, afr_private_t *priv,
- int child)
+
+static int
+sh_missing_entries_symlink (call_frame_t *frame, xlator_t *this,
+ const char *link, struct iatt *buf)
{
+ afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ dict_t *dict = NULL;
+ int i = 0;
+ int ret = 0;
+ int enoent_count = 0;
+ int call_count = 0;
+
+ local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
- if (local->child_up[child] &&
- (!afr_is_child_present (sh->fresh_parent_dirs, priv->child_count,
- child))
- && (sh->child_errno[child] != ENOENT))
- return _gf_true;
+ for (i = 0; i < priv->child_count; i++)
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
- return _gf_false;
-}
+ call_count = enoent_count;
+ local->call_count = call_count;
-gf_boolean_t
-afr_sh_purge_stale_entry_condition (afr_local_t *local, afr_private_t *priv,
- int child)
-{
- afr_self_heal_t *sh = NULL;
+ dict = dict_new ();
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ sh_missing_entries_finish (frame, this);
+ return 0;
+ }
- sh = &local->self_heal;
+ ret = afr_set_dict_gfid (dict, buf->ia_gfid);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: dict gfid set failed", local->loc.path);
- if (local->child_up[child] &&
- (!afr_is_child_present (sh->fresh_children, priv->child_count,
- child))
- && (sh->child_errno[child] != ENOENT))
- return _gf_true;
+ gf_log (this->name, GF_LOG_TRACE,
+ "symlink %s -> %s on %d subvolumes",
+ local->loc.path, link, enoent_count);
- return _gf_false;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->child_errno[i] == ENOENT) {
+ STACK_WIND_COOKIE (frame,
+ sh_missing_entries_newentry_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->symlink,
+ link, &local->loc, dict);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ return 0;
}
-void
-afr_sh_purge_entry_common (call_frame_t *frame, xlator_t *this,
- gf_boolean_t purge_condition (afr_local_t *local,
- afr_private_t *priv,
- int child))
+
+static int
+sh_missing_entries_readlink_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ const char *link, struct iatt *sbuf)
{
afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
afr_self_heal_t *sh = NULL;
- int i = 0;
- int call_count = 0;
+ afr_private_t *priv = NULL;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- for (i = 0; i < priv->child_count; i++) {
- if (purge_condition (local, priv, i))
- call_count++;
- }
-
- if (call_count == 0) {
- sh->post_remove_call (frame, this);
- goto out;
+ if (op_ret > 0)
+ sh_missing_entries_symlink (frame, this, link, sbuf);
+ else {
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: failed to do readlink on %s (%s)",
+ local->loc.path, priv->children[sh->source]->name,
+ strerror (op_errno));
+ sh_missing_entries_finish (frame, this);
}
- local->call_count = call_count;
- for (i = 0; i < priv->child_count; i++) {
- if (!purge_condition (local, priv, i))
- continue;
- gf_log (this->name, GF_LOG_INFO, "purging the stale entry %s "
- "on %d", local->loc.path, i);
- afr_sh_call_entry_expunge_remove (frame, this,
- (long) i, &sh->buf[i],
- &sh->parentbufs[i],
- afr_sh_remove_entry_cbk);
- }
-out:
- return;
+ return 0;
}
-void
-afr_sh_purge_entry (call_frame_t *frame, xlator_t *this)
+
+static int
+sh_missing_entries_readlink (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
local = frame->local;
sh = &local->self_heal;
- sh->post_remove_call = afr_sh_missing_entries_finish;
+ priv = this->private;
- afr_sh_purge_entry_common (frame, this, afr_sh_purge_entry_condition);
+ STACK_WIND (frame, sh_missing_entries_readlink_cbk,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->readlink,
+ &local->loc, 4096);
+
+ return 0;
}
-void
-afr_sh_purge_stale_entry (call_frame_t *frame, xlator_t *this)
+
+static int
+sh_missing_entries_create (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ int type = 0;
+ int i = 0;
afr_private_t *priv = NULL;
- int i = 0;
+ int enoent_count = 0;
+ int govinda_gOvinda = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- sh->post_remove_call = afr_sh_purge_stale_entries_done;
-
for (i = 0; i < priv->child_count; i++) {
- if (afr_is_child_present (sh->fresh_children,
- priv->child_count, i))
- continue;
-
- if ((!local->child_up[i]) || sh->child_errno[i] != 0)
+ if (!local->child_up[i])
continue;
- GF_ASSERT (!uuid_is_null (sh->entrybuf.ia_gfid) ||
- uuid_is_null (sh->buf[i].ia_gfid));
+ if (sh->child_errno[i]) {
+ if (sh->child_errno[i] == ENOENT)
+ enoent_count++;
+ } else {
+ if (type) {
+ if (type != sh->buf[i].ia_type) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "file %s is not recoverable "
+ "automatically!",
+ local->loc.path);
+
+ govinda_gOvinda = 1;
+ }
+ } else {
+ sh->source = i;
+ type = sh->buf[i].ia_type;
+ }
+ }
+ }
- if ((sh->entrybuf.ia_type != sh->buf[i].ia_type) ||
- (uuid_compare (sh->buf[i].ia_gfid,
- sh->entrybuf.ia_gfid)))
- continue;
+ if (govinda_gOvinda) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "conflicting filetypes exist for path %s. returning.",
+ local->loc.path);
- afr_children_add_child (sh->fresh_children, i,
- priv->child_count);
+ local->govinda_gOvinda = 1;
+ sh_missing_entries_finish (frame, this);
+ return 0;
+ }
+ if (!type) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "no source found for %s. all nodes down?. returning.",
+ local->loc.path);
+ /* subvolumes down and/or file does not exist */
+ sh_missing_entries_finish (frame, this);
+ return 0;
}
- afr_sh_purge_entry_common (frame, this,
- afr_sh_purge_stale_entry_condition);
-}
-void
-afr_sh_save_child_iatts_from_policy (int32_t *children, struct iatt *bufs,
- struct iatt *save,
- unsigned int child_count)
-{
- int i = 0;
- int child = 0;
- gf_boolean_t saved = _gf_false;
+ if (enoent_count == 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "no missing files - %s. proceeding to metadata check",
+ local->loc.path);
+ /* proceed to next step - metadata self-heal */
+ sh_missing_entries_finish (frame, this);
+ return 0;
+ }
- GF_ASSERT (save);
- //if iatt buf with gfid exists sets it
- for (i = 0; i < child_count; i++) {
- child = children[i];
- if (child == -1)
- break;
- *save = bufs[child];
- saved = _gf_true;
- if (!uuid_is_null (save->ia_gfid))
- break;
+ switch (type) {
+ case IA_IFSOCK:
+ case IA_IFREG:
+ case IA_IFBLK:
+ case IA_IFCHR:
+ case IA_IFIFO:
+ sh_missing_entries_mknod (frame, this);
+ break;
+ case IA_IFLNK:
+ sh_missing_entries_readlink (frame, this);
+ break;
+ case IA_IFDIR:
+ sh_missing_entries_mkdir (frame, this);
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: unknown file type: 0%o", local->loc.path, type);
+ local->govinda_gOvinda = 1;
+ sh_missing_entries_finish (frame, this);
}
- GF_ASSERT (saved);
-}
-void
-afr_get_children_of_fresh_parent_dirs (afr_self_heal_t *sh,
- unsigned int child_count)
-{
- afr_children_intersection_get (sh->success_children,
- sh->fresh_parent_dirs,
- sh->sources, child_count);
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, child_count);
- memset (sh->sources, 0, sizeof (*sh->sources) * child_count);
+ return 0;
}
-void
-afr_sh_children_lookup_done (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+
+static int
+sh_missing_entries_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- int32_t fresh_child_enoents = 0;
- int32_t fresh_parent_count = 0;
+ int child_index = 0;
+ afr_local_t *local = NULL;
+ int call_count = 0;
+ afr_private_t *priv = NULL;
+ mode_t st_mode = 0;
local = frame->local;
- sh = &local->self_heal;
priv = this->private;
- if (op_ret < 0)
- goto fail;
- afr_get_children_of_fresh_parent_dirs (sh, priv->child_count);
- fresh_parent_count = afr_get_children_count (sh->fresh_parent_dirs,
- priv->child_count);
- //we need the enoent count of the subvols present in fresh_parent_dirs
- fresh_child_enoents = afr_errno_count (sh->fresh_parent_dirs,
- sh->child_errno,
- priv->child_count, ENOENT);
- if (fresh_child_enoents == fresh_parent_count) {
- gf_log (this->name, GF_LOG_INFO, "Deleting stale file %s",
- local->loc.path);
- afr_sh_set_error (sh, ENOENT);
- sh->op_failed = 1;
- afr_sh_purge_entry (frame, this);
- } else if (!afr_conflicting_iattrs (sh->buf, sh->fresh_children,
- priv->child_count, local->loc.path,
- this->name)) {
- afr_sh_save_child_iatts_from_policy (sh->fresh_children,
- sh->buf, &sh->entrybuf,
- priv->child_count);
- afr_update_gfid_from_iatts (sh->sh_gfid_req, sh->buf,
- sh->fresh_children,
- priv->child_count);
- afr_sh_purge_stale_entry (frame, this);
- } else {
- op_errno = EIO;
- local->govinda_gOvinda = 1;
- goto fail;
- }
+ child_index = (long) cookie;
- return;
+ if (buf)
+ st_mode = st_mode_from_ia (buf->ia_prot, buf->ia_type);
-fail:
- sh->op_failed = 1;
- afr_sh_set_error (sh, op_errno);
- afr_sh_missing_entries_finish (frame, this);
- return;
-}
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "path %s on subvolume %s is of mode 0%o",
+ local->loc.path,
+ priv->children[child_index]->name,
+ st_mode);
-static void
-afr_sh_find_fresh_parents (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int enoent_count = 0;
- int nsources = 0;
- int source = -1;
- int32_t subvol_status = 0;
+ local->self_heal.buf[child_index] = *buf;
+ local->self_heal.parentbuf = *postparent;
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "path %s on subvolume %s => -1 (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ local->self_heal.child_errno[child_index] = op_errno;
+ }
- if (op_ret < 0)
- goto out;
- enoent_count = afr_errno_count (NULL, sh->child_errno,
- priv->child_count, ENOENT);
- if (enoent_count > 0) {
- gf_log (this->name, GF_LOG_INFO, "Parent dir missing for %s,"
- " in missing entry self-heal, aborting missing-entry "
- "self-heal",
- local->loc.path);
- afr_sh_missing_entries_finish (frame, this);
- return;
}
+ UNLOCK (&frame->lock);
- nsources = afr_build_sources (this, sh->xattr, sh->buf,
- sh->pending_matrix, sh->sources,
- sh->success_children,
- AFR_ENTRY_TRANSACTION, &subvol_status,
- _gf_true);
- if ((subvol_status & ALL_FOOLS) ||
- (subvol_status & SPLIT_BRAIN)) {
- gf_log (this->name, GF_LOG_INFO, "%s: Performing conservative "
- "merge", sh->parent_loc.path);
- afr_mark_success_children_sources (sh->sources,
- sh->success_children,
- priv->child_count);
- } else if (nsources < 0) {
- gf_log (this->name, GF_LOG_ERROR, "No sources for dir "
- "of %s, in missing entry self-heal, aborting "
- "self-heal", local->loc.path);
- op_errno = EIO;
- goto out;
- }
+ call_count = afr_frame_return (frame);
- source = afr_sh_select_source (sh->sources, priv->child_count);
- if (source == -1) {
- GF_ASSERT (0);
- gf_log (this->name, GF_LOG_DEBUG, "No active sources found.");
- op_errno = EIO;
- goto out;
+ if (call_count == 0) {
+ sh_missing_entries_create (frame, this);
}
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_parent_dirs, priv->child_count);
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_children_lookup_done, NULL, 0,
- NULL);
- return;
-out:
- afr_sh_set_error (sh, op_errno);
- sh->op_failed = 1;
- afr_sh_missing_entries_finish (frame, this);
- return;
+ return 0;
}
-void
-afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count)
-{
- int i = 0;
- for (i = 0; i < child_count; i++) {
- memset (&sh->buf[i], 0, sizeof (sh->buf[i]));
- memset (&sh->parentbufs[i], 0, sizeof (sh->parentbufs[i]));
- sh->child_errno[i] = 0;
- }
- memset (&sh->parentbuf, 0, sizeof (sh->parentbuf));
- sh->success_count = 0;
- afr_reset_children (sh->success_children, child_count);
- afr_reset_children (sh->fresh_children, child_count);
- afr_reset_xattr (sh->xattr, child_count);
- loc_wipe (&sh->lookup_loc);
-}
-
-/* afr self-heal state will be lost if this call is made
- * please check the afr_sh_common_reset that is called in this function
- */
-int
-afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- afr_lookup_done_cbk_t lookup_done , uuid_t gfid,
- int32_t flags, dict_t *xdata)
+static int
+sh_missing_entries_lookup (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
int i = 0;
int call_count = 0;
afr_private_t *priv = NULL;
dict_t *xattr_req = NULL;
- afr_self_heal_t *sh = NULL;
+ int ret = -1;
local = frame->local;
priv = this->private;
- sh = &local->self_heal;
- call_count = afr_up_children_count (local->child_up, priv->child_count);
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
local->call_count = call_count;
xattr_req = dict_new();
if (xattr_req) {
- afr_xattr_req_prepare (this, xattr_req, loc->path);
- if (gfid) {
- gf_log (this->name, GF_LOG_DEBUG,
- "looking up %s with gfid: %s",
- loc->path, uuid_utoa (gfid));
- GF_ASSERT (!uuid_is_null (gfid));
- afr_set_dict_gfid (xattr_req, gfid);
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_uint64 (xattr_req,
+ priv->pending_key[i],
+ 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: failed to set value for %s",
+ local->loc.path, priv->pending_key[i]);
}
}
- afr_sh_common_reset (sh, priv->child_count);
- sh->lookup_done = lookup_done;
- loc_copy (&sh->lookup_loc, loc);
- sh->lookup_flags = flags;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_TRACE,
"looking up %s on subvolume %s",
- loc->path, priv->children[i]->name);
+ local->loc.path, priv->children[i]->name);
STACK_WIND_COOKIE (frame,
- afr_sh_common_lookup_cbk,
+ sh_missing_entries_lookup_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->lookup,
- loc, xattr_req);
+ &local->loc, xattr_req);
if (!--call_count)
break;
@@ -1944,80 +1374,47 @@ afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
-afr_sh_post_nb_entrylk_conflicting_sh_cbk (call_frame_t *frame, xlator_t *this)
+afr_sh_post_nonblocking_entrylk_cbk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
local = frame->local;
int_lock = &local->internal_lock;
- sh = &local->self_heal;
if (int_lock->lock_op_ret < 0) {
gf_log (this->name, GF_LOG_INFO,
"Non blocking entrylks failed.");
- sh->op_failed = -1;
afr_sh_missing_entries_done (frame, this);
} else {
gf_log (this->name, GF_LOG_DEBUG,
"Non blocking entrylks done. Proceeding to FOP");
- afr_sh_common_lookup (frame, this, &sh->parent_loc,
- afr_sh_find_fresh_parents,
- NULL, AFR_LOOKUP_FAIL_CONFLICTS,
- NULL);
+ sh_missing_entries_lookup (frame, this);
}
return 0;
}
-int
-afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)
+static int
+afr_sh_entrylk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
local = frame->local;
- sh = &local->self_heal;
- int_lock = &local->internal_lock;
-
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "Non blocking entrylks failed.");
- afr_sh_missing_entries_done (frame, this);
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
- "Non blocking entrylks done. Proceeding to FOP");
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_missing_entries_lookup_done,
- sh->sh_gfid_req, AFR_LOOKUP_FAIL_CONFLICTS|
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
- }
-
- return 0;
-}
-
-int
-afr_sh_entrylk (call_frame_t *frame, xlator_t *this, loc_t *loc,
- char *base_name, afr_lock_cbk_t lock_cbk)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
-
- local = frame->local;
int_lock = &local->internal_lock;
+ sh = &local->self_heal;
int_lock->transaction_lk_type = AFR_SELFHEAL_LK;
int_lock->selfheal_lk_type = AFR_ENTRY_SELF_HEAL_LK;
afr_set_lock_number (frame, this);
- int_lock->lk_basename = base_name;
- int_lock->lk_loc = loc;
- int_lock->lock_cbk = lock_cbk;
+ int_lock->lk_basename = local->loc.name;
+ int_lock->lk_loc = &sh->parent_loc;
+ int_lock->lock_cbk = afr_sh_post_nonblocking_entrylk_cbk;
afr_nonblocking_entrylk (frame, this);
@@ -2025,49 +1422,25 @@ afr_sh_entrylk (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
static int
-afr_self_heal_parent_entrylk (call_frame_t *frame, xlator_t *this,
- afr_lock_cbk_t lock_cbk)
+afr_self_heal_missing_entries (call_frame_t *frame, xlator_t *this)
{
+ afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
- afr_internal_lock_t *int_lock = NULL;
- int ret = -1;
- int32_t op_errno = 0;
+ afr_private_t *priv = NULL;
local = frame->local;
+ int_lock = &local->internal_lock;
sh = &local->self_heal;
+ priv = this->private;
gf_log (this->name, GF_LOG_TRACE,
"attempting to recreate missing entries for path=%s",
local->loc.path);
- ret = afr_build_parent_loc (&sh->parent_loc, &local->loc, &op_errno);
- if (ret)
- goto out;
+ afr_build_parent_loc (&sh->parent_loc, &local->loc);
- afr_sh_entrylk (frame, this, &sh->parent_loc, NULL,
- lock_cbk);
- return 0;
-out:
- int_lock = &local->internal_lock;
- int_lock->lock_op_ret = -1;
- lock_cbk (frame, this);
- return 0;
-}
-
-static int
-afr_self_heal_conflicting_entries (call_frame_t *frame, xlator_t *this)
-{
- afr_self_heal_parent_entrylk (frame, this,
- afr_sh_post_nb_entrylk_conflicting_sh_cbk);
- return 0;
-}
-
-static int
-afr_self_heal_gfids (call_frame_t *frame, xlator_t *this)
-{
- afr_self_heal_parent_entrylk (frame, this,
- afr_sh_post_nb_entrylk_gfid_sh_cbk);
+ afr_sh_entrylk (frame, this);
return 0;
}
@@ -2082,30 +1455,31 @@ afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
sh = &l->self_heal;
- lc = mem_get0 (this->local_pool);
+ lc = GF_CALLOC (1, sizeof (afr_local_t),
+ gf_afr_mt_afr_local_t);
if (!lc)
goto out;
shc = &lc->self_heal;
shc->unwind = sh->unwind;
- shc->gfid_sh_success_cbk = sh->gfid_sh_success_cbk;
- shc->do_missing_entry_self_heal = sh->do_missing_entry_self_heal;
- shc->do_gfid_self_heal = sh->do_gfid_self_heal;
- shc->do_data_self_heal = sh->do_data_self_heal;
- shc->do_metadata_self_heal = sh->do_metadata_self_heal;
- shc->do_entry_self_heal = sh->do_entry_self_heal;
- shc->force_confirm_spb = sh->force_confirm_spb;
+ shc->need_data_self_heal = sh->need_data_self_heal;
+ shc->need_metadata_self_heal = sh->need_metadata_self_heal;
+ shc->need_entry_self_heal = sh->need_entry_self_heal;
shc->forced_merge = sh->forced_merge;
+ shc->healing_fd_opened = sh->healing_fd_opened;
+ shc->data_lock_held = sh->data_lock_held;
+ if (sh->healing_fd && !sh->healing_fd_opened)
+ shc->healing_fd = fd_ref (sh->healing_fd);
+ else
+ shc->healing_fd = sh->healing_fd;
shc->background = sh->background;
shc->type = sh->type;
- uuid_copy (shc->sh_gfid_req, sh->sh_gfid_req);
if (l->loc.path)
loc_copy (&lc->loc, &l->loc);
- lc->child_up = memdup (l->child_up,
- sizeof (*lc->child_up) * priv->child_count);
+ lc->child_up = memdup (l->child_up, priv->child_count);
if (l->xattr_req)
lc->xattr_req = dict_ref (l->xattr_req);
@@ -2116,7 +1490,7 @@ afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
if (l->internal_lock.inode_locked_nodes)
lc->internal_lock.inode_locked_nodes =
memdup (l->internal_lock.inode_locked_nodes,
- sizeof (*lc->internal_lock.inode_locked_nodes) * priv->child_count);
+ priv->child_count);
else
lc->internal_lock.inode_locked_nodes =
GF_CALLOC (sizeof (*l->internal_lock.inode_locked_nodes),
@@ -2125,7 +1499,7 @@ afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
if (l->internal_lock.entry_locked_nodes)
lc->internal_lock.entry_locked_nodes =
memdup (l->internal_lock.entry_locked_nodes,
- sizeof (*lc->internal_lock.entry_locked_nodes) * priv->child_count);
+ priv->child_count);
else
lc->internal_lock.entry_locked_nodes =
GF_CALLOC (sizeof (*l->internal_lock.entry_locked_nodes),
@@ -2134,7 +1508,7 @@ afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
if (l->internal_lock.locked_nodes)
lc->internal_lock.locked_nodes =
memdup (l->internal_lock.locked_nodes,
- sizeof (*lc->internal_lock.locked_nodes) * priv->child_count);
+ priv->child_count);
else
lc->internal_lock.locked_nodes =
GF_CALLOC (sizeof (*l->internal_lock.locked_nodes),
@@ -2157,32 +1531,28 @@ afr_self_heal_completion_cbk (call_frame_t *bgsh_frame, xlator_t *this)
afr_local_t * local = NULL;
afr_self_heal_t * sh = NULL;
char sh_type_str[256] = {0,};
- gf_boolean_t split_brain = _gf_false;
priv = this->private;
local = bgsh_frame->local;
sh = &local->self_heal;
- if (local->govinda_gOvinda || sh->mdata_spb || sh->data_spb)
- split_brain = _gf_true;
-
- afr_set_split_brain (this, sh->inode, split_brain);
-
- afr_self_heal_type_str_get (sh, sh_type_str,
- sizeof(sh_type_str));
- if (sh->op_failed) {
- gf_log (this->name, GF_LOG_ERROR, "background %s self-heal "
- "failed on %s", sh_type_str, local->loc.path);
+ if (local->govinda_gOvinda) {
+ afr_set_split_brain (this, local->cont.lookup.inode,
+ _gf_true);
} else {
- gf_log (this->name, GF_LOG_INFO, "background %s self-heal "
- "completed on %s", sh_type_str, local->loc.path);
+ afr_set_split_brain (this, local->cont.lookup.inode,
+ _gf_false);
}
+ afr_self_heal_type_str_get(sh, sh_type_str,
+ sizeof(sh_type_str));
+ gf_log (this->name, GF_LOG_DEBUG,
+ "background %s self-heal completed on %s", sh_type_str,
+ local->loc.path);
FRAME_SU_UNDO (bgsh_frame, afr_local_t);
- if (!sh->unwound && sh->unwind) {
- sh->unwind (sh->orig_frame, this, sh->op_ret, sh->op_errno,
- sh->op_failed);
+ if (!sh->unwound) {
+ sh->unwind (sh->orig_frame, this);
}
if (sh->background) {
@@ -2199,131 +1569,96 @@ afr_self_heal_completion_cbk (call_frame_t *bgsh_frame, xlator_t *this)
}
int
-afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
+afr_self_heal (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- int32_t op_errno = 0;
- int ret = 0;
- afr_self_heal_t *orig_sh = NULL;
- call_frame_t *sh_frame = NULL;
- afr_local_t *sh_local = NULL;
- loc_t *loc = NULL;
+ int i = 0;
+
+ call_frame_t *sh_frame = NULL;
+ afr_local_t *sh_local = NULL;
local = frame->local;
- orig_sh = &local->self_heal;
priv = this->private;
GF_ASSERT (local->loc.path);
+ afr_set_lk_owner (frame, this);
+
+ if (local->self_heal.background) {
+ LOCK (&priv->lock);
+ {
+ if (priv->background_self_heals_started
+ > priv->background_self_heal_count) {
+
+ local->self_heal.background = _gf_false;
+
+ } else {
+ priv->background_self_heals_started++;
+ }
+ }
+ UNLOCK (&priv->lock);
+ }
+
gf_log (this->name, GF_LOG_TRACE,
"performing self heal on %s (metadata=%d data=%d entry=%d)",
local->loc.path,
- local->self_heal.do_metadata_self_heal,
- local->self_heal.do_data_self_heal,
- local->self_heal.do_entry_self_heal);
+ local->self_heal.need_metadata_self_heal,
+ local->self_heal.need_data_self_heal,
+ local->self_heal.need_entry_self_heal);
- op_errno = ENOMEM;
sh_frame = copy_frame (frame);
- if (!sh_frame)
- goto out;
- afr_set_lk_owner (sh_frame, this, sh_frame->root);
- afr_set_low_priority (sh_frame);
-
sh_local = afr_local_copy (local, this);
- if (!sh_local)
- goto out;
sh_frame->local = sh_local;
sh = &sh_local->self_heal;
- sh->inode = inode_ref (inode);
sh->orig_frame = frame;
sh->completion_cbk = afr_self_heal_completion_cbk;
- sh->success = GF_CALLOC (priv->child_count, sizeof (*sh->success),
- gf_afr_mt_char);
- if (!sh->success)
- goto out;
+ sh->buf = GF_CALLOC (priv->child_count, sizeof (struct iatt),
+ gf_afr_mt_iatt);
+ sh->child_errno = GF_CALLOC (priv->child_count, sizeof (int),
+ gf_afr_mt_int);
+ sh->success = GF_CALLOC (priv->child_count, sizeof (int),
+ gf_afr_mt_int);
+ sh->xattr = GF_CALLOC (priv->child_count, sizeof (dict_t *),
+ gf_afr_mt_dict_t);
sh->sources = GF_CALLOC (sizeof (*sh->sources), priv->child_count,
gf_afr_mt_int);
- if (!sh->sources)
- goto out;
sh->locked_nodes = GF_CALLOC (sizeof (*sh->locked_nodes),
priv->child_count,
gf_afr_mt_int);
- if (!sh->locked_nodes)
- goto out;
-
- sh->pending_matrix = afr_matrix_create (priv->child_count,
- priv->child_count);
- if (!sh->pending_matrix)
- goto out;
-
- sh->delta_matrix = afr_matrix_create (priv->child_count,
- priv->child_count);
- if (!sh->delta_matrix)
- goto out;
-
- sh->fresh_parent_dirs = afr_children_create (priv->child_count);
- if (!sh->fresh_parent_dirs)
- goto out;
- ret = afr_sh_common_create (sh, priv->child_count);
- if (ret) {
- op_errno = -ret;
- goto out;
- }
-
- if (local->self_heal.background) {
- LOCK (&priv->lock);
- {
- if (priv->background_self_heals_started
- < priv->background_self_heal_count) {
- priv->background_self_heals_started++;
+ sh->pending_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,
+ gf_afr_mt_int32_t);
- } else {
- local->self_heal.background = _gf_false;
- sh->background = _gf_false;
- }
- }
- UNLOCK (&priv->lock);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->pending_matrix[i] = GF_CALLOC (sizeof (int32_t),
+ priv->child_count,
+ gf_afr_mt_int32_t);
}
- if (!local->loc.parent) {
- sh->do_missing_entry_self_heal = _gf_false;
- sh->do_gfid_self_heal = _gf_false;
+ sh->delta_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,
+ gf_afr_mt_int32_t);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->delta_matrix[i] = GF_CALLOC (sizeof (int32_t),
+ priv->child_count,
+ gf_afr_mt_int32_t);
}
FRAME_SU_DO (sh_frame, afr_local_t);
- if (sh->do_missing_entry_self_heal) {
- afr_self_heal_conflicting_entries (sh_frame, this);
- } else if (sh->do_gfid_self_heal) {
- GF_ASSERT (!uuid_is_null (sh->sh_gfid_req));
- afr_self_heal_gfids (sh_frame, this);
+ if (local->success_count && local->enoent_count) {
+ afr_self_heal_missing_entries (sh_frame, this);
} else {
- loc = &sh_local->loc;
- if (uuid_is_null (loc->inode->gfid) && uuid_is_null (loc->gfid)) {
- if (!uuid_is_null (inode->gfid))
- GF_ASSERT (!uuid_compare (inode->gfid,
- sh->sh_gfid_req));
- uuid_copy (loc->gfid, sh->sh_gfid_req);
- }
gf_log (this->name, GF_LOG_TRACE,
"proceeding to metadata check on %s",
local->loc.path);
afr_sh_missing_entries_done (sh_frame, this);
}
- op_errno = 0;
-out:
- if (op_errno) {
- orig_sh->unwind (frame, this, -1, op_errno, 1);
- if (sh_frame)
- AFR_STACK_DESTROY (sh_frame);
- }
return 0;
}
@@ -2331,186 +1666,17 @@ void
afr_self_heal_type_str_get (afr_self_heal_t *self_heal_p, char *str,
size_t size)
{
- GF_ASSERT (str && (size > strlen (" missing-entry gfid "
- "meta-data data entry")));
-
- if (self_heal_p->do_metadata_self_heal) {
- snprintf (str, size, " meta-data");
- }
-
- if (self_heal_p->do_data_self_heal) {
- snprintf (str + strlen(str), size - strlen(str), " data");
- }
+ GF_ASSERT (str && (size > 0));
- if (self_heal_p->do_entry_self_heal) {
- snprintf (str + strlen(str), size - strlen(str), " entry");
+ if (self_heal_p->need_metadata_self_heal) {
+ snprintf(str, size, " meta-data");
}
- if (self_heal_p->do_missing_entry_self_heal) {
- snprintf (str + strlen(str), size - strlen(str),
- " missing-entry");
+ if (self_heal_p->need_data_self_heal) {
+ snprintf(str + strlen(str), size - strlen(str), " data");
}
- if (self_heal_p->do_gfid_self_heal) {
- snprintf (str + strlen(str), size - strlen(str), " gfid");
+ if (self_heal_p->need_entry_self_heal) {
+ snprintf(str + strlen(str), size - strlen(str), " entry");
}
}
-
-afr_self_heal_type
-afr_self_heal_type_for_transaction (afr_transaction_type type)
-{
- afr_self_heal_type sh_type = AFR_SELF_HEAL_INVALID;
-
- switch (type) {
- case AFR_DATA_TRANSACTION:
- sh_type = AFR_SELF_HEAL_DATA;
- break;
- case AFR_METADATA_TRANSACTION:
- sh_type = AFR_SELF_HEAL_METADATA;
- break;
- case AFR_ENTRY_TRANSACTION:
- sh_type = AFR_SELF_HEAL_ENTRY;
- break;
- case AFR_ENTRY_RENAME_TRANSACTION:
- GF_ASSERT (0);
- break;
- }
- return sh_type;
-}
-
-int
-afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
-{
- int ret = -1;
- uuid_t pargfid = {0};
-
- if (!child)
- goto out;
-
- if (!uuid_is_null (parent->inode->gfid))
- uuid_copy (pargfid, parent->inode->gfid);
- else if (!uuid_is_null (parent->gfid))
- uuid_copy (pargfid, parent->gfid);
-
- if (uuid_is_null (pargfid))
- goto out;
-
- if (strcmp (parent->path, "/") == 0)
- ret = gf_asprintf ((char **)&child->path, "/%s", name);
- else
- ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path,
- name);
-
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "asprintf failed while setting child path");
- }
-
- child->name = strrchr (child->path, '/');
- if (child->name)
- child->name++;
-
- child->parent = inode_ref (parent->inode);
- child->inode = inode_new (parent->inode->table);
- uuid_copy (child->pargfid, pargfid);
-
- if (!child->inode) {
- ret = -1;
- goto out;
- }
-
- ret = 0;
-out:
- if ((ret == -1) && child)
- loc_wipe (child);
-
- return ret;
-}
-
-int
-afr_sh_erase_pending (call_frame_t *frame, xlator_t *this,
- afr_transaction_type type, afr_fxattrop_cbk_t cbk,
- int (*finish)(call_frame_t *frame, xlator_t *this))
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
- int i = 0;
- dict_t **erase_xattr = NULL;
- int ret = -1;
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
-
- afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix,
- sh->success, priv->child_count, type);
-
- erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count,
- gf_afr_mt_dict_t);
- if (!erase_xattr)
- goto out;
-
- for (i = 0; i < priv->child_count; i++) {
- if (sh->xattr[i]) {
- call_count++;
- erase_xattr[i] = dict_new ();
- if (!erase_xattr[i])
- goto out;
- }
- }
-
- afr_sh_delta_to_xattr (this, sh->delta_matrix, erase_xattr,
- priv->child_count, type);
-
- gf_log (this->name, GF_LOG_DEBUG, "Delta matrix for: %s",
- lkowner_utoa (&frame->root->lk_owner));
- afr_sh_print_pending_matrix (sh->delta_matrix, this);
- local->call_count = call_count;
- if (call_count == 0) {
- ret = 0;
- finish (frame, this);
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (!erase_xattr[i])
- continue;
-
- if (sh->healing_fd) {//true for ENTRY, reg file DATA transaction
- STACK_WIND_COOKIE (frame, cbk, (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->fxattrop,
- sh->healing_fd,
- GF_XATTROP_ADD_ARRAY, erase_xattr[i],
- NULL);
- } else {
- STACK_WIND_COOKIE (frame, cbk, (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->xattrop,
- &local->loc,
- GF_XATTROP_ADD_ARRAY, erase_xattr[i],
- NULL);
- }
- }
-
- ret = 0;
-out:
- if (erase_xattr) {
- for (i = 0; i < priv->child_count; i++) {
- if (erase_xattr[i]) {
- dict_unref (erase_xattr[i]);
- }
- }
- }
-
- GF_FREE (erase_xattr);
-
- if (ret < 0) {
- sh->op_failed = _gf_true;
- finish (frame, this);
- }
-
- return 0;
-}
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.h b/xlators/cluster/afr/src/afr-self-heal-common.h
index 6eabd1766..6431feaff 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.h
+++ b/xlators/cluster/afr/src/afr-self-heal-common.h
@@ -1,132 +1,73 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __AFR_SELF_HEAL_COMMON_H__
#define __AFR_SELF_HEAL_COMMON_H__
#define FILE_HAS_HOLES(buf) (((buf)->ia_size) > ((buf)->ia_blocks * 512))
-#define AFR_SH_MIN_PARTICIPANTS 2
typedef enum {
AFR_SELF_HEAL_ENTRY,
AFR_SELF_HEAL_METADATA,
AFR_SELF_HEAL_DATA,
- AFR_SELF_HEAL_INVALID = -1,
} afr_self_heal_type;
-typedef enum {
- AFR_LOOKUP_FAIL_CONFLICTS = 1,
- AFR_LOOKUP_FAIL_MISSING_GFIDS = 2,
-} afr_lookup_flags_t;
-
int
afr_sh_select_source (int sources[], int child_count);
int
+afr_sh_sink_count (int sources[], int child_count);
+
+int
afr_sh_source_count (int sources[], int child_count);
+int
+afr_sh_supress_errenous_children (int sources[], int child_errno[],
+ int child_count);
+
void
afr_sh_print_pending_matrix (int32_t *pending_matrix[], xlator_t *this);
-int
-afr_build_pending_matrix (char **pending_key, int32_t **pending_matrix,
- unsigned char *ignorant_subvols,
- dict_t *xattr[], afr_transaction_type type,
- size_t child_count);
+void
+afr_sh_build_pending_matrix (afr_private_t *priv,
+ int32_t *pending_matrix[], dict_t *xattr[],
+ int child_count, afr_transaction_type type);
void
afr_sh_pending_to_delta (afr_private_t *priv, dict_t **xattr,
- int32_t *delta_matrix[], unsigned char success[],
+ int32_t *delta_matrix[], int success[],
int child_count, afr_transaction_type type);
int
-afr_mark_sources (xlator_t *this, int32_t *sources, int32_t **pending_matrix,
- struct iatt *bufs, afr_self_heal_type type,
- int32_t *success_children, int32_t *subvol_status);
+afr_sh_mark_sources (afr_self_heal_t *sh, int child_count,
+ afr_self_heal_type type);
int
-afr_sh_delta_to_xattr (xlator_t *this,
+afr_sh_delta_to_xattr (afr_private_t *priv,
int32_t *delta_matrix[], dict_t *xattr[],
int child_count, afr_transaction_type type);
-void
-afr_self_heal_type_str_get (afr_self_heal_t *self_heal_p, char *str,
- size_t size);
-
-afr_self_heal_type
-afr_self_heal_type_for_transaction (afr_transaction_type type);
-
int
-afr_build_sources (xlator_t *this, dict_t **xattr, struct iatt *bufs,
- int32_t **pending_matrix, int32_t *sources,
- int32_t *success_children, afr_transaction_type type,
- int32_t *subvol_status, gf_boolean_t ignore_ignorant);
-void
-afr_sh_common_reset (afr_self_heal_t *sh, unsigned int child_count);
+afr_sh_is_matrix_zero (int32_t *pending_matrix[], int child_count);
void
-afr_sh_common_lookup_resp_handler (call_frame_t *frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent,
- loc_t *loc);
-
-int
-afr_sh_common_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- afr_lookup_done_cbk_t lookup_cbk, uuid_t uuid,
- int32_t flags, dict_t *xdata);
-int
-afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
- int active_src, struct iatt *buf,
- struct iatt *parentbuf);
-int
-afr_sh_entrylk (call_frame_t *frame, xlator_t *this, loc_t *loc,
- char *base_name, afr_lock_cbk_t lock_cbk);
-int
-afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,
- int child_index);
-int
-afr_sh_data_unlock (call_frame_t *frame, xlator_t *this,
- afr_lock_cbk_t lock_cbk);
-afr_local_t *
-afr_local_copy (afr_local_t *l, xlator_t *this);
-int
-afr_sh_data_lock (call_frame_t *frame, xlator_t *this,
- off_t start, off_t len,
- afr_lock_cbk_t success_handler,
- afr_lock_cbk_t failure_handler);
-void
-afr_sh_set_error (afr_self_heal_t *sh, int32_t op_errno);
-void
-afr_sh_mark_source_sinks (call_frame_t *frame, xlator_t *this);
-typedef int
-(*afr_fxattrop_cbk_t) (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata);
-int
-afr_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name);
-int
-afr_impunge_frame_create (call_frame_t *frame, xlator_t *this,
- int active_source, call_frame_t **impunge_frame);
-void
-afr_sh_reset (call_frame_t *frame, xlator_t *this);
+afr_self_heal_type_str_get (afr_self_heal_t *self_heal_p, char *str,
+ size_t size);
-void
-afr_children_intersection_get (int32_t *set1, int32_t *set2,
- int *intersection, unsigned int child_count);
-int
-afr_get_no_xattr_dir_read_child (xlator_t *this, int32_t *success_children,
- struct iatt *bufs);
-int
-afr_sh_erase_pending (call_frame_t *frame, xlator_t *this,
- afr_transaction_type type, afr_fxattrop_cbk_t cbk,
- int (*finish)(call_frame_t *frame, xlator_t *this));
#endif /* __AFR_SELF_HEAL_COMMON_H__ */
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
index 6619c1353..950fcb167 100644
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -40,35 +49,35 @@
#include "afr-self-heal-common.h"
#include "afr-self-heal-algorithm.h"
-int
-afr_sh_data_fail (call_frame_t *frame, xlator_t *this);
-
-static inline gf_boolean_t
-afr_sh_data_proceed (unsigned int success_count)
-{
- return (success_count >= AFR_SH_MIN_PARTICIPANTS);
-}
-
-extern int
-sh_loop_finish (call_frame_t *loop_frame, xlator_t *this);
-
-int
-afr_post_sh_big_lock_success (call_frame_t *frame, xlator_t *this);
-
-int
-afr_post_sh_big_lock_failure (call_frame_t *frame, xlator_t *this);
-
-int
-afr_sh_data_finish (call_frame_t *frame, xlator_t *this);
int
afr_sh_data_done (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
+
+ /*
+ TODO: cleanup sh->*
+ */
+
+ if (sh->healing_fd && !sh->healing_fd_opened) {
+ /* unref only if we created the fd ourselves */
+
+ fd_unref (sh->healing_fd);
+ sh->healing_fd = NULL;
+ }
+
+ /* for (i = 0; i < priv->child_count; i++) */
+ /* sh->locked_nodes[i] = 0; */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "self heal of %s completed",
+ local->loc.path);
sh->completion_cbk (frame, this);
@@ -78,7 +87,7 @@ afr_sh_data_done (call_frame_t *frame, xlator_t *this)
int
afr_sh_data_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -92,7 +101,7 @@ afr_sh_data_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
{
if (op_ret == -1) {
gf_log (this->name, GF_LOG_INFO,
- "flush failed on %s on subvolume %s: %s",
+ "flush or setattr failed on %s on subvolume %s: %s",
local->loc.path, priv->children[child_index]->name,
strerror (op_errno));
}
@@ -108,89 +117,20 @@ afr_sh_data_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-int
-afr_sh_data_close (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_self_heal_t *sh = NULL;
- int i = 0;
- int call_count = 0;
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
-
- if (!sh->healing_fd) {
- //This happens when file is non-reg
- afr_sh_data_done (frame, this);
- return 0;
- }
- call_count = afr_set_elem_count_get (sh->success,
- priv->child_count);
- local->call_count = call_count;
-
- if (call_count == 0) {
- afr_sh_data_done (frame, this);
- return 0;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (!sh->success[i])
- continue;
- gf_log (this->name, GF_LOG_DEBUG,
- "closing fd of %s on %s",
- local->loc.path, priv->children[i]->name);
-
- STACK_WIND_COOKIE (frame, afr_sh_data_flush_cbk,
- (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->flush,
- sh->healing_fd, NULL);
-
- if (!--call_count)
- break;
- }
-
- return 0;
-}
int
afr_sh_data_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
-
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- int call_count = 0;
- int child_index = (long) cookie;
-
- local = frame->local;
- priv = this->private;
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "setattr failed on %s on subvolume %s: %s",
- local->loc.path, priv->children[child_index]->name,
- strerror (op_errno));
- }
- }
- UNLOCK (&frame->lock);
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- afr_sh_data_finish (frame, this);
- }
+ afr_sh_data_flush_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
+
int
-afr_sh_data_setattr (call_frame_t *frame, xlator_t *this)
+afr_sh_data_close (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
@@ -214,25 +154,65 @@ afr_sh_data_setattr (call_frame_t *frame, xlator_t *this)
stbuf.ia_mtime = sh->buf[source].ia_mtime;
stbuf.ia_mtime_nsec = sh->buf[source].ia_mtime_nsec;
- call_count = afr_set_elem_count_get (sh->success,
- priv->child_count);
- local->call_count = call_count;
+ if (sh->healing_fd_opened) {
+ /* not our job to close the fd */
- if (call_count == 0) {
- GF_ASSERT (0);
- afr_sh_data_finish (frame, this);
+ afr_sh_data_done (frame, this);
+ return 0;
+ }
+
+ if (!sh->healing_fd) {
+ afr_sh_data_done (frame, this);
return 0;
}
+ call_count = (sh->active_sinks + 1) * 2;
+ local->call_count = call_count;
+
+ /* closed source */
+ gf_log (this->name, GF_LOG_TRACE,
+ "closing fd of %s on %s",
+ local->loc.path, priv->children[sh->source]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_flush_cbk,
+ (void *) (long) sh->source,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->flush,
+ sh->healing_fd);
+ call_count--;
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_setattr_cbk,
+ (void *) (long) sh->source,
+ priv->children[sh->source],
+ priv->children[sh->source]->fops->setattr,
+ &local->loc, &stbuf, valid);
+
+ call_count--;
+
+ if (call_count == 0)
+ return 0;
+
for (i = 0; i < priv->child_count; i++) {
- if (!sh->success[i])
+ if (sh->sources[i] || !local->child_up[i])
continue;
+ gf_log (this->name, GF_LOG_TRACE,
+ "closing fd of %s on %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_data_flush_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->flush,
+ sh->healing_fd);
+
+ call_count--;
+
STACK_WIND_COOKIE (frame, afr_sh_data_setattr_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->setattr,
- &local->loc, &stbuf, valid, NULL);
+ &local->loc, &stbuf, valid);
if (!--call_count)
break;
@@ -241,59 +221,44 @@ afr_sh_data_setattr (call_frame_t *frame, xlator_t *this)
return 0;
}
+
int
-afr_sh_data_setattr_fstat_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
+afr_sh_data_unlck_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- int child_index = (long) cookie;
+ afr_local_t * local = NULL;
+ int call_count = 0;
+ int child_index = (long) cookie;
local = frame->local;
- sh = &local->self_heal;
- GF_ASSERT (sh->source == child_index);
- if (op_ret != -1) {
- sh->buf[child_index] = *buf;
- afr_sh_data_setattr (frame, this);
- } else {
- gf_log (this->name, GF_LOG_ERROR, "%s: Failed to set "
- "time-stamps after self-heal", local->loc.path);
- afr_sh_data_fail (frame, this);
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO,
+ "locking inode of %s on child %d failed: %s",
+ local->loc.path, child_index,
+ strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode of %s on child %d locked",
+ local->loc.path, child_index);
+ }
}
+ UNLOCK (&frame->lock);
- return 0;
-}
-
-/*
- * If there are any writes after the self-heal is triggered then the
- * stbuf stored in local->self_heal.buf[] will be invalid so we do one more
- * stat on the source and then set the [am]times
- */
-int
-afr_sh_set_timestamps (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
- afr_self_heal_t *sh = NULL;
+ call_count = afr_frame_return (frame);
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
+ if (call_count == 0) {
+ afr_sh_data_close (frame, this);
+ }
- STACK_WIND_COOKIE (frame, afr_sh_data_setattr_fstat_cbk,
- (void *) (long) sh->source,
- priv->children[sh->source],
- priv->children[sh->source]->fops->fstat,
- sh->healing_fd, NULL);
return 0;
}
-//Fun fact, lock_cbk is being used for both lock & unlock
+
int
-afr_sh_data_unlock (call_frame_t *frame, xlator_t *this,
- afr_lock_cbk_t lock_cbk)
+afr_sh_data_unlock (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_internal_lock_t *int_lock = NULL;
@@ -303,15 +268,15 @@ afr_sh_data_unlock (call_frame_t *frame, xlator_t *this,
int_lock = &local->internal_lock;
sh = &local->self_heal;
- GF_ASSERT (sh->data_lock_held);
+ GF_ASSERT (!sh->data_lock_held);
- sh->data_lock_held = _gf_false;
- int_lock->lock_cbk = lock_cbk;
+ int_lock->lock_cbk = afr_sh_data_close;
afr_unlock (frame, this);
return 0;
}
+
int
afr_sh_data_finish (call_frame_t *frame, xlator_t *this)
{
@@ -321,237 +286,131 @@ afr_sh_data_finish (call_frame_t *frame, xlator_t *this)
local = frame->local;
sh = &local->self_heal;
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_TRACE,
"finishing data selfheal of %s", local->loc.path);
- if (sh->data_lock_held)
- afr_sh_data_unlock (frame, this, afr_sh_data_close);
+ if (!sh->data_lock_held)
+ afr_sh_data_unlock (frame, this);
else
afr_sh_data_close (frame, this);
return 0;
}
+
int
-afr_sh_data_fail (call_frame_t *frame, xlator_t *this)
+afr_sh_data_erase_pending_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, dict_t *xattr)
{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
+ int call_count = 0;
- local = frame->local;
- sh = &local->self_heal;
+ call_count = afr_frame_return (frame);
- gf_log (this->name, GF_LOG_DEBUG,
- "finishing failed data selfheal of %s", local->loc.path);
+ if (call_count == 0)
+ afr_sh_data_finish (frame, this);
- sh->op_failed = 1;
- if (sh->data_lock_held)
- afr_sh_data_unlock (frame, this, afr_sh_data_close);
- else
- afr_sh_data_close (frame, this);
return 0;
}
+
int
-afr_sh_data_erase_pending_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata)
+afr_sh_data_erase_pending (call_frame_t *frame, xlator_t *this)
{
- int call_count = 0;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- int32_t child_index = (long) cookie;
+ int call_count = 0;
+ int i = 0;
+ dict_t **erase_xattr = NULL;
- priv = this->private;
local = frame->local;
- sh = &local->self_heal;
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Erasing of pending change "
- "log failed on %s for subvol %s, reason: %s",
- local->loc.path, priv->children[child_index]->name,
- strerror (op_errno));
- sh->op_failed = 1;
- }
-
- call_count = afr_frame_return (frame);
-
- if (call_count == 0) {
- if (sh->op_failed) {
- if (sh->old_loop_frame)
- sh_loop_finish (sh->old_loop_frame, this);
- sh->old_loop_frame = NULL;
- afr_sh_data_fail (frame, this);
- goto out;
- }
- if (!IA_ISREG (sh->type)) {
- afr_sh_data_finish (frame, this);
- goto out;
- }
- GF_ASSERT (sh->old_loop_frame);
- afr_sh_data_lock (frame, this, 0, 0,
- afr_post_sh_big_lock_success,
- afr_post_sh_big_lock_failure);
- }
-out:
- return 0;
-}
+ sh = &local->self_heal;
+ priv = this->private;
-int
-afr_sh_data_erase_pending (call_frame_t *frame, xlator_t *this)
-{
- afr_sh_erase_pending (frame, this, AFR_DATA_TRANSACTION,
- afr_sh_data_erase_pending_cbk,
- afr_sh_data_finish);
- return 0;
-}
+ afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, sh->success,
+ priv->child_count, AFR_DATA_TRANSACTION);
+ erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count,
+ gf_afr_mt_dict_t);
-static struct afr_sh_algorithm *
-sh_algo_from_name (xlator_t *this, char *name)
-{
- int i = 0;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i]) {
+ call_count++;
- while (afr_self_heal_algorithms[i].name) {
- if (!strcmp (name, afr_self_heal_algorithms[i].name)) {
- return &afr_self_heal_algorithms[i];
+ erase_xattr[i] = get_new_dict();
+ dict_ref (erase_xattr[i]);
}
-
- i++;
}
- return NULL;
-}
+ afr_sh_delta_to_xattr (priv, sh->delta_matrix, erase_xattr,
+ priv->child_count, AFR_DATA_TRANSACTION);
+ local->call_count = call_count;
+ for (i = 0; i < priv->child_count; i++) {
+ if (!erase_xattr[i])
+ continue;
-static int
-sh_zero_byte_files_exist (afr_local_t *local, int child_count)
-{
- int i = 0;
- int ret = 0;
- afr_self_heal_t *sh = NULL;
+ gf_log (this->name, GF_LOG_TRACE,
+ "erasing pending flags from %s on %s",
+ local->loc.path, priv->children[i]->name);
- sh = &local->self_heal;
- for (i = 0; i < child_count; i++) {
- if (!local->child_up[i] || sh->child_errno[i])
- continue;
- if (sh->buf[i].ia_size == 0) {
- ret = 1;
+ STACK_WIND_COOKIE (frame, afr_sh_data_erase_pending_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fxattrop,
+ sh->healing_fd,
+ GF_XATTROP_ADD_ARRAY, erase_xattr[i]);
+ if (!--call_count)
break;
- }
}
- return ret;
-}
-
-
-struct afr_sh_algorithm *
-afr_sh_data_pick_algo (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t * priv = NULL;
- struct afr_sh_algorithm * algo = NULL;
- afr_local_t * local = NULL;
- afr_self_heal_t * sh = NULL;
-
- priv = this->private;
- local = frame->local;
- sh = &local->self_heal;
- algo = sh_algo_from_name (this, priv->data_self_heal_algorithm);
-
- if (algo == NULL) {
- /* option not set, so fall back on heuristics */
-
- if (sh_zero_byte_files_exist (local, priv->child_count)
- || (sh->file_size <= (priv->data_self_heal_window_size *
- this->ctx->page_size))) {
-
- /*
- * If the file does not exist on one of the subvolumes,
- * or a zero-byte file exists (created by entry self-heal)
- * the entire content has to be copied anyway, so there
- * is no benefit from using the "diff" algorithm.
- *
- * If the file size is about the same as page size,
- * the entire file can be read and written with a few
- * (pipelined) STACK_WINDs, which will be faster
- * than "diff" which has to read checksums and then
- * read and write.
- */
-
- algo = sh_algo_from_name (this, "full");
-
- } else {
- algo = sh_algo_from_name (this, "diff");
+ for (i = 0; i < priv->child_count; i++) {
+ if (erase_xattr[i]) {
+ dict_unref (erase_xattr[i]);
}
}
-
- return algo;
-}
-
-
-int
-afr_sh_data_sync_prepare (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- struct afr_sh_algorithm *sh_algo = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
-
- sh->algo_completion_cbk = afr_sh_data_erase_pending;
- sh->algo_abort_cbk = afr_sh_data_fail;
-
- sh_algo = afr_sh_data_pick_algo (frame, this);
-
- sh->algo = sh_algo;
- sh_algo->fn (frame, this);
+ GF_FREE (erase_xattr);
return 0;
}
+
int
afr_sh_data_trim_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
int call_count = 0;
int child_index = 0;
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- priv = this->private;
+ priv = this->private;
local = frame->local;
- sh = &local->self_heal;
child_index = (long) cookie;
LOCK (&frame->lock);
{
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
"ftruncate of %s on subvolume %s failed (%s)",
local->loc.path,
priv->children[child_index]->name,
strerror (op_errno));
- sh->op_failed = 1;
- } else {
- gf_log (this->name, GF_LOG_DEBUG,
+ else
+ gf_log (this->name, GF_LOG_TRACE,
"ftruncate of %s on subvolume %s completed",
local->loc.path,
priv->children[child_index]->name);
- }
}
UNLOCK (&frame->lock);
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (sh->op_failed)
- afr_sh_data_fail (frame, this);
- else
- afr_sh_data_sync_prepare (frame, this);
+ afr_sh_data_erase_pending (frame, this);
}
return 0;
@@ -586,8 +445,7 @@ afr_sh_data_trim_sinks (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->ftruncate,
- sh->healing_fd, sh->file_size,
- NULL);
+ sh->healing_fd, sh->file_size);
if (!--call_count)
break;
@@ -596,98 +454,170 @@ afr_sh_data_trim_sinks (call_frame_t *frame, xlator_t *this)
return 0;
}
-int
-afr_sh_inode_set_read_ctx (afr_self_heal_t *sh, xlator_t *this)
+
+static struct afr_sh_algorithm *
+sh_algo_from_name (xlator_t *this, char *name)
{
- afr_private_t *priv = NULL;
- int ret = 0;
- int i = 0;
+ int i = 0;
- priv = this->private;
- sh->source = afr_sh_select_source (sh->sources, priv->child_count);
- if (sh->source < 0) {
- ret = -1;
- goto out;
+ while (afr_self_heal_algorithms[i].name) {
+ if (!strcmp (name, afr_self_heal_algorithms[i].name)) {
+ return &afr_self_heal_algorithms[i];
+ }
+
+ i++;
}
- /* detect changes not visible through pending flags -- JIC */
- for (i = 0; i < priv->child_count; i++) {
- if (i == sh->source || sh->child_errno[i])
- continue;
+ return NULL;
+}
- if (SIZE_DIFFERS (&sh->buf[i], &sh->buf[sh->source]))
- sh->sources[i] = 0;
+
+static int
+sh_zero_byte_files_exist (afr_self_heal_t *sh, int child_count)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < child_count; i++) {
+ if (sh->buf[i].ia_size == 0) {
+ ret = 1;
+ break;
+ }
}
- afr_reset_children (sh->fresh_children, priv->child_count);
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, priv->child_count);
- afr_inode_set_read_ctx (this, sh->inode, sh->source,
- sh->fresh_children);
-out:
return ret;
}
-void
-afr_sh_data_fix (call_frame_t *frame, xlator_t *this)
+
+struct afr_sh_algorithm *
+afr_sh_data_pick_algo (call_frame_t *frame, xlator_t *this)
{
- int source = 0;
- afr_local_t *local = NULL;
+ afr_private_t * priv = NULL;
+ struct afr_sh_algorithm * algo = NULL;
+ afr_local_t * local = NULL;
+ afr_self_heal_t * sh = NULL;
+
+ priv = this->private;
+ local = frame->local;
+ sh = &local->self_heal;
+ algo = sh_algo_from_name (this, priv->data_self_heal_algorithm);
+
+ if (algo == NULL) {
+ /* option not set, so fall back on heuristics */
+
+ if ((local->enoent_count != 0)
+ || sh_zero_byte_files_exist (sh, priv->child_count)
+ || (sh->file_size <= (priv->data_self_heal_window_size *
+ this->ctx->page_size))) {
+
+ /*
+ * If the file does not exist on one of the subvolumes,
+ * or a zero-byte file exists (created by entry self-heal)
+ * the entire content has to be copied anyway, so there
+ * is no benefit from using the "diff" algorithm.
+ *
+ * If the file size is about the same as page size,
+ * the entire file can be read and written with a few
+ * (pipelined) STACK_WINDs, which will be faster
+ * than "diff" which has to read checksums and then
+ * read and write.
+ */
+
+ algo = sh_algo_from_name (this, "full");
+
+ } else {
+ algo = sh_algo_from_name (this, "diff");
+ }
+ }
+
+ return algo;
+}
+
+
+int
+afr_sh_data_sync_prepare (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
+ int active_sinks = 0;
+ int source = 0;
+ int i = 0;
+ struct afr_sh_algorithm *sh_algo = NULL;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- source = sh->source;
- sh->block_size = this->ctx->page_size;
- sh->file_size = sh->buf[source].ia_size;
-
- if (FILE_HAS_HOLES (&sh->buf[source]))
- sh->file_has_holes = 1;
+ source = sh->source;
- if (sh->background && sh->unwind && !sh->unwound) {
- sh->unwind (sh->orig_frame, this, sh->op_ret, sh->op_errno,
- sh->op_failed);
- sh->unwound = _gf_true;
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->sources[i] == 0 && local->child_up[i] == 1) {
+ active_sinks++;
+ sh->success[i] = 1;
+ }
}
+ sh->success[source] = 1;
- afr_sh_mark_source_sinks (frame, this);
- if (sh->active_sinks == 0) {
+ if (active_sinks == 0) {
gf_log (this->name, GF_LOG_INFO,
"no active sinks for performing self-heal on file %s",
local->loc.path);
afr_sh_data_finish (frame, this);
- return;
+ return 0;
}
+ sh->active_sinks = active_sinks;
gf_log (this->name, GF_LOG_DEBUG,
"self-healing file %s from subvolume %s to %d other",
- local->loc.path, priv->children[sh->source]->name,
- sh->active_sinks);
- afr_sh_data_trim_sinks (frame, this);
+ local->loc.path, priv->children[source]->name, active_sinks);
+
+ sh->algo_completion_cbk = afr_sh_data_trim_sinks;
+ sh->algo_abort_cbk = afr_sh_data_finish;
+
+ sh_algo = afr_sh_data_pick_algo (frame, this);
+
+ sh_algo->fn (frame, this);
+
+ return 0;
}
+
int
-afr_sh_data_fxattrop_fstat_done (call_frame_t *frame, xlator_t *this)
+afr_sh_data_fix (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
+ afr_local_t * orig_local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
int nsources = 0;
- int ret = 0;
+ int source = 0;
+ int i = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- gf_log (this->name, GF_LOG_DEBUG, "Pending matrix for: %s",
- lkowner_utoa (&frame->root->lk_owner));
+ afr_sh_build_pending_matrix (priv, sh->pending_matrix, sh->xattr,
+ priv->child_count, AFR_DATA_TRANSACTION);
+
+ afr_sh_print_pending_matrix (sh->pending_matrix, this);
+
+ nsources = afr_sh_mark_sources (sh, priv->child_count,
+ AFR_SELF_HEAL_DATA);
+
+ afr_sh_supress_errenous_children (sh->sources, sh->child_errno,
+ priv->child_count);
+
+ if (nsources == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "No self-heal needed for %s",
+ local->loc.path);
+
+ afr_sh_data_finish (frame, this);
+ return 0;
+ }
- nsources = afr_build_sources (this, sh->xattr, sh->buf, sh->pending_matrix,
- sh->sources, sh->success_children,
- AFR_DATA_TRANSACTION, NULL, _gf_true);
if ((nsources == -1)
&& (priv->favorite_child != -1)
&& (sh->child_errno[priv->favorite_child] == 0)) {
@@ -710,111 +640,100 @@ afr_sh_data_fxattrop_fstat_done (call_frame_t *frame, xlator_t *this)
"split-brain). Please delete the file from all but "
"the preferred subvolume.", local->loc.path);
- sh->data_spb = _gf_true;
- afr_sh_data_fail (frame, this);
+ local->govinda_gOvinda = 1;
+
+ afr_sh_data_finish (frame, this);
return 0;
}
- sh->data_spb = _gf_false;
- ret = afr_sh_inode_set_read_ctx (sh, this);
- if (ret) {
+ source = afr_sh_select_source (sh->sources, priv->child_count);
+
+ if (source == -1) {
gf_log (this->name, GF_LOG_DEBUG,
"No active sources found.");
- afr_sh_data_fail (frame, this);
+ afr_sh_data_finish (frame, this);
return 0;
}
- if (sh->sync_done) {
- afr_sh_data_setattr (frame, this);
- } else {
- if (nsources == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "No self-heal needed for %s",
- local->loc.path);
+ sh->source = source;
+ sh->block_size = 65536; /* TODO: make it configurable or use macro */
+ sh->file_size = sh->buf[source].ia_size;
- afr_sh_data_finish (frame, this);
- return 0;
- }
+ if (FILE_HAS_HOLES (&sh->buf[source]))
+ sh->file_has_holes = 1;
- if (sh->do_data_self_heal &&
- afr_data_self_heal_enabled (priv->data_self_heal))
- afr_sh_data_fix (frame, this);
- else
- afr_sh_data_finish (frame, this);
+ orig_local = sh->orig_frame->local;
+ orig_local->cont.lookup.buf.ia_size = sh->buf[source].ia_size;
+
+ /* detect changes not visible through pending flags -- JIC */
+ for (i = 0; i < priv->child_count; i++) {
+ if (i == source || sh->child_errno[i])
+ continue;
+
+ if (SIZE_DIFFERS (&sh->buf[i], &sh->buf[source]))
+ sh->sources[i] = 0;
+ }
+
+ afr_set_read_child (this, local->loc.inode, sh->source);
+
+ /*
+ quick-read might have read the file, so send xattr from
+ the source subvolume (http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=815)
+ */
+
+ dict_unref (orig_local->cont.lookup.xattr);
+ if (orig_local->cont.lookup.xattrs)
+ orig_local->cont.lookup.xattr = dict_ref (orig_local->cont.lookup.xattrs[sh->source]);
+
+ if (sh->background) {
+ sh->unwind (sh->orig_frame, this);
+ sh->unwound = _gf_true;
}
+
+ afr_sh_data_sync_prepare (frame, this);
+
return 0;
}
+
int
-afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,
- dict_t **xattr,
- afr_transaction_type txn_type,
- uuid_t gfid)
+afr_self_heal_get_source (xlator_t *this, afr_local_t *local, dict_t **xattr)
{
- afr_private_t *priv = NULL;
- int read_child = -1;
- int32_t **pending_matrix = NULL;
- int32_t *sources = NULL;
- int32_t *success_children = NULL;
- struct iatt *bufs = NULL;
- int32_t nsources = 0;
- int32_t prev_read_child = -1;
- int32_t config_read_child = -1;
- int32_t subvol_status = 0;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int source = 0;
+ int i = 0;
+ sh = &local->self_heal;
priv = this->private;
- bufs = local->cont.lookup.bufs;
- success_children = local->cont.lookup.success_children;
-
- pending_matrix = local->cont.lookup.pending_matrix;
- sources = local->cont.lookup.sources;
- memset (sources, 0, sizeof (*sources) * priv->child_count);
-
- nsources = afr_build_sources (this, xattr, bufs, pending_matrix,
- sources, success_children, txn_type,
- &subvol_status, _gf_false);
- if (subvol_status & SPLIT_BRAIN) {
- gf_log (this->name, GF_LOG_WARNING, "%s: Possible split-brain",
- local->loc.path);
- switch (txn_type) {
- case AFR_DATA_TRANSACTION:
- local->cont.lookup.possible_spb = _gf_true;
- nsources = 1;
- sources[success_children[0]] = 1;
- break;
- case AFR_ENTRY_TRANSACTION:
- read_child = afr_get_no_xattr_dir_read_child (this,
- success_children,
- bufs);
- sources[read_child] = 1;
- nsources = 1;
- break;
- default:
- break;
- }
+
+ sh->pending_matrix = GF_CALLOC (sizeof (int32_t *), priv->child_count,
+ gf_afr_mt_int32_t);
+ for (i = 0; i < priv->child_count; i++) {
+ sh->pending_matrix[i] = GF_CALLOC (sizeof (int32_t),
+ priv->child_count,
+ gf_afr_mt_int32_t);
}
- if (nsources < 0)
- goto out;
-
- prev_read_child = local->read_child_index;
- config_read_child = priv->read_child;
- read_child = afr_select_read_child_from_policy (success_children,
- priv->child_count,
- prev_read_child,
- config_read_child,
- sources,
- priv->hash_mode, gfid);
-out:
- gf_log (this->name, GF_LOG_DEBUG, "returning read_child: %d",
- read_child);
- return read_child;
+
+ sh->sources = GF_CALLOC (priv->child_count, sizeof (*sh->sources),
+ gf_afr_mt_int32_t);
+
+ afr_sh_build_pending_matrix (priv, sh->pending_matrix, xattr,
+ priv->child_count, AFR_DATA_TRANSACTION);
+
+ (void)afr_sh_mark_sources (sh, priv->child_count, AFR_SELF_HEAL_DATA);
+
+ source = afr_sh_select_source (sh->sources, priv->child_count);
+
+ return source;
}
+
int
afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
@@ -835,14 +754,6 @@ afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,
priv->children[child_index]->name);
sh->buf[child_index] = *buf;
- sh->success_children[sh->success_count] = child_index;
- sh->success_count++;
- } else {
- gf_log (this->name, GF_LOG_ERROR, "%s: fstat failed "
- "on %s, reason %s", local->loc.path,
- priv->children[child_index]->name,
- strerror (op_errno));
- sh->child_errno[child_index] = op_errno;
}
}
UNLOCK (&frame->lock);
@@ -850,20 +761,9 @@ afr_sh_data_fstat_cbk (call_frame_t *frame, void *cookie,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- /* Previous versions of glusterfs might have set
- * the pending data xattrs which need to be erased
- */
- if (!afr_sh_data_proceed (sh->success_count)) {
- gf_log (this->name, GF_LOG_ERROR, "inspecting metadata "
- "succeeded on < %d children, aborting "
- "self-heal for %s", AFR_SH_MIN_PARTICIPANTS,
- local->loc.path);
- afr_sh_data_fail (frame, this);
- goto out;
- }
- afr_sh_data_fxattrop_fstat_done (frame, this);
+ afr_sh_data_fix (frame, this);
}
-out:
+
return 0;
}
@@ -874,52 +774,44 @@ afr_sh_data_fstat (call_frame_t *frame, xlator_t *this)
afr_self_heal_t *sh = NULL;
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
- int call_count = 0;
- int i = 0;
- int child = 0;
- int32_t *fstat_children = NULL;
+ int call_count = 0;
+ int i = 0;
priv = this->private;
local = frame->local;
sh = &local->self_heal;
- fstat_children = memdup (sh->success_children,
- sizeof (*fstat_children) * priv->child_count);
- if (!fstat_children) {
- afr_sh_data_fail (frame, this);
- goto out;
- }
- call_count = sh->success_count;
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+
local->call_count = call_count;
- memset (sh->buf, 0, sizeof (*sh->buf) * priv->child_count);
- afr_reset_children (sh->success_children, priv->child_count);
- sh->success_count = 0;
for (i = 0; i < priv->child_count; i++) {
- child = fstat_children[i];
- if (child == -1)
- break;
- STACK_WIND_COOKIE (frame, afr_sh_data_fstat_cbk,
- (void *) (long) child,
- priv->children[child],
- priv->children[child]->fops->fstat,
- sh->healing_fd, NULL);
- --call_count;
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_sh_data_fstat_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->fstat,
+ sh->healing_fd);
+
+ if (!--call_count)
+ break;
+ }
}
- GF_ASSERT (!call_count);
-out:
- GF_FREE (fstat_children);
+
return 0;
}
-void
-afr_sh_common_fxattrop_resp_handler (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xattr)
+
+int
+afr_sh_data_fxattrop_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *xattr)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ int call_count = -1;
int child_index = (long) cookie;
local = frame->local;
@@ -935,46 +827,16 @@ afr_sh_common_fxattrop_resp_handler (call_frame_t *frame, void *cookie,
priv->children[child_index]->name);
sh->xattr[child_index] = dict_ref (xattr);
- sh->success_children[sh->success_count] = child_index;
- sh->success_count++;
- } else {
- gf_log (this->name, GF_LOG_ERROR, "fxattrop of %s "
- "failed on %s, reason %s", local->loc.path,
- priv->children[child_index]->name,
- strerror (op_errno));
- sh->child_errno[child_index] = op_errno;
}
}
UNLOCK (&frame->lock);
-}
-
-int
-afr_sh_data_fxattrop_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata)
-{
- int call_count = -1;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
-
- afr_sh_common_fxattrop_resp_handler (frame, cookie, this, op_ret,
- op_errno, xattr);
call_count = afr_frame_return (frame);
+
if (call_count == 0) {
- if (!afr_sh_data_proceed (sh->success_count)) {
- gf_log (this->name, GF_LOG_ERROR, "%s, inspecting "
- "change log succeeded on < %d children",
- local->loc.path, AFR_SH_MIN_PARTICIPANTS);
- afr_sh_data_fail (frame, this);
- goto out;
- }
afr_sh_data_fstat (frame, this);
}
-out:
+
return 0;
}
@@ -986,7 +848,7 @@ afr_sh_data_fxattrop (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
dict_t *xattr_req = NULL;
- int32_t *zero_pending = NULL;
+ int32_t zero_pending[3] = {0,};
int call_count = 0;
int i = 0;
int ret = 0;
@@ -995,41 +857,22 @@ afr_sh_data_fxattrop (call_frame_t *frame, xlator_t *this)
local = frame->local;
sh = &local->self_heal;
- call_count = afr_up_children_count (local->child_up,
- priv->child_count);
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
local->call_count = call_count;
xattr_req = dict_new();
- if (!xattr_req) {
- ret = -1;
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- zero_pending = GF_CALLOC (3, sizeof (*zero_pending),
- gf_afr_mt_int32_t);
- if (!zero_pending) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynptr (xattr_req, priv->pending_key[i],
- zero_pending,
- 3 * sizeof (*zero_pending));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "Unable to set dict value");
- goto out;
- } else {
- zero_pending = NULL;
+ if (xattr_req) {
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_static_bin (xattr_req, priv->pending_key[i],
+ zero_pending, 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unable to set dict value");
}
}
- afr_reset_xattr (sh->xattr, priv->child_count);
- afr_reset_children (sh->success_children, priv->child_count);
- memset (sh->child_errno, 0,
- sizeof (*sh->child_errno) * priv->child_count);
- sh->success_count = 0;
for (i = 0; i < priv->child_count; i++) {
if (local->child_up[i]) {
STACK_WIND_COOKIE (frame, afr_sh_data_fxattrop_cbk,
@@ -1037,176 +880,101 @@ afr_sh_data_fxattrop (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
sh->healing_fd, GF_XATTROP_ADD_ARRAY,
- xattr_req, NULL);
+ xattr_req);
if (!--call_count)
break;
}
}
-out:
if (xattr_req)
dict_unref (xattr_req);
- if (ret) {
- GF_FREE (zero_pending);
- afr_sh_data_fail (frame, this);
- }
-
return 0;
}
-int
-afr_sh_data_big_lock_success (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
-
- sh->data_lock_held = _gf_true;
- afr_sh_data_fxattrop (frame, this);
- return 0;
-}
int
-afr_sh_data_post_blocking_inodelk_cbk (call_frame_t *frame, xlator_t *this)
-{
- afr_internal_lock_t *int_lock = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- int_lock = &local->internal_lock;
- sh = &local->self_heal;
-
- if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Blocking data inodelks "
- "failed for %s. by %s",
- local->loc.path, lkowner_utoa (&frame->root->lk_owner));
-
- sh->data_lock_failure_handler (frame, this);
- } else {
-
- gf_log (this->name, GF_LOG_DEBUG, "Blocking data inodelks "
- "done for %s by %s. Proceding to self-heal",
- local->loc.path, lkowner_utoa (&frame->root->lk_owner));
-
- sh->data_lock_success_handler (frame, this);
- }
-
- return 0;
-}
+afr_sh_data_lock_rec (call_frame_t *frame, xlator_t *this);
int
afr_sh_data_post_nonblocking_inodelk_cbk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
local = frame->local;
int_lock = &local->internal_lock;
- sh = &local->self_heal;
if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "Non Blocking data inodelks "
- "failed for %s. by %s",
- local->loc.path, lkowner_utoa (&frame->root->lk_owner));
-
- int_lock->lock_cbk = afr_sh_data_post_blocking_inodelk_cbk;
- afr_blocking_lock (frame, this);
+ gf_log (this->name, GF_LOG_INFO,
+ "Non Blocking inodelks failed.");
+ afr_sh_data_done (frame, this);
} else {
- gf_log (this->name, GF_LOG_DEBUG, "Non Blocking data inodelks "
- "done for %s by %s. Proceeding to self-heal",
- local->loc.path, lkowner_utoa (&frame->root->lk_owner));
- sh->data_lock_success_handler (frame, this);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Non Blocking inodelks done. Proceeding to FOP");
+ afr_sh_data_fxattrop (frame, this);
}
return 0;
}
int
-afr_sh_data_lock_rec (call_frame_t *frame, xlator_t *this, off_t start, off_t len)
+afr_sh_data_lock_rec (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
local = frame->local;
int_lock = &local->internal_lock;
+ sh = &local->self_heal;
int_lock->transaction_lk_type = AFR_SELFHEAL_LK;
int_lock->selfheal_lk_type = AFR_DATA_SELF_HEAL_LK;
afr_set_lock_number (frame, this);
- int_lock->lk_flock.l_start = start;
- int_lock->lk_flock.l_len = len;
+ int_lock->lk_flock.l_start = 0;
+ int_lock->lk_flock.l_len = 0;
int_lock->lk_flock.l_type = F_WRLCK;
int_lock->lock_cbk = afr_sh_data_post_nonblocking_inodelk_cbk;
afr_nonblocking_inodelk (frame, this);
- return 0;
-}
-
-int
-afr_post_sh_big_lock_success (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
-
- GF_ASSERT (sh->old_loop_frame);
- sh_loop_finish (sh->old_loop_frame, this);
- sh->old_loop_frame = NULL;
- sh->data_lock_held = _gf_true;
- sh->sync_done = _gf_true;
- afr_sh_data_fxattrop (frame, this);
- return 0;
-}
-
-int
-afr_post_sh_big_lock_failure (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
- GF_ASSERT (sh->old_loop_frame);
- sh_loop_finish (sh->old_loop_frame, this);
- sh->old_loop_frame = NULL;
- afr_sh_set_timestamps (frame, this);
return 0;
}
int
-afr_sh_data_lock (call_frame_t *frame, xlator_t *this,
- off_t start, off_t len,
- afr_lock_cbk_t success_handler,
- afr_lock_cbk_t failure_handler)
+afr_sh_data_lock (call_frame_t *frame, xlator_t *this)
{
afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
afr_self_heal_t * sh = NULL;
+
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
+
+ if (sh->data_lock_held) {
+ /* caller has held the lock already,
+ so skip locking */
- sh->data_lock_success_handler = success_handler;
- sh->data_lock_failure_handler = failure_handler;
- return afr_sh_data_lock_rec (frame, this, start, len);
+ afr_sh_data_fxattrop (frame, this);
+ return 0;
+ }
+
+ return afr_sh_data_lock_rec (frame, this);
}
+
int
afr_sh_data_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -1227,18 +995,18 @@ afr_sh_data_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
LOCK (&frame->lock);
{
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"open of %s failed on child %s (%s)",
local->loc.path,
priv->children[child_index]->name,
strerror (op_errno));
sh->op_failed = 1;
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "open of %s succeeded on child %s",
- local->loc.path,
- priv->children[child_index]->name);
}
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "open of %s succeeded on child %s",
+ local->loc.path,
+ priv->children[child_index]->name);
}
UNLOCK (&frame->lock);
@@ -1246,7 +1014,7 @@ afr_sh_data_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (call_count == 0) {
if (sh->op_failed) {
- afr_sh_data_fail (frame, this);
+ afr_sh_data_finish (frame, this);
return 0;
}
@@ -1254,9 +1022,7 @@ afr_sh_data_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"fd for %s opened, commencing sync",
local->loc.path);
- afr_sh_data_lock (frame, this, 0, 0,
- afr_sh_data_big_lock_success,
- afr_sh_data_fail);
+ afr_sh_data_lock (frame, this);
}
return 0;
@@ -1277,7 +1043,14 @@ afr_sh_data_open (call_frame_t *frame, xlator_t *this)
sh = &local->self_heal;
priv = this->private;
- call_count = afr_up_children_count (local->child_up, priv->child_count);
+ if (sh->healing_fd_opened) {
+ /* caller has opened the fd for us already, so skip open */
+
+ afr_sh_data_lock (frame, this);
+ return 0;
+ }
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
local->call_count = call_count;
fd = fd_create (local->loc.inode, frame->root->pid);
@@ -1293,7 +1066,7 @@ afr_sh_data_open (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->open,
&local->loc,
- O_RDWR|O_LARGEFILE, fd, NULL);
+ O_RDWR|O_LARGEFILE, fd, 0);
if (!--call_count)
break;
@@ -1302,61 +1075,6 @@ afr_sh_data_open (call_frame_t *frame, xlator_t *this)
return 0;
}
-void
-afr_sh_non_reg_fix (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- afr_private_t *priv = NULL;
- afr_self_heal_t *sh = NULL;
- afr_local_t *local = NULL;
- int i = 0;
-
- if (op_ret < 0) {
- afr_sh_data_fail (frame, this);
- return;
- }
-
- local = frame->local;
- sh = &local->self_heal;
- priv = this->private;
-
- for (i = 0; i < priv->child_count ; i++) {
- if (1 == local->child_up[i])
- sh->success[i] = 1;
- }
-
- afr_sh_erase_pending (frame, this, AFR_DATA_TRANSACTION,
- afr_sh_data_erase_pending_cbk,
- afr_sh_data_finish);
-}
-
-int
-afr_sh_non_reg_lock_success (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
-
- local = frame->local;
- sh = &local->self_heal;
- sh->data_lock_held = _gf_true;
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_non_reg_fix, NULL,
- AFR_LOOKUP_FAIL_CONFLICTS |
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
- return 0;
-}
-
-gf_boolean_t
-afr_can_start_data_self_heal (afr_self_heal_t *sh, afr_private_t *priv)
-{
- if (sh->force_confirm_spb)
- return _gf_true;
- if (sh->do_data_self_heal &&
- afr_data_self_heal_enabled (priv->data_self_heal))
- return _gf_true;
- return _gf_false;
-}
int
afr_self_heal_data (call_frame_t *frame, xlator_t *this)
@@ -1368,21 +1086,8 @@ afr_self_heal_data (call_frame_t *frame, xlator_t *this)
local = frame->local;
sh = &local->self_heal;
- /* Self-heal completion cbk changes inode split-brain status based on
- * govinda_gOvinda, mdata_spb, data_spb value.
- * Initialize data_spb with current split-brain status.
- * If for some reason self-heal fails(locking phase etc), it makes sure
- * we retain the split-brain status before this self-heal started.
- */
- sh->data_spb = afr_is_split_brain (this, sh->inode);
- if (afr_can_start_data_self_heal (sh, priv)) {
- if (IA_ISREG (sh->type)) {
- afr_sh_data_open (frame, this);
- } else {
- afr_sh_data_lock (frame, this, 0, 0,
- afr_sh_non_reg_lock_success,
- afr_sh_data_fail);
- }
+ if (sh->need_data_self_heal && priv->data_self_heal) {
+ afr_sh_data_open (frame, this);
} else {
gf_log (this->name, GF_LOG_TRACE,
"not doing data self heal on %s",
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c
index 14ce3aa9f..88bf2448d 100644
--- a/xlators/cluster/afr/src/afr-self-heal-entry.c
+++ b/xlators/cluster/afr/src/afr-self-heal-entry.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -40,26 +49,34 @@
#include "afr-self-heal.h"
#include "afr-self-heal-common.h"
-#define AFR_INIT_SH_FRAME_VALS(_frame, _local, _sh, _sh_frame, _sh_local, _sh_sh)\
- do {\
- _local = _frame->local;\
- _sh = &_local->self_heal;\
- _sh_frame = _sh->sh_frame;\
- _sh_local = _sh_frame->local;\
- _sh_sh = &_sh_local->self_heal;\
- } while (0);
-
int
-afr_sh_entry_impunge_create_file (call_frame_t *impunge_frame, xlator_t *this,
- int child_index);
+afr_sh_post_nonblocking_entrylk_cbk (call_frame_t *frame, xlator_t *this);
+
int
afr_sh_entry_done (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
+
+ /*
+ TODO: cleanup sh->*
+ */
+
+ if (sh->healing_fd)
+ fd_unref (sh->healing_fd);
+ sh->healing_fd = NULL;
+
+ /* for (i = 0; i < priv->child_count; i++) { */
+ /* sh->locked_nodes[i] = 0; */
+ /* } */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "self heal of %s completed", local->loc.path);
sh->completion_cbk (frame, this);
@@ -102,7 +119,7 @@ afr_sh_entry_finish (call_frame_t *frame, xlator_t *this)
int
afr_sh_entry_erase_pending_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata)
+ int32_t op_errno, dict_t *xattr)
{
long i = 0;
int call_count = 0;
@@ -111,16 +128,12 @@ afr_sh_entry_erase_pending_cbk (call_frame_t *frame, void *cookie,
afr_local_t *orig_local = NULL;
call_frame_t *orig_frame = NULL;
afr_private_t *priv = NULL;
- int32_t read_child = -1;
local = frame->local;
priv = this->private;
- sh = &local->self_heal;
- i = (long)cookie;
-
- afr_children_add_child (sh->fresh_children, i, priv->child_count);
if (op_ret == -1) {
+ i = (long)cookie;
gf_log (this->name, GF_LOG_INFO,
"%s: failed to erase pending xattrs on %s (%s)",
local->loc.path, priv->children[i]->name,
@@ -130,14 +143,8 @@ afr_sh_entry_erase_pending_cbk (call_frame_t *frame, void *cookie,
call_count = afr_frame_return (frame);
if (call_count == 0) {
- if (sh->source == -1) {
- //this happens if the forced merge option is set
- read_child = sh->fresh_children[0];
- } else {
- read_child = sh->source;
- }
- afr_inode_set_read_ctx (this, sh->inode, read_child,
- sh->fresh_children);
+ sh = &local->self_heal;
+
orig_frame = sh->orig_frame;
orig_local = orig_frame->local;
@@ -157,20 +164,66 @@ afr_sh_entry_erase_pending (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int i = 0;
+ dict_t **erase_xattr = NULL;
+ int need_unwind = 0;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
- if (sh->entries_skipped) {
- sh->op_failed = _gf_true;
- goto out;
+ afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix, sh->success,
+ priv->child_count, AFR_ENTRY_TRANSACTION);
+
+ erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count,
+ gf_afr_mt_dict_t);
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i]) {
+ call_count++;
+
+ erase_xattr[i] = get_new_dict();
+ dict_ref (erase_xattr[i]);
+ }
}
- afr_sh_erase_pending (frame, this, AFR_ENTRY_TRANSACTION,
- afr_sh_entry_erase_pending_cbk,
- afr_sh_entry_finish);
- return 0;
-out:
- afr_sh_entry_finish (frame, this);
+
+ if (call_count == 0)
+ need_unwind = 1;
+
+ afr_sh_delta_to_xattr (priv, sh->delta_matrix, erase_xattr,
+ priv->child_count, AFR_ENTRY_TRANSACTION);
+
+ local->call_count = call_count;
+ for (i = 0; i < priv->child_count; i++) {
+ if (!erase_xattr[i])
+ continue;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "erasing pending flags from %s on %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_entry_erase_pending_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &local->loc,
+ GF_XATTROP_ADD_ARRAY, erase_xattr[i]);
+ if (!--call_count)
+ break;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (erase_xattr[i]) {
+ dict_unref (erase_xattr[i]);
+ }
+ }
+ GF_FREE (erase_xattr);
+
+ if (need_unwind)
+ afr_sh_entry_finish (frame, this);
+
return 0;
}
@@ -251,11 +304,57 @@ next_active_sink (call_frame_t *frame, xlator_t *this,
return next_active_sink;
}
+
+int
+build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name)
+{
+ int ret = -1;
+
+ if (!child) {
+ goto out;
+ }
+
+ if (strcmp (parent->path, "/") == 0)
+ ret = gf_asprintf ((char **)&child->path, "/%s", name);
+ else
+ ret = gf_asprintf ((char **)&child->path, "%s/%s", parent->path,
+ name);
+
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting child path");
+ }
+
+ if (!child->path) {
+ goto out;
+ }
+
+ child->name = strrchr (child->path, '/');
+ if (child->name)
+ child->name++;
+
+ child->parent = inode_ref (parent->inode);
+ child->inode = inode_new (parent->inode->table);
+
+ if (!child->inode) {
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret == -1)
+ loc_wipe (child);
+
+ return ret;
+}
+
+
int
afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this);
int
-afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this);
+afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this,
+ int active_src);
int
afr_sh_entry_expunge_all (call_frame_t *frame, xlator_t *this);
@@ -266,8 +365,7 @@ afr_sh_entry_expunge_subvol (call_frame_t *frame, xlator_t *this,
int
afr_sh_entry_expunge_entry_done (call_frame_t *frame, xlator_t *this,
- int active_src, int32_t op_ret,
- int32_t op_errno)
+ int active_src)
{
int call_count = 0;
@@ -283,33 +381,28 @@ int
afr_sh_entry_expunge_parent_setattr_cbk (call_frame_t *expunge_frame,
void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop,
- dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
afr_private_t *priv = NULL;
afr_local_t *expunge_local = NULL;
afr_self_heal_t *expunge_sh = NULL;
call_frame_t *frame = NULL;
int active_src = (long) cookie;
- afr_self_heal_t *sh = NULL;
- afr_local_t *local = NULL;
priv = this->private;
expunge_local = expunge_frame->local;
expunge_sh = &expunge_local->self_heal;
frame = expunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
if (op_ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"setattr on parent directory of %s on subvolume %s failed: %s",
expunge_local->loc.path,
priv->children[active_src]->name, strerror (op_errno));
}
AFR_STACK_DESTROY (expunge_frame);
- sh->expunge_done (frame, this, active_src, op_ret, op_errno);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
return 0;
}
@@ -320,17 +413,19 @@ afr_sh_entry_expunge_remove_cbk (call_frame_t *expunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
afr_private_t *priv = NULL;
afr_local_t *expunge_local = NULL;
afr_self_heal_t *expunge_sh = NULL;
int active_src = 0;
+ call_frame_t *frame = NULL;
int32_t valid = 0;
priv = this->private;
expunge_local = expunge_frame->local;
expunge_sh = &expunge_local->self_heal;
+ frame = expunge_sh->sh_frame;
active_src = (long) cookie;
@@ -348,6 +443,7 @@ afr_sh_entry_expunge_remove_cbk (call_frame_t *expunge_frame, void *cookie,
}
valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+ afr_build_parent_loc (&expunge_sh->parent_loc, &expunge_local->loc);
STACK_WIND_COOKIE (expunge_frame, afr_sh_entry_expunge_parent_setattr_cbk,
(void *) (long) active_src,
@@ -355,7 +451,7 @@ afr_sh_entry_expunge_remove_cbk (call_frame_t *expunge_frame, void *cookie,
priv->children[active_src]->fops->setattr,
&expunge_sh->parent_loc,
&expunge_sh->parentbuf,
- valid, NULL);
+ valid);
return 0;
}
@@ -379,7 +475,7 @@ afr_sh_entry_expunge_unlink (call_frame_t *expunge_frame, xlator_t *this,
(void *) (long) active_src,
priv->children[active_src],
priv->children[active_src]->fops->unlink,
- &expunge_local->loc, 0, NULL);
+ &expunge_local->loc);
return 0;
}
@@ -404,7 +500,7 @@ afr_sh_entry_expunge_rmdir (call_frame_t *expunge_frame, xlator_t *this,
(void *) (long) active_src,
priv->children[active_src],
priv->children[active_src]->fops->rmdir,
- &expunge_local->loc, 1, NULL);
+ &expunge_local->loc, 1);
return 0;
}
@@ -412,29 +508,22 @@ afr_sh_entry_expunge_rmdir (call_frame_t *expunge_frame, xlator_t *this,
int
afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
- int active_src, struct iatt *buf,
- struct iatt *parentbuf)
+ int active_src, struct iatt *buf)
{
afr_private_t *priv = NULL;
afr_local_t *expunge_local = NULL;
afr_self_heal_t *expunge_sh = NULL;
+ int source = 0;
call_frame_t *frame = NULL;
int type = 0;
- afr_self_heal_t *sh = NULL;
- afr_local_t *local = NULL;
- loc_t *loc = NULL;
priv = this->private;
expunge_local = expunge_frame->local;
expunge_sh = &expunge_local->self_heal;
frame = expunge_sh->sh_frame;
- local = frame->local;
- sh = &local->self_heal;
- loc = &expunge_local->loc;
+ source = expunge_sh->source;
type = buf->ia_type;
- if (loc->parent && uuid_is_null (loc->parent->gfid))
- uuid_copy (loc->pargfid, parentbuf->ia_gfid);
switch (type) {
case IA_IFSOCK:
@@ -452,7 +541,7 @@ afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
gf_log (this->name, GF_LOG_ERROR,
"%s has unknown file type on %s: 0%o",
expunge_local->loc.path,
- priv->children[active_src]->name, type);
+ priv->children[source]->name, type);
goto out;
break;
}
@@ -460,7 +549,7 @@ afr_sh_entry_expunge_remove (call_frame_t *expunge_frame, xlator_t *this,
return 0;
out:
AFR_STACK_DESTROY (expunge_frame);
- sh->expunge_done (frame, this, active_src, -1, EINVAL);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
return 0;
}
@@ -478,19 +567,15 @@ afr_sh_entry_expunge_lookup_cbk (call_frame_t *expunge_frame, void *cookie,
afr_self_heal_t *expunge_sh = NULL;
call_frame_t *frame = NULL;
int active_src = 0;
- afr_self_heal_t *sh = NULL;
- afr_local_t *local = NULL;
priv = this->private;
expunge_local = expunge_frame->local;
expunge_sh = &expunge_local->self_heal;
frame = expunge_sh->sh_frame;
active_src = (long) cookie;
- local = frame->local;
- sh = &local->self_heal;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_DEBUG,
"lookup of %s on %s failed (%s)",
expunge_local->loc.path,
priv->children[active_src]->name,
@@ -498,13 +583,12 @@ afr_sh_entry_expunge_lookup_cbk (call_frame_t *expunge_frame, void *cookie,
goto out;
}
- afr_sh_entry_expunge_remove (expunge_frame, this, active_src, buf,
- postparent);
+ afr_sh_entry_expunge_remove (expunge_frame, this, active_src, buf);
return 0;
out:
AFR_STACK_DESTROY (expunge_frame);
- sh->expunge_done (frame, this, active_src, op_ret, op_errno);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
return 0;
}
@@ -528,7 +612,7 @@ afr_sh_entry_expunge_purge (call_frame_t *expunge_frame, xlator_t *this,
(void *) (long) active_src,
priv->children[active_src],
priv->children[active_src]->fops->lookup,
- &expunge_local->loc, NULL);
+ &expunge_local->loc, 0);
return 0;
}
@@ -547,8 +631,7 @@ afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie,
call_frame_t *frame = NULL;
int active_src = 0;
int need_expunge = 0;
- afr_self_heal_t *sh = NULL;
- afr_local_t *local = NULL;
+
priv = this->private;
expunge_local = expunge_frame->local;
@@ -556,8 +639,6 @@ afr_sh_entry_expunge_entry_cbk (call_frame_t *expunge_frame, void *cookie,
frame = expunge_sh->sh_frame;
active_src = expunge_sh->active_source;
source = (long) cookie;
- local = frame->local;
- sh = &local->self_heal;
if (op_ret == -1 && op_errno == ENOENT)
need_expunge = 1;
@@ -607,7 +688,7 @@ out:
}
AFR_STACK_DESTROY (expunge_frame);
- sh->expunge_done (frame, this, active_src, op_ret, op_errno);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
return 0;
}
@@ -628,7 +709,6 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
int source = 0;
int op_errno = 0;
char *name = NULL;
- int op_ret = -1;
priv = this->private;
local = frame->local;
@@ -636,43 +716,39 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
active_src = sh->active_source;
source = sh->source;
- sh->expunge_done = afr_sh_entry_expunge_entry_done;
name = entry->d_name;
if ((strcmp (name, ".") == 0)
- || (strcmp (name, "..") == 0)) {
+ || (strcmp (name, "..") == 0)
+ || ((strcmp (local->loc.path, "/") == 0)
+ && (strcmp (name, GF_REPLICATE_TRASH_DIR) == 0))) {
gf_log (this->name, GF_LOG_TRACE,
"skipping inspection of %s under %s",
name, local->loc.path);
- op_ret = 0;
goto out;
}
gf_log (this->name, GF_LOG_TRACE,
- "inspecting existence of %s under %s",
+ "inspecting existance of %s under %s",
name, local->loc.path);
expunge_frame = copy_frame (frame);
if (!expunge_frame) {
- op_errno = ENOMEM;
goto out;
}
- AFR_LOCAL_ALLOC_OR_GOTO (expunge_local, out);
+ ALLOC_OR_GOTO (expunge_local, afr_local_t, out);
expunge_frame->local = expunge_local;
expunge_sh = &expunge_local->self_heal;
expunge_sh->sh_frame = frame;
expunge_sh->active_source = active_src;
expunge_sh->entrybuf = entry->d_stat;
- loc_copy (&expunge_sh->parent_loc, &local->loc);
- ret = afr_build_child_loc (this, &expunge_local->loc, &local->loc,
- name);
+ ret = build_child_loc (this, &expunge_local->loc, &local->loc, name);
if (ret != 0) {
- op_errno = EINVAL;
goto out;
}
@@ -685,12 +761,12 @@ afr_sh_entry_expunge_entry (call_frame_t *frame, xlator_t *this,
(void *) (long) source,
priv->children[source],
priv->children[source]->fops->lookup,
- &expunge_local->loc, NULL);
+ &expunge_local->loc, 0);
ret = 0;
out:
if (ret == -1)
- sh->expunge_done (frame, this, active_src, op_ret, op_errno);
+ afr_sh_entry_expunge_entry_done (frame, this, active_src);
return 0;
}
@@ -700,7 +776,7 @@ int
afr_sh_entry_expunge_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
+ gf_dirent_t *entries)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
@@ -768,7 +844,7 @@ afr_sh_entry_expunge_subvol (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, afr_sh_entry_expunge_readdir_cbk,
priv->children[active_src],
priv->children[active_src]->fops->readdirp,
- sh->healing_fd, sh->block_size, sh->offset, NULL);
+ sh->healing_fd, sh->block_size, sh->offset);
return 0;
}
@@ -823,58 +899,46 @@ out:
int
afr_sh_entry_impunge_entry_done (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+ int active_src)
{
int call_count = 0;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- local = frame->local;
- sh = &local->self_heal;
- if (op_ret < 0)
- sh->entries_skipped = _gf_true;
call_count = afr_frame_return (frame);
+
if (call_count == 0)
- afr_sh_entry_impunge_subvol (frame, this);
+ afr_sh_entry_impunge_subvol (frame, this, active_src);
return 0;
}
-void
-afr_sh_entry_call_impunge_done (call_frame_t *impunge_frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
-{
- afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- call_frame_t *frame = NULL;
-
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
-
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, op_ret, op_errno);
-}
int
afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop,
- dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
int call_count = 0;
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ call_frame_t *frame = NULL;
+ int active_src = 0;
int child_index = 0;
priv = this->private;
impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
+ local = frame->local;
+ sh = &local->self_heal;
+ active_src = sh->active_source;
child_index = (long) cookie;
if (op_ret == 0) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_TRACE,
"setattr done for %s on %s",
impunge_local->loc.path,
priv->children[child_index]->name);
@@ -886,117 +950,38 @@ afr_sh_entry_impunge_setattr_cbk (call_frame_t *impunge_frame, void *cookie,
strerror (op_errno));
}
- call_count = afr_frame_return (impunge_frame);
- if (call_count == 0) {
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- 0, op_errno);
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
}
+ UNLOCK (&impunge_frame->lock);
- return 0;
-}
-
-int
-afr_sh_entry_impunge_parent_setattr_cbk (call_frame_t *setattr_frame,
- void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop,
- dict_t *xdata)
-{
- int call_count = 0;
- afr_local_t *setattr_local = NULL;
-
- setattr_local = setattr_frame->local;
- if (op_ret != 0) {
- gf_log (this->name, GF_LOG_INFO,
- "setattr on parent directory (%s) failed: %s",
- setattr_local->loc.path, strerror (op_errno));
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
}
- call_count = afr_frame_return (setattr_frame);
- if (call_count == 0)
- AFR_STACK_DESTROY (setattr_frame);
return 0;
}
-int
-afr_sh_entry_impunge_setattr (call_frame_t *impunge_frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- afr_local_t *impunge_local = NULL;
- afr_local_t *setattr_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- call_frame_t *setattr_frame = NULL;
- int32_t valid = 0;
- int32_t op_errno = 0;
- int child_index = 0;
- int call_count = 0;
- int i = 0;
-
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "setting ownership of %s on %s to %d/%d",
- impunge_local->loc.path,
- priv->children[child_index]->name,
- impunge_sh->entrybuf.ia_uid,
- impunge_sh->entrybuf.ia_gid);
-
- setattr_frame = copy_frame (impunge_frame);
- if (!setattr_frame) {
- op_errno = ENOMEM;
- goto out;
- }
- AFR_LOCAL_ALLOC_OR_GOTO (setattr_frame->local, out);
- setattr_local = setattr_frame->local;
- call_count = afr_errno_count (NULL, impunge_sh->child_errno,
- priv->child_count, 0);
- loc_copy (&setattr_local->loc, &impunge_sh->parent_loc);
- impunge_local->call_count = call_count;
- setattr_local->call_count = call_count;
- for (i = 0; i < priv->child_count; i++) {
- if (impunge_sh->child_errno[i])
- continue;
- valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
- STACK_WIND_COOKIE (setattr_frame,
- afr_sh_entry_impunge_parent_setattr_cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->setattr,
- &setattr_local->loc,
- &impunge_sh->parentbuf, valid, NULL);
-
- valid = GF_SET_ATTR_UID | GF_SET_ATTR_GID |
- GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
- STACK_WIND_COOKIE (impunge_frame,
- afr_sh_entry_impunge_setattr_cbk,
- (void *) (long) i, priv->children[i],
- priv->children[i]->fops->setattr,
- &impunge_local->loc,
- &impunge_sh->entrybuf, valid, NULL);
- call_count--;
- }
- GF_ASSERT (!call_count);
- return 0;
-out:
- if (setattr_frame)
- AFR_STACK_DESTROY (setattr_frame);
- afr_sh_entry_call_impunge_done (impunge_frame, this, 0, op_errno);
- return 0;
-}
int
afr_sh_entry_impunge_xattrop_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- dict_t *xattr, dict_t *xdata)
+ dict_t *xattr)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
int child_index = 0;
+ struct iatt stbuf;
+ int32_t valid = 0;
+
priv = this->private;
impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
child_index = (long) cookie;
@@ -1006,254 +991,163 @@ afr_sh_entry_impunge_xattrop_cbk (call_frame_t *impunge_frame, void *cookie,
impunge_local->loc.path,
priv->children[child_index]->name,
strerror (op_errno));
- goto out;
}
- afr_sh_entry_impunge_setattr (impunge_frame, this);
- return 0;
-out:
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- -1, op_errno);
- return 0;
-}
+ gf_log (this->name, GF_LOG_TRACE,
+ "setting ownership of %s on %s to %d/%d",
+ impunge_local->loc.path,
+ priv->children[child_index]->name,
+ impunge_local->cont.lookup.buf.ia_uid,
+ impunge_local->cont.lookup.buf.ia_gid);
-void
-afr_sh_prepare_new_entry_pending_matrix (int32_t **pending,
- int *child_errno,
- struct iatt *buf,
- unsigned int child_count)
-{
- int midx = 0;
- int idx = 0;
- int i = 0;
+ stbuf.ia_atime = impunge_local->cont.lookup.buf.ia_atime;
+ stbuf.ia_atime_nsec = impunge_local->cont.lookup.buf.ia_atime_nsec;
+ stbuf.ia_mtime = impunge_local->cont.lookup.buf.ia_mtime;
+ stbuf.ia_mtime_nsec = impunge_local->cont.lookup.buf.ia_mtime_nsec;
- midx = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION);
- if (IA_ISDIR (buf->ia_type))
- idx = afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION);
- else if (IA_ISREG (buf->ia_type))
- idx = afr_index_for_transaction_type (AFR_DATA_TRANSACTION);
- else
- idx = -1;
- for (i = 0; i < child_count; i++) {
- if (child_errno[i])
- continue;
- pending[i][midx] = hton32 (1);
- if (idx == -1)
- continue;
- pending[i][idx] = hton32 (1);
- }
+ stbuf.ia_uid = impunge_local->cont.lookup.buf.ia_uid;
+ stbuf.ia_gid = impunge_local->cont.lookup.buf.ia_gid;
+
+ valid = GF_SET_ATTR_UID | GF_SET_ATTR_GID |
+ GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_setattr_cbk,
+ (void *) (long) child_index,
+ priv->children[child_index],
+ priv->children[child_index]->fops->setattr,
+ &impunge_local->loc,
+ &stbuf, valid);
+ return 0;
}
+
int
-afr_sh_entry_impunge_perform_xattrop (call_frame_t *impunge_frame,
- xlator_t *this)
+afr_sh_entry_impunge_parent_setattr_cbk (call_frame_t *setattr_frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *preop, struct iatt *postop)
{
- int active_src = 0;
- dict_t *xattr = NULL;
- afr_private_t *priv = NULL;
- afr_local_t *impunge_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- int32_t op_errno = 0;
-
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
- active_src = impunge_sh->active_source;
+ loc_t *parent_loc = cookie;
- afr_sh_prepare_new_entry_pending_matrix (impunge_local->pending,
- impunge_sh->child_errno,
- &impunge_sh->entrybuf,
- priv->child_count);
- xattr = dict_new ();
- if (!xattr) {
- op_errno = ENOMEM;
- goto out;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "setattr on parent directory (%s) failed: %s",
+ parent_loc->path, strerror (op_errno));
}
- afr_set_pending_dict (priv, xattr, impunge_local->pending, active_src,
- LOCAL_LAST);
+ loc_wipe (parent_loc);
- STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_xattrop_cbk,
- (void *) (long) active_src,
- priv->children[active_src],
- priv->children[active_src]->fops->xattrop,
- &impunge_local->loc, GF_XATTROP_ADD_ARRAY, xattr, NULL);
+ GF_FREE (parent_loc);
- if (xattr)
- dict_unref (xattr);
- return 0;
-out:
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- -1, op_errno);
+ AFR_STACK_DESTROY (setattr_frame);
return 0;
}
+
int
afr_sh_entry_impunge_newfile_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf,
struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int call_count = 0;
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
+ call_frame_t *frame = NULL;
+ int active_src = 0;
int child_index = 0;
+ int pending_array[3] = {0, };
+ dict_t *xattr = NULL;
+ int ret = 0;
+ int idx = 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ call_frame_t *setattr_frame = NULL;
+ int32_t valid = 0;
+ loc_t *parent_loc = NULL;
+ struct iatt parentbuf = {0,};
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
+ local = frame->local;
+ sh = &local->self_heal;
+ active_src = sh->active_source;
child_index = (long) cookie;
if (op_ret == -1) {
- impunge_sh->child_errno[child_index] = op_errno;
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"creation of %s on %s failed (%s)",
impunge_local->loc.path,
priv->children[child_index]->name,
strerror (op_errno));
- } else {
- impunge_sh->child_errno[child_index] = 0;
+ goto out;
}
- call_count = afr_frame_return (impunge_frame);
- if (call_count == 0) {
- if (!afr_errno_count (NULL, impunge_sh->child_errno,
- priv->child_count, 0)) {
- // new_file creation failed every where
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- -1, op_errno);
- goto out;
- }
- afr_sh_entry_impunge_perform_xattrop (impunge_frame, this);
- }
-out:
- return 0;
-}
+ inode->ia_type = stbuf->ia_type;
-int
-afr_sh_entry_impunge_hardlink_cbk (call_frame_t *impunge_frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- int call_count = 0;
- afr_local_t *impunge_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
+ xattr = get_new_dict ();
+ dict_ref (xattr);
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
-
- if (IA_IFLNK == impunge_sh->entrybuf.ia_type) {
- //For symlinks impunge is attempted un-conditionally
- //So the file can already exist.
- if ((op_ret < 0) && (op_errno == EEXIST))
- op_ret = 0;
- }
-
- call_count = afr_frame_return (impunge_frame);
- if (call_count == 0)
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- op_ret, op_errno);
-
- return 0;
-}
+ idx = afr_index_for_transaction_type (AFR_METADATA_TRANSACTION);
+ pending_array[idx] = hton32 (1);
+ if (IA_ISDIR (stbuf->ia_type))
+ idx = afr_index_for_transaction_type (AFR_ENTRY_TRANSACTION);
+ else
+ idx = afr_index_for_transaction_type (AFR_DATA_TRANSACTION);
+ pending_array[idx] = hton32 (1);
-int
-afr_sh_entry_impunge_hardlink (call_frame_t *impunge_frame, xlator_t *this,
- int child_index)
-{
- afr_private_t *priv = NULL;
- afr_local_t *impunge_local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- loc_t *loc = NULL;
- struct iatt *buf = NULL;
- loc_t oldloc = {0};
+ ret = dict_set_static_bin (xattr, priv->pending_key[child_index],
+ pending_array, sizeof (pending_array));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unable to set dict value.");
- priv = this->private;
- impunge_local = impunge_frame->local;
- impunge_sh = &impunge_local->self_heal;
- loc = &impunge_local->loc;
- buf = &impunge_sh->entrybuf;
+ valid = GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME;
+ parentbuf = impunge_sh->parentbuf;
+ setattr_frame = copy_frame (impunge_frame);
- oldloc.inode = inode_ref (loc->inode);
- uuid_copy (oldloc.gfid, buf->ia_gfid);
- gf_log (this->name, GF_LOG_DEBUG, "linking missing file %s on %s",
- loc->path, priv->children[child_index]->name);
+ parent_loc = GF_CALLOC (1, sizeof (*parent_loc),
+ gf_afr_mt_loc_t);
+ afr_build_parent_loc (parent_loc, &impunge_local->loc);
- STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_hardlink_cbk,
+ STACK_WIND_COOKIE (impunge_frame, afr_sh_entry_impunge_xattrop_cbk,
(void *) (long) child_index,
+ priv->children[active_src],
+ priv->children[active_src]->fops->xattrop,
+ &impunge_local->loc, GF_XATTROP_ADD_ARRAY, xattr);
+
+ STACK_WIND_COOKIE (setattr_frame, afr_sh_entry_impunge_parent_setattr_cbk,
+ (void *) (long) parent_loc,
priv->children[child_index],
- priv->children[child_index]->fops->link,
- &oldloc, loc, NULL);
- loc_wipe (&oldloc);
+ priv->children[child_index]->fops->setattr,
+ parent_loc, &parentbuf, valid);
- return 0;
-}
+ dict_unref (xattr);
-int
-afr_sh_nameless_lookup_cbk (call_frame_t *impunge_frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
-{
- if (op_ret < 0) {
- afr_sh_entry_impunge_create_file (impunge_frame, this,
- (long)cookie);
- } else {
- afr_sh_entry_impunge_hardlink (impunge_frame, this,
- (long)cookie);
- }
return 0;
-}
-
-int
-afr_sh_entry_impunge_check_hardlink (call_frame_t *impunge_frame,
- xlator_t *this,
- int child_index, struct iatt *stbuf)
-{
- afr_private_t *priv = NULL;
- call_frame_t *frame = NULL;
- afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- afr_self_heal_t *sh = NULL;
- loc_t *loc = NULL;
- dict_t *xattr_req = NULL;
- loc_t oldloc = {0};
- int ret = -1;
- priv = this->private;
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
- loc = &impunge_local->loc;
+out:
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ UNLOCK (&impunge_frame->lock);
- xattr_req = dict_new ();
- if (!xattr_req)
- goto out;
- oldloc.inode = inode_ref (loc->inode);
- uuid_copy (oldloc.gfid, stbuf->ia_gfid);
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
- STACK_WIND_COOKIE (impunge_frame, afr_sh_nameless_lookup_cbk,
- (void *) (long) child_index,
- priv->children[child_index],
- priv->children[child_index]->fops->lookup,
- &oldloc, xattr_req);
- ret = 0;
-out:
- if (xattr_req)
- dict_unref (xattr_req);
- loc_wipe (&oldloc);
- if (ret)
- sh->impunge_done (frame, this, -1, ENOMEM);
return 0;
}
+
int
afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,
int child_index, struct iatt *stbuf)
@@ -1275,7 +1169,6 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,
if (!dict)
gf_log (this->name, GF_LOG_ERROR, "Out of memory");
- GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));
ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed",
@@ -1287,8 +1180,7 @@ afr_sh_entry_impunge_mknod (call_frame_t *impunge_frame, xlator_t *this,
priv->children[child_index]->fops->mknod,
&impunge_local->loc,
st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type),
- makedev (ia_major (stbuf->ia_rdev),
- ia_minor (stbuf->ia_rdev)), 0, dict);
+ stbuf->ia_rdev, dict);
if (dict)
dict_unref (dict);
@@ -1318,7 +1210,6 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this,
return 0;
}
- GF_ASSERT (!uuid_is_null (stbuf->ia_gfid));
ret = afr_set_dict_gfid (dict, stbuf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO, "%s: gfid set failed",
@@ -1335,7 +1226,7 @@ afr_sh_entry_impunge_mkdir (call_frame_t *impunge_frame, xlator_t *this,
priv->children[child_index]->fops->mkdir,
&impunge_local->loc,
st_mode_from_ia (stbuf->ia_prot, stbuf->ia_type),
- 0, dict);
+ dict);
if (dict)
dict_unref (dict);
@@ -1348,11 +1239,11 @@ int
afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this,
int child_index, const char *linkname)
{
- afr_private_t *priv = NULL;
- afr_local_t *impunge_local = NULL;
- dict_t *dict = NULL;
- struct iatt *buf = NULL;
- int ret = 0;
+ afr_private_t *priv = NULL;
+ afr_local_t *impunge_local = NULL;
+ dict_t *dict = NULL;
+ struct iatt *buf = NULL;
+ int ret = 0;
priv = this->private;
impunge_local = impunge_frame->local;
@@ -1361,12 +1252,11 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this,
dict = dict_new ();
if (!dict) {
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- -1, ENOMEM);
- goto out;
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ afr_sh_entry_impunge_entry_done (impunge_frame, this, 0);
}
- GF_ASSERT (!uuid_is_null (buf->ia_gfid));
ret = afr_set_dict_gfid (dict, buf->ia_gfid);
if (ret)
gf_log (this->name, GF_LOG_INFO,
@@ -1382,11 +1272,11 @@ afr_sh_entry_impunge_symlink (call_frame_t *impunge_frame, xlator_t *this,
(void *) (long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->symlink,
- linkname, &impunge_local->loc, 0, dict);
+ linkname, &impunge_local->loc, dict);
if (dict)
dict_unref (dict);
-out:
+
return 0;
}
@@ -1396,17 +1286,21 @@ afr_sh_entry_impunge_symlink_unlink_cbk (call_frame_t *impunge_frame,
void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
+ call_frame_t *frame = NULL;
int call_count = -1;
+ int active_src = -1;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
+ active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1430,9 +1324,10 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0)
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- op_ret, op_errno);
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
return 0;
}
@@ -1457,7 +1352,7 @@ afr_sh_entry_impunge_symlink_unlink (call_frame_t *impunge_frame, xlator_t *this
(void *) (long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->unlink,
- &impunge_local->loc, 0, NULL);
+ &impunge_local->loc);
return 0;
}
@@ -1467,18 +1362,20 @@ int
afr_sh_entry_impunge_readlink_sink_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- const char *linkname, struct iatt *sbuf, dict_t *xdata)
+ const char *linkname, struct iatt *sbuf)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
+ call_frame_t *frame = NULL;
int call_count = -1;
int active_src = -1;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1523,9 +1420,10 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0)
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- op_ret, op_errno);
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
return 0;
}
@@ -1549,7 +1447,7 @@ afr_sh_entry_impunge_readlink_sink (call_frame_t *impunge_frame, xlator_t *this,
(void *) (long) child_index,
priv->children[child_index],
priv->children[child_index]->fops->readlink,
- &impunge_local->loc, 4096, NULL);
+ &impunge_local->loc, 4096);
return 0;
}
@@ -1559,18 +1457,20 @@ int
afr_sh_entry_impunge_readlink_cbk (call_frame_t *impunge_frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- const char *linkname, struct iatt *sbuf, dict_t *xdata)
+ const char *linkname, struct iatt *sbuf)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
int child_index = -1;
+ call_frame_t *frame = NULL;
int call_count = -1;
int active_src = -1;
priv = this->private;
impunge_local = impunge_frame->local;
impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
active_src = impunge_sh->active_source;
child_index = (long) cookie;
@@ -1596,9 +1496,10 @@ out:
}
UNLOCK (&impunge_frame->lock);
- if (call_count == 0)
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- op_ret, op_errno);
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
return 0;
}
@@ -1623,78 +1524,50 @@ afr_sh_entry_impunge_readlink (call_frame_t *impunge_frame, xlator_t *this,
(void *) (long) child_index,
priv->children[active_src],
priv->children[active_src]->fops->readlink,
- &impunge_local->loc, 4096, NULL);
+ &impunge_local->loc, 4096);
return 0;
}
+
int
-afr_sh_entry_impunge_create (call_frame_t *impunge_frame, xlator_t *this,
- int child_index)
+afr_sh_entry_impunge_recreate_lookup_cbk (call_frame_t *impunge_frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf,
+ dict_t *xattr,struct iatt *postparent)
{
- call_frame_t *frame = NULL;
- afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
- ia_type_t type = IA_INVAL;
- int active_src = 0;
- struct iatt *buf = NULL;
+ afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
+ int active_src = 0;
+ int type = 0;
+ int child_index = 0;
+ call_frame_t *frame = NULL;
+ int call_count = 0;
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
- active_src = impunge_sh->active_source;
- afr_update_loc_gfids (&impunge_local->loc, &impunge_sh->entrybuf,
- &impunge_sh->parentbuf);
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
- buf = &impunge_sh->entrybuf;
- type = buf->ia_type;
+ child_index = (long) cookie;
- switch (type) {
- case IA_IFSOCK:
- case IA_IFREG:
- case IA_IFBLK:
- case IA_IFCHR:
- case IA_IFIFO:
- case IA_IFLNK:
- afr_sh_entry_impunge_check_hardlink (impunge_frame, this,
- child_index, buf);
- break;
- case IA_IFDIR:
- afr_sh_entry_impunge_mkdir (impunge_frame, this,
- child_index, buf);
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "%s has unknown file type on %s: 0%o",
+ active_src = impunge_sh->active_source;
+
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "looking up %s on %s (for %s) failed (%s)",
impunge_local->loc.path,
- priv->children[active_src]->name, type);
- sh->impunge_done (frame, this, -1, EINVAL);
- break;
+ priv->children[active_src]->name,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ goto out;
}
- return 0;
-}
-
-int
-afr_sh_entry_impunge_create_file (call_frame_t *impunge_frame, xlator_t *this,
- int child_index)
-{
- call_frame_t *frame = NULL;
- afr_local_t *impunge_local = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *impunge_sh = NULL;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
- ia_type_t type = IA_INVAL;
- int active_src = 0;
- struct iatt *buf = NULL;
+ impunge_sh->parentbuf = *postparent;
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
- active_src = impunge_sh->active_source;
- buf = &impunge_sh->entrybuf;
+ impunge_local->cont.lookup.buf = *buf;
type = buf->ia_type;
switch (type) {
@@ -1710,236 +1583,235 @@ afr_sh_entry_impunge_create_file (call_frame_t *impunge_frame, xlator_t *this,
afr_sh_entry_impunge_readlink (impunge_frame, this,
child_index, buf);
break;
+ case IA_IFDIR:
+ afr_sh_entry_impunge_mkdir (impunge_frame, this,
+ child_index, buf);
+ break;
default:
gf_log (this->name, GF_LOG_ERROR,
"%s has unknown file type on %s: 0%o",
impunge_local->loc.path,
priv->children[active_src]->name, type);
- sh->impunge_done (frame, this, -1, EINVAL);
+ goto out;
break;
}
return 0;
-}
-gf_boolean_t
-afr_sh_need_recreate (afr_self_heal_t *impunge_sh, unsigned int child,
- unsigned int child_count)
-{
- gf_boolean_t recreate = _gf_false;
-
- GF_ASSERT (impunge_sh->child_errno);
-
- if (child == impunge_sh->active_source)
- goto out;
-
- if (IA_IFLNK == impunge_sh->entrybuf.ia_type) {
- recreate = _gf_true;
- goto out;
- }
-
- if (impunge_sh->child_errno[child] == ENOENT)
- recreate = _gf_true;
out:
- return recreate;
-}
-
-unsigned int
-afr_sh_recreate_count (afr_self_heal_t *impunge_sh, int *sources,
- unsigned int child_count)
-{
- int count = 0;
- int i = 0;
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
+ }
+ UNLOCK (&impunge_frame->lock);
- for (i = 0; i < child_count; i++) {
- if (afr_sh_need_recreate (impunge_sh, i, child_count))
- count++;
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
}
- return count;
+ return 0;
}
+
int
-afr_sh_entry_call_impunge_recreate (call_frame_t *impunge_frame,
- xlator_t *this)
+afr_sh_entry_impunge_recreate (call_frame_t *impunge_frame, xlator_t *this,
+ int child_index)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
- call_frame_t *frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- unsigned int recreate_count = 0;
- int i = 0;
int active_src = 0;
- priv = this->private;
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
+
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+
active_src = impunge_sh->active_source;
- impunge_sh->entrybuf = impunge_sh->buf[active_src];
- impunge_sh->parentbuf = impunge_sh->parentbufs[active_src];
- recreate_count = afr_sh_recreate_count (impunge_sh, sh->sources,
- priv->child_count);
- if (!recreate_count) {
- afr_sh_entry_call_impunge_done (impunge_frame, this, 0, 0);
- goto out;
- }
- impunge_local->call_count = recreate_count;
- for (i = 0; i < priv->child_count; i++) {
- if (!impunge_local->child_up[i]) {
- impunge_sh->child_errno[i] = ENOTCONN;
- continue;
- }
- if (!afr_sh_need_recreate (impunge_sh, i, priv->child_count)) {
- impunge_sh->child_errno[i] = EEXIST;
- continue;
- }
- }
- for (i = 0; i < priv->child_count; i++) {
- if (!afr_sh_need_recreate (impunge_sh, i, priv->child_count))
- continue;
- (void)afr_sh_entry_impunge_create (impunge_frame, this, i);
- recreate_count--;
- }
- GF_ASSERT (!recreate_count);
-out:
+
+ STACK_WIND_COOKIE (impunge_frame,
+ afr_sh_entry_impunge_recreate_lookup_cbk,
+ (void *) (long) child_index,
+ priv->children[active_src],
+ priv->children[active_src]->fops->lookup,
+ &impunge_local->loc, 0);
+
return 0;
}
-void
-afr_sh_entry_common_lookup_done (call_frame_t *impunge_frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+
+int
+afr_sh_entry_impunge_entry_cbk (call_frame_t *impunge_frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *x,
+ struct iatt *postparent)
{
afr_private_t *priv = NULL;
afr_local_t *impunge_local = NULL;
afr_self_heal_t *impunge_sh = NULL;
+ int call_count = 0;
+ int child_index = 0;
call_frame_t *frame = NULL;
- afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
- unsigned int gfid_miss_count = 0;
- unsigned int children_up_count = 0;
- uuid_t gfid = {0};
int active_src = 0;
- priv = this->private;
- AFR_INIT_SH_FRAME_VALS (impunge_frame, impunge_local, impunge_sh,
- frame, local, sh);
- active_src = impunge_sh->active_source;
+ priv = this->private;
+ impunge_local = impunge_frame->local;
+ impunge_sh = &impunge_local->self_heal;
+ frame = impunge_sh->sh_frame;
+ child_index = (long) cookie;
+ active_src = impunge_sh->active_source;
- if (op_ret < 0)
- goto done;
- if (impunge_sh->child_errno[active_src]) {
- op_ret = -1;
- op_errno = impunge_sh->child_errno[active_src];
- goto done;
- }
-
- gfid_miss_count = afr_gfid_missing_count (this->name,
- impunge_sh->success_children,
- impunge_sh->buf, priv->child_count,
- impunge_local->loc.path);
- children_up_count = afr_up_children_count (impunge_local->child_up,
- priv->child_count);
- if ((gfid_miss_count == children_up_count) &&
- (children_up_count < priv->child_count)) {
- op_ret = -1;
- op_errno = ENODATA;
- gf_log (this->name, GF_LOG_ERROR, "Not all children are up, "
- "gfid should not be assigned in this state for %s",
- impunge_local->loc.path);
- goto done;
- }
-
- if (gfid_miss_count) {
- afr_update_gfid_from_iatts (gfid, impunge_sh->buf,
- impunge_sh->success_children,
- priv->child_count);
- if (uuid_is_null (gfid)) {
- sh->entries_skipped = _gf_true;
- gf_log (this->name, GF_LOG_INFO, "%s: Skipping entry "
- "self-heal because of gfid absence",
- impunge_local->loc.path);
- goto done;
- }
- afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc,
- afr_sh_entry_common_lookup_done, gfid,
- AFR_LOOKUP_FAIL_CONFLICTS |
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
+ if ((op_ret == -1 && op_errno == ENOENT)
+ || (IA_ISLNK (impunge_sh->impunging_entry_mode))) {
+
+ /*
+ * A symlink's target might have changed, so
+ * always go down the recreate path for them.
+ */
+
+ /* decrease call_count in recreate-callback */
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "missing entry %s on %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+
+ afr_sh_entry_impunge_recreate (impunge_frame, this,
+ child_index);
+ return 0;
+ }
+
+ if (op_ret == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%s exists under %s",
+ impunge_local->loc.path,
+ priv->children[child_index]->name);
+
+ impunge_sh->parentbuf = *postparent;
} else {
- afr_sh_entry_call_impunge_recreate (impunge_frame, this);
+ gf_log (this->name, GF_LOG_WARNING,
+ "looking up %s under %s failed (%s)",
+ impunge_local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+ }
+
+ LOCK (&impunge_frame->lock);
+ {
+ call_count = --impunge_local->call_count;
}
- return;
-done:
- afr_sh_entry_call_impunge_done (impunge_frame, this,
- op_ret, op_errno);
- return;
+ UNLOCK (&impunge_frame->lock);
+
+ if (call_count == 0) {
+ AFR_STACK_DESTROY (impunge_frame);
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+ }
+
+ return 0;
}
+
int
afr_sh_entry_impunge_entry (call_frame_t *frame, xlator_t *this,
gf_dirent_t *entry)
{
+ afr_private_t *priv = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
- afr_self_heal_t *impunge_sh = NULL;
int ret = -1;
call_frame_t *impunge_frame = NULL;
afr_local_t *impunge_local = NULL;
+ afr_self_heal_t *impunge_sh = NULL;
int active_src = 0;
+ int i = 0;
+ int call_count = 0;
int op_errno = 0;
- int op_ret = -1;
+ priv = this->private;
local = frame->local;
sh = &local->self_heal;
active_src = sh->active_source;
- sh->impunge_done = afr_sh_entry_impunge_entry_done;
if ((strcmp (entry->d_name, ".") == 0)
- || (strcmp (entry->d_name, "..") == 0)) {
+ || (strcmp (entry->d_name, "..") == 0)
+ || ((strcmp (local->loc.path, "/") == 0)
+ && (strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR) == 0))) {
gf_log (this->name, GF_LOG_TRACE,
"skipping inspection of %s under %s",
entry->d_name, local->loc.path);
- op_ret = 0;
goto out;
}
gf_log (this->name, GF_LOG_TRACE,
- "inspecting existence of %s under %s",
+ "inspecting existance of %s under %s",
entry->d_name, local->loc.path);
- ret = afr_impunge_frame_create (frame, this, active_src,
- &impunge_frame);
- if (ret) {
- op_errno = -ret;
+ impunge_frame = copy_frame (frame);
+ if (!impunge_frame) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory.");
goto out;
}
- impunge_local = impunge_frame->local;
+ ALLOC_OR_GOTO (impunge_local, afr_local_t, out);
+
+ impunge_frame->local = impunge_local;
impunge_sh = &impunge_local->self_heal;
- ret = afr_build_child_loc (this, &impunge_local->loc, &local->loc,
- entry->d_name);
- loc_copy (&impunge_sh->parent_loc, &local->loc);
+ impunge_sh->sh_frame = frame;
+ impunge_sh->active_source = active_src;
+
+ impunge_sh->impunging_entry_mode =
+ st_mode_from_ia (entry->d_stat.ia_prot, entry->d_stat.ia_type);
+
+ ret = build_child_loc (this, &impunge_local->loc, &local->loc, entry->d_name);
if (ret != 0) {
- op_errno = ENOMEM;
goto out;
}
- afr_sh_common_lookup (impunge_frame, this, &impunge_local->loc,
- afr_sh_entry_common_lookup_done, NULL,
- AFR_LOOKUP_FAIL_CONFLICTS, NULL);
+ for (i = 0; i < priv->child_count; i++) {
+ if (i == active_src)
+ continue;
+ if (local->child_up[i] == 0)
+ continue;
+ if (sh->sources[i] == 1)
+ continue;
+ call_count++;
+ }
- op_ret = 0;
-out:
- if (ret) {
- if (impunge_frame)
- AFR_STACK_DESTROY (impunge_frame);
- sh->impunge_done (frame, this, op_ret, op_errno);
+ impunge_local->call_count = call_count;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (i == active_src)
+ continue;
+ if (local->child_up[i] == 0)
+ continue;
+ if (sh->sources[i] == 1)
+ continue;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s", impunge_local->loc.path,
+ priv->children[i]->name);
+
+ STACK_WIND_COOKIE (impunge_frame,
+ afr_sh_entry_impunge_entry_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->lookup,
+ &impunge_local->loc, 0);
+
+ if (!--call_count)
+ break;
}
+ ret = 0;
+out:
+ if (ret == -1)
+ afr_sh_entry_impunge_entry_done (frame, this, active_src);
+
return 0;
}
@@ -1948,7 +1820,7 @@ int
afr_sh_entry_impunge_readdir_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
+ gf_dirent_t *entries)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
@@ -1971,7 +1843,6 @@ afr_sh_entry_impunge_readdir_cbk (call_frame_t *frame, void *cookie,
local->loc.path,
priv->children[active_src]->name,
strerror (op_errno));
- sh->op_failed = 1;
} else {
gf_log (this->name, GF_LOG_TRACE,
"readdir of %s on subvolume %s complete",
@@ -1988,7 +1859,7 @@ afr_sh_entry_impunge_readdir_cbk (call_frame_t *frame, void *cookie,
entry_count++;
}
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_TRACE,
"readdir'ed %d entries from %s",
entry_count, priv->children[active_src]->name);
@@ -2004,24 +1875,21 @@ afr_sh_entry_impunge_readdir_cbk (call_frame_t *frame, void *cookie,
int
-afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this)
+afr_sh_entry_impunge_subvol (call_frame_t *frame, xlator_t *this,
+ int active_src)
{
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
- int32_t active_src = 0;
priv = this->private;
local = frame->local;
sh = &local->self_heal;
- active_src = sh->active_source;
- gf_log (this->name, GF_LOG_DEBUG, "%s: readdir from offset %zd",
- local->loc.path, sh->offset);
STACK_WIND (frame, afr_sh_entry_impunge_readdir_cbk,
priv->children[active_src],
priv->children[active_src]->fops->readdirp,
- sh->healing_fd, sh->block_size, sh->offset, NULL);
+ sh->healing_fd, sh->block_size, sh->offset);
return 0;
}
@@ -2059,7 +1927,7 @@ afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this)
"impunging entries of %s on %s to other sinks",
local->loc.path, priv->children[active_src]->name);
- afr_sh_entry_impunge_subvol (frame, this);
+ afr_sh_entry_impunge_subvol (frame, this, active_src);
return 0;
}
@@ -2067,7 +1935,7 @@ afr_sh_entry_impunge_all (call_frame_t *frame, xlator_t *this)
int
afr_sh_entry_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -2088,7 +1956,7 @@ afr_sh_entry_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
LOCK (&frame->lock);
{
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"opendir of %s failed on child %s (%s)",
local->loc.path,
priv->children[child_index]->name,
@@ -2161,7 +2029,7 @@ afr_sh_entry_open (call_frame_t *frame, xlator_t *this)
(void *) (long) source,
priv->children[source],
priv->children[source]->fops->opendir,
- &local->loc, fd, NULL);
+ &local->loc, fd);
call_count--;
}
@@ -2178,7 +2046,7 @@ afr_sh_entry_open (call_frame_t *frame, xlator_t *this)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->opendir,
- &local->loc, fd, NULL);
+ &local->loc, fd);
if (!--call_count)
break;
@@ -2194,7 +2062,9 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
+ int active_sinks = 0;
int source = 0;
+ int i = 0;
local = frame->local;
sh = &local->self_heal;
@@ -2202,31 +2072,37 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
source = sh->source;
- afr_sh_mark_source_sinks (frame, this);
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->sources[i] == 0 && local->child_up[i] == 1) {
+ active_sinks++;
+ sh->success[i] = 1;
+ }
+ }
if (source != -1)
sh->success[source] = 1;
- if (sh->active_sinks == 0) {
+ if (active_sinks == 0) {
gf_log (this->name, GF_LOG_TRACE,
"no active sinks for self-heal on dir %s",
local->loc.path);
afr_sh_entry_finish (frame, this);
return 0;
}
- if (source == -1 && sh->active_sinks < 2) {
+ if (source == -1 && active_sinks < 2) {
gf_log (this->name, GF_LOG_TRACE,
"cannot sync with 0 sources and 1 sink on dir %s",
local->loc.path);
afr_sh_entry_finish (frame, this);
return 0;
}
+ sh->active_sinks = active_sinks;
if (source != -1)
gf_log (this->name, GF_LOG_DEBUG,
"self-healing directory %s from subvolume %s to "
"%d other",
local->loc.path, priv->children[source]->name,
- sh->active_sinks);
+ active_sinks);
else
gf_log (this->name, GF_LOG_DEBUG,
"no active sources for %s found. "
@@ -2239,69 +2115,140 @@ afr_sh_entry_sync_prepare (call_frame_t *frame, xlator_t *this)
}
-void
-afr_sh_entry_fix (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+int
+afr_sh_entry_fix (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
int source = 0;
- int nsources = 0;
- int32_t subvol_status = 0;
+
+ int nsources = 0;
local = frame->local;
sh = &local->self_heal;
priv = this->private;
- if (op_ret < 0) {
- sh->op_failed = 1;
- afr_sh_set_error (sh, op_errno);
- afr_sh_entry_finish (frame, this);
- goto out;
- }
-
if (sh->forced_merge) {
sh->source = -1;
goto heal;
}
- nsources = afr_build_sources (this, sh->xattr, sh->buf,
- sh->pending_matrix, sh->sources,
- sh->success_children,
- AFR_ENTRY_TRANSACTION, &subvol_status,
- _gf_true);
- if ((subvol_status & ALL_FOOLS) ||
- (subvol_status & SPLIT_BRAIN)) {
- gf_log (this->name, GF_LOG_INFO, "%s: Performing conservative "
- "merge", local->loc.path);
- source = -1;
- memset (sh->sources, 0,
- sizeof (*sh->sources) * priv->child_count);
- } else if (nsources == 0) {
+ afr_sh_build_pending_matrix (priv, sh->pending_matrix, sh->xattr,
+ priv->child_count, AFR_ENTRY_TRANSACTION);
+
+ afr_sh_print_pending_matrix (sh->pending_matrix, this);
+
+ nsources = afr_sh_mark_sources (sh, priv->child_count,
+ AFR_SELF_HEAL_ENTRY);
+
+ if (nsources == 0) {
gf_log (this->name, GF_LOG_TRACE,
"No self-heal needed for %s",
local->loc.path);
afr_sh_entry_finish (frame, this);
- return;
- } else {
- source = afr_sh_select_source (sh->sources, priv->child_count);
+ return 0;
}
- sh->source = source;
+ afr_sh_supress_errenous_children (sh->sources, sh->child_errno,
+ priv->child_count);
+
+ source = afr_sh_select_source (sh->sources, priv->child_count);
- afr_reset_children (sh->fresh_children, priv->child_count);
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, priv->child_count);
- if (sh->source >= 0)
- afr_inode_set_read_ctx (this, sh->inode, sh->source,
- sh->fresh_children);
+ sh->source = source;
heal:
afr_sh_entry_sync_prepare (frame, this);
-out:
- return;
+
+ return 0;
+}
+
+
+
+int
+afr_sh_entry_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+
+ int call_count = -1;
+ int child_index = (long) cookie;
+
+ local = frame->local;
+ sh = &local->self_heal;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret != -1) {
+ sh->xattr[child_index] = dict_ref (xattr);
+ sh->buf[child_index] = *buf;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0) {
+ afr_sh_entry_fix (frame, this);
+ }
+
+ return 0;
+}
+
+
+
+int
+afr_sh_entry_lookup (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
+ dict_t *xattr_req = NULL;
+ int ret = 0;
+ int call_count = 0;
+ int i = 0;
+
+ priv = this->private;
+ local = frame->local;
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+
+ local->call_count = call_count;
+
+ xattr_req = dict_new();
+ if (xattr_req) {
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_uint64 (xattr_req,
+ priv->pending_key[i],
+ 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: Unable to set dict value.",
+ local->loc.path);
+ }
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame,
+ afr_sh_entry_lookup_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->lookup,
+ &local->loc, xattr_req);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ if (xattr_req)
+ dict_unref (xattr_req);
+
+ return 0;
}
int
@@ -2309,32 +2256,50 @@ afr_sh_post_nonblocking_entry_cbk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
- afr_self_heal_t *sh = NULL;
local = frame->local;
int_lock = &local->internal_lock;
- sh = &local->self_heal;
if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Non Blocking entrylks "
- "failed for %s.", local->loc.path);
- sh->op_failed = 1;
+ gf_log (this->name, GF_LOG_INFO,
+ "Non Blocking entrylks failed.");
afr_sh_entry_done (frame, this);
} else {
- gf_log (this->name, GF_LOG_DEBUG, "Non Blocking entrylks done "
- "for %s. Proceeding to FOP", local->loc.path);
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_entry_fix, NULL,
- AFR_LOOKUP_FAIL_CONFLICTS |
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Non Blocking entrylks done. Proceeding to FOP");
+ afr_sh_entry_lookup(frame, this);
}
return 0;
}
int
+afr_sh_entry_lock (call_frame_t *frame, xlator_t *this)
+{
+ afr_internal_lock_t *int_lock = NULL;
+ afr_local_t *local = NULL;
+
+ local = frame->local;
+ int_lock = &local->internal_lock;
+
+ int_lock->transaction_lk_type = AFR_SELFHEAL_LK;
+ int_lock->selfheal_lk_type = AFR_ENTRY_SELF_HEAL_LK;
+
+ afr_set_lock_number (frame, this);
+
+ int_lock->lk_basename = NULL;
+ int_lock->lk_loc = &local->loc;
+ int_lock->lock_cbk = afr_sh_post_nonblocking_entry_cbk;
+
+ afr_nonblocking_entrylk (frame, this);
+
+
+ return 0;
+}
+
+
+int
afr_self_heal_entry (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
@@ -2344,9 +2309,8 @@ afr_self_heal_entry (call_frame_t *frame, xlator_t *this)
priv = this->private;
local = frame->local;
- if (local->self_heal.do_entry_self_heal && priv->entry_self_heal) {
- afr_sh_entrylk (frame, this, &local->loc, NULL,
- afr_sh_post_nonblocking_entry_cbk);
+ if (local->self_heal.need_entry_self_heal && priv->entry_self_heal) {
+ afr_sh_entry_lock (frame, this);
} else {
gf_log (this->name, GF_LOG_TRACE,
"proceeding to completion on %s",
diff --git a/xlators/cluster/afr/src/afr-self-heal-metadata.c b/xlators/cluster/afr/src/afr-self-heal-metadata.c
index 79ce07d00..ee27a7bd1 100644
--- a/xlators/cluster/afr/src/afr-self-heal-metadata.c
+++ b/xlators/cluster/afr/src/afr-self-heal-metadata.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -45,18 +54,41 @@ afr_sh_metadata_done (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
local = frame->local;
sh = &local->self_heal;
+ priv = this->private;
+
+// memset (sh->child_errno, 0, sizeof (int) * priv->child_count);
+ memset (sh->buf, 0, sizeof (struct iatt) * priv->child_count);
+ memset (sh->success, 0, sizeof (int) * priv->child_count);
- afr_sh_reset (frame, this);
- if (sh->mdata_spb) {
+/* for (i = 0; i < priv->child_count; i++) { */
+/* sh->locked_nodes[i] = 1; */
+/* } */
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i])
+ dict_unref (sh->xattr[i]);
+ sh->xattr[i] = NULL;
+ }
+
+ if (local->govinda_gOvinda) {
gf_log (this->name, GF_LOG_INFO,
- "split-brain detected, aborting selfheal of %s",
+ "aborting selfheal of %s",
local->loc.path);
- sh->op_failed = 1;
sh->completion_cbk (frame, this);
} else {
+ if (IA_ISREG (sh->type)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "proceeding to data check on %s",
+ local->loc.path);
+ afr_self_heal_data (frame, this);
+ return 0;
+ }
+
if (IA_ISDIR (sh->type)) {
gf_log (this->name, GF_LOG_DEBUG,
"proceeding to entry check on %s",
@@ -65,14 +97,30 @@ afr_sh_metadata_done (call_frame_t *frame, xlator_t *this)
return 0;
}
gf_log (this->name, GF_LOG_DEBUG,
- "proceeding to data check on %s",
+ "completed self heal of %s",
local->loc.path);
- afr_self_heal_data (frame, this);
+
+ sh->completion_cbk (frame, this);
}
return 0;
}
+
+int
+afr_sh_metadata_unlck_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ int call_count = 0;
+
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_metadata_done (frame, this);
+
+ return 0;
+}
+
int
afr_sh_inode_unlock (call_frame_t *frame, xlator_t *this)
{
@@ -100,51 +148,100 @@ afr_sh_metadata_finish (call_frame_t *frame, xlator_t *this)
int
afr_sh_metadata_erase_pending_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xattr, dict_t *xdata)
+ int32_t op_errno, dict_t *xattr)
{
- afr_local_t *local = NULL;
+ afr_local_t *local = NULL;
int call_count = 0;
- long i = 0;
- afr_self_heal_t *sh = NULL;
- afr_private_t *priv = NULL;
local = frame->local;
- priv = this->private;
- sh = &local->self_heal;
- i = (long)cookie;
- if ((!IA_ISREG (sh->buf[sh->source].ia_type)) &&
- (!IA_ISDIR (sh->buf[sh->source].ia_type))) {
- afr_children_add_child (sh->fresh_children, i,
- priv->child_count);
- }
call_count = afr_frame_return (frame);
- if (call_count == 0) {
- if ((!IA_ISREG (sh->buf[sh->source].ia_type)) &&
- (!IA_ISDIR (sh->buf[sh->source].ia_type))) {
- afr_inode_set_read_ctx (this, sh->inode, sh->source,
- sh->fresh_children);
- }
+ if (call_count == 0)
afr_sh_metadata_finish (frame, this);
- }
return 0;
}
+
int
afr_sh_metadata_erase_pending (call_frame_t *frame, xlator_t *this)
{
- afr_sh_erase_pending (frame, this, AFR_METADATA_TRANSACTION,
- afr_sh_metadata_erase_pending_cbk,
- afr_sh_metadata_finish);
- return 0;
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int i = 0;
+ dict_t **erase_xattr = NULL;
+
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ afr_sh_pending_to_delta (priv, sh->xattr, sh->delta_matrix,
+ sh->success, priv->child_count,
+ AFR_METADATA_TRANSACTION);
+
+ erase_xattr = GF_CALLOC (sizeof (*erase_xattr), priv->child_count,
+ gf_afr_mt_dict_t);
+ if (!erase_xattr)
+ return -ENOMEM;
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->xattr[i]) {
+ call_count++;
+
+ erase_xattr[i] = get_new_dict();
+ dict_ref (erase_xattr[i]);
+ }
+ }
+
+ afr_sh_delta_to_xattr (priv, sh->delta_matrix, erase_xattr,
+ priv->child_count, AFR_METADATA_TRANSACTION);
+
+ local->call_count = call_count;
+
+ if (call_count == 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "metadata of %s not healed on any subvolume",
+ local->loc.path);
+
+ afr_sh_metadata_finish (frame, this);
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (!erase_xattr[i])
+ continue;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "erasing pending flags from %s on %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_metadata_erase_pending_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->xattrop,
+ &local->loc,
+ GF_XATTROP_ADD_ARRAY, erase_xattr[i]);
+ if (!--call_count)
+ break;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (erase_xattr[i]) {
+ dict_unref (erase_xattr[i]);
+ }
+ }
+ GF_FREE (erase_xattr);
+
+ return 0;
}
int
afr_sh_metadata_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -185,9 +282,9 @@ afr_sh_metadata_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_sh_metadata_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
- afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
@@ -195,9 +292,9 @@ afr_sh_metadata_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
afr_sh_metadata_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ afr_sh_metadata_sync_cbk (frame, cookie, this, op_ret, op_errno);
return 0;
}
@@ -265,7 +362,7 @@ afr_sh_metadata_sync (call_frame_t *frame, xlator_t *this, dict_t *xattr)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->setattr,
- &local->loc, &stbuf, valid, NULL);
+ &local->loc, &stbuf, valid);
call_count--;
@@ -276,7 +373,7 @@ afr_sh_metadata_sync (call_frame_t *frame, xlator_t *this, dict_t *xattr)
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->setxattr,
- &local->loc, xattr, 0, NULL);
+ &local->loc, xattr, 0);
call_count--;
}
@@ -285,9 +382,9 @@ afr_sh_metadata_sync (call_frame_t *frame, xlator_t *this, dict_t *xattr)
int
-afr_sh_metadata_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
+afr_sh_metadata_getxattr_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -327,7 +424,9 @@ afr_sh_metadata_sync_prepare (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
afr_private_t *priv = NULL;
+ int active_sinks = 0;
int source = 0;
+ int i = 0;
local = frame->local;
sh = &local->self_heal;
@@ -335,32 +434,38 @@ afr_sh_metadata_sync_prepare (call_frame_t *frame, xlator_t *this)
source = sh->source;
- afr_sh_mark_source_sinks (frame, this);
- if (sh->active_sinks == 0) {
+ for (i = 0; i < priv->child_count; i++) {
+ if (sh->sources[i] == 0 && local->child_up[i] == 1) {
+ active_sinks++;
+ sh->success[i] = 1;
+ }
+ }
+ sh->success[source] = 1;
+
+ if (active_sinks == 0) {
gf_log (this->name, GF_LOG_DEBUG,
"no active sinks for performing self-heal on file %s",
local->loc.path);
afr_sh_metadata_finish (frame, this);
return 0;
}
+ sh->active_sinks = active_sinks;
gf_log (this->name, GF_LOG_TRACE,
"syncing metadata of %s from subvolume %s to %d active sinks",
- local->loc.path, priv->children[source]->name,
- sh->active_sinks);
+ local->loc.path, priv->children[source]->name, active_sinks);
STACK_WIND (frame, afr_sh_metadata_getxattr_cbk,
priv->children[source],
priv->children[source]->fops->getxattr,
- &local->loc, NULL, NULL);
+ &local->loc, NULL);
return 0;
}
-void
-afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno)
+int
+afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_self_heal_t *sh = NULL;
@@ -373,16 +478,27 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
sh = &local->self_heal;
priv = this->private;
- if (op_ret < 0) {
- sh->op_failed = 1;
- afr_sh_set_error (sh, op_errno);
+ afr_sh_build_pending_matrix (priv, sh->pending_matrix, sh->xattr,
+ priv->child_count,
+ AFR_METADATA_TRANSACTION);
+
+ afr_sh_print_pending_matrix (sh->pending_matrix, this);
+
+ nsources = afr_sh_mark_sources (sh, priv->child_count,
+ AFR_SELF_HEAL_METADATA);
+
+ afr_sh_supress_errenous_children (sh->sources, sh->child_errno,
+ priv->child_count);
+
+ if (nsources == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "No self-heal needed for %s",
+ local->loc.path);
+
afr_sh_metadata_finish (frame, this);
- goto out;
+ return 0;
}
- nsources = afr_build_sources (this, sh->xattr, sh->buf,
- sh->pending_matrix, sh->sources,
- sh->success_children,
- AFR_METADATA_TRANSACTION, NULL, _gf_false);
+
if ((nsources == -1)
&& (priv->favorite_child != -1)
&& (sh->child_errno[priv->favorite_child] == 0)) {
@@ -404,20 +520,10 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
"(possible split-brain). Please fix the file on "
"all backend volumes", local->loc.path);
- sh->mdata_spb = _gf_true;
+ local->govinda_gOvinda = 1;
afr_sh_metadata_finish (frame, this);
- goto out;
- }
-
- sh->mdata_spb = _gf_false;
- if (nsources == 0) {
- gf_log (this->name, GF_LOG_TRACE,
- "No self-heal needed for %s",
- local->loc.path);
-
- afr_sh_metadata_finish (frame, this);
- goto out;
+ return 0;
}
source = afr_sh_select_source (sh->sources, priv->child_count);
@@ -427,7 +533,7 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
"No active sources found.");
afr_sh_metadata_finish (frame, this);
- goto out;
+ return 0;
}
sh->source = source;
@@ -444,26 +550,118 @@ afr_sh_metadata_fix (call_frame_t *frame, xlator_t *this,
sh->sources[i] = 0;
}
- if ((!IA_ISREG (sh->buf[source].ia_type)) &&
- (!IA_ISDIR (sh->buf[source].ia_type))) {
- afr_reset_children (sh->fresh_children, priv->child_count);
- afr_get_fresh_children (sh->success_children, sh->sources,
- sh->fresh_children, priv->child_count);
- afr_inode_set_read_ctx (this, sh->inode, sh->source,
- sh->fresh_children);
+ afr_sh_metadata_sync_prepare (frame, this);
+
+ return 0;
+}
+
+
+int
+afr_sh_metadata_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ afr_local_t *local = NULL;
+ afr_self_heal_t *sh = NULL;
+ afr_private_t *priv = NULL;
+ int call_count = 0;
+ int child_index = 0;
+
+
+ local = frame->local;
+ sh = &local->self_heal;
+ priv = this->private;
+
+ child_index = (long) cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "path %s on subvolume %s is of mode 0%o",
+ local->loc.path,
+ priv->children[child_index]->name,
+ buf->ia_type);
+
+ sh->buf[child_index] = *buf;
+ if (xattr)
+ sh->xattr[child_index] = dict_ref (xattr);
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "path %s on subvolume %s => -1 (%s)",
+ local->loc.path,
+ priv->children[child_index]->name,
+ strerror (op_errno));
+
+ sh->child_errno[child_index] = op_errno;
+ }
}
+ UNLOCK (&frame->lock);
- if (sh->do_metadata_self_heal && priv->metadata_self_heal)
- afr_sh_metadata_sync_prepare (frame, this);
- else
- afr_sh_metadata_finish (frame, this);
-out:
- return;
+ call_count = afr_frame_return (frame);
+
+ if (call_count == 0)
+ afr_sh_metadata_fix (frame, this);
+
+ return 0;
}
+
int
-afr_sh_metadata_post_nonblocking_inodelk_cbk (call_frame_t *frame,
- xlator_t *this)
+afr_sh_metadata_lookup (call_frame_t *frame, xlator_t *this)
+{
+ afr_local_t *local = NULL;
+ afr_private_t *priv = NULL;
+ int i = 0;
+ int call_count = 0;
+ dict_t *xattr_req = NULL;
+ int ret = 0;
+
+ local = frame->local;
+ priv = this->private;
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+ local->call_count = call_count;
+
+ xattr_req = dict_new();
+
+ if (xattr_req) {
+ for (i = 0; i < priv->child_count; i++) {
+ ret = dict_set_uint64 (xattr_req,
+ priv->pending_key[i],
+ 3 * sizeof(int32_t));
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unable to set dict value.");
+ }
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ if (local->child_up[i]) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "looking up %s on %s",
+ local->loc.path, priv->children[i]->name);
+
+ STACK_WIND_COOKIE (frame, afr_sh_metadata_lookup_cbk,
+ (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->lookup,
+ &local->loc, xattr_req);
+ if (!--call_count)
+ break;
+ }
+ }
+
+ if (xattr_req)
+ dict_unref (xattr_req);
+
+ return 0;
+}
+
+int
+afr_sh_post_nonblocking_inodelk_cbk (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
@@ -472,21 +670,14 @@ afr_sh_metadata_post_nonblocking_inodelk_cbk (call_frame_t *frame,
int_lock = &local->internal_lock;
if (int_lock->lock_op_ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Non Blocking metadata "
- "inodelks failed for %s.", local->loc.path);
- gf_log (this->name, GF_LOG_ERROR, "Metadata self-heal "
- "failed for %s.", local->loc.path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Non Blocking inodelks failed.");
afr_sh_metadata_done (frame, this);
} else {
- gf_log (this->name, GF_LOG_DEBUG, "Non Blocking metadata "
- "inodelks done for %s. Proceeding to FOP",
- local->loc.path);
- afr_sh_common_lookup (frame, this, &local->loc,
- afr_sh_metadata_fix, NULL,
- AFR_LOOKUP_FAIL_CONFLICTS |
- AFR_LOOKUP_FAIL_MISSING_GFIDS,
- NULL);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Non Blocking inodelks done. Proceeding to FOP");
+ afr_sh_metadata_lookup (frame, this);
}
return 0;
@@ -506,45 +697,27 @@ afr_sh_metadata_lock (call_frame_t *frame, xlator_t *this)
afr_set_lock_number (frame, this);
- int_lock->lk_flock.l_start = LLONG_MAX - 1;
+ int_lock->lk_flock.l_start = 0;
int_lock->lk_flock.l_len = 0;
int_lock->lk_flock.l_type = F_WRLCK;
- int_lock->lock_cbk = afr_sh_metadata_post_nonblocking_inodelk_cbk;
+ int_lock->lock_cbk = afr_sh_post_nonblocking_inodelk_cbk;
afr_nonblocking_inodelk (frame, this);
return 0;
}
-gf_boolean_t
-afr_can_start_metadata_self_heal (afr_self_heal_t *sh, afr_private_t *priv)
-{
- if (sh->force_confirm_spb)
- return _gf_true;
- if (sh->do_metadata_self_heal && priv->metadata_self_heal)
- return _gf_true;
- return _gf_false;
-}
int
afr_self_heal_metadata (call_frame_t *frame, xlator_t *this)
{
afr_local_t *local = NULL;
afr_private_t *priv = this->private;
- afr_self_heal_t *sh = &local->self_heal;
- local = frame->local;
- sh = &local->self_heal;
- /* Self-heal completion cbk changes inode split-brain status based on
- * govinda_gOvinda, mdata_spb, data_spb value.
- * Initialize mdata_spb with current split-brain status.
- * If for some reason self-heal fails(locking phase etc), it makes sure
- * we retain the split-brain status before this self-heal started.
- */
- sh->mdata_spb = afr_is_split_brain (this, sh->inode);
+ local = frame->local;
- if (afr_can_start_metadata_self_heal (sh, priv)) {
+ if (local->self_heal.need_metadata_self_heal && priv->metadata_self_heal) {
afr_sh_metadata_lock (frame, this);
} else {
afr_sh_metadata_done (frame, this);
diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h
index 2efc1116d..b10ae3fc0 100644
--- a/xlators/cluster/afr/src/afr-self-heal.h
+++ b/xlators/cluster/afr/src/afr-self-heal.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __AFR_SELF_HEAL_H__
@@ -21,11 +30,11 @@
#define SIZE_GREATER(buf1,buf2) ((buf1)->ia_size > (buf2)->ia_size)
int
-afr_sh_has_metadata_pending (dict_t *xattr, xlator_t *this);
+afr_sh_has_metadata_pending (dict_t *xattr, int child_count, xlator_t *this);
int
-afr_sh_has_entry_pending (dict_t *xattr, xlator_t *this);
+afr_sh_has_entry_pending (dict_t *xattr, int child_count, xlator_t *this);
int
-afr_sh_has_data_pending (dict_t *xattr, xlator_t *this);
+afr_sh_has_data_pending (dict_t *xattr, int child_count, xlator_t *this);
int
afr_self_heal_entry (call_frame_t *frame, xlator_t *this);
@@ -40,11 +49,6 @@ int
afr_self_heal_get_source (xlator_t *this, afr_local_t *local, dict_t **xattr);
int
-afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode);
+afr_self_heal (call_frame_t *frame, xlator_t *this);
-int
-afr_lookup_select_read_child_by_txn_type (xlator_t *this, afr_local_t *local,
- dict_t **xattr,
- afr_transaction_type txn_type,
- uuid_t gfid);
#endif /* __AFR_SELF_HEAL_H__ */
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
deleted file mode 100644
index f87e57344..000000000
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ /dev/null
@@ -1,1228 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-#include "afr.h"
-#include "syncop.h"
-#include "afr-self-heald.h"
-#include "afr-self-heal-common.h"
-#include "protocol-common.h"
-#include "event-history.h"
-
-typedef enum {
- STOP_CRAWL_ON_SINGLE_SUBVOL = 1
-} afr_crawl_flags_t;
-
-typedef enum {
- HEAL = 1,
- INFO
-} shd_crawl_op;
-
-typedef struct shd_dump {
- dict_t *dict;
- xlator_t *this;
- int child;
-} shd_dump_t;
-
-typedef struct shd_event_ {
- int child;
- char *path;
-} shd_event_t;
-
-typedef struct shd_pos_ {
- int child;
- xlator_t *this;
- afr_child_pos_t pos;
-} shd_pos_t;
-
-typedef int
-(*afr_crawl_done_cbk_t) (int ret, call_frame_t *sync_frame, void *crawl_data);
-
-void
-afr_start_crawl (xlator_t *this, int idx, afr_crawl_type_t crawl,
- process_entry_cbk_t process_entry, void *op_data,
- gf_boolean_t exclusive, int crawl_flags,
- afr_crawl_done_cbk_t crawl_done);
-
-static int
-_crawl_directory (fd_t *fd, loc_t *loc, afr_crawl_data_t *crawl_data);
-
-int
-afr_syncop_find_child_position (void *data);
-
-static int
-_loc_assign_gfid_path (loc_t *loc)
-{
- int ret = -1;
- char gfid_path[64] = {0};
-
- if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
- ret = inode_path (loc->inode, NULL, (char**)&loc->path);
- } else if (!uuid_is_null (loc->gfid)) {
- snprintf (gfid_path, sizeof (gfid_path), "<gfid:%s>",
- uuid_utoa (loc->gfid));
- loc->path = gf_strdup (gfid_path);
- if (loc->path)
- ret = 0;
- }
- return ret;
-}
-
-void
-shd_cleanup_event (void *event)
-{
- shd_event_t *shd_event = event;
-
- if (!shd_event)
- goto out;
- GF_FREE (shd_event->path);
- GF_FREE (shd_event);
-out:
- return;
-}
-
-int
-afr_get_local_child (afr_self_heald_t *shd, unsigned int child_count)
-{
- int i = 0;
- int ret = -1;
- for (i = 0; i < child_count; i++) {
- if (shd->pos[i] == AFR_POS_LOCAL) {
- ret = i;
- break;
- }
- }
- return ret;
-}
-
-static int
-_build_index_loc (xlator_t *this, loc_t *loc, char *name, loc_t *parent)
-{
- int ret = 0;
-
- uuid_copy (loc->pargfid, parent->inode->gfid);
- loc->path = "";
- loc->name = name;
- loc->parent = inode_ref (parent->inode);
- if (!loc->parent) {
- loc->path = NULL;
- loc_wipe (loc);
- ret = -1;
- }
- return ret;
-}
-
-int
-_add_path_to_dict (xlator_t *this, dict_t *output, int child, char *path,
- struct timeval *tv, gf_boolean_t dyn)
-{
- //subkey not used for now
- int ret = -1;
- uint64_t count = 0;
- char key[256] = {0};
- int xl_id = 0;
-
- ret = dict_get_int32 (output, this->name, &xl_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "xl does not have id");
- goto out;
- }
-
- snprintf (key, sizeof (key), "%d-%d-count", xl_id, child);
- ret = dict_get_uint64 (output, key, &count);
-
- snprintf (key, sizeof (key), "%d-%d-%"PRIu64, xl_id, child, count);
- if (dyn)
- ret = dict_set_dynstr (output, key, path);
- else
- ret = dict_set_str (output, key, path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Could not add to output",
- path);
- goto out;
- }
-
- if (!tv)
- goto inc_count;
- snprintf (key, sizeof (key), "%d-%d-%"PRIu64"-time", xl_id,
- child, count);
- ret = dict_set_uint32 (output, key, tv->tv_sec);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Could not set time",
- path);
- goto out;
- }
-
-inc_count:
- snprintf (key, sizeof (key), "%d-%d-count", xl_id, child);
- ret = dict_set_uint64 (output, key, count + 1);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not increment count");
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-int
-_get_path_from_gfid_loc (xlator_t *this, xlator_t *readdir_xl, loc_t *child,
- char **fpath)
-{
- dict_t *xattr = NULL;
- char *path = NULL;
- int ret = -1;
-
- ret = syncop_getxattr (readdir_xl, child, &xattr,
- GFID_TO_PATH_KEY);
- if (ret)
- goto out;
- ret = dict_get_str (xattr, GFID_TO_PATH_KEY, &path);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get path for "
- "gfid %s", uuid_utoa (child->gfid));
- goto out;
- }
- path = gf_strdup (path);
- if (!path) {
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- if (!ret)
- *fpath = path;
- if (xattr)
- dict_unref (xattr);
- return ret;
-}
-
-int
-_add_event_to_dict (circular_buffer_t *cb, void *data)
-{
- int ret = 0;
- shd_dump_t *dump_data = NULL;
- shd_event_t *shd_event = NULL;
-
- dump_data = data;
- shd_event = cb->data;
- if (shd_event->child != dump_data->child)
- goto out;
- ret = _add_path_to_dict (dump_data->this, dump_data->dict,
- dump_data->child, shd_event->path, &cb->tv,
- _gf_false);
-out:
- return ret;
-}
-
-int
-_add_eh_to_dict (xlator_t *this, eh_t *eh, dict_t *dict, int child)
-{
- shd_dump_t dump_data = {0};
-
- dump_data.this = this;
- dump_data.dict = dict;
- dump_data.child = child;
- eh_dump (eh, &dump_data, _add_event_to_dict);
- return 0;
-}
-
-int
-_add_summary_to_dict (xlator_t *this, afr_crawl_data_t *crawl_data,
- gf_dirent_t *entry,
- loc_t *childloc, loc_t *parentloc, struct iatt *iattr)
-{
- dict_t *output = NULL;
- xlator_t *readdir_xl = NULL;
- int ret = -1;
- char *path = NULL;
-
- if (uuid_is_null (childloc->gfid))
- goto out;
-
- output = crawl_data->op_data;
- readdir_xl = crawl_data->readdir_xl;
-
- ret = _get_path_from_gfid_loc (this, readdir_xl, childloc, &path);
- if (ret)
- goto out;
-
- ret = _add_path_to_dict (this, output, crawl_data->child, path, NULL,
- _gf_true);
-out:
- if (ret && path)
- GF_FREE (path);
- return ret;
-}
-
-void
-_remove_stale_index (xlator_t *this, xlator_t *readdir_xl,
- loc_t *parent, char *fname)
-{
- int ret = 0;
- loc_t index_loc = {0};
-
- ret = _build_index_loc (this, &index_loc, fname, parent);
- if (ret)
- goto out;
- gf_log (this->name, GF_LOG_INFO, "Removing stale index "
- "for %s on %s", index_loc.name, readdir_xl->name);
- ret = syncop_unlink (readdir_xl, &index_loc);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Failed to remove"
- " index on %s - %s", index_loc.name,
- readdir_xl->name, strerror (errno));
- }
- index_loc.path = NULL;
- loc_wipe (&index_loc);
-out:
- return;
-}
-
-void
-_crawl_post_sh_action (xlator_t *this, loc_t *parent, loc_t *child,
- int32_t op_ret, int32_t op_errno, dict_t *xattr_rsp,
- afr_crawl_data_t *crawl_data)
-{
- int ret = 0;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- eh_t *eh = NULL;
- char *path = NULL;
- shd_event_t *event = NULL;
- int32_t sh_failed = 0;
- gf_boolean_t split_brain = 0;
-
- priv = this->private;
- shd = &priv->shd;
- if (crawl_data->crawl == INDEX) {
- if ((op_ret < 0) && (op_errno == ENOENT)) {
- _remove_stale_index (this, crawl_data->readdir_xl,
- parent, uuid_utoa (child->gfid));
- goto out;
- }
- ret = _get_path_from_gfid_loc (this, crawl_data->readdir_xl,
- child, &path);
- if (ret)
- goto out;
- } else {
- path = gf_strdup (child->path);
- if (!path) {
- ret = -1;
- goto out;
- }
- }
-
- if (xattr_rsp)
- ret = dict_get_int32 (xattr_rsp, "sh-failed", &sh_failed);
- split_brain = afr_is_split_brain (this, child->inode);
- if ((op_ret < 0 && op_errno == EIO) || split_brain)
- eh = shd->split_brain;
- else if ((op_ret < 0) || sh_failed)
- eh = shd->heal_failed;
- else
- eh = shd->healed;
- ret = -1;
- event = GF_CALLOC (1, sizeof (*event), gf_afr_mt_shd_event_t);
- if (!event)
- goto out;
- event->child = crawl_data->child;
- event->path = path;
- ret = eh_save_history (eh, event);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "%s:Failed to save to "
- "event history, (%d, %s)", path, op_ret, strerror (op_errno));
- goto out;
- }
- ret = 0;
-out:
- if (ret && path)
- GF_FREE (path);
- return;
-}
-
-int
-_self_heal_entry (xlator_t *this, afr_crawl_data_t *crawl_data, gf_dirent_t *entry,
- loc_t *child, loc_t *parent, struct iatt *iattr)
-{
- struct iatt parentbuf = {0};
- int ret = 0;
- dict_t *xattr_rsp = NULL;
-
- gf_log (this->name, GF_LOG_DEBUG, "lookup %s", child->path);
-
- ret = syncop_lookup (this, child, NULL,
- iattr, &xattr_rsp, &parentbuf);
- _crawl_post_sh_action (this, parent, child, ret, errno, xattr_rsp,
- crawl_data);
- if (xattr_rsp)
- dict_unref (xattr_rsp);
- return ret;
-}
-
-static int
-afr_crawl_done (int ret, call_frame_t *sync_frame, void *data)
-{
- GF_FREE (data);
- STACK_DESTROY (sync_frame->root);
- return 0;
-}
-
-void
-_do_self_heal_on_subvol (xlator_t *this, int child, afr_crawl_type_t crawl)
-{
- afr_start_crawl (this, child, crawl, _self_heal_entry,
- NULL, _gf_true, STOP_CRAWL_ON_SINGLE_SUBVOL,
- afr_crawl_done);
-}
-
-gf_boolean_t
-_crawl_proceed (xlator_t *this, int child, int crawl_flags, char **reason)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- gf_boolean_t proceed = _gf_false;
- char *msg = NULL;
-
- priv = this->private;
- shd = &priv->shd;
- if (!shd->enabled) {
- msg = "Self-heal daemon is not enabled";
- gf_log (this->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
- if (!priv->child_up[child]) {
- gf_log (this->name, GF_LOG_ERROR, "Stopping crawl for %s , "
- "subvol went down", priv->children[child]->name);
- msg = "Brick is Not connected";
- goto out;
- }
-
- if (crawl_flags & STOP_CRAWL_ON_SINGLE_SUBVOL) {
- if (afr_up_children_count (priv->child_up,
- priv->child_count) < 2) {
- gf_log (this->name, GF_LOG_ERROR, "Stopping crawl as "
- "< 2 children are up");
- msg = "< 2 bricks in replica are running";
- goto out;
- }
- }
- proceed = _gf_true;
-out:
- if (reason)
- *reason = msg;
- return proceed;
-}
-
-int
-_do_crawl_op_on_local_subvols (xlator_t *this, afr_crawl_type_t crawl,
- shd_crawl_op op, dict_t *output)
-{
- afr_private_t *priv = NULL;
- char *status = NULL;
- char *subkey = NULL;
- char key[256] = {0};
- shd_pos_t pos_data = {0};
- int op_ret = -1;
- int xl_id = -1;
- int i = 0;
- int ret = 0;
- int crawl_flags = 0;
-
- priv = this->private;
- if (op == HEAL)
- crawl_flags |= STOP_CRAWL_ON_SINGLE_SUBVOL;
-
- ret = dict_get_int32 (output, this->name, &xl_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid input, "
- "translator-id is not available");
- goto out;
- }
- pos_data.this = this;
- subkey = "status";
- for (i = 0; i < priv->child_count; i++) {
- if (_crawl_proceed (this, i, crawl_flags, &status)) {
- pos_data.child = i;
- ret = synctask_new (this->ctx->env,
- afr_syncop_find_child_position,
- NULL, NULL, &pos_data);
- if (ret) {
- status = "Not able to find brick location";
- } else if (pos_data.pos == AFR_POS_REMOTE) {
- status = "brick is remote";
- } else {
- op_ret = 0;
- if (op == HEAL) {
- status = "Started self-heal";
- _do_self_heal_on_subvol (this, i,
- crawl);
- } else {
- status = "";
- afr_start_crawl (this, i, INDEX,
- _add_summary_to_dict,
- output, _gf_false, 0,
- NULL);
- }
- }
- snprintf (key, sizeof (key), "%d-%d-%s", xl_id,
- i, subkey);
- ret = dict_set_str (output, key, status);
- if (!op_ret && (crawl == FULL))
- break;
- }
- snprintf (key, sizeof (key), "%d-%d-%s", xl_id, i, subkey);
- ret = dict_set_str (output, key, status);
- }
-out:
- return op_ret;
-}
-
-int
-_do_self_heal_on_local_subvols (xlator_t *this, afr_crawl_type_t crawl,
- dict_t *output)
-{
- return _do_crawl_op_on_local_subvols (this, crawl, HEAL, output);
-}
-
-int
-_get_index_summary_on_local_subvols (xlator_t *this, dict_t *output)
-{
- return _do_crawl_op_on_local_subvols (this, INDEX, INFO, output);
-}
-
-int
-_add_all_subvols_eh_to_dict (xlator_t *this, eh_t *eh, dict_t *dict)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- int i = 0;
-
- priv = this->private;
- shd = &priv->shd;
-
- for (i = 0; i < priv->child_count; i++) {
- if (shd->pos[i] != AFR_POS_LOCAL)
- continue;
- _add_eh_to_dict (this, eh, dict, i);
- }
- return 0;
-}
-
-int
-afr_xl_op (xlator_t *this, dict_t *input, dict_t *output)
-{
- gf_xl_afr_op_t op = GF_AFR_OP_INVALID;
- int ret = 0;
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- int xl_id = 0;
-
- priv = this->private;
- shd = &priv->shd;
-
- ret = dict_get_int32 (input, "xl-op", (int32_t*)&op);
- if (ret)
- goto out;
- ret = dict_get_int32 (input, this->name, &xl_id);
- if (ret)
- goto out;
- ret = dict_set_int32 (output, this->name, xl_id);
- if (ret)
- goto out;
- switch (op) {
- case GF_AFR_OP_HEAL_INDEX:
- ret = _do_self_heal_on_local_subvols (this, INDEX, output);
- break;
- case GF_AFR_OP_HEAL_FULL:
- ret = _do_self_heal_on_local_subvols (this, FULL, output);
- break;
- case GF_AFR_OP_INDEX_SUMMARY:
- (void)_get_index_summary_on_local_subvols (this, output);
- ret = 0;
- break;
- case GF_AFR_OP_HEALED_FILES:
- ret = _add_all_subvols_eh_to_dict (this, shd->healed, output);
- break;
- case GF_AFR_OP_HEAL_FAILED_FILES:
- ret = _add_all_subvols_eh_to_dict (this, shd->heal_failed,
- output);
- break;
- case GF_AFR_OP_SPLIT_BRAIN_FILES:
- ret = _add_all_subvols_eh_to_dict (this, shd->split_brain,
- output);
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR, "Unknown set op %d", op);
- break;
- }
-out:
- dict_del (output, this->name);
- return ret;
-}
-
-void
-afr_poll_self_heal (void *data)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- struct timeval timeout = {0};
- xlator_t *this = NULL;
- long child = (long)data;
- gf_timer_t *old_timer = NULL;
- gf_timer_t *new_timer = NULL;
- shd_pos_t pos_data = {0};
- int ret = 0;
-
- this = THIS;
- priv = this->private;
- shd = &priv->shd;
-
- if (shd->pos[child] == AFR_POS_UNKNOWN) {
- pos_data.this = this;
- pos_data.child = child;
- ret = synctask_new (this->ctx->env,
- afr_syncop_find_child_position,
- NULL, NULL, &pos_data);
- if (!ret)
- shd->pos[child] = pos_data.pos;
- }
- if (shd->enabled && (shd->pos[child] == AFR_POS_LOCAL))
- _do_self_heal_on_subvol (this, child, INDEX);
- timeout.tv_sec = shd->timeout;
- timeout.tv_usec = 0;
- //notify and previous timer should be synchronized.
- LOCK (&priv->lock);
- {
- old_timer = shd->timer[child];
- if (shd->pos[child] == AFR_POS_REMOTE)
- goto unlock;
- shd->timer[child] = gf_timer_call_after (this->ctx, timeout,
- afr_poll_self_heal,
- data);
- new_timer = shd->timer[child];
- }
-unlock:
- UNLOCK (&priv->lock);
-
- if (old_timer)
- gf_timer_call_cancel (this->ctx, old_timer);
- if (!new_timer && (shd->pos[child] != AFR_POS_REMOTE)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Could not create self-heal polling timer for %s",
- priv->children[child]->name);
- }
- return;
-}
-
-static int
-afr_local_child_poll_self_heal (int ret, call_frame_t *sync_frame, void *data)
-{
- afr_self_heald_t *shd = NULL;
- shd_pos_t *pos_data = data;
- afr_private_t *priv = NULL;
-
- if (ret)
- goto out;
-
- priv = pos_data->this->private;
- shd = &priv->shd;
- shd->pos[pos_data->child] = pos_data->pos;
- if (pos_data->pos != AFR_POS_REMOTE)
- afr_poll_self_heal ((void*)(long)pos_data->child);
-out:
- GF_FREE (data);
- return 0;
-}
-
-void
-afr_proactive_self_heal (void *data)
-{
- xlator_t *this = NULL;
- long child = (long)data;
- shd_pos_t *pos_data = NULL;
- int ret = 0;
-
- this = THIS;
-
- //Position of brick could have changed and it could be local now.
- //Compute the position again
- pos_data = GF_CALLOC (1, sizeof (*pos_data), gf_afr_mt_pos_data_t);
- if (!pos_data)
- goto out;
- pos_data->this = this;
- pos_data->child = child;
- ret = synctask_new (this->ctx->env, afr_syncop_find_child_position,
- afr_local_child_poll_self_heal, NULL, pos_data);
- if (ret)
- goto out;
-out:
- return;
-}
-
-static int
-get_pathinfo_host (char *pathinfo, char *hostname, size_t size)
-{
- char *start = NULL;
- char *end = NULL;
- int ret = -1;
- int i = 0;
-
- if (!pathinfo)
- goto out;
-
- start = strchr (pathinfo, ':');
- if (!start)
- goto out;
- end = strrchr (pathinfo, ':');
- if (start == end)
- goto out;
-
- memset (hostname, 0, size);
- i = 0;
- while (++start != end)
- hostname[i++] = *start;
- ret = 0;
-out:
- return ret;
-}
-
-int
-_link_inode_update_loc (xlator_t *this, loc_t *loc, struct iatt *iattr)
-{
- inode_t *link_inode = NULL;
- int ret = -1;
-
- link_inode = inode_link (loc->inode, NULL, NULL, iattr);
- if (link_inode == NULL) {
- gf_log (this->name, GF_LOG_ERROR, "inode link failed "
- "on the inode (%s)", uuid_utoa (iattr->ia_gfid));
- goto out;
- }
- inode_unref (loc->inode);
- loc->inode = link_inode;
- ret = 0;
-out:
- return ret;
-}
-
-int
-afr_local_pathinfo (char *pathinfo, gf_boolean_t *local)
-{
- int ret = 0;
- char pathinfohost[1024] = {0};
- char localhost[1024] = {0};
- xlator_t *this = THIS;
-
- *local = _gf_false;
- ret = get_pathinfo_host (pathinfo, pathinfohost, sizeof (pathinfohost));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid pathinfo: %s",
- pathinfo);
- goto out;
- }
-
- ret = gethostname (localhost, sizeof (localhost));
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "gethostname() failed, "
- "reason: %s", strerror (errno));
- goto out;
- }
-
- if (!strcmp (localhost, pathinfohost))
- *local = _gf_true;
-out:
- return ret;
-}
-
-int
-afr_crawl_build_start_loc (xlator_t *this, afr_crawl_data_t *crawl_data,
- loc_t *dirloc)
-{
- afr_private_t *priv = NULL;
- dict_t *xattr = NULL;
- void *index_gfid = NULL;
- loc_t rootloc = {0};
- struct iatt iattr = {0};
- struct iatt parent = {0};
- int ret = 0;
- xlator_t *readdir_xl = crawl_data->readdir_xl;
-
- priv = this->private;
- if (crawl_data->crawl == FULL) {
- afr_build_root_loc (this, dirloc);
- } else {
- afr_build_root_loc (this, &rootloc);
- ret = syncop_getxattr (readdir_xl, &rootloc, &xattr,
- GF_XATTROP_INDEX_GFID);
- if (ret < 0)
- goto out;
- ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get index "
- "dir gfid on %s", readdir_xl->name);
- goto out;
- }
- if (!index_gfid) {
- gf_log (this->name, GF_LOG_ERROR, "index gfid empty "
- "on %s", readdir_xl->name);
- ret = -1;
- goto out;
- }
- uuid_copy (dirloc->gfid, index_gfid);
- dirloc->path = "";
- dirloc->inode = inode_new (priv->root_inode->table);
- ret = syncop_lookup (readdir_xl, dirloc, NULL,
- &iattr, NULL, &parent);
- if (ret < 0) {
- if (errno != ENOENT) {
- gf_log (this->name, GF_LOG_ERROR, "lookup "
- "failed on index dir on %s - (%s)",
- readdir_xl->name, strerror (errno));
- }
- goto out;
- }
- ret = _link_inode_update_loc (this, dirloc, &iattr);
- if (ret)
- goto out;
- }
- ret = 0;
-out:
- if (xattr)
- dict_unref (xattr);
- loc_wipe (&rootloc);
- return ret;
-}
-
-int
-afr_crawl_opendir (xlator_t *this, afr_crawl_data_t *crawl_data, fd_t **dirfd,
- loc_t *dirloc)
-{
- fd_t *fd = NULL;
- int ret = 0;
-
- if (crawl_data->crawl == FULL) {
- fd = fd_create (dirloc->inode, crawl_data->pid);
- if (!fd) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to create fd for %s", dirloc->path);
- ret = -1;
- goto out;
- }
-
- ret = syncop_opendir (crawl_data->readdir_xl, dirloc, fd);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "opendir failed on %s", dirloc->path);
- goto out;
- }
- } else {
- fd = fd_anonymous (dirloc->inode);
- }
- ret = 0;
-out:
- if (!ret)
- *dirfd = fd;
- return ret;
-}
-
-xlator_t*
-afr_crawl_readdir_xl_get (xlator_t *this, afr_crawl_data_t *crawl_data)
-{
- afr_private_t *priv = this->private;
-
- if (crawl_data->crawl == FULL) {
- return this;
- } else {
- return priv->children[crawl_data->child];
- }
- return NULL;
-}
-
-int
-afr_crawl_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent,
- gf_dirent_t *entry, afr_crawl_data_t *crawl_data)
-{
- int ret = -1;
- afr_private_t *priv = NULL;
-
- priv = this->private;
- if (crawl_data->crawl == FULL) {
- ret = afr_build_child_loc (this, child, parent, entry->d_name);
- } else {
- child->inode = inode_new (priv->root_inode->table);
- if (!child->inode)
- goto out;
- uuid_parse (entry->d_name, child->gfid);
- ret = _loc_assign_gfid_path (child);
- }
-out:
- return ret;
-}
-
-static int
-_process_entries (xlator_t *this, loc_t *parentloc, gf_dirent_t *entries,
- off_t *offset, afr_crawl_data_t *crawl_data)
-{
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- int ret = 0;
- loc_t entry_loc = {0};
- fd_t *fd = NULL;
- struct iatt iattr = {0};
-
- list_for_each_entry_safe (entry, tmp, &entries->list, list) {
- if (!_crawl_proceed (this, crawl_data->child,
- crawl_data->crawl_flags, NULL)) {
- ret = -1;
- goto out;
- }
- *offset = entry->d_off;
- if (IS_ENTRY_CWD (entry->d_name) ||
- IS_ENTRY_PARENT (entry->d_name))
- continue;
- if ((crawl_data->crawl == FULL) &&
- uuid_is_null (entry->d_stat.ia_gfid)) {
- gf_log (this->name, GF_LOG_WARNING, "%s/%s: No "
- "gfid present skipping",
- parentloc->path, entry->d_name);
- continue;
- }
-
- loc_wipe (&entry_loc);
- ret = afr_crawl_build_child_loc (this, &entry_loc, parentloc,
- entry, crawl_data);
- if (ret)
- goto out;
-
- ret = crawl_data->process_entry (this, crawl_data, entry,
- &entry_loc, parentloc, &iattr);
-
- if (ret)
- continue;
-
- ret = _link_inode_update_loc (this, &entry_loc, &iattr);
- if (ret)
- goto out;
- if (crawl_data->crawl == INDEX)
- continue;
-
- if (!IA_ISDIR (iattr.ia_type))
- continue;
- fd = NULL;
- ret = afr_crawl_opendir (this, crawl_data, &fd, &entry_loc);
- if (ret)
- continue;
- ret = _crawl_directory (fd, &entry_loc, crawl_data);
- if (fd)
- fd_unref (fd);
- }
- ret = 0;
-out:
- loc_wipe (&entry_loc);
- return ret;
-}
-
-static int
-_crawl_directory (fd_t *fd, loc_t *loc, afr_crawl_data_t *crawl_data)
-{
- xlator_t *this = NULL;
- off_t offset = 0;
- gf_dirent_t entries;
- int ret = 0;
- gf_boolean_t free_entries = _gf_false;
- xlator_t *readdir_xl = crawl_data->readdir_xl;
-
- INIT_LIST_HEAD (&entries.list);
- this = THIS;
-
- GF_ASSERT (loc->inode);
-
- if (crawl_data->crawl == FULL)
- gf_log (this->name, GF_LOG_DEBUG, "crawling %s", loc->path);
- else
- gf_log (this->name, GF_LOG_DEBUG, "crawling INDEX %s",
- uuid_utoa (loc->gfid));
-
- while (1) {
- if (crawl_data->crawl == FULL)
- ret = syncop_readdirp (readdir_xl, fd, 131072, offset,
- NULL, &entries);
- else
- ret = syncop_readdir (readdir_xl, fd, 131072, offset,
- &entries);
- if (ret <= 0)
- break;
- ret = 0;
- free_entries = _gf_true;
-
- if (!_crawl_proceed (this, crawl_data->child,
- crawl_data->crawl_flags, NULL)) {
- ret = -1;
- goto out;
- }
- if (list_empty (&entries.list))
- goto out;
-
- ret = _process_entries (this, loc, &entries, &offset,
- crawl_data);
- gf_dirent_free (&entries);
- free_entries = _gf_false;
- }
- ret = 0;
-out:
- if (free_entries)
- gf_dirent_free (&entries);
- return ret;
-}
-
-static char*
-position_str_get (afr_child_pos_t pos)
-{
- switch (pos) {
- case AFR_POS_UNKNOWN:
- return "unknown";
- case AFR_POS_LOCAL:
- return "local";
- case AFR_POS_REMOTE:
- return "remote";
- }
- return NULL;
-}
-
-int
-afr_find_child_position (xlator_t *this, int child, afr_child_pos_t *pos)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- dict_t *xattr_rsp = NULL;
- loc_t loc = {0};
- int ret = 0;
- char *node_uuid = NULL;
-
- priv = this->private;
- shd = &priv->shd;
-
- afr_build_root_loc (this, &loc);
-
- ret = syncop_getxattr (priv->children[child], &loc, &xattr_rsp,
- GF_XATTR_NODE_UUID_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "getxattr failed on %s - "
- "(%s)", priv->children[child]->name, strerror (errno));
- goto out;
- }
-
- ret = dict_get_str (xattr_rsp, GF_XATTR_NODE_UUID_KEY, &node_uuid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "node-uuid key not found on "
- "child %s", priv->children[child]->name);
- goto out;
- }
-
- if (!strcmp (node_uuid, shd->node_uuid))
- *pos = AFR_POS_LOCAL;
- else
- *pos = AFR_POS_REMOTE;
-
- gf_log (this->name, GF_LOG_DEBUG, "child %s is %s",
- priv->children[child]->name, position_str_get (*pos));
-out:
- if (ret)
- *pos = AFR_POS_UNKNOWN;
- loc_wipe (&loc);
- return ret;
-}
-
-int
-afr_syncop_find_child_position (void *data)
-{
- shd_pos_t *pos_data = data;
- int ret = 0;
-
- ret = afr_find_child_position (pos_data->this, pos_data->child,
- &pos_data->pos);
- return ret;
-}
-
-static int
-afr_dir_crawl (void *data)
-{
- xlator_t *this = NULL;
- int ret = -1;
- xlator_t *readdir_xl = NULL;
- fd_t *fd = NULL;
- loc_t dirloc = {0};
- afr_crawl_data_t *crawl_data = data;
-
- this = THIS;
-
- if (!_crawl_proceed (this, crawl_data->child, crawl_data->crawl_flags,
- NULL))
- goto out;
-
- readdir_xl = afr_crawl_readdir_xl_get (this, crawl_data);
- if (!readdir_xl)
- goto out;
- crawl_data->readdir_xl = readdir_xl;
-
- ret = afr_crawl_build_start_loc (this, crawl_data, &dirloc);
- if (ret)
- goto out;
-
- ret = afr_crawl_opendir (this, crawl_data, &fd, &dirloc);
- if (ret)
- goto out;
-
- ret = _crawl_directory (fd, &dirloc, crawl_data);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Crawl failed on %s",
- readdir_xl->name);
- else
- gf_log (this->name, GF_LOG_DEBUG, "Crawl completed "
- "on %s", readdir_xl->name);
- if (crawl_data->crawl == INDEX)
- dirloc.path = NULL;
-out:
- if (fd)
- fd_unref (fd);
- if (crawl_data->crawl == INDEX)
- dirloc.path = NULL;
- loc_wipe (&dirloc);
- return ret;
-}
-
-static int
-afr_dir_exclusive_crawl (void *data)
-{
- afr_private_t *priv = NULL;
- afr_self_heald_t *shd = NULL;
- gf_boolean_t crawl = _gf_false;
- int ret = 0;
- int child = -1;
- xlator_t *this = NULL;
- afr_crawl_data_t *crawl_data = data;
-
- this = THIS;
- priv = this->private;
- shd = &priv->shd;
- child = crawl_data->child;
-
- LOCK (&priv->lock);
- {
- if (shd->inprogress[child]) {
- if (shd->pending[child] != FULL)
- shd->pending[child] = crawl_data->crawl;
- } else {
- shd->inprogress[child] = _gf_true;
- crawl = _gf_true;
- }
- }
- UNLOCK (&priv->lock);
-
- if (!crawl) {
- gf_log (this->name, GF_LOG_INFO, "Another crawl is in progress "
- "for %s", priv->children[child]->name);
- goto out;
- }
-
- do {
- afr_dir_crawl (data);
- LOCK (&priv->lock);
- {
- if (shd->pending[child] != NONE) {
- crawl_data->crawl = shd->pending[child];
- shd->pending[child] = NONE;
- } else {
- shd->inprogress[child] = _gf_false;
- crawl = _gf_false;
- }
- }
- UNLOCK (&priv->lock);
- } while (crawl);
-out:
- return ret;
-}
-
-void
-afr_start_crawl (xlator_t *this, int idx, afr_crawl_type_t crawl,
- process_entry_cbk_t process_entry, void *op_data,
- gf_boolean_t exclusive, int crawl_flags,
- afr_crawl_done_cbk_t crawl_done)
-{
- afr_private_t *priv = NULL;
- call_frame_t *frame = NULL;
- afr_crawl_data_t *crawl_data = NULL;
- int ret = 0;
- int (*crawler) (void*) = NULL;
-
- priv = this->private;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- afr_set_lk_owner (frame, this, frame->root);
- afr_set_low_priority (frame);
- crawl_data = GF_CALLOC (1, sizeof (*crawl_data),
- gf_afr_mt_crawl_data_t);
- if (!crawl_data)
- goto out;
- crawl_data->process_entry = process_entry;
- crawl_data->child = idx;
- crawl_data->pid = frame->root->pid;
- crawl_data->crawl = crawl;
- crawl_data->op_data = op_data;
- crawl_data->crawl_flags = crawl_flags;
- gf_log (this->name, GF_LOG_DEBUG, "starting crawl %d for %s",
- crawl_data->crawl, priv->children[idx]->name);
-
- if (exclusive)
- crawler = afr_dir_exclusive_crawl;
- else
- crawler = afr_dir_crawl;
- ret = synctask_new (this->ctx->env, crawler,
- crawl_done, frame, crawl_data);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Could not create the "
- "task for %d ret %d", idx, ret);
-out:
- return;
-}
-
-void
-afr_build_root_loc (xlator_t *this, loc_t *loc)
-{
- afr_private_t *priv = NULL;
-
- priv = this->private;
- loc->path = gf_strdup ("/");
- loc->name = "";
- loc->inode = inode_ref (priv->root_inode);
- uuid_copy (loc->gfid, loc->inode->gfid);
-}
-
-int
-afr_set_root_gfid (dict_t *dict)
-{
- uuid_t gfid;
- int ret = 0;
-
- memset (gfid, 0, 16);
- gfid[15] = 1;
-
- ret = afr_set_dict_gfid (dict, gfid);
-
- return ret;
-}
-
diff --git a/xlators/cluster/afr/src/afr-self-heald.h b/xlators/cluster/afr/src/afr-self-heald.h
deleted file mode 100644
index 32a8aaca5..000000000
--- a/xlators/cluster/afr/src/afr-self-heald.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef __AFR_SELF_HEALD_H__
-#define __AFR_SELF_HEALD_H__
-#include "xlator.h"
-
-#define IS_ROOT_PATH(path) (!strcmp (path, "/"))
-#define IS_ENTRY_CWD(entry) (!strcmp (entry, "."))
-#define IS_ENTRY_PARENT(entry) (!strcmp (entry, ".."))
-#define AFR_ALL_CHILDREN -1
-
-typedef struct afr_crawl_data_ {
- int child;
- pid_t pid;
- afr_crawl_type_t crawl;
- xlator_t *readdir_xl;
- void *op_data;
- int crawl_flags;
- int (*process_entry) (xlator_t *this, struct afr_crawl_data_ *crawl_data,
- gf_dirent_t *entry, loc_t *child, loc_t *parent,
- struct iatt *iattr);
-} afr_crawl_data_t;
-
-typedef int (*process_entry_cbk_t) (xlator_t *this, afr_crawl_data_t *crawl_data,
- gf_dirent_t *entry, loc_t *child, loc_t *parent,
- struct iatt *iattr);
-
-void afr_build_root_loc (xlator_t *this, loc_t *loc);
-
-int afr_set_root_gfid (dict_t *dict);
-
-void
-afr_proactive_self_heal (void *data);
-
-int
-afr_xl_op (xlator_t *this, dict_t *input, dict_t *output);
-
-/*
- * In addition to its self-heal use, this is used to find a local default
- * read_child.
- */
-int
-afr_local_pathinfo (char *pathinfo, gf_boolean_t *local);
-#endif /* __AFR_SELF_HEALD_H__ */
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 2144f483f..7652d3d1e 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -1,17 +1,25 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include "dict.h"
#include "byte-order.h"
#include "common-utils.h"
-#include "timer.h"
#include "afr.h"
#include "afr-transaction.h"
@@ -24,73 +32,45 @@
of RENAME */
#define LOCKED_LOWER 0x2 /* for lower_path of RENAME */
+
afr_fd_ctx_t *
-__afr_fd_ctx_get (fd_t *fd, xlator_t *this)
+afr_fd_ctx_get (fd_t *fd, xlator_t *this)
{
uint64_t ctx = 0;
- int ret = 0;
afr_fd_ctx_t *fd_ctx = NULL;
- int i = 0;
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- ret = __fd_ctx_get (fd, this, &ctx);
-
- if (ret < 0 && fd_is_anonymous (fd)) {
- ret = __afr_fd_ctx_set (this, fd);
- if (ret < 0)
- goto out;
+ int ret = 0;
- ret = __fd_ctx_get (fd, this, &ctx);
- if (ret < 0)
- goto out;
+ ret = fd_ctx_get (fd, this, &ctx);
- fd_ctx = (afr_fd_ctx_t *)(long) ctx;
- for (i = 0; i < priv->child_count; i++)
- fd_ctx->opened_on[i] = AFR_FD_OPENED;
- }
+ if (ret < 0)
+ goto out;
fd_ctx = (afr_fd_ctx_t *)(long) ctx;
-out:
- return fd_ctx;
-}
-
-
-afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this)
-{
- afr_fd_ctx_t *fd_ctx = NULL;
-
- LOCK(&fd->lock);
- {
- fd_ctx = __afr_fd_ctx_get (fd, this);
- }
- UNLOCK(&fd->lock);
+out:
return fd_ctx;
}
static void
-afr_save_lk_owner (call_frame_t *frame)
+afr_pid_save (call_frame_t *frame)
{
afr_local_t * local = NULL;
local = frame->local;
- local->saved_lk_owner = frame->root->lk_owner;
+ local->saved_pid = frame->root->pid;
}
static void
-afr_restore_lk_owner (call_frame_t *frame)
+afr_pid_restore (call_frame_t *frame)
{
afr_local_t * local = NULL;
local = frame->local;
- frame->root->lk_owner = local->saved_lk_owner;
+ frame->root->pid = local->saved_pid;
}
@@ -235,7 +215,39 @@ __changelog_enabled (afr_private_t *priv, afr_transaction_type type)
static int
-__fop_changelog_needed (call_frame_t *frame, xlator_t *this)
+__changelog_needed_pre_op (call_frame_t *frame, xlator_t *this)
+{
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+
+ int op_ret = 0;
+
+ priv = this->private;
+ local = frame->local;
+
+ if (__changelog_enabled (priv, local->transaction.type)) {
+ switch (local->op) {
+
+ case GF_FOP_WRITE:
+ case GF_FOP_FTRUNCATE:
+ op_ret = 1;
+ break;
+
+ case GF_FOP_FLUSH:
+ op_ret = 0;
+ break;
+
+ default:
+ op_ret = 1;
+ }
+ }
+
+ return op_ret;
+}
+
+
+static int
+__changelog_needed_post_op (call_frame_t *frame, xlator_t *this)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
@@ -266,42 +278,64 @@ __fop_changelog_needed (call_frame_t *frame, xlator_t *this)
return op_ret;
}
-int
-afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending,
- int child, afr_xattrop_type_t op)
+
+static int
+afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending)
{
int i = 0;
int ret = 0;
- if (op == LOCAL_FIRST) {
- ret = dict_set_static_bin (xattr, priv->pending_key[child],
- pending[child],
- AFR_NUM_CHANGE_LOGS * sizeof (int32_t));
- if (ret)
- goto out;
- }
for (i = 0; i < priv->child_count; i++) {
- if (i == child)
- continue;
ret = dict_set_static_bin (xattr, priv->pending_key[i],
- pending[i],
- AFR_NUM_CHANGE_LOGS * sizeof (int32_t));
+ pending[i], 3 * sizeof (int32_t));
/* 3 = data+metadata+entry */
if (ret < 0)
goto out;
}
- if (op == LOCAL_LAST) {
- ret = dict_set_static_bin (xattr, priv->pending_key[child],
- pending[child],
- AFR_NUM_CHANGE_LOGS * sizeof (int32_t));
- if (ret)
+
+out:
+ return ret;
+}
+
+
+static int
+afr_set_piggyback_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending,
+ afr_transaction_type type)
+{
+ int i = 0;
+ int ret = 0;
+ int *arr = NULL;
+ int index = 0;
+ size_t pending_xattr_size = 3 * sizeof (int32_t);
+ /* 3 = data+metadata+entry */
+
+ index = afr_index_for_transaction_type (type);
+
+ for (i = 0; i < priv->child_count; i++) {
+ arr = GF_CALLOC (1, pending_xattr_size,
+ gf_afr_mt_char);
+ if (!arr) {
+ ret = -1;
+ goto out;
+ }
+
+ memcpy (arr, pending[i], pending_xattr_size);
+
+ arr[index]++;
+
+ ret = dict_set_bin (xattr, priv->pending_key[i],
+ arr, pending_xattr_size);
+
+ if (ret < 0)
goto out;
}
+
out:
return ret;
}
+
int
afr_lock_server_count (afr_private_t *priv, afr_transaction_type type)
{
@@ -329,18 +363,27 @@ afr_lock_server_count (afr_private_t *priv, afr_transaction_type type)
int32_t
afr_changelog_post_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
afr_internal_lock_t *int_lock = NULL;
afr_private_t *priv = NULL;
afr_local_t *local = NULL;
+ int child_index = 0;
int call_count = -1;
priv = this->private;
local = frame->local;
int_lock = &local->internal_lock;
+ child_index = (long) cookie;
+
+ if (op_ret == 1) {
+ }
+
+ if (op_ret == 0) {
+ __mark_pre_op_undone_on_fd (frame, this, child_index);
+ }
+
LOCK (&frame->lock);
{
call_count = --local->call_count;
@@ -361,172 +404,55 @@ afr_changelog_post_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
void
-afr_transaction_rm_stale_children (call_frame_t *frame, xlator_t *this,
- inode_t *inode, afr_transaction_type type)
+afr_update_read_child (call_frame_t *frame, xlator_t *this, inode_t *inode,
+ afr_transaction_type type)
{
- int i = -1;
- int count = 0;
- int read_child = -1;
+ int curr_read_child = -1;
+ int new_read_child = -1;
afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- int **pending = NULL;
- int idx = 0;
- int32_t *stale_children = NULL;
- int32_t *fresh_children = NULL;
- gf_boolean_t rm_stale_children = _gf_false;
+ afr_local_t *local = NULL;
+ int **pending = NULL;
+ int idx = 0;
idx = afr_index_for_transaction_type (type);
priv = this->private;
local = frame->local;
+ curr_read_child = afr_read_child (this, inode);
pending = local->pending;
- if (local->op_ret < 0)
- goto out;
- fresh_children = local->fresh_children;
- read_child = afr_inode_get_read_ctx (this, inode, fresh_children);
- if (read_child < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "Possible split-brain "
- "for %s", uuid_utoa (inode->gfid));
- goto out;
- }
-
- for (i = 0; i < priv->child_count; i++) {
- if (!afr_is_child_present (fresh_children,
- priv->child_count, i))
- continue;
- if (pending[i][idx])
- continue;
- /* child is down or op failed on it */
- if (!stale_children)
- stale_children = afr_children_create (priv->child_count);
- if (!stale_children)
- goto out;
-
- rm_stale_children = _gf_true;
- stale_children[count++] = i;
- gf_log (this->name, GF_LOG_DEBUG, "Removing stale child "
- "%d for %s", i, uuid_utoa (inode->gfid));
- }
-
- if (!rm_stale_children)
- goto out;
-
- afr_inode_rm_stale_children (this, inode, stale_children);
-out:
- GF_FREE (stale_children);
- return;
-}
-
-unsigned char*
-afr_locked_nodes_get (afr_transaction_type type, afr_internal_lock_t *int_lock)
-{
- unsigned char *locked_nodes = NULL;
- switch (type) {
- case AFR_DATA_TRANSACTION:
- case AFR_METADATA_TRANSACTION:
- locked_nodes = int_lock->inode_locked_nodes;
- break;
-
- case AFR_ENTRY_TRANSACTION:
- case AFR_ENTRY_RENAME_TRANSACTION:
- locked_nodes = int_lock->entry_locked_nodes;
- break;
- }
- return locked_nodes;
-}
-
-int
-afr_changelog_pre_op_call_count (afr_transaction_type type,
- afr_internal_lock_t *int_lock,
- unsigned int child_count)
-{
- int call_count = 0;
- unsigned char *locked_nodes = NULL;
-
- locked_nodes = afr_locked_nodes_get (type, int_lock);
- GF_ASSERT (locked_nodes);
-
- call_count = afr_locked_children_count (locked_nodes, child_count);
- if (type == AFR_ENTRY_RENAME_TRANSACTION)
- call_count *= 2;
-
- return call_count;
-}
-
-int
-afr_changelog_post_op_call_count (afr_transaction_type type,
- unsigned char *pre_op,
- unsigned int child_count)
-{
- int call_count = 0;
+ if (pending[curr_read_child][idx] != 0)
+ return;
- call_count = afr_pre_op_done_children_count (pre_op, child_count);
- if (type == AFR_ENTRY_RENAME_TRANSACTION)
- call_count *= 2;
+ /* need to set new read_child */
+ for (new_read_child = 0; new_read_child < priv->child_count;
+ new_read_child++) {
- return call_count;
-}
+ if (!priv->child_up[new_read_child])
+ /* child is down */
+ continue;
-void
-afr_compute_txn_changelog (afr_local_t *local, afr_private_t *priv)
-{
- int i = 0;
- int index = 0;
- int32_t postop = 0;
- int32_t preop = 1;
- int32_t **txn_changelog = NULL;
+ if (pending[new_read_child][idx] == 0)
+ /* op just failed */
+ continue;
- txn_changelog = local->transaction.txn_changelog;
- index = afr_index_for_transaction_type (local->transaction.type);
- for (i = 0; i < priv->child_count; i++) {
- postop = ntoh32 (local->pending[i][index]);
- txn_changelog[i][index] = hton32 (postop + preop);
+ break;
}
-}
-afr_xattrop_type_t
-afr_get_postop_xattrop_type (int32_t **pending, int optimized, int child,
- afr_transaction_type type)
-{
- int index = 0;
- afr_xattrop_type_t op = LOCAL_LAST;
+ if (new_read_child == priv->child_count)
+ /* all children uneligible. leave as-is */
+ return;
- index = afr_index_for_transaction_type (type);
- if (optimized && !pending[child][index])
- op = LOCAL_FIRST;
- return op;
+ afr_set_read_child (this, inode, new_read_child);
}
-void
-afr_set_postop_dict (afr_local_t *local, xlator_t *this, dict_t *xattr,
- int optimized, int child)
-{
- int32_t **txn_changelog = NULL;
- int32_t **changelog = NULL;
- afr_private_t *priv = NULL;
- int ret = 0;
- afr_xattrop_type_t op = LOCAL_LAST;
-
- priv = this->private;
- txn_changelog = local->transaction.txn_changelog;
- op = afr_get_postop_xattrop_type (local->pending, optimized, child,
- local->transaction.type);
- if (optimized)
- changelog = txn_changelog;
- else
- changelog = local->pending;
- ret = afr_set_pending_dict (priv, xattr, changelog, child, op);
- if (ret < 0)
- gf_log (this->name, GF_LOG_INFO,
- "failed to set pending entry");
-}
int
-afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
+afr_changelog_post_op (call_frame_t *frame, xlator_t *this)
{
afr_private_t * priv = this->private;
afr_internal_lock_t *int_lock = NULL;
+ int ret = 0;
int i = 0;
int call_count = 0;
@@ -544,19 +470,22 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
local->child_up, local->transaction.type);
if (local->fd)
- afr_transaction_rm_stale_children (frame, this,
- local->fd->inode,
- local->transaction.type);
+ afr_update_read_child (frame, this, local->fd->inode,
+ local->transaction.type);
xattr = alloca (priv->child_count * sizeof (*xattr));
memset (xattr, 0, (priv->child_count * sizeof (*xattr)));
for (i = 0; i < priv->child_count; i++) {
- xattr[i] = dict_new ();
+ xattr[i] = get_new_dict ();
+ dict_ref (xattr[i]);
+ }
+
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
+
+ if (local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) {
+ call_count *= 2;
}
- call_count = afr_changelog_post_op_call_count (local->transaction.type,
- local->transaction.pre_op,
- priv->child_count);
local->call_count = call_count;
if (local->fd)
@@ -564,9 +493,13 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
if (call_count == 0) {
/* no child is up */
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
+ }
+
int_lock->lock_cbk = local->transaction.done;
afr_unlock (frame, this);
- goto out;
+ return 0;
}
/* check if something has failed, to handle piggybacking */
@@ -579,27 +512,35 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
}
}
- afr_compute_txn_changelog (local , priv);
+ index = afr_index_for_transaction_type (local->transaction.type);
+ if (local->optimistic_change_log &&
+ local->transaction.type != AFR_DATA_TRANSACTION) {
+ /* if nothing_failed, then local->pending[..] == {0 .. 0} */
+ for (i = 0; i < priv->child_count; i++)
+ local->pending[i][index]++;
+ }
for (i = 0; i < priv->child_count; i++) {
- if (!local->transaction.pre_op[i])
+ if (!local->child_up[i])
continue;
- if (local->transaction.type != AFR_DATA_TRANSACTION)
- afr_set_postop_dict (local, this, xattr[i],
- local->optimistic_change_log, i);
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
+
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_INFO,
+ "failed to set pending entry");
+
+
switch (local->transaction.type) {
case AFR_DATA_TRANSACTION:
{
if (!fdctx) {
- afr_set_postop_dict (local, this, xattr[i],
- 0, i);
STACK_WIND (frame, afr_changelog_post_op_cbk,
priv->children[i],
priv->children[i]->fops->xattrop,
&local->loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
break;
}
@@ -613,31 +554,30 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
}
UNLOCK (&local->fd->lock);
- afr_set_postop_dict (local, this, xattr[i],
- piggyback, i);
+ if (piggyback && !nothing_failed)
+ ret = afr_set_piggyback_dict (priv, xattr[i],
+ local->pending,
+ local->transaction.type);
if (nothing_failed && piggyback) {
afr_changelog_post_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i], NULL);
+ this, 1, 0, xattr[i]);
} else {
- __mark_pre_op_undone_on_fd (frame, this, i);
STACK_WIND_COOKIE (frame,
afr_changelog_post_op_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
}
break;
case AFR_METADATA_TRANSACTION:
{
- if (nothing_failed && local->optimistic_change_log) {
+ if (nothing_failed) {
afr_changelog_post_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
break;
}
@@ -646,32 +586,28 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
else
STACK_WIND (frame, afr_changelog_post_op_cbk,
priv->children[i],
priv->children[i]->fops->xattrop,
&local->loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
break;
case AFR_ENTRY_RENAME_TRANSACTION:
{
- if (nothing_failed && local->optimistic_change_log) {
+ if (nothing_failed) {
afr_changelog_post_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
} else {
STACK_WIND_COOKIE (frame, afr_changelog_post_op_cbk,
(void *) (long) i,
priv->children[i],
priv->children[i]->fops->xattrop,
&local->transaction.new_parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
call_count--;
}
@@ -684,17 +620,20 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
value
*/
- afr_set_postop_dict (local, this, xattr[i],
- local->optimistic_change_log, i);
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
+
+ if (ret < 0)
+ gf_log (this->name, GF_LOG_INFO,
+ "failed to set pending entry");
/* fall through */
case AFR_ENTRY_TRANSACTION:
{
- if (nothing_failed && local->optimistic_change_log) {
+ if (nothing_failed) {
afr_changelog_post_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
break;
}
@@ -703,15 +642,13 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
else
STACK_WIND (frame, afr_changelog_post_op_cbk,
priv->children[i],
priv->children[i]->fops->xattrop,
&local->transaction.parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
break;
}
@@ -720,7 +657,6 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)
break;
}
-out:
for (i = 0; i < priv->child_count; i++) {
dict_unref (xattr[i]);
}
@@ -731,27 +667,30 @@ out:
int32_t
afr_changelog_pre_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
afr_local_t * local = NULL;
afr_private_t * priv = this->private;
+ loc_t * loc = NULL;
int call_count = -1;
int child_index = (long) cookie;
local = frame->local;
+ loc = &local->loc;
LOCK (&frame->lock);
{
- switch (op_ret) {
- case 0:
- __mark_pre_op_done_on_fd (frame, this, child_index);
- //fallthrough we need to mark the pre_op
- case 1:
- local->transaction.pre_op[child_index] = 1;
+ if (op_ret == 1) {
/* special op_ret for piggyback */
- break;
- case -1:
+ }
+
+ if (op_ret == 0) {
+ __mark_pre_op_done_on_fd (frame, this, child_index);
+ }
+
+ if (op_ret == -1) {
+ local->child_up[child_index] = 0;
+
if (op_errno == ENOTSUP) {
gf_log (this->name, GF_LOG_ERROR,
"xattrop not supported by %s",
@@ -765,7 +704,6 @@ afr_changelog_pre_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
strerror (op_errno));
}
local->op_errno = op_errno;
- break;
}
call_count = --local->call_count;
@@ -780,13 +718,7 @@ afr_changelog_pre_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
__mark_all_success (local->pending, priv->child_count,
local->transaction.type);
- /* Perform fops with the lk-owner from top xlator.
- * Eg: lk-owner of posix-lk and flush should be same,
- * flush cant clear the posix-lks without that lk-owner.
- */
- afr_save_lk_owner (frame);
- frame->root->lk_owner =
- local->transaction.main_frame->root->lk_owner;
+ afr_pid_restore (frame);
local->transaction.fop (frame, this);
}
@@ -795,6 +727,7 @@ afr_changelog_pre_op_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
+
int
afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
{
@@ -806,27 +739,34 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
afr_fd_ctx_t *fdctx = NULL;
afr_local_t *local = NULL;
int piggyback = 0;
- afr_internal_lock_t *int_lock = NULL;
- unsigned char *locked_nodes = NULL;
local = frame->local;
- int_lock = &local->internal_lock;
xattr = alloca (priv->child_count * sizeof (*xattr));
memset (xattr, 0, (priv->child_count * sizeof (*xattr)));
for (i = 0; i < priv->child_count; i++) {
- xattr[i] = dict_new ();
+ xattr[i] = get_new_dict ();
+ dict_ref (xattr[i]);
+ }
+
+ call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+
+ if (local->transaction.type == AFR_ENTRY_RENAME_TRANSACTION) {
+ call_count *= 2;
}
- call_count = afr_changelog_pre_op_call_count (local->transaction.type,
- int_lock,
- priv->child_count);
if (call_count == 0) {
+ /* no child is up */
+ for (i = 0; i < priv->child_count; i++) {
+ dict_unref (xattr[i]);
+ }
+
local->internal_lock.lock_cbk =
local->transaction.done;
afr_unlock (frame, this);
- goto out;
+ return 0;
}
local->call_count = call_count;
@@ -837,12 +777,11 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
if (local->fd)
fdctx = afr_fd_ctx_get (local->fd, this);
- locked_nodes = afr_locked_nodes_get (local->transaction.type, int_lock);
for (i = 0; i < priv->child_count; i++) {
- if (!locked_nodes[i])
+ if (!local->child_up[i])
continue;
- ret = afr_set_pending_dict (priv, xattr[i], local->pending,
- i, LOCAL_FIRST);
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
if (ret < 0)
gf_log (this->name, GF_LOG_INFO,
@@ -859,8 +798,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->xattrop,
&(local->loc),
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
break;
}
@@ -877,12 +815,9 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
}
UNLOCK (&local->fd->lock);
- afr_set_delayed_post_op (frame, this);
-
if (piggyback)
afr_changelog_pre_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
else
STACK_WIND_COOKIE (frame,
afr_changelog_pre_op_cbk,
@@ -890,16 +825,14 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
break;
case AFR_METADATA_TRANSACTION:
{
if (local->optimistic_change_log) {
afr_changelog_pre_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
break;
}
@@ -910,8 +843,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
else
STACK_WIND_COOKIE (frame,
afr_changelog_pre_op_cbk,
@@ -919,8 +851,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->xattrop,
&(local->loc),
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
break;
@@ -928,8 +859,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
{
if (local->optimistic_change_log) {
afr_changelog_pre_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
} else {
STACK_WIND_COOKIE (frame,
afr_changelog_pre_op_cbk,
@@ -937,8 +867,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->xattrop,
&local->transaction.new_parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
call_count--;
@@ -953,8 +882,8 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
value
*/
- ret = afr_set_pending_dict (priv, xattr[i], local->pending,
- i, LOCAL_FIRST);
+ ret = afr_set_pending_dict (priv, xattr[i],
+ local->pending);
if (ret < 0)
gf_log (this->name, GF_LOG_INFO,
@@ -966,8 +895,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
{
if (local->optimistic_change_log) {
afr_changelog_pre_op_cbk (frame, (void *)(long)i,
- this, 1, 0, xattr[i],
- NULL);
+ this, 1, 0, xattr[i]);
break;
}
@@ -978,8 +906,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->fxattrop,
local->fd,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
else
STACK_WIND_COOKIE (frame,
afr_changelog_pre_op_cbk,
@@ -987,8 +914,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
priv->children[i],
priv->children[i]->fops->xattrop,
&local->transaction.parent_loc,
- GF_XATTROP_ADD_ARRAY, xattr[i],
- NULL);
+ GF_XATTROP_ADD_ARRAY, xattr[i]);
}
break;
}
@@ -996,7 +922,7 @@ afr_changelog_pre_op (call_frame_t *frame, xlator_t *this)
if (!--call_count)
break;
}
-out:
+
for (i = 0; i < priv->child_count; i++) {
dict_unref (xattr[i]);
}
@@ -1206,6 +1132,12 @@ afr_lock_rec (call_frame_t *frame, xlator_t *this)
int
afr_lock (call_frame_t *frame, xlator_t *this)
{
+ afr_pid_save (frame);
+
+ frame->root->pid = (long) frame->root;
+
+ afr_set_lk_owner (frame, this);
+
afr_set_lock_number (frame, this);
return afr_lock_rec (frame, this);
@@ -1223,20 +1155,13 @@ afr_internal_lock_finish (call_frame_t *frame, xlator_t *this)
priv = this->private;
local = frame->local;
- if (__fop_changelog_needed (frame, this)) {
+ if (__changelog_needed_pre_op (frame, this)) {
afr_changelog_pre_op (frame, this);
} else {
__mark_all_success (local->pending, priv->child_count,
local->transaction.type);
-
- /* Perform fops with the lk-owner from top xlator.
- * Eg: lk-owner of posix-lk and flush should be same,
- * flush cant clear the posix-lks without that lk-owner.
- */
- afr_save_lk_owner (frame);
- frame->root->lk_owner =
- local->transaction.main_frame->root->lk_owner;
+ afr_pid_restore (frame);
local->transaction.fop (frame, this);
}
@@ -1245,162 +1170,18 @@ afr_internal_lock_finish (call_frame_t *frame, xlator_t *this)
}
-void
-afr_set_delayed_post_op (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- afr_private_t *priv = NULL;
-
- /* call this function from any of the related optimizations
- which benefit from delaying post op are enabled, namely:
-
- - changelog piggybacking
- - eager locking
- */
-
- priv = this->private;
- if (!priv)
- return;
-
- if (!priv->post_op_delay_secs)
- return;
-
- local = frame->local;
- if (!local)
- return;
-
- if (!local->fd)
- return;
-
- if (local->op == GF_FOP_WRITE)
- local->delayed_post_op = _gf_true;
-}
-
-
-gf_boolean_t
-is_afr_delayed_changelog_post_op_needed (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
- gf_boolean_t res = _gf_false;
-
- local = frame->local;
- if (!local)
- goto out;
-
- if (!local->delayed_post_op)
- goto out;
-
- res = _gf_true;
-out:
- return res;
-}
-
-
-void
-afr_delayed_changelog_post_op (xlator_t *this, call_frame_t *frame, fd_t *fd);
-
-void
-afr_delayed_changelog_wake_up (xlator_t *this, fd_t *fd);
-
-void
-afr_delayed_changelog_wake_up_cbk (void *data)
-{
- fd_t *fd = NULL;
-
- fd = data;
-
- afr_delayed_changelog_wake_up (THIS, fd);
-}
-
-
-void
-afr_delayed_changelog_post_op (xlator_t *this, call_frame_t *frame, fd_t *fd)
-{
- afr_fd_ctx_t *fd_ctx = NULL;
- call_frame_t *prev_frame = NULL;
- struct timeval delta = {0, };
- afr_private_t *priv = NULL;
-
- priv = this->private;
-
- fd_ctx = afr_fd_ctx_get (fd, this);
- if (!fd_ctx)
- return;
-
- delta.tv_sec = priv->post_op_delay_secs;
- delta.tv_usec = 0;
-
- pthread_mutex_lock (&fd_ctx->delay_lock);
- {
- prev_frame = fd_ctx->delay_frame;
- fd_ctx->delay_frame = NULL;
- if (fd_ctx->delay_timer)
- gf_timer_call_cancel (this->ctx, fd_ctx->delay_timer);
- fd_ctx->delay_timer = NULL;
- if (!frame)
- goto unlock;
- fd_ctx->delay_timer = gf_timer_call_after (this->ctx, delta,
- afr_delayed_changelog_wake_up_cbk,
- fd);
- fd_ctx->delay_frame = frame;
- }
-unlock:
- pthread_mutex_unlock (&fd_ctx->delay_lock);
-
- if (prev_frame) {
- afr_changelog_post_op_now (prev_frame, this);
- }
-}
-
-
-void
-afr_changelog_post_op (call_frame_t *frame, xlator_t *this)
-{
- afr_local_t *local = NULL;
-
- local = frame->local;
-
- if (is_afr_delayed_changelog_post_op_needed (frame, this))
- afr_delayed_changelog_post_op (this, frame, local->fd);
- else
- afr_changelog_post_op_now (frame, this);
-}
-
-
-void
-afr_delayed_changelog_wake_up (xlator_t *this, fd_t *fd)
-{
- afr_delayed_changelog_post_op (this, NULL, fd);
-}
-
-
int
afr_transaction_resume (call_frame_t *frame, xlator_t *this)
{
afr_internal_lock_t *int_lock = NULL;
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
- fd_t *fd = NULL;
local = frame->local;
int_lock = &local->internal_lock;
priv = this->private;
- fd = local->fd;
-
- if (fd)
- /* The wake up needs to happen independent of
- what type of fop arrives here. If it was
- a write, then it has already inherited the
- lock and changelog. If it was not a write,
- then the presumption of the optimization (of
- optimizing for successive write operations)
- fails.
- */
- afr_delayed_changelog_wake_up (this, fd);
-
- afr_restore_lk_owner (frame);
-
- if (__fop_changelog_needed (frame, this)) {
+
+ if (__changelog_needed_post_op (frame, this)) {
afr_changelog_post_op (frame, this);
} else {
if (afr_lock_server_count (priv, local->transaction.type) == 0) {
@@ -1432,6 +1213,7 @@ afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this, int child_index
child_index, local->transaction.type);
}
+
int
afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
{
@@ -1441,13 +1223,7 @@ afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type)
local = frame->local;
priv = this->private;
- if (local->fd && priv->eager_lock &&
- local->transaction.type == AFR_DATA_TRANSACTION)
- afr_set_lk_owner (frame, this, local->fd);
- else
- afr_set_lk_owner (frame, this, frame->root);
-
- afr_transaction_local_init (local, this);
+ afr_transaction_local_init (local, priv);
local->transaction.resume = afr_transaction_resume;
local->transaction.type = type;
diff --git a/xlators/cluster/afr/src/afr-transaction.h b/xlators/cluster/afr/src/afr-transaction.h
index 102599633..84cf31d63 100644
--- a/xlators/cluster/afr/src/afr-transaction.h
+++ b/xlators/cluster/afr/src/afr-transaction.h
@@ -1,21 +1,25 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __TRANSACTION_H__
#define __TRANSACTION_H__
-typedef enum {
- LOCAL_FIRST = 1,
- LOCAL_LAST = 2
-} afr_xattrop_type_t;
-
void
afr_transaction_fop_failed (call_frame_t *frame, xlator_t *this,
int child_index);
@@ -26,11 +30,4 @@ afr_lock_server_count (afr_private_t *priv, afr_transaction_type type);
int32_t
afr_transaction (call_frame_t *frame, xlator_t *this, afr_transaction_type type);
-afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this);
-int
-afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int32_t **pending,
- int child, afr_xattrop_type_t op);
-void
-afr_set_delayed_post_op (call_frame_t *frame, xlator_t *this);
#endif /* __TRANSACTION_H__ */
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index 846f985de..79753c91b 100644
--- a/xlators/cluster/afr/src/afr.c
+++ b/xlators/cluster/afr/src/afr.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <libgen.h>
@@ -21,25 +30,13 @@
#endif
#include "afr-common.c"
-#define SHD_INODE_LRU_LIMIT 2048
-#define AFR_EH_HEALED_LIMIT 1024
-#define AFR_EH_HEAL_FAIL_LIMIT 1024
-#define AFR_EH_SPLIT_BRAIN_LIMIT 1024
-
-struct volume_options options[];
-
int32_t
notify (xlator_t *this, int32_t event,
void *data, ...)
{
int ret = -1;
- va_list ap;
- void *data2 = NULL;
- va_start (ap, data);
- data2 = va_arg (ap, dict_t*);
- va_end (ap);
- ret = afr_notify (this, event, data, data2);
+ ret = afr_notify (this, event, data);
return ret;
}
@@ -63,133 +60,284 @@ mem_acct_init (xlator_t *this)
return ret;
}
-
int
-xlator_subvolume_index (xlator_t *this, xlator_t *subvol)
+validate_options (xlator_t *this, char **op_errstr)
{
- int index = -1;
- int i = 0;
- xlator_list_t *list = NULL;
-
- list = this->children;
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- while (list) {
- if (subvol == list->xlator ||
- strcmp (subvol->name, list->xlator->name) == 0) {
- index = i;
- break;
- }
- list = list->next;
- i++;
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
}
- return index;
-}
+ if (list_empty (&this->volume_options))
+ goto out;
-void
-fix_quorum_options (xlator_t *this, afr_private_t *priv, char *qtype)
-{
- if (priv->quorum_count && strcmp(qtype,"fixed")) {
- gf_log(this->name,GF_LOG_WARNING,
- "quorum-type %s overriding quorum-count %u",
- qtype, priv->quorum_count);
- }
- if (!strcmp(qtype,"none")) {
- priv->quorum_count = 0;
- }
- else if (!strcmp(qtype,"auto")) {
- priv->quorum_count = AFR_QUORUM_AUTO;
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
}
+
+out:
+
+ return ret;
}
+
int
reconfigure (xlator_t *this, dict_t *options)
{
- afr_private_t *priv = NULL;
- xlator_t *read_subvol = NULL;
- int read_subvol_index = -1;
- int ret = -1;
- int index = -1;
- char *qtype = NULL;
+
+ gf_boolean_t metadata_self_heal; /* on/off */
+ gf_boolean_t entry_self_heal;
+ gf_boolean_t data_self_heal;
+ gf_boolean_t data_change_log; /* on/off */
+ gf_boolean_t metadata_change_log; /* on/off */
+ gf_boolean_t entry_change_log; /* on/off */
+ gf_boolean_t strict_readdir;
+
+ afr_private_t * priv = NULL;
+ xlator_list_t * trav = NULL;
+
+ char * read_subvol = NULL;
+ char * self_heal = NULL;
+ char * change_log = NULL;
+ char * str_readdir = NULL;
+ char * self_heal_algo = NULL;
+
+ int32_t background_count = 0;
+ int32_t window_size = 0;
+
+ int read_ret = -1;
+ int dict_ret = -1;
+ int flag = 1;
+ int ret = 0;
+ int temp_ret = -1;
priv = this->private;
- GF_OPTION_RECONF ("background-self-heal-count",
- priv->background_self_heal_count, options, uint32,
- out);
+ dict_ret = dict_get_int32 (options, "background-self-heal-count",
+ &background_count);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring background self-heal count to %d",
+ background_count);
+
+ priv->background_self_heal_count = background_count;
+ }
- GF_OPTION_RECONF ("metadata-self-heal",
- priv->metadata_self_heal, options, bool, out);
+ dict_ret = dict_get_str (options, "metadata-self-heal",
+ &self_heal);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (self_heal, &metadata_self_heal);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Reconfiguration Invalid 'option metadata"
+ "-self-heal %s'. Defaulting to old value.",
+ self_heal);
+ ret = -1;
+ goto out;
+ }
- GF_OPTION_RECONF ("data-self-heal", priv->data_self_heal, options, str,
- out);
+ priv->metadata_self_heal = metadata_self_heal;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option metadata"
+ "-self-heal %s'.",
+ self_heal);
+ }
- GF_OPTION_RECONF ("entry-self-heal", priv->entry_self_heal, options,
- bool, out);
+ dict_ret = dict_get_str (options, "data-self-heal", &self_heal);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (self_heal, &data_self_heal);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Reconfiguration Invalid 'option data"
+ "-self-heal %s'. Defaulting to old value.",
+ self_heal);
+ ret = -1;
+ goto out;
+ }
- GF_OPTION_RECONF ("strict-readdir", priv->strict_readdir, options, bool,
- out);
+ priv->data_self_heal = data_self_heal;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option data"
+ "-self-heal %s'.", self_heal);
+ }
- GF_OPTION_RECONF ("data-self-heal-window-size",
- priv->data_self_heal_window_size, options,
- uint32, out);
+ dict_ret = dict_get_str (options, "entry-self-heal",
+ &self_heal);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (self_heal, &entry_self_heal);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Reconfiguration Invalid 'option data"
+ "-self-heal %s'. Defaulting to old value.",
+ self_heal);
+ ret = -1;
+ goto out;
+ }
- GF_OPTION_RECONF ("data-change-log", priv->data_change_log, options,
- bool, out);
+ priv->entry_self_heal = entry_self_heal;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option entry"
+ "-self-heal %s'.", self_heal);
+ }
- GF_OPTION_RECONF ("metadata-change-log",
- priv->metadata_change_log, options, bool, out);
- GF_OPTION_RECONF ("entry-change-log", priv->entry_change_log, options,
- bool, out);
+ dict_ret = dict_get_str (options, "strict-readdir",
+ &str_readdir);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (str_readdir, &strict_readdir);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option strict-readdir %s'. "
+ "Defaulting to old value.",
+ str_readdir);
+ ret = -1;
+ goto out;
+ }
- GF_OPTION_RECONF ("data-self-heal-algorithm",
- priv->data_self_heal_algorithm, options, str, out);
+ priv->strict_readdir = strict_readdir;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option strict"
+ "-readdir %s'.", str_readdir);
+ }
- GF_OPTION_RECONF ("self-heal-daemon", priv->shd.enabled, options, bool, out);
+ dict_ret = dict_get_int32 (options, "data-self-heal-window-size",
+ &window_size);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring, Setting data self-heal window size to %d",
+ window_size);
- GF_OPTION_RECONF ("read-subvolume", read_subvol, options, xlator, out);
+ priv->data_self_heal_window_size = window_size;
+ }
+ else {
+ priv->data_self_heal_window_size = 16;
+ }
- GF_OPTION_RECONF ("read-hash-mode", priv->hash_mode,
- options, uint32, out);
- if (read_subvol) {
- index = xlator_subvolume_index (this, read_subvol);
- if (index == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s not a subvolume",
- read_subvol->name);
+ dict_ret = dict_get_str (options, "data-change-log", &change_log);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (change_log, &data_change_log);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Reconfiguration Invalid 'option data-"
+ "change-log %s'. Defaulting to old value.",
+ change_log);
+ ret = -1;
goto out;
}
- priv->read_child = index;
+
+ priv->data_change_log = data_change_log;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option data-"
+ "change-log %s'.", change_log);
}
- GF_OPTION_RECONF ("read-subvolume-index",read_subvol_index, options,int32,out);
+ dict_ret = dict_get_str (options, "metadata-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (change_log,
+ &metadata_change_log);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option metadata-change-log %s'. "
+ "Defaulting to metadata-change-log as 'off'.",
+ change_log);
+ ret = -1;
+ goto out;
+ }
+
+ priv->metadata_change_log = metadata_change_log;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option metadata-"
+ "change-log %s'.", change_log);
+ }
- if (read_subvol_index >-1) {
- index=read_subvol_index;
- if (index >= priv->child_count) {
- gf_log (this->name, GF_LOG_ERROR, "%d not a subvolume-index",
- index);
+ dict_ret = dict_get_str (options, "entry-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ temp_ret = gf_string2boolean (change_log, &entry_change_log);
+ if (temp_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option entry-change-log %s'. "
+ "Defaulting to entry-change-log as 'on'.",
+ change_log);
+ ret = -1;
goto out;
}
- priv->read_child = index;
+
+ priv->entry_change_log = entry_change_log;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option entry-"
+ "change-log %s'.", change_log);
}
- GF_OPTION_RECONF ("eager-lock", priv->eager_lock, options, bool, out);
- GF_OPTION_RECONF ("quorum-type", qtype, options, str, out);
- GF_OPTION_RECONF ("quorum-count", priv->quorum_count, options,
- uint32, out);
- fix_quorum_options(this,priv,qtype);
- GF_OPTION_RECONF ("heal-timeout", priv->shd.timeout, options,
- int32, out);
+ dict_ret = dict_get_str (options, "data-self-heal-algorithm",
+ &self_heal_algo);
+ if (dict_ret == 0) {
+ /* Handling both strcmp cases - s1 > s2 and s1 < s2 */
+
+ if (!strcmp (self_heal_algo, "full")) {
+ priv->data_self_heal_algorithm = self_heal_algo;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option data-self"
+ "heal-algorithm %s'.", self_heal_algo);
+ goto next;
+ }
- GF_OPTION_RECONF ("post-op-delay-secs", priv->post_op_delay_secs, options,
- uint32, out);
+ if (!strcmp (self_heal_algo, "diff")) {
+ priv->data_self_heal_algorithm = self_heal_algo;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring 'option data-self"
+ "heal-algorithm %s'.", self_heal_algo);
+ goto next;
+ }
- /* Reset this so we re-discover in case the topology changed. */
- priv->did_discovery = _gf_false;
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid self-heal algorithm %s,"
+ "defaulting back to old value",
+ self_heal_algo);
+ ret = -1;
+ goto out;
+ }
- ret = 0;
+ read_ret = dict_get_str (options, "read-subvolume", &read_subvol);
+
+ if (read_ret < 0)
+ goto next;// No need to traverse, hence set the next option
+
+ trav = this->children;
+ flag = 0;
+ while (trav) {
+ if (!read_ret && !strcmp (read_subvol, trav->xlator->name)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Subvolume '%s' specified as read child.",
+ trav->xlator->name);
+
+ flag = 1;
+ break;
+ }
+
+ trav = trav->next;
+ }
+
+ if (flag == 0 ) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Invalid 'option read-subvolume %s', no such subvolume"
+ , read_subvol);
+ ret = -1;
+ goto out;
+ }
+
+next:
out:
return ret;
@@ -204,20 +352,38 @@ static const char *favorite_child_warning_str = "You have specified subvolume '%
"subvolumes. All versions of the file except that on '%s' "
"WILL BE LOST.";
+static const char *no_lock_servers_warning_str = "You have set lock-server-count = 0. "
+ "This means correctness is NO LONGER GUARANTEED in all cases. If two or more "
+ "applications write to the same region of a file, there is a possibility that "
+ "its copies will be INCONSISTENT. Set it to a value greater than 0 unless you "
+ "are ABSOLUTELY SURE of what you are doing and WILL NOT HOLD GlusterFS "
+ "RESPONSIBLE for inconsistent data. If you are in doubt, set it to a value "
+ "greater than 0.";
int32_t
init (xlator_t *this)
{
- afr_private_t *priv = NULL;
- int child_count = 0;
- xlator_list_t *trav = NULL;
- int i = 0;
- int ret = -1;
- GF_UNUSED int op_errno = 0;
- xlator_t *read_subvol = NULL;
- int read_subvol_index = -1;
- xlator_t *fav_child = NULL;
- char *qtype = NULL;
+ afr_private_t * priv = NULL;
+ int child_count = 0;
+ xlator_list_t * trav = NULL;
+ int i = 0;
+ int ret = -1;
+ int op_errno = 0;
+ char * read_subvol = NULL;
+ char * fav_child = NULL;
+ char * self_heal = NULL;
+ char * algo = NULL;
+ char * change_log = NULL;
+ char * strict_readdir = NULL;
+ char * inodelk_trace = NULL;
+ char * entrylk_trace = NULL;
+ int32_t background_count = 0;
+ int32_t lock_server_count = 1;
+ int32_t window_size = 0;
+ int fav_ret = -1;
+ int read_ret = -1;
+ int dict_ret = -1;
+
if (!this->children) {
gf_log (this->name, GF_LOG_ERROR,
@@ -231,106 +397,267 @@ init (xlator_t *this)
"Volume is dangling.");
}
- this->private = GF_CALLOC (1, sizeof (afr_private_t),
- gf_afr_mt_afr_private_t);
- if (!this->private)
- goto out;
+ ALLOC_OR_GOTO (this->private, afr_private_t, out);
priv = this->private;
- LOCK_INIT (&priv->lock);
- LOCK_INIT (&priv->read_child_lock);
- //lock recovery is not done in afr
- pthread_mutex_init (&priv->mutex, NULL);
- INIT_LIST_HEAD (&priv->saved_fds);
- child_count = xlator_subvolume_count (this);
+ read_ret = dict_get_str (this->options, "read-subvolume", &read_subvol);
+ priv->read_child = -1;
- priv->child_count = child_count;
+ fav_ret = dict_get_str (this->options, "favorite-child", &fav_child);
+ priv->favorite_child = -1;
- priv->read_child = -1;
+ priv->background_self_heal_count = 16;
- GF_OPTION_INIT ("read-subvolume", read_subvol, xlator, out);
- if (read_subvol) {
- priv->read_child = xlator_subvolume_index (this, read_subvol);
- if (priv->read_child == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s not a subvolume",
- read_subvol->name);
- goto out;
+ dict_ret = dict_get_int32 (this->options, "background-self-heal-count",
+ &background_count);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Setting background self-heal count to %d",
+ background_count);
+
+ priv->background_self_heal_count = background_count;
+ }
+
+ /* Default values */
+
+ priv->data_self_heal = 1;
+ priv->metadata_self_heal = 1;
+ priv->entry_self_heal = 1;
+
+ dict_ret = dict_get_str (this->options, "data-self-heal", &self_heal);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (self_heal, &priv->data_self_heal);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option data-self-heal %s'. "
+ "Defaulting to data-self-heal as 'on'",
+ self_heal);
+ priv->data_self_heal = 1;
}
}
- GF_OPTION_INIT ("read-subvolume-index",read_subvol_index,int32,out);
- if (read_subvol_index > -1) {
- if (read_subvol_index >= priv->child_count) {
- gf_log (this->name, GF_LOG_ERROR, "%d not a subvolume-index",
- read_subvol_index);
- goto out;
+
+ priv->data_self_heal_algorithm = "";
+
+ dict_ret = dict_get_str (this->options, "data-self-heal-algorithm",
+ &algo);
+ if (dict_ret == 0) {
+ priv->data_self_heal_algorithm = gf_strdup (algo);
+ }
+
+
+ priv->data_self_heal_window_size = 16;
+
+ dict_ret = dict_get_int32 (this->options, "data-self-heal-window-size",
+ &window_size);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Setting data self-heal window size to %d",
+ window_size);
+
+ priv->data_self_heal_window_size = window_size;
+ }
+
+ dict_ret = dict_get_str (this->options, "metadata-self-heal",
+ &self_heal);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (self_heal, &priv->metadata_self_heal);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option metadata-self-heal %s'. "
+ "Defaulting to metadata-self-heal as 'on'.",
+ self_heal);
+ priv->metadata_self_heal = 1;
}
- priv->read_child = read_subvol_index;
}
- GF_OPTION_INIT ("choose-local", priv->choose_local, bool, out);
- GF_OPTION_INIT ("read-hash-mode", priv->hash_mode, uint32, out);
+ dict_ret = dict_get_str (this->options, "entry-self-heal", &self_heal);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (self_heal, &priv->entry_self_heal);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option entry-self-heal %s'. "
+ "Defaulting to entry-self-heal as 'on'.",
+ self_heal);
+ priv->entry_self_heal = 1;
+ }
+ }
- priv->favorite_child = -1;
- GF_OPTION_INIT ("favorite-child", fav_child, xlator, out);
- if (fav_child) {
- priv->favorite_child = xlator_subvolume_index (this, fav_child);
- if (priv->favorite_child == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s not a subvolume",
- fav_child->name);
- goto out;
+ /* Change log options */
+
+ priv->data_change_log = 1;
+ priv->metadata_change_log = 1;
+ priv->entry_change_log = 1;
+ priv->optimistic_change_log = 1;
+
+ dict_ret = dict_get_str (this->options, "data-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (change_log, &priv->data_change_log);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option data-change-log %s'. "
+ "Defaulting to data-change-log as 'on'.",
+ change_log);
+ priv->data_change_log = 1;
+ }
+ }
+
+ dict_ret = dict_get_str (this->options, "metadata-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (change_log,
+ &priv->metadata_change_log);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option metadata-change-log %s'. "
+ "Defaulting to metadata-change-log as 'off'.",
+ change_log);
+ priv->metadata_change_log = 0;
+ }
+ }
+
+ dict_ret = dict_get_str (this->options, "entry-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (change_log, &priv->entry_change_log);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option entry-change-log %s'. "
+ "Defaulting to entry-change-log as 'on'.",
+ change_log);
+ priv->entry_change_log = 1;
+ }
+ }
+
+ dict_ret = dict_get_str (this->options, "optimistic-change-log",
+ &change_log);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (change_log, &priv->optimistic_change_log);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option optimistic-change-log %s'. "
+ "Defaulting to optimistic-change-log as 'on'.",
+ change_log);
+ priv->optimistic_change_log = 1;
+ }
+ }
+
+ /* Locking options */
+
+ priv->inodelk_trace = 0;
+ priv->entrylk_trace = 0;
+
+ dict_ret = dict_get_str (this->options, "inodelk-trace",
+ &inodelk_trace);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (inodelk_trace, &priv->inodelk_trace);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option inodelk-trace %s' ",
+ inodelk_trace);
+
+ priv->inodelk_trace = 0;
}
- gf_log (this->name, GF_LOG_WARNING,
- favorite_child_warning_str, fav_child->name,
- fav_child->name, fav_child->name);
}
- GF_OPTION_INIT ("background-self-heal-count",
- priv->background_self_heal_count, uint32, out);
+ dict_ret = dict_get_str (this->options, "entrylk-trace",
+ &entrylk_trace);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (entrylk_trace, &priv->entrylk_trace);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option entrylk-trace %s' ",
+ inodelk_trace);
- GF_OPTION_INIT ("data-self-heal", priv->data_self_heal, str, out);
+ priv->entrylk_trace = 0;
+ }
+ }
- GF_OPTION_INIT ("data-self-heal-algorithm",
- priv->data_self_heal_algorithm, str, out);
- GF_OPTION_INIT ("data-self-heal-window-size",
- priv->data_self_heal_window_size, uint32, out);
+ priv->data_lock_server_count = 1;
+ priv->metadata_lock_server_count = 0;
+ priv->entry_lock_server_count = 1;
- GF_OPTION_INIT ("metadata-self-heal", priv->metadata_self_heal, bool,
- out);
+ dict_ret = dict_get_int32 (this->options, "data-lock-server-count",
+ &lock_server_count);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Setting data lock server count to %d.",
+ lock_server_count);
- GF_OPTION_INIT ("entry-self-heal", priv->entry_self_heal, bool, out);
+ if (lock_server_count == 0)
+ gf_log (this->name, GF_LOG_WARNING, "%s",
+ no_lock_servers_warning_str);
- GF_OPTION_INIT ("self-heal-daemon", priv->shd.enabled, bool, out);
+ priv->data_lock_server_count = lock_server_count;
+ }
- GF_OPTION_INIT ("iam-self-heal-daemon", priv->shd.iamshd, bool, out);
- GF_OPTION_INIT ("data-change-log", priv->data_change_log, bool, out);
+ dict_ret = dict_get_int32 (this->options,
+ "metadata-lock-server-count",
+ &lock_server_count);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Setting metadata lock server count to %d.",
+ lock_server_count);
+ priv->metadata_lock_server_count = lock_server_count;
+ }
- GF_OPTION_INIT ("metadata-change-log", priv->metadata_change_log, bool,
- out);
- GF_OPTION_INIT ("entry-change-log", priv->entry_change_log, bool, out);
+ dict_ret = dict_get_int32 (this->options, "entry-lock-server-count",
+ &lock_server_count);
+ if (dict_ret == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Setting entry lock server count to %d.",
+ lock_server_count);
- GF_OPTION_INIT ("optimistic-change-log", priv->optimistic_change_log,
- bool, out);
+ priv->entry_lock_server_count = lock_server_count;
+ }
- GF_OPTION_INIT ("inodelk-trace", priv->inodelk_trace, bool, out);
+ priv->strict_readdir = _gf_false;
+
+ dict_ret = dict_get_str (this->options, "strict-readdir",
+ &strict_readdir);
+ if (dict_ret == 0) {
+ ret = gf_string2boolean (strict_readdir, &priv->strict_readdir);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Invalid 'option strict-readdir %s'. "
+ "Defaulting to strict-readdir as 'off'.",
+ strict_readdir);
+ }
+ }
- GF_OPTION_INIT ("entrylk-trace", priv->entrylk_trace, bool, out);
+ trav = this->children;
+ while (trav) {
+ if (!read_ret && !strcmp (read_subvol, trav->xlator->name)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Subvolume '%s' specified as read child.",
+ trav->xlator->name);
- GF_OPTION_INIT ("strict-readdir", priv->strict_readdir, bool, out);
+ priv->read_child = child_count;
+ }
- GF_OPTION_INIT ("eager-lock", priv->eager_lock, bool, out);
- GF_OPTION_INIT ("quorum-type", qtype, str, out);
- GF_OPTION_INIT ("quorum-count", priv->quorum_count, uint32, out);
- fix_quorum_options(this,priv,qtype);
+ if (fav_ret == 0 && !strcmp (fav_child, trav->xlator->name)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ favorite_child_warning_str, trav->xlator->name,
+ trav->xlator->name, trav->xlator->name);
+ priv->favorite_child = child_count;
+ }
- GF_OPTION_INIT ("post-op-delay-secs", priv->post_op_delay_secs, uint32, out);
+ child_count++;
+ trav = trav->next;
+ }
priv->wait_count = 1;
+ priv->child_count = child_count;
+
+ LOCK_INIT (&priv->lock);
+ LOCK_INIT (&priv->read_child_lock);
+
priv->child_up = GF_CALLOC (sizeof (unsigned char), child_count,
gf_afr_mt_char);
if (!priv->child_up) {
@@ -379,68 +706,12 @@ init (xlator_t *this)
i++;
}
- priv->last_event = GF_CALLOC (child_count, sizeof (*priv->last_event),
- gf_afr_mt_int32_t);
- if (!priv->last_event) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* keep more local here as we may need them for self-heal etc */
- this->local_pool = mem_pool_new (afr_local_t, 512);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
+ LOCK_INIT (&priv->root_inode_lk);
priv->first_lookup = 1;
priv->root_inode = NULL;
- if (!priv->shd.iamshd) {
- ret = 0;
- goto out;
- }
-
- ret = -ENOMEM;
- priv->shd.pos = GF_CALLOC (sizeof (*priv->shd.pos), child_count,
- gf_afr_mt_brick_pos_t);
- if (!priv->shd.pos)
- goto out;
-
- priv->shd.pending = GF_CALLOC (sizeof (*priv->shd.pending), child_count,
- gf_afr_mt_int32_t);
- if (!priv->shd.pending)
- goto out;
-
- priv->shd.inprogress = GF_CALLOC (sizeof (*priv->shd.inprogress),
- child_count, gf_afr_mt_shd_bool_t);
- if (!priv->shd.inprogress)
- goto out;
- priv->shd.timer = GF_CALLOC (sizeof (*priv->shd.timer), child_count,
- gf_afr_mt_shd_timer_t);
- if (!priv->shd.timer)
- goto out;
-
- priv->shd.healed = eh_new (AFR_EH_HEALED_LIMIT, _gf_false);
- if (!priv->shd.healed)
- goto out;
-
- priv->shd.heal_failed = eh_new (AFR_EH_HEAL_FAIL_LIMIT, _gf_false);
- if (!priv->shd.heal_failed)
- goto out;
-
- priv->shd.split_brain = eh_new (AFR_EH_SPLIT_BRAIN_LIMIT, _gf_false);
- if (!priv->shd.split_brain)
- goto out;
-
- this->itable = inode_table_new (SHD_INODE_LRU_LIMIT, this);
- if (!this->itable)
- goto out;
- priv->root_inode = inode_ref (this->itable->root);
- GF_OPTION_INIT ("node-uuid", priv->shd.node_uuid, str, out);
- GF_OPTION_INIT ("heal-timeout", priv->shd.timeout, int32, out);
+ pthread_mutex_init (&priv->mutex, NULL);
+ INIT_LIST_HEAD (&priv->saved_fds);
ret = 0;
out:
@@ -451,13 +722,6 @@ out:
int
fini (xlator_t *this)
{
- afr_private_t *priv = NULL;
-
- priv = this->private;
- this->private = NULL;
- afr_priv_destroy (priv);
- if (this->itable);//I dont see any destroy func
-
return 0;
}
@@ -483,7 +747,6 @@ struct xlator_fops fops = {
.fstat = afr_fstat,
.readlink = afr_readlink,
.getxattr = afr_getxattr,
- .fgetxattr = afr_fgetxattr,
.readv = afr_readv,
/* inode write */
@@ -491,11 +754,9 @@ struct xlator_fops fops = {
.truncate = afr_truncate,
.ftruncate = afr_ftruncate,
.setxattr = afr_setxattr,
- .fsetxattr = afr_fsetxattr,
.setattr = afr_setattr,
.fsetattr = afr_fsetattr,
.removexattr = afr_removexattr,
- .fremovexattr = afr_fremovexattr,
/* dir read */
.opendir = afr_opendir,
@@ -522,7 +783,6 @@ struct xlator_dumpops dumpops = {
struct xlator_cbks cbks = {
.release = afr_release,
.releasedir = afr_releasedir,
- .forget = afr_forget,
};
@@ -530,145 +790,56 @@ struct volume_options options[] = {
{ .key = {"read-subvolume" },
.type = GF_OPTION_TYPE_XLATOR
},
- { .key = {"read-subvolume-index" },
- .type = GF_OPTION_TYPE_INT,
- .default_value = "-1",
- },
- { .key = {"read-hash-mode" },
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = 2,
- .default_value = "0",
- .description = "0 = first responder, "
- "1 = hash by GFID (all clients use same subvolume), "
- "2 = hash by GFID and client PID",
- },
- { .key = {"choose-local" },
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "true",
- .description = "Choose a local subvolume to read from if "
- "read-subvolume is not explicitly set.",
- },
{ .key = {"favorite-child"},
.type = GF_OPTION_TYPE_XLATOR
},
{ .key = {"background-self-heal-count"},
.type = GF_OPTION_TYPE_INT,
- .min = 0,
- .default_value = "16",
- .validate = GF_OPT_VALIDATE_MIN,
+ .min = 0
},
{ .key = {"data-self-heal"},
- .type = GF_OPTION_TYPE_STR,
- .value = {"1", "on", "yes", "true", "enable",
- "0", "off", "no", "false", "disable",
- "open"},
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"data-self-heal-algorithm"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "",
- .description = "Select between \"full\", \"diff\". The "
- "\"full\" algorithm copies the entire file from "
- "source to sink. The \"diff\" algorithm copies to "
- "sink only those blocks whose checksums don't match "
- "with those of source.",
- .value = { "diff", "full", "" }
+ .type = GF_OPTION_TYPE_STR
},
{ .key = {"data-self-heal-window-size"},
.type = GF_OPTION_TYPE_INT,
.min = 1,
- .max = 1024,
- .default_value = "1",
- .description = "Maximum number blocks per file for which self-heal "
- "process would be applied simultaneously."
+ .max = 1024
},
{ .key = {"metadata-self-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"entry-self-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"data-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"metadata-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"entry-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"optimistic-change-log"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- },
- { .key = {"strict-readdir"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"inodelk-trace"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"entrylk-trace"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {"eager-lock"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- },
- { .key = {"self-heal-daemon"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"iam-self-heal-daemon"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"quorum-type"},
- .type = GF_OPTION_TYPE_STR,
- .value = { "none", "auto", "fixed", "" },
- .default_value = "none",
- .description = "If value is \"fixed\" only allow writes if "
- "quorum-count bricks are present. If value is "
- "\"auto\" only allow writes if more than half of "
- "bricks, or exactly half including the first, are "
- "present.",
- },
- { .key = {"quorum-count"},
+ { .key = {"data-lock-server-count"},
.type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = INT_MAX,
- .default_value = 0,
- .description = "If quorum-type is \"fixed\" only allow writes if "
- "this many bricks or present. Other quorum types "
- "will OVERWRITE this value.",
- },
- { .key = {"node-uuid"},
- .type = GF_OPTION_TYPE_STR,
- .description = "Local glusterd uuid string",
+ .min = 0
},
- { .key = {"heal-timeout"},
+ { .key = {"metadata-lock-server-count"},
.type = GF_OPTION_TYPE_INT,
- .min = 60,
- .max = INT_MAX,
- .default_value = "600",
- .description = "Poll timeout for checking the need to self-heal"
+ .min = 0
},
- { .key = {"post-op-delay-secs"},
+ { .key = {"entry-lock-server-count"},
.type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = INT_MAX,
- .default_value = "1",
- .description = "Time interval induced artificially before "
- "post-operation phase of the transaction to "
- "enhance overlap of adjacent write operations.",
+ .min = 0
+ },
+ { .key = {"strict-readdir"},
+ .type = GF_OPTION_TYPE_BOOL,
},
{ .key = {NULL} },
};
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 5ed478c4a..f1b0efbd2 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -20,85 +29,13 @@
#include "call-stub.h"
#include "compat-errno.h"
#include "afr-mem-types.h"
-#include "afr-self-heal-algorithm.h"
#include "libxlator.h"
-#include "timer.h"
#define AFR_XATTR_PREFIX "trusted.afr"
-#define AFR_PATHINFO_HEADER "REPLICATE:"
struct _pump_private;
-typedef int (*afr_expunge_done_cbk_t) (call_frame_t *frame, xlator_t *this,
- int child, int32_t op_error,
- int32_t op_errno);
-
-typedef int (*afr_impunge_done_cbk_t) (call_frame_t *frame, xlator_t *this,
- int32_t op_error, int32_t op_errno);
-typedef int (*afr_post_remove_call_t) (call_frame_t *frame, xlator_t *this);
-
-typedef int (*afr_lock_cbk_t) (call_frame_t *frame, xlator_t *this);
-typedef void (*afr_lookup_done_cbk_t) (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno);
-
-typedef enum {
- AFR_POS_UNKNOWN,
- AFR_POS_LOCAL,
- AFR_POS_REMOTE
-} afr_child_pos_t;
-
-typedef enum {
- SPLIT_BRAIN = 1,
- ALL_FOOLS = 2
-} afr_subvol_status_t;
-
-typedef enum {
- AFR_INODE_SET_READ_CTX = 1,
- AFR_INODE_RM_STALE_CHILDREN,
- AFR_INODE_SET_OPENDIR_DONE,
- AFR_INODE_SET_SPLIT_BRAIN,
- AFR_INODE_GET_READ_CTX,
- AFR_INODE_GET_OPENDIR_DONE,
- AFR_INODE_GET_SPLIT_BRAIN,
-} afr_inode_op_t;
-
-typedef struct afr_inode_params_ {
- afr_inode_op_t op;
- union {
- gf_boolean_t value;
- struct {
- int32_t read_child;
- int32_t *children;
- } read_ctx;
- } u;
-} afr_inode_params_t;
-
-typedef struct afr_inode_ctx_ {
- uint64_t masks;
- int32_t *fresh_children;//increasing order of latency
-} afr_inode_ctx_t;
-
-typedef enum {
- NONE,
- INDEX,
- FULL,
-} afr_crawl_type_t;
-
-typedef struct afr_self_heald_ {
- gf_boolean_t enabled;
- gf_boolean_t iamshd;
- afr_crawl_type_t *pending;
- gf_boolean_t *inprogress;
- afr_child_pos_t *pos;
- gf_timer_t **timer;
- eh_t *healed;
- eh_t *heal_failed;
- eh_t *split_brain;
- char *node_uuid;
- int timeout;
-} afr_self_heald_t;
-
typedef struct _afr_private {
gf_lock_t lock; /* to guard access to child_count, etc */
unsigned int child_count; /* total number of children */
@@ -108,6 +45,7 @@ typedef struct _afr_private {
xlator_t **children;
+ gf_lock_t root_inode_lk;
int first_lookup;
inode_t *root_inode;
@@ -115,7 +53,7 @@ typedef struct _afr_private {
char **pending_key;
- char *data_self_heal; /* on/off/open */
+ gf_boolean_t data_self_heal; /* on/off */
char * data_self_heal_algorithm; /* name of algorithm */
unsigned int data_self_heal_window_size; /* max number of pipelined
read/writes */
@@ -130,10 +68,13 @@ typedef struct _afr_private {
gf_boolean_t entry_change_log; /* on/off */
int read_child; /* read-subvolume */
- unsigned int hash_mode; /* for when read_child is not set */
int favorite_child; /* subvolume to be preferred in resolving
split-brain cases */
+ unsigned int data_lock_server_count;
+ unsigned int metadata_lock_server_count;
+ unsigned int entry_lock_server_count;
+
gf_boolean_t inodelk_trace;
gf_boolean_t entrylk_trace;
@@ -149,131 +90,94 @@ typedef struct _afr_private {
pthread_mutex_t mutex;
struct list_head saved_fds; /* list of fds on which locks have succeeded */
- gf_boolean_t optimistic_change_log;
- gf_boolean_t eager_lock;
- uint32_t post_op_delay_secs;
- unsigned int quorum_count;
+ gf_boolean_t optimistic_change_log;
char vol_uuid[UUID_SIZE + 1];
- int32_t *last_event;
- afr_self_heald_t shd;
- gf_boolean_t choose_local;
- gf_boolean_t did_discovery;
} afr_private_t;
typedef struct {
/* External interface: These are variables (some optional) that
are set by whoever has triggered self-heal */
- gf_boolean_t do_data_self_heal;
- gf_boolean_t do_metadata_self_heal;
- gf_boolean_t do_entry_self_heal;
- gf_boolean_t do_gfid_self_heal;
- gf_boolean_t do_missing_entry_self_heal;
- gf_boolean_t force_confirm_spb; /* Check for split-brains even when
- self-heal is turned off */
+ gf_boolean_t need_data_self_heal;
+ gf_boolean_t need_metadata_self_heal;
+ gf_boolean_t need_entry_self_heal;
gf_boolean_t forced_merge; /* Is this a self-heal triggered to
forcibly merge the directories? */
+ gf_boolean_t healing_fd_opened; /* true if caller has already
+ opened fd */
+
+ gf_boolean_t data_lock_held; /* true if caller has already
+ acquired 0-0 lock */
+
+ fd_t *healing_fd; /* set if callers has opened fd */
+
gf_boolean_t background; /* do self-heal in background
if possible */
+
ia_type_t type; /* st_mode of the entry we're doing
self-heal on */
- inode_t *inode; /* inode on which the self-heal is
- performed on */
- uuid_t sh_gfid_req; /* gfid self-heal needs to be done
- with this gfid if it is not null */
/* Function to call to unwind. If self-heal is being done in the
background, this function will be called as soon as possible. */
- int (*unwind) (call_frame_t *frame, xlator_t *this, int32_t op_ret,
- int32_t op_errno, int32_t sh_failed);
+ int (*unwind) (call_frame_t *frame, xlator_t *this);
/* End of external interface members */
/* array of stat's, one for each child */
struct iatt *buf;
- struct iatt *parentbufs;
struct iatt parentbuf;
struct iatt entrybuf;
- afr_expunge_done_cbk_t expunge_done;
- afr_impunge_done_cbk_t impunge_done;
-
/* array of xattr's, one for each child */
dict_t **xattr;
- /* array containing if the lookups succeeded in the order of response
- */
- int32_t *success_children;
- int success_count;
- /* array containing the fresh children found in the self-heal process */
- int32_t *fresh_children;
- /* array containing the fresh children found in the parent lookup */
- int32_t *fresh_parent_dirs;
/* array of errno's, one for each child */
int *child_errno;
- /*loc used for lookup*/
- loc_t lookup_loc;
- int32_t lookup_flags;
- afr_lookup_done_cbk_t lookup_done;
int32_t **pending_matrix;
int32_t **delta_matrix;
- int32_t op_ret;
- int32_t op_errno;
-
int *sources;
int source;
int active_source;
int active_sinks;
- unsigned char *success;
+ int *success;
unsigned char *locked_nodes;
int lock_count;
+ mode_t impunging_entry_mode;
const char *linkname;
- gf_boolean_t entries_skipped;
int op_failed;
- gf_boolean_t sync_done;
- gf_boolean_t data_lock_held;
- gf_boolean_t eof_reached;
- fd_t *healing_fd;
int file_has_holes;
blksize_t block_size;
off_t file_size;
off_t offset;
- unsigned char *write_needed;
- uint8_t *checksum;
- afr_post_remove_call_t post_remove_call;
loc_t parent_loc;
call_frame_t *orig_frame;
- call_frame_t *old_loop_frame;
gf_boolean_t unwound;
- afr_sh_algo_private_t *private;
+ /* private data for the particular self-heal algorithm */
+ void *private;
+
+ int (*flush_self_heal_cbk) (call_frame_t *frame, xlator_t *this);
- struct afr_sh_algorithm *algo;
- afr_lock_cbk_t data_lock_success_handler;
- afr_lock_cbk_t data_lock_failure_handler;
int (*completion_cbk) (call_frame_t *frame, xlator_t *this);
- int (*sh_data_algo_start) (call_frame_t *frame, xlator_t *this);
int (*algo_completion_cbk) (call_frame_t *frame, xlator_t *this);
int (*algo_abort_cbk) (call_frame_t *frame, xlator_t *this);
- void (*gfid_sh_success_cbk) (call_frame_t *sh_frame, xlator_t *this);
- gf_boolean_t mdata_spb;
- gf_boolean_t data_spb;
call_frame_t *sh_frame;
} afr_self_heal_t;
+
typedef enum {
AFR_DATA_TRANSACTION, /* truncate, write, ... */
AFR_METADATA_TRANSACTION, /* chmod, chown, ... */
@@ -359,11 +263,12 @@ typedef struct {
uint64_t lock_number;
int32_t lk_call_count;
- int32_t lk_expected_count;
int32_t lock_op_ret;
int32_t lock_op_errno;
- afr_lock_cbk_t lock_cbk;
+
+ int (*lock_cbk) (call_frame_t *, xlator_t *);
+
} afr_internal_lock_t;
typedef struct _afr_locked_fd {
@@ -385,7 +290,7 @@ typedef struct _afr_local {
unsigned char read_child_returned;
unsigned int first_up_child;
- gf_lkowner_t saved_lk_owner;
+ pid_t saved_pid;
int32_t op_ret;
int32_t op_errno;
@@ -396,12 +301,10 @@ typedef struct _afr_local {
loc_t newloc;
fd_t *fd;
- unsigned char *fd_open_on;
glusterfs_fop_t fop;
unsigned char *child_up;
- int32_t *fresh_children; //in the order of response
int32_t *child_errno;
@@ -418,10 +321,8 @@ typedef struct _afr_local {
dict_t *dict;
int optimistic_change_log;
- gf_boolean_t delayed_post_op;
- gf_boolean_t fop_paused;
- int (*fop_call_continue) (call_frame_t *frame, xlator_t *this);
+ int (*openfd_flush_cbk) (call_frame_t *frame, xlator_t *this);
/*
This struct contains the arguments for the "continuation"
@@ -436,25 +337,21 @@ typedef struct _afr_local {
} statfs;
struct {
- uint32_t parent_entrylk;
- uuid_t gfid_req;
inode_t *inode;
struct iatt buf;
+ struct iatt read_child_buf;
struct iatt postparent;
- dict_t **xattrs;
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
dict_t *xattr;
- struct iatt *postparents;
- struct iatt *bufs;
- int32_t read_child;
- int32_t *sources;
- int32_t *success_children;
- int32_t **pending_matrix;
- gf_boolean_t fresh_lookup;
- gf_boolean_t possible_spb;
+ dict_t **xattrs;
+ gf_boolean_t is_revalidate;
} lookup;
struct {
int32_t flags;
+ int32_t wbflags;
} open;
struct {
@@ -468,33 +365,35 @@ typedef struct _afr_local {
struct {
int32_t mask;
- int last_index; /* index of the child we tried previously */
+ int last_tried; /* index of the child we tried previously */
} access;
struct {
- int last_index;
+ int last_tried;
+ ino_t ino;
} stat;
struct {
- int last_index;
+ int last_tried;
+ ino_t ino;
} fstat;
struct {
size_t size;
- int last_index;
+ int last_tried;
+ ino_t ino;
} readlink;
struct {
char *name;
- int last_index;
- long xattr_len;
+ int last_tried;
} getxattr;
struct {
+ ino_t ino;
size_t size;
off_t offset;
- int last_index;
- uint32_t flags;
+ int last_tried;
} readv;
/* dir read */
@@ -512,13 +411,26 @@ typedef struct _afr_local {
int32_t op_errno;
size_t size;
off_t offset;
- dict_t *dict;
+
gf_boolean_t failed;
- int last_index;
+ int last_tried;
} readdir;
+
+ struct {
+ int32_t op_ret;
+ int32_t op_errno;
+
+ size_t size;
+ off_t offset;
+ int32_t flag;
+
+ int last_tried;
+ } getdents;
+
/* inode write */
struct {
+ ino_t ino;
struct iatt prebuf;
struct iatt postbuf;
@@ -528,27 +440,30 @@ typedef struct _afr_local {
struct iobref *iobref;
int32_t count;
off_t offset;
- uint32_t flags;
} writev;
struct {
+ ino_t ino;
struct iatt prebuf;
struct iatt postbuf;
} fsync;
struct {
+ ino_t ino;
off_t offset;
struct iatt prebuf;
struct iatt postbuf;
} truncate;
struct {
+ ino_t ino;
off_t offset;
struct iatt prebuf;
struct iatt postbuf;
} ftruncate;
struct {
+ ino_t ino;
struct iatt in_buf;
int32_t valid;
struct iatt preop_buf;
@@ -556,6 +471,7 @@ typedef struct _afr_local {
} setattr;
struct {
+ ino_t ino;
struct iatt in_buf;
int32_t valid;
struct iatt preop_buf;
@@ -568,25 +484,15 @@ typedef struct _afr_local {
} setxattr;
struct {
- dict_t *dict;
- int32_t flags;
- } fsetxattr;
-
- struct {
char *name;
} removexattr;
- struct {
- dict_t *xattr;
- } xattrop;
-
- struct {
- dict_t *xattr;
- } fxattrop;
-
/* dir write */
struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
fd_t *fd;
dict_t *params;
int32_t flags;
@@ -599,6 +505,9 @@ typedef struct _afr_local {
} create;
struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
dev_t dev;
mode_t mode;
dict_t *params;
@@ -610,6 +519,9 @@ typedef struct _afr_local {
} mknod;
struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
int32_t mode;
dict_t *params;
inode_t *inode;
@@ -620,6 +532,7 @@ typedef struct _afr_local {
} mkdir;
struct {
+ ino_t parent_ino;
int32_t op_ret;
int32_t op_errno;
struct iatt preparent;
@@ -628,6 +541,7 @@ typedef struct _afr_local {
struct {
int flags;
+ ino_t parent_ino;
int32_t op_ret;
int32_t op_errno;
struct iatt preparent;
@@ -635,6 +549,9 @@ typedef struct _afr_local {
} rmdir;
struct {
+ ino_t oldparent_ino;
+ ino_t newparent_ino;
+ ino_t ino;
struct iatt buf;
struct iatt read_child_buf;
struct iatt preoldparent;
@@ -644,6 +561,9 @@ typedef struct _afr_local {
} rename;
struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
inode_t *inode;
struct iatt buf;
struct iatt read_child_buf;
@@ -652,6 +572,9 @@ typedef struct _afr_local {
} link;
struct {
+ ino_t ino;
+ uint64_t gen;
+ ino_t parent_ino;
inode_t *inode;
dict_t *params;
struct iatt buf;
@@ -671,8 +594,6 @@ typedef struct _afr_local {
struct {
off_t start, len;
- int *eager_lock;
-
char *basename;
char *new_basename;
@@ -681,8 +602,12 @@ typedef struct _afr_local {
afr_transaction_type type;
- int32_t **txn_changelog;//changelog after pre+post ops
- unsigned char *pre_op;
+ int success_count;
+ int erase_pending;
+ int failure_count;
+
+ int last_tried;
+ int32_t *child_errno;
call_frame_t *main_frame;
@@ -700,36 +625,16 @@ typedef struct _afr_local {
afr_self_heal_t self_heal;
struct marker_str marker;
-
- /* extra data for fops */
- dict_t *xdata_req;
- dict_t *xdata_rsp;
-
- mode_t umask;
- int xflag;
- gf_boolean_t do_discovery;
} afr_local_t;
-typedef enum {
- AFR_FD_NOT_OPENED,
- AFR_FD_OPENED,
- AFR_FD_OPENING
-} afr_fd_open_status_t;
-
-typedef struct {
- struct list_head call_list;
- call_frame_t *frame;
-} afr_fd_paused_call_t;
typedef struct {
unsigned int *pre_op_done;
- afr_fd_open_status_t *opened_on; /* which subvolumes the fd is open on */
+ unsigned int *opened_on; /* which subvolumes the fd is open on */
unsigned int *pre_op_piggyback;
- unsigned int *lock_piggyback;
- unsigned int *lock_acquired;
-
int flags;
+ int32_t wbflags;
uint64_t up_count; /* number of CHILD_UPs this fd has seen */
uint64_t down_count; /* number of CHILD_DOWNs this fd has seen */
@@ -740,24 +645,19 @@ typedef struct {
struct list_head entries; /* needed for readdir failover */
unsigned char *locked_on; /* which subvolumes locks have been successful */
- struct list_head paused_calls; /* queued calls while fix_open happens */
-
- /* used for delayed-post-op optimization */
- pthread_mutex_t delay_lock;
- gf_timer_t *delay_timer;
- call_frame_t *delay_frame;
} afr_fd_ctx_t;
/* try alloc and if it fails, goto label */
-#define AFR_LOCAL_ALLOC_OR_GOTO(var, label) do { \
- var = mem_get0 (THIS->local_pool); \
- if (!var) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "out of memory :("); \
- op_errno = ENOMEM; \
- goto label; \
- } \
+#define ALLOC_OR_GOTO(var, type, label) do { \
+ var = GF_CALLOC (sizeof (type), 1, \
+ gf_afr_mt_##type); \
+ if (!var) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "out of memory :("); \
+ op_errno = ENOMEM; \
+ goto label; \
+ } \
} while (0);
@@ -778,7 +678,8 @@ int
pump_command_reply (call_frame_t *frame, xlator_t *this);
int32_t
-afr_notify (xlator_t *this, int32_t event, void *data, void *data2);
+afr_notify (xlator_t *this, int32_t event,
+ void *data, ...);
int
afr_attempt_lock_recovery (xlator_t *this, int32_t child_index);
@@ -791,7 +692,7 @@ afr_mark_locked_nodes (xlator_t *this, fd_t *fd,
unsigned char *locked_nodes);
void
-afr_set_lk_owner (call_frame_t *frame, xlator_t *this, void *lk_owner);
+afr_set_lk_owner (call_frame_t *frame, xlator_t *this);
int
afr_set_lock_number (call_frame_t *frame, xlator_t *this);
@@ -815,46 +716,32 @@ afr_blocking_lock (call_frame_t *frame, xlator_t *this);
int
afr_internal_lock_finish (call_frame_t *frame, xlator_t *this);
-void
-afr_lk_transfer_datalock (call_frame_t *dst, call_frame_t *src,
- unsigned int child_count);
int pump_start (call_frame_t *frame, xlator_t *this);
int
-__afr_fd_ctx_set (xlator_t *this, fd_t *fd);
-
-int
afr_fd_ctx_set (xlator_t *this, fd_t *fd);
-int32_t
-afr_inode_get_read_ctx (xlator_t *this, inode_t *inode, int32_t *fresh_children);
+uint64_t
+afr_read_child (xlator_t *this, inode_t *inode);
void
-afr_inode_set_read_ctx (xlator_t *this, inode_t *inode, int32_t read_child,
- int32_t *fresh_children);
-
-int
-afr_build_parent_loc (loc_t *parent, loc_t *child, int32_t *op_errno);
-
-unsigned int
-afr_up_children_count (unsigned char *child_up, unsigned int child_count);
+afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child);
-unsigned int
-afr_locked_children_count (unsigned char *children, unsigned int child_count);
+void
+afr_build_parent_loc (loc_t *parent, loc_t *child);
-unsigned int
-afr_pre_op_done_children_count (unsigned char *pre_op,
- unsigned int child_count);
+int
+afr_up_children_count (int child_count, unsigned char *child_up);
-gf_boolean_t
-afr_is_fresh_lookup (loc_t *loc, xlator_t *this);
+int
+afr_locked_nodes_count (unsigned char *locked_nodes, int child_count);
-void
-afr_update_loc_gfids (loc_t *loc, struct iatt *buf, struct iatt *postparent);
+ino64_t
+afr_itransform (ino64_t ino, int child_count, int child_index);
int
-afr_locked_nodes_count (unsigned char *locked_nodes, int child_count);
+afr_deitransform (ino64_t ino, int child_count);
void
afr_local_cleanup (afr_local_t *local, xlator_t *this);
@@ -862,7 +749,7 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this);
int
afr_frame_return (call_frame_t *frame);
-gf_boolean_t
+uint64_t
afr_is_split_brain (xlator_t *this, inode_t *inode);
void
@@ -870,12 +757,12 @@ afr_set_split_brain (xlator_t *this, inode_t *inode, gf_boolean_t set);
int
afr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata);
+ fd_t *fd, int32_t wbflags);
void
afr_set_opendir_done (xlator_t *this, inode_t *inode);
-gf_boolean_t
+uint64_t
afr_is_opendir_done (xlator_t *this, inode_t *inode);
void
@@ -885,7 +772,7 @@ int
afr_cleanup_fd_ctx (xlator_t *this, fd_t *fd);
int
-afr_launch_openfd_self_heal (call_frame_t *frame, xlator_t *this, fd_t *fd);
+afr_openfd_flush (call_frame_t *frame, xlator_t *this, fd_t *fd);
#define AFR_STACK_UNWIND(fop, frame, params ...) \
do { \
@@ -897,27 +784,22 @@ afr_launch_openfd_self_heal (call_frame_t *frame, xlator_t *this, fd_t *fd);
frame->local = NULL; \
} \
STACK_UNWIND_STRICT (fop, frame, params); \
- if (__local) { \
- afr_local_cleanup (__local, __this); \
- mem_put (__local); \
- } \
- } while (0)
+ afr_local_cleanup (__local, __this); \
+ GF_FREE (__local); \
+ } while (0);
-#define AFR_STACK_DESTROY(frame) \
- do { \
- afr_local_t *__local = NULL; \
- xlator_t *__this = NULL; \
- __local = frame->local; \
- __this = frame->this; \
- frame->local = NULL; \
- STACK_DESTROY (frame->root); \
- if (__local) { \
- afr_local_cleanup (__local, __this); \
- mem_put (__local); \
- } \
+#define AFR_STACK_DESTROY(frame) \
+ do { \
+ afr_local_t *__local = NULL; \
+ xlator_t *__this = NULL; \
+ __local = frame->local; \
+ __this = frame->this; \
+ frame->local = NULL; \
+ STACK_DESTROY (frame->root); \
+ afr_local_cleanup (__local, __this); \
+ GF_FREE (__local); \
} while (0);
-#define AFR_NUM_CHANGE_LOGS 3 /*data + metadata + entry*/
/* allocate and return a string that is the basename of argument */
static inline char *
AFR_BASENAME (const char *str)
@@ -930,149 +812,134 @@ AFR_BASENAME (const char *str)
return __basename_str;
}
-int
-afr_transaction_local_init (afr_local_t *local, xlator_t *this);
+/* initialize local_t */
+static inline int
+AFR_LOCAL_INIT (afr_local_t *local, afr_private_t *priv)
+{
+ int child_up_count = 0;
-int32_t
-afr_marker_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name,afr_local_t *local, afr_private_t *priv );
+ local->child_up = GF_CALLOC (sizeof (*local->child_up),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!local->child_up) {
+ return -ENOMEM;
+ }
-int32_t *
-afr_children_create (int32_t child_count);
+ memcpy (local->child_up, priv->child_up,
+ sizeof (*local->child_up) * priv->child_count);
-int
-afr_local_init (afr_local_t *local, afr_private_t *priv, int32_t *op_errno);
+ child_up_count = afr_up_children_count (priv->child_count, local->child_up);
-int
-afr_internal_lock_init (afr_internal_lock_t *lk, size_t child_count,
- transaction_lk_type_t lk_type);
+ if (priv->optimistic_change_log && child_up_count == priv->child_count)
+ local->optimistic_change_log = 1;
-int
-afr_first_up_child (unsigned char *child_up, size_t child_count);
+ local->call_count = afr_up_children_count (priv->child_count, local->child_up);
+ if (local->call_count == 0) {
+ gf_log (THIS->name, GF_LOG_INFO, "no subvolumes up");
+ return -ENOTCONN;
+ }
-int
-afr_select_read_child_from_policy (int32_t *fresh_children, int32_t child_count,
- int32_t prev_read_child,
- int32_t config_read_child, int32_t *sources,
- unsigned int hmode, uuid_t gfid);
+ local->transaction.erase_pending = 1;
-void
-afr_set_read_ctx_from_policy (xlator_t *this, inode_t *inode,
- int32_t *fresh_children, int32_t prev_read_child,
- int32_t config_read_child, uuid_t gfid);
+ local->op_ret = -1;
+ local->op_errno = EUCLEAN;
-int32_t
-afr_get_call_child (xlator_t *this, unsigned char *child_up, int32_t read_child,
- int32_t *fresh_children,
- int32_t *call_child, int32_t *last_index);
+ local->internal_lock.lock_op_ret = -1;
+ local->internal_lock.lock_op_errno = EUCLEAN;
-int32_t
-afr_next_call_child (int32_t *fresh_children, unsigned char *child_up,
- size_t child_count, int32_t *last_index,
- int32_t read_child);
-void
-afr_get_fresh_children (int32_t *success_children, int32_t *sources,
- int32_t *children, unsigned int child_count);
-void
-afr_children_add_child (int32_t *children, int32_t child,
- int32_t child_count);
-void
-afr_children_rm_child (int32_t *children, int32_t child,
- int32_t child_count);
-void
-afr_reset_children (int32_t *children, int32_t child_count);
-gf_boolean_t
-afr_error_more_important (int32_t old_errno, int32_t new_errno);
-int
-afr_errno_count (int32_t *children, int *child_errno,
- unsigned int child_count, int32_t op_errno);
-int
-afr_get_children_count (int32_t *children, unsigned int child_count);
-gf_boolean_t
-afr_is_child_present (int32_t *success_children, int32_t child_count,
- int32_t child);
-void
-afr_update_gfid_from_iatts (uuid_t uuid, struct iatt *bufs,
- int32_t *success_children,
- unsigned int child_count);
-void
-afr_reset_xattr (dict_t **xattr, unsigned int child_count);
-gf_boolean_t
-afr_conflicting_iattrs (struct iatt *bufs, int32_t *success_children,
- unsigned int child_count, const char *path,
- const char *xlator_name);
-unsigned int
-afr_gfid_missing_count (const char *xlator_name, int32_t *children,
- struct iatt *bufs, unsigned int child_count,
- const char *path);
-void
-afr_xattr_req_prepare (xlator_t *this, dict_t *xattr_req, const char *path);
-void
-afr_children_copy (int32_t *dst, int32_t *src, unsigned int child_count);
-afr_transaction_type
-afr_transaction_type_get (ia_type_t ia_type);
-int32_t
-afr_resultant_errno_get (int32_t *children,
- int *child_errno, unsigned int child_count);
-void
-afr_inode_rm_stale_children (xlator_t *this, inode_t *inode,
- int32_t *stale_children);
-void
-afr_launch_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode,
- gf_boolean_t background, ia_type_t ia_type, char *reason,
- void (*gfid_sh_success_cbk) (call_frame_t *sh_frame,
- xlator_t *this),
- int (*unwind) (call_frame_t *frame, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- int32_t sh_failed));
-int
-afr_fix_open (call_frame_t *frame, xlator_t *this, afr_fd_ctx_t *fd_ctx,
- int need_open_count, int *need_open);
-int
-afr_open_fd_fix (call_frame_t *frame, xlator_t *this, gf_boolean_t pause_fop);
-int
-afr_set_elem_count_get (unsigned char *elems, int child_count);
-afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this);
+ return 0;
+}
-gf_boolean_t
-afr_open_only_data_self_heal (char *data_self_heal);
-gf_boolean_t
-afr_data_self_heal_enabled (char *data_self_heal);
+/**
+ * first_up_child - return the index of the first child that is up
+ */
-void
-afr_set_low_priority (call_frame_t *frame);
-int
-afr_child_fd_ctx_set (xlator_t *this, fd_t *fd, int32_t child,
- int flags);
+static inline int
+afr_first_up_child (afr_private_t *priv)
+{
+ xlator_t ** children = NULL;
+ int ret = -1;
+ int i = 0;
+
+ LOCK (&priv->lock);
+ {
+ children = priv->children;
+ for (i = 0; i < priv->child_count; i++) {
+ if (priv->child_up[i]) {
+ ret = i;
+ break;
+ }
+ }
+ }
+ UNLOCK (&priv->lock);
-gf_boolean_t
-afr_have_quorum (char *logname, afr_private_t *priv);
+ return ret;
+}
-void
-afr_matrix_cleanup (int32_t **pending, unsigned int m);
-int32_t**
-afr_matrix_create (unsigned int m, unsigned int n);
-/*
- * Special value indicating we should use the "auto" quorum method instead of
- * a fixed value (including zero to turn off quorum enforcement).
- */
-#define AFR_QUORUM_AUTO INT_MAX
+static inline int
+afr_transaction_local_init (afr_local_t *local, afr_private_t *priv)
+{
+ int i;
-/*
- * Having this as a macro will make debugging a bit weirder, but does reduce
- * the probability of functions handling this check inconsistently.
- */
-#define QUORUM_CHECK(_func,_label) do { \
- if (priv->quorum_count && !afr_have_quorum(this->name,priv)) { \
- gf_log(this->name,GF_LOG_WARNING, \
- "failing "#_func" due to lack of quorum"); \
- op_errno = EROFS; \
- goto _label; \
- } \
-} while (0);
+ local->first_up_child = afr_first_up_child (priv);
+
+ local->child_errno = GF_CALLOC (sizeof (*local->child_errno),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+ if (!local->child_errno) {
+ return -ENOMEM;
+ }
+
+ local->pending = GF_CALLOC (sizeof (*local->pending),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+
+ if (!local->pending) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < priv->child_count; i++) {
+ local->pending[i] = GF_CALLOC (sizeof (*local->pending[i]),
+ 3, /* data + metadata + entry */
+ gf_afr_mt_int32_t);
+ if (!local->pending[i])
+ return -ENOMEM;
+ }
+
+ local->internal_lock.inode_locked_nodes =
+ GF_CALLOC (sizeof (*local->internal_lock.inode_locked_nodes),
+ priv->child_count,
+ gf_afr_mt_char);
+
+ local->internal_lock.entry_locked_nodes =
+ GF_CALLOC (sizeof (*local->internal_lock.entry_locked_nodes),
+ priv->child_count,
+ gf_afr_mt_char);
+
+ local->internal_lock.locked_nodes =
+ GF_CALLOC (sizeof (*local->internal_lock.locked_nodes),
+ priv->child_count,
+ gf_afr_mt_char);
+
+ local->internal_lock.lower_locked_nodes
+ = GF_CALLOC (sizeof (*local->internal_lock.lower_locked_nodes),
+ priv->child_count,
+ gf_afr_mt_char);
+
+ local->transaction.child_errno = GF_CALLOC (sizeof (*local->transaction.child_errno),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+
+ local->internal_lock.transaction_lk_type = AFR_TRANSACTION_LK;
+
+ return 0;
+}
+
+int32_t
+afr_marker_getxattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, const char *name,afr_local_t *local, afr_private_t *priv );
#endif /* __AFR_H__ */
diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c
index ff42d8dc1..c63011c81 100644
--- a/xlators/cluster/afr/src/pump.c
+++ b/xlators/cluster/afr/src/pump.c
@@ -1,17 +1,25 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
-#include <fnmatch.h>
#ifndef _CONFIG_H
#define _CONFIG_H
@@ -20,15 +28,6 @@
#include "afr-common.c"
#include "defaults.c"
-#include "glusterfs.h"
-
-static uint64_t pump_pid = 0;
-static inline void
-pump_fill_loc_info (loc_t *loc, struct iatt *iatt, struct iatt *parent)
-{
- afr_update_loc_gfids (loc, iatt, parent);
- uuid_copy (loc->inode->gfid, iatt->ia_gfid);
-}
static int
pump_mark_start_pending (xlator_t *this)
@@ -140,17 +139,85 @@ pump_set_resume_path (xlator_t *this, const char *path)
LOCK (&pump_priv->resume_path_lock);
{
- strncpy (pump_priv->resume_path, path, strlen (path) + 1);
+ pump_priv->resume_path = strdup (path);
+ if (!pump_priv->resume_path)
+ ret = -1;
}
UNLOCK (&pump_priv->resume_path_lock);
return ret;
}
+static void
+build_child_loc (loc_t *parent, loc_t *child, char *path, char *name)
+{
+ child->path = path;
+ child->name = name;
+
+ child->parent = inode_ref (parent->inode);
+ child->inode = inode_new (parent->inode->table);
+}
+
+static char *
+build_file_path (loc_t *loc, gf_dirent_t *entry)
+{
+ xlator_t *this = NULL;
+ char *file_path = NULL;
+ int pathlen = 0;
+ int total_size = 0;
+
+ this = THIS;
+
+ pathlen = STRLEN_0 (loc->path);
+
+ if (IS_ROOT_PATH (loc->path)) {
+ total_size = pathlen + entry->d_len;
+ file_path = GF_CALLOC (1, total_size, gf_afr_mt_char);
+ if (!file_path) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return NULL;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "constructing file path of size=%d"
+ "pathlen=%d, d_len=%d",
+ total_size, pathlen,
+ entry->d_len);
+
+ snprintf(file_path, total_size, "%s%s", loc->path, entry->d_name);
+
+ } else {
+ total_size = pathlen + entry->d_len + 1; /* for the extra '/' in the path */
+ file_path = GF_CALLOC (1, total_size + 1, gf_afr_mt_char);
+ if (!file_path) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return NULL;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "constructing file path of size=%d"
+ "pathlen=%d, d_len=%d",
+ total_size, pathlen,
+ entry->d_len);
+
+ snprintf(file_path, total_size, "%s/%s", loc->path, entry->d_name);
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "path=%s and d_name=%s", loc->path, entry->d_name);
+ gf_log (this->name, GF_LOG_TRACE,
+ "constructed file_path=%s of size=%d", file_path, total_size);
+
+ return file_path;
+}
+
static int
pump_save_path (xlator_t *this, const char *path)
{
afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
pump_state_t state;
dict_t *dict = NULL;
loc_t loc = {0};
@@ -162,30 +229,29 @@ pump_save_path (xlator_t *this, const char *path)
return 0;
priv = this->private;
+ pump_priv = priv->pump_private;
GF_ASSERT (priv->root_inode);
- afr_build_root_loc (this, &loc);
+ build_root_loc (priv->root_inode, &loc);
dict = dict_new ();
dict_ret = dict_set_str (dict, PUMP_PATH, (char *)path);
- if (dict_ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set the key %s", path, PUMP_PATH);
ret = syncop_setxattr (PUMP_SOURCE_CHILD (this), &loc, dict, 0);
if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
+ gf_log (this->name, GF_LOG_DEBUG,
"setxattr failed - could not save path=%s", path);
} else {
gf_log (this->name, GF_LOG_DEBUG,
"setxattr succeeded - saved path=%s", path);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Saving path for status info");
}
dict_unref (dict);
- loc_wipe (&loc);
return 0;
}
@@ -248,9 +314,15 @@ pump_get_resume_path (xlator_t *this)
static int
pump_update_resume_state (xlator_t *this, const char *path)
{
+ afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
+
pump_state_t state;
const char *resume_path = NULL;
+ priv = this->private;
+ pump_priv = priv->pump_private;
+
state = pump_get_state ();
if (state == PUMP_STATE_RESUME) {
@@ -278,10 +350,16 @@ pump_update_resume_state (xlator_t *this, const char *path)
static gf_boolean_t
is_pump_traversal_allowed (xlator_t *this, const char *path)
{
+ afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
+
pump_state_t state;
const char *resume_path = NULL;
gf_boolean_t ret = _gf_true;
+ priv = this->private;
+ pump_priv = priv->pump_private;
+
state = pump_get_state ();
if (state == PUMP_STATE_RESUME) {
@@ -324,33 +402,38 @@ pump_save_file_stats (xlator_t *this, const char *path)
static int
gf_pump_traverse_directory (loc_t *loc)
{
- xlator_t *this = NULL;
- fd_t *fd = NULL;
- off_t offset = 0;
- loc_t entry_loc = {0};
- gf_dirent_t *entry = NULL;
- gf_dirent_t *tmp = NULL;
- gf_dirent_t entries;
- struct iatt iatt = {0};
- struct iatt parent = {0};
- dict_t *xattr_rsp = NULL;
- int ret = 0;
- gf_boolean_t is_directory_empty = _gf_true;
- gf_boolean_t free_entries = _gf_false;
+ xlator_t *this = NULL;
+ afr_private_t *priv = NULL;
+ fd_t *fd = NULL;
+
+ off_t offset = 0;
+ loc_t entry_loc;
+ gf_dirent_t *entry = NULL;
+ gf_dirent_t *tmp = NULL;
+ gf_dirent_t entries;
+
+ struct iatt iatt, parent;
+ dict_t *xattr_rsp;
+
+ int source = 0;
+
+ char *file_path = NULL;
+ int ret = 0;
INIT_LIST_HEAD (&entries.list);
this = THIS;
+ priv = this->private;
GF_ASSERT (loc->inode);
- fd = fd_create (loc->inode, pump_pid);
+ fd = fd_create (loc->inode, PUMP_PID);
if (!fd) {
gf_log (this->name, GF_LOG_ERROR,
"Failed to create fd for %s", loc->path);
goto out;
}
- ret = syncop_opendir (this, loc, fd);
+ ret = syncop_opendir (priv->children[source], loc, fd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"opendir failed on %s", loc->path);
@@ -361,8 +444,7 @@ gf_pump_traverse_directory (loc_t *loc)
"pump opendir on %s returned=%d",
loc->path, ret);
- while (syncop_readdirp (this, fd, 131072, offset, NULL, &entries)) {
- free_entries = _gf_true;
+ while (syncop_readdirp (priv->children[source], fd, 131072, offset, &entries)) {
if (list_empty (&entries.list)) {
gf_log (this->name, GF_LOG_TRACE,
@@ -374,23 +456,25 @@ gf_pump_traverse_directory (loc_t *loc)
gf_log (this->name, GF_LOG_DEBUG,
"found readdir entry=%s", entry->d_name);
- offset = entry->d_off;
- if (uuid_is_null (entry->d_stat.ia_gfid)) {
- gf_log (this->name, GF_LOG_WARNING, "%s/%s: No "
- "gfid present skipping",
- loc->path, entry->d_name);
- continue;
- }
- loc_wipe (&entry_loc);
- ret = afr_build_child_loc (this, &entry_loc, loc,
- entry->d_name);
- if (ret)
+ file_path = build_file_path (loc, entry);
+ if (!file_path) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "file path construction failed");
goto out;
+ }
+
+ build_child_loc (loc, &entry_loc, file_path, entry->d_name);
if (!IS_ENTRY_CWD (entry->d_name) &&
- !IS_ENTRY_PARENT (entry->d_name)) {
+ !IS_ENTRY_PARENT (entry->d_name)) {
+
+ ret = syncop_lookup (this, &entry_loc, NULL,
+ &iatt, &xattr_rsp, &parent);
+
+ entry_loc.ino = iatt.ia_ino;
+ entry_loc.inode->ino = iatt.ia_ino;
+ memcpy (entry_loc.inode->gfid, iatt.ia_gfid, 16);
- is_directory_empty = _gf_false;
gf_log (this->name, GF_LOG_DEBUG,
"lookup %s => %"PRId64,
entry_loc.path,
@@ -399,14 +483,12 @@ gf_pump_traverse_directory (loc_t *loc)
ret = syncop_lookup (this, &entry_loc, NULL,
&iatt, &xattr_rsp, &parent);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: lookup failed",
- entry_loc.path);
- continue;
- }
- pump_fill_loc_info (&entry_loc, &iatt,
- &parent);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "second lookup ret=%d: %s => %"PRId64,
+ ret,
+ entry_loc.path,
+ iatt.ia_ino);
pump_update_resume_state (this, entry_loc.path);
@@ -420,6 +502,10 @@ gf_pump_traverse_directory (loc_t *loc)
goto out;
}
+ gf_log (this->name, GF_LOG_TRACE,
+ "type of file=%d, IFDIR=%d",
+ iatt.ia_type, IA_IFDIR);
+
if (IA_ISDIR (iatt.ia_type)) {
if (is_pump_traversal_allowed (this, entry_loc.path)) {
gf_log (this->name, GF_LOG_TRACE,
@@ -428,40 +514,47 @@ gf_pump_traverse_directory (loc_t *loc)
gf_pump_traverse_directory (&entry_loc);
}
}
- }
+ }
+ offset = entry->d_off;
+ loc_wipe (&entry_loc);
}
gf_dirent_free (&entries);
- free_entries = _gf_false;
gf_log (this->name, GF_LOG_TRACE,
"offset incremented to %d",
(int32_t ) offset);
}
- ret = syncop_close (fd);
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG, "closing the fd failed");
-
- if (is_directory_empty && IS_ROOT_PATH (loc->path)) {
- pump_change_state (this, PUMP_STATE_RUNNING);
- gf_log (this->name, GF_LOG_INFO, "Empty source brick. "
- "Nothing to be done.");
- }
-
out:
- if (entry_loc.path)
- loc_wipe (&entry_loc);
- if (free_entries)
- gf_dirent_free (&entries);
return 0;
+
+}
+
+void
+build_root_loc (inode_t *inode, loc_t *loc)
+{
+ loc->path = "/";
+ loc->name = "";
+ loc->inode = inode;
+ loc->ino = 1;
+ loc->inode->ino = 1;
+ memset (loc->inode->gfid, 0, 16);
+ loc->inode->gfid[15] = 1;
+
}
static int
pump_update_resume_path (xlator_t *this)
{
+ afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
+
const char *resume_path = NULL;
+ priv = this->private;
+ pump_priv = priv->pump_private;
+
resume_path = pump_get_resume_path (this);
if (resume_path) {
@@ -480,39 +573,6 @@ pump_update_resume_path (xlator_t *this)
return 0;
}
-static int32_t
-pump_xattr_cleaner (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- afr_private_t *priv = NULL;
- loc_t loc = {0};
- int i = 0;
- int ret = 0;
- int source = 0;
- int sink = 1;
-
- priv = this->private;
-
- afr_build_root_loc (this, &loc);
-
- ret = syncop_removexattr (priv->children[source], &loc,
- PUMP_PATH);
-
- ret = syncop_removexattr (priv->children[sink], &loc,
- PUMP_SINK_COMPLETE);
-
- for (i = 0; i < priv->child_count; i++) {
- ret = syncop_removexattr (priv->children[i], &loc,
- PUMP_SOURCE_COMPLETE);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "removexattr "
- "failed with %s", strerror (errno));
- }
-
- loc_wipe (&loc);
- return pump_command_reply (frame, this);
-}
-
static int
pump_complete_migration (xlator_t *this)
{
@@ -529,7 +589,7 @@ pump_complete_migration (xlator_t *this)
GF_ASSERT (priv->root_inode);
- afr_build_root_loc (this, &loc);
+ build_root_loc (priv->root_inode, &loc);
dict = dict_new ();
@@ -541,10 +601,6 @@ pump_complete_migration (xlator_t *this)
pump_priv->pump_finished = _gf_true;
dict_ret = dict_set_str (dict, PUMP_SOURCE_COMPLETE, "jargon");
- if (dict_ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set the key %s",
- loc.path, PUMP_SOURCE_COMPLETE);
ret = syncop_setxattr (PUMP_SOURCE_CHILD (this), &loc, dict, 0);
if (ret < 0) {
@@ -552,10 +608,6 @@ pump_complete_migration (xlator_t *this)
"setxattr failed - while notifying source complete");
}
dict_ret = dict_set_str (dict, PUMP_SINK_COMPLETE, "jargon");
- if (dict_ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set the key %s",
- loc.path, PUMP_SINK_COMPLETE);
ret = syncop_setxattr (PUMP_SINK_CHILD (this), &loc, dict, 0);
if (ret < 0) {
@@ -564,18 +616,26 @@ pump_complete_migration (xlator_t *this)
}
pump_save_path (this, "/");
-
- } else if (state == PUMP_STATE_ABORT) {
- gf_log (this->name, GF_LOG_DEBUG, "Starting cleanup "
- "of pump internal xattrs");
- call_resume (pump_priv->cleaner);
}
- loc_wipe (&loc);
return 0;
}
static int
+pump_set_root_gfid (dict_t *dict)
+{
+ uuid_t gfid;
+ int ret = 0;
+
+ memset (gfid, 0, 16);
+ gfid[15] = 1;
+
+ ret = afr_set_dict_gfid (dict, gfid);
+
+ return ret;
+}
+
+static int
pump_lookup_sink (loc_t *loc)
{
xlator_t *this = NULL;
@@ -588,7 +648,7 @@ pump_lookup_sink (loc_t *loc)
xattr_req = dict_new ();
- ret = afr_set_root_gfid (xattr_req);
+ ret = pump_set_root_gfid (xattr_req);
if (ret)
goto out;
@@ -627,7 +687,7 @@ pump_task (void *data)
GF_ASSERT (priv->root_inode);
- afr_build_root_loc (this, &loc);
+ build_root_loc (priv->root_inode, &loc);
xattr_req = dict_new ();
if (!xattr_req) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -636,13 +696,14 @@ pump_task (void *data)
goto out;
}
- afr_set_root_gfid (xattr_req);
+ pump_set_root_gfid (xattr_req);
ret = syncop_lookup (this, &loc, xattr_req,
&iatt, &xattr_rsp, &parent);
gf_log (this->name, GF_LOG_TRACE,
- "lookup: path=%s gfid=%s",
- loc.path, uuid_utoa (loc.inode->gfid));
+ "lookup: ino=%"PRId64", path=%s",
+ loc.ino,
+ loc.path);
ret = pump_check_and_update_status (this);
if (ret < 0) {
@@ -651,7 +712,7 @@ pump_task (void *data)
pump_update_resume_path (this);
- afr_set_root_gfid (xattr_req);
+ pump_set_root_gfid (xattr_req);
ret = pump_lookup_sink (&loc);
if (ret) {
pump_update_resume_path (this);
@@ -665,23 +726,26 @@ out:
if (xattr_req)
dict_unref (xattr_req);
- loc_wipe (&loc);
return 0;
}
static int
-pump_task_completion (int ret, call_frame_t *sync_frame, void *data)
+pump_task_completion (int ret, void *data)
{
xlator_t *this = NULL;
+ call_frame_t *frame = NULL;
afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
this = THIS;
+ frame = (call_frame_t *) data;
+
priv = this->private;
+ pump_priv = priv->pump_private;
inode_unref (priv->root_inode);
- STACK_DESTROY (sync_frame->root);
gf_log (this->name, GF_LOG_DEBUG,
"Pump xlator exiting");
@@ -699,22 +763,21 @@ pump_start (call_frame_t *pump_frame, xlator_t *this)
priv = this->private;
pump_priv = priv->pump_private;
- afr_set_lk_owner (pump_frame, this, pump_frame->root);
- pump_pid = (uint64_t) (unsigned long)pump_frame->root;
+ if (!pump_frame->root->lk_owner)
+ pump_frame->root->lk_owner = PUMP_LK_OWNER;
ret = synctask_new (pump_priv->env, pump_task,
pump_task_completion,
- pump_frame, NULL);
+ pump_frame);
if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_DEBUG,
"starting pump failed");
pump_change_state (this, PUMP_STATE_ABORT);
goto out;
}
- gf_log (this->name, GF_LOG_DEBUG,
- "setting pump as started lk_owner: %s %"PRIu64,
- lkowner_utoa (&pump_frame->root->lk_owner), pump_pid);
+ gf_log (this->name, GF_LOG_TRACE,
+ "setting pump as started");
priv->use_afr_in_pump = 1;
out:
@@ -748,7 +811,7 @@ pump_cmd_start_setxattr_cbk (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
call_frame_t *prev = NULL;
@@ -769,13 +832,13 @@ pump_cmd_start_setxattr_cbk (call_frame_t *frame,
"Successfully initiated destination "
"brick connect");
- pump_mark_start_pending (this);
-
/* send the PARENT_UP as pump is ready now */
prev = cookie;
if (prev && prev->this)
prev->this->notify (prev->this, GF_EVENT_PARENT_UP, this);
+ pump_mark_start_pending (this);
+
out:
local->op_ret = ret;
pump_command_reply (frame, this);
@@ -789,8 +852,7 @@ pump_initiate_sink_connect (call_frame_t *frame, xlator_t *this)
afr_local_t *local = NULL;
afr_private_t *priv = NULL;
dict_t *dict = NULL;
- data_t *data = NULL;
- char *clnt_cmd = NULL;
+ char *dst_brick = NULL;
loc_t loc = {0};
int ret = 0;
@@ -800,11 +862,10 @@ pump_initiate_sink_connect (call_frame_t *frame, xlator_t *this)
GF_ASSERT (priv->root_inode);
- afr_build_root_loc (this, &loc);
+ build_root_loc (priv->root_inode, &loc);
- data = data_ref (dict_get (local->dict, RB_PUMP_CMD_START));
- if (!data) {
- ret = -1;
+ ret = dict_get_str (local->dict, PUMP_CMD_START, &dst_brick);
+ if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"Could not get destination brick value");
goto out;
@@ -812,22 +873,17 @@ pump_initiate_sink_connect (call_frame_t *frame, xlator_t *this)
dict = dict_new ();
if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
ret = -1;
goto out;
}
- clnt_cmd = GF_CALLOC (1, data->len+1, gf_common_mt_char);
- if (!clnt_cmd) {
- ret = -1;
- goto out;
- }
-
- memcpy (clnt_cmd, data->data, data->len);
- clnt_cmd[data->len] = '\0';
- gf_log (this->name, GF_LOG_DEBUG, "Got destination brick %s\n",
- clnt_cmd);
+ GF_ASSERT (dst_brick);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Got destination brick as %s", dst_brick);
- ret = dict_set_dynstr (dict, CLIENT_CMD_CONNECT, clnt_cmd);
+ ret = dict_set_str (dict, CLIENT_CMD_CONNECT, dst_brick);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
"Could not inititiate destination brick "
@@ -841,21 +897,12 @@ pump_initiate_sink_connect (call_frame_t *frame, xlator_t *this)
PUMP_SINK_CHILD(this)->fops->setxattr,
&loc,
dict,
- 0, NULL);
+ 0);
ret = 0;
+ dict_unref (dict);
out:
- if (dict)
- dict_unref (dict);
-
- if (data)
- data_unref (data);
-
- if (ret && clnt_cmd)
- GF_FREE (clnt_cmd);
-
- loc_wipe (&loc);
return ret;
}
@@ -875,7 +922,7 @@ pump_cmd_start_getxattr_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
afr_local_t *local = NULL;
char *path = NULL;
@@ -979,23 +1026,19 @@ pump_execute_status (call_frame_t *frame, xlator_t *this)
dict = dict_new ();
- ret = dict_set_dynstr (dict, RB_PUMP_CMD_STATUS, dict_str);
+ ret = dict_set_str (dict, PUMP_CMD_STATUS, dict_str);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
- "dict_set_dynstr returned negative value");
- } else {
- dict_str = NULL;
+ "dict_set_str returned negative value");
}
op_ret = 0;
out:
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
-
- if (dict)
- dict_unref (dict);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+ dict_unref (dict);
GF_FREE (dict_str);
return 0;
@@ -1038,14 +1081,14 @@ pump_execute_start (call_frame_t *frame, xlator_t *this)
GF_ASSERT (priv->root_inode);
- afr_build_root_loc (this, &loc);
+ build_root_loc (priv->root_inode, &loc);
STACK_WIND (frame,
pump_cmd_start_getxattr_cbk,
PUMP_SOURCE_CHILD(this),
PUMP_SOURCE_CHILD(this)->fops->getxattr,
&loc,
- PUMP_PATH, NULL);
+ PUMP_PATH);
ret = 0;
@@ -1055,69 +1098,15 @@ out:
pump_command_reply (frame, this);
}
- loc_wipe (&loc);
return 0;
}
-static int
-pump_cleanup_helper (void *data) {
- call_frame_t *frame = data;
-
- pump_xattr_cleaner (frame, 0, frame->this, 0, 0, NULL);
-
- return 0;
-}
-
-static int
-pump_cleanup_done (int ret, call_frame_t *sync_frame, void *data)
-{
- STACK_DESTROY (sync_frame->root);
-
- return 0;
-}
-
-int
-pump_execute_commit (call_frame_t *frame, xlator_t *this)
-{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *sync_frame = NULL;
- int ret = 0;
-
- priv = this->private;
- pump_priv = priv->pump_private;
- local = frame->local;
-
- local->op_ret = 0;
- if (pump_priv->pump_finished) {
- pump_change_state (this, PUMP_STATE_COMMIT);
- sync_frame = create_frame (this, this->ctx->pool);
- ret = synctask_new (pump_priv->env, pump_cleanup_helper,
- pump_cleanup_done, sync_frame, frame);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Couldn't create "
- "synctask for cleaning up xattrs.");
- }
-
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Commit can't proceed. "
- "Migration in progress");
- local->op_ret = -1;
- local->op_errno = EINPROGRESS;
- pump_command_reply (frame, this);
- }
-
- return 0;
-}
int
pump_execute_abort (call_frame_t *frame, xlator_t *this)
{
- afr_private_t *priv = NULL;
- pump_private_t *pump_priv = NULL;
- afr_local_t *local = NULL;
- call_frame_t *sync_frame = NULL;
- int ret = 0;
+ afr_private_t *priv = NULL;
+ pump_private_t *pump_priv = NULL;
+ afr_local_t *local = NULL;
priv = this->private;
pump_priv = priv->pump_private;
@@ -1133,20 +1122,7 @@ pump_execute_abort (call_frame_t *frame, xlator_t *this)
UNLOCK (&pump_priv->resume_path_lock);
local->op_ret = 0;
- if (pump_priv->pump_finished) {
- sync_frame = create_frame (this, this->ctx->pool);
- ret = synctask_new (pump_priv->env, pump_cleanup_helper,
- pump_cleanup_done, sync_frame, frame);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Couldn't create "
- "synctask for cleaning up xattrs.");
- }
-
- } else {
- pump_priv->cleaner = fop_setxattr_cbk_stub (frame,
- pump_xattr_cleaner,
- 0, 0, NULL);
- }
+ pump_command_reply (frame, this);
return 0;
}
@@ -1158,7 +1134,7 @@ pump_command_status (xlator_t *this, dict_t *dict)
int dict_ret = -1;
int ret = _gf_true;
- dict_ret = dict_get_str (dict, RB_PUMP_CMD_STATUS, &cmd);
+ dict_ret = dict_get_str (dict, PUMP_CMD_STATUS, &cmd);
if (dict_ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"Not a pump status command");
@@ -1182,7 +1158,7 @@ pump_command_pause (xlator_t *this, dict_t *dict)
int dict_ret = -1;
int ret = _gf_true;
- dict_ret = dict_get_str (dict, RB_PUMP_CMD_PAUSE, &cmd);
+ dict_ret = dict_get_str (dict, PUMP_CMD_PAUSE, &cmd);
if (dict_ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"Not a pump pause command");
@@ -1200,37 +1176,13 @@ out:
}
gf_boolean_t
-pump_command_commit (xlator_t *this, dict_t *dict)
-{
- char *cmd = NULL;
- int dict_ret = -1;
- int ret = _gf_true;
-
- dict_ret = dict_get_str (dict, RB_PUMP_CMD_COMMIT, &cmd);
- if (dict_ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Not a pump commit command");
- ret = _gf_false;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Hit a pump command - commit");
- ret = _gf_true;
-
-out:
- return ret;
-
-}
-
-gf_boolean_t
pump_command_abort (xlator_t *this, dict_t *dict)
{
char *cmd = NULL;
int dict_ret = -1;
int ret = _gf_true;
- dict_ret = dict_get_str (dict, RB_PUMP_CMD_ABORT, &cmd);
+ dict_ret = dict_get_str (dict, PUMP_CMD_ABORT, &cmd);
if (dict_ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"Not a pump abort command");
@@ -1254,7 +1206,7 @@ pump_command_start (xlator_t *this, dict_t *dict)
int dict_ret = -1;
int ret = _gf_true;
- dict_ret = dict_get_str (dict, RB_PUMP_CMD_START, &cmd);
+ dict_ret = dict_get_str (dict, PUMP_CMD_START, &cmd);
if (dict_ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
"Not a pump start command");
@@ -1322,17 +1274,16 @@ __filter_xattrs (dict_t *dict)
int32_t
pump_getxattr_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
- afr_private_t *priv = NULL;
- afr_local_t *local = NULL;
- xlator_t **children = NULL;
- int unwind = 1;
- int32_t *last_index = NULL;
- int32_t next_call_child = -1;
- int32_t read_child = -1;
- int32_t *fresh_children = NULL;
+ afr_private_t * priv = NULL;
+ afr_local_t * local = NULL;
+ xlator_t ** children = NULL;
+ int unwind = 1;
+ int last_tried = -1;
+ int this_try = -1;
+ int read_child = -1;
priv = this->private;
children = priv->children;
@@ -1342,22 +1293,25 @@ pump_getxattr_cbk (call_frame_t *frame, void *cookie,
read_child = (long) cookie;
if (op_ret == -1) {
- last_index = &local->cont.getxattr.last_index;
- fresh_children = local->fresh_children;
- next_call_child = afr_next_call_child (fresh_children,
- local->child_up,
- priv->child_count,
- last_index, read_child);
- if (next_call_child < 0)
- goto out;
+ retry:
+ last_tried = local->cont.getxattr.last_tried;
+
+ if (all_tried (last_tried, priv->child_count)) {
+ goto out;
+ }
+ this_try = ++local->cont.getxattr.last_tried;
+
+ if (this_try == read_child) {
+ goto retry;
+ }
unwind = 0;
STACK_WIND_COOKIE (frame, pump_getxattr_cbk,
(void *) (long) read_child,
- children[next_call_child],
- children[next_call_child]->fops->getxattr,
+ children[this_try],
+ children[this_try]->fops->getxattr,
&local->loc,
- local->cont.getxattr.name, NULL);
+ local->cont.getxattr.name);
}
out:
@@ -1365,7 +1319,7 @@ out:
if (op_ret >= 0 && dict)
__filter_xattrs (dict);
- AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
}
return 0;
@@ -1373,15 +1327,17 @@ out:
int32_t
pump_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
afr_private_t * priv = NULL;
xlator_t ** children = NULL;
int call_child = 0;
- afr_local_t *local = NULL;
- int32_t ret = -1;
- int32_t op_errno = 0;
- uint64_t read_child = 0;
+ afr_local_t * local = NULL;
+
+ int read_child = -1;
+
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
@@ -1392,21 +1348,9 @@ pump_getxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (priv->children, out);
children = priv->children;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_getxattr_cbk,
- FIRST_CHILD (this),
- (FIRST_CHILD (this))->fops->getxattr,
- loc, name, xdata);
- return 0;
- }
-
- AFR_LOCAL_ALLOC_OR_GOTO (frame->local, out);
- local = frame->local;
-
- ret = afr_local_init (local, priv, &op_errno);
- if (ret < 0)
- goto out;
+ ALLOC_OR_GOTO (local, afr_local_t, out);
+ frame->local = local;
if (name) {
if (!strncmp (name, AFR_XATTR_PREFIX,
@@ -1416,33 +1360,42 @@ pump_getxattr (call_frame_t *frame, xlator_t *this,
goto out;
}
- if (!strcmp (name, RB_PUMP_CMD_STATUS)) {
+ if (!strcmp (name, PUMP_CMD_STATUS)) {
gf_log (this->name, GF_LOG_DEBUG,
"Hit pump command - status");
pump_execute_status (frame, this);
- ret = 0;
+ op_ret = 0;
goto out;
}
}
- local->fresh_children = GF_CALLOC (priv->child_count,
- sizeof (*local->fresh_children),
- gf_afr_mt_int32_t);
- if (!local->fresh_children) {
- ret = -1;
- op_errno = ENOMEM;
- goto out;
+ if (!priv->use_afr_in_pump) {
+ STACK_WIND (frame, default_getxattr_cbk,
+ FIRST_CHILD (this),
+ (FIRST_CHILD (this))->fops->getxattr,
+ loc, name);
+ return 0;
}
- read_child = afr_inode_get_read_ctx (this, loc->inode, local->fresh_children);
- ret = afr_get_call_child (this, local->child_up, read_child,
- local->fresh_children,
- &call_child,
- &local->cont.getxattr.last_index);
- if (ret < 0) {
- op_errno = -ret;
- goto out;
+ read_child = afr_read_child (this, loc->inode);
+
+ if (read_child >= 0) {
+ call_child = read_child;
+
+ local->cont.getxattr.last_tried = -1;
+ } else {
+ call_child = afr_first_up_child (priv);
+
+ if (call_child == -1) {
+ op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no child is up");
+ goto out;
+ }
+
+ local->cont.getxattr.last_tried = call_child;
}
+
loc_copy (&local->loc, loc);
if (name)
local->cont.getxattr.name = gf_strdup (name);
@@ -1450,12 +1403,13 @@ pump_getxattr (call_frame_t *frame, xlator_t *this,
STACK_WIND_COOKIE (frame, pump_getxattr_cbk,
(void *) (long) call_child,
children[call_child], children[call_child]->fops->getxattr,
- loc, name, xdata);
+ loc, name);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0)
- AFR_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
+ if (op_ret == -1) {
+ AFR_STACK_UNWIND (getxattr, frame, op_ret, op_errno, NULL);
+ }
return 0;
}
@@ -1463,9 +1417,11 @@ static int
afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
{
afr_local_t * local = NULL;
+ afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
local = frame->local;
+ priv = this->private;
LOCK (&frame->lock);
{
@@ -1477,14 +1433,14 @@ afr_setxattr_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
AFR_STACK_UNWIND (setxattr, main_frame,
- local->op_ret, local->op_errno, NULL);
+ local->op_ret, local->op_errno)
}
return 0;
}
static int
afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
@@ -1536,7 +1492,7 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
local = frame->local;
priv = this->private;
- call_count = afr_up_children_count (local->child_up, priv->child_count);
+ call_count = afr_up_children_count (priv->child_count, local->child_up);
if (call_count == 0) {
local->transaction.resume (frame, this);
@@ -1553,7 +1509,7 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this)
priv->children[i]->fops->setxattr,
&local->loc,
local->cont.setxattr.dict,
- local->cont.setxattr.flags, NULL);
+ local->cont.setxattr.flags);
if (!--call_count)
break;
@@ -1581,9 +1537,11 @@ pump_setxattr_cbk (call_frame_t *frame,
void *cookie,
xlator_t *this,
int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
- AFR_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND (frame,
+ op_ret,
+ op_errno);
return 0;
}
@@ -1601,10 +1559,12 @@ pump_command_reply (call_frame_t *frame, xlator_t *this)
gf_log (this->name, GF_LOG_INFO,
"Command succeeded");
+ dict_unref (local->dict);
+
AFR_STACK_UNWIND (setxattr,
frame,
local->op_ret,
- local->op_errno, NULL);
+ local->op_errno);
return 0;
}
@@ -1630,65 +1590,56 @@ pump_parse_command (call_frame_t *frame, xlator_t *this,
frame->local = local;
local->dict = dict_ref (dict);
ret = pump_execute_abort (frame, this);
-
- } else if (pump_command_commit (this, dict)) {
- frame->local = local;
- local->dict = dict_ref (dict);
- ret = pump_execute_commit (frame, this);
}
return ret;
}
int
pump_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata)
+ loc_t *loc, dict_t *dict, int32_t flags)
{
afr_private_t * priv = NULL;
afr_local_t * local = NULL;
call_frame_t *transaction_frame = NULL;
- data_pair_t * trav = NULL;
+
int ret = -1;
+
+ int op_ret = -1;
int op_errno = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (this->private, out);
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.pump*", dict,
- trav, op_errno, out);
-
priv = this->private;
- if (!priv->use_afr_in_pump) {
- STACK_WIND (frame, default_setxattr_cbk,
- FIRST_CHILD (this),
- (FIRST_CHILD (this))->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
- }
+ ALLOC_OR_GOTO (local, afr_local_t, out);
- AFR_LOCAL_ALLOC_OR_GOTO (local, out);
-
- ret = afr_local_init (local, priv, &op_errno);
+ ret = AFR_LOCAL_INIT (local, priv);
if (ret < 0) {
- afr_local_cleanup (local, this);
+ op_errno = -ret;
goto out;
- }
+ }
ret = pump_parse_command (frame, this,
local, dict);
if (ret >= 0) {
- ret = 0;
+ op_ret = 0;
goto out;
}
+ if (!priv->use_afr_in_pump) {
+ STACK_WIND (frame, default_setxattr_cbk,
+ FIRST_CHILD (this),
+ (FIRST_CHILD (this))->fops->setxattr,
+ loc, dict, flags);
+ return 0;
+ }
+
transaction_frame = copy_frame (frame);
if (!transaction_frame) {
gf_log (this->name, GF_LOG_ERROR,
"Out of memory.");
- op_errno = ENOMEM;
- ret = -1;
- afr_local_cleanup (local, this);
goto out;
}
@@ -1711,12 +1662,12 @@ pump_setxattr (call_frame_t *frame, xlator_t *this,
afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION);
- ret = 0;
+ op_ret = 0;
out:
- if (ret < 0) {
+ if (op_ret == -1) {
if (transaction_frame)
AFR_STACK_DESTROY (transaction_frame);
- AFR_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
+ AFR_STACK_UNWIND (setxattr, frame, op_ret, op_errno);
}
return 0;
@@ -1750,7 +1701,7 @@ static int32_t
pump_truncate (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1760,11 +1711,11 @@ pump_truncate (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
loc,
- offset, xdata);
+ offset);
return 0;
}
- afr_truncate (frame, this, loc, offset, xdata);
+ afr_truncate (frame, this, loc, offset);
return 0;
}
@@ -1773,7 +1724,7 @@ static int32_t
pump_ftruncate (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1783,11 +1734,11 @@ pump_ftruncate (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
fd,
- offset, xdata);
+ offset);
return 0;
}
- afr_ftruncate (frame, this, fd, offset, xdata);
+ afr_ftruncate (frame, this, fd, offset);
return 0;
}
@@ -1796,7 +1747,7 @@ pump_ftruncate (call_frame_t *frame,
int
pump_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dev_t rdev, dict_t *parms)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1804,10 +1755,10 @@ pump_mknod (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
+ loc, mode, rdev, parms);
return 0;
}
- afr_mknod (frame, this, loc, mode, rdev, umask, xdata);
+ afr_mknod (frame, this, loc, mode, rdev, parms);
return 0;
}
@@ -1816,7 +1767,7 @@ pump_mknod (call_frame_t *frame, xlator_t *this,
int
pump_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dict_t *params)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1824,10 +1775,10 @@ pump_mkdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
+ loc, mode, params);
return 0;
}
- afr_mkdir (frame, this, loc, mode, umask, xdata);
+ afr_mkdir (frame, this, loc, mode, params);
return 0;
}
@@ -1836,7 +1787,7 @@ pump_mkdir (call_frame_t *frame, xlator_t *this,
static int32_t
pump_unlink (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
+ loc_t *loc)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1845,10 +1796,10 @@ pump_unlink (call_frame_t *frame,
default_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
+ loc);
return 0;
}
- afr_unlink (frame, this, loc, xflag, xdata);
+ afr_unlink (frame, this, loc);
return 0;
}
@@ -1856,7 +1807,7 @@ pump_unlink (call_frame_t *frame,
static int
pump_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
+ loc_t *loc, int flags)
{
afr_private_t *priv = NULL;
@@ -1866,11 +1817,11 @@ pump_rmdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
+ loc, flags);
return 0;
}
- afr_rmdir (frame, this, loc, flags, xdata);
+ afr_rmdir (frame, this, loc, flags);
return 0;
}
@@ -1879,7 +1830,7 @@ pump_rmdir (call_frame_t *frame, xlator_t *this,
int
pump_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata)
+ const char *linkpath, loc_t *loc, dict_t *params)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1887,10 +1838,10 @@ pump_symlink (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
+ linkpath, loc, params);
return 0;
}
- afr_symlink (frame, this, linkpath, loc, umask, xdata);
+ afr_symlink (frame, this, linkpath, loc, params);
return 0;
}
@@ -1900,7 +1851,7 @@ static int32_t
pump_rename (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1909,10 +1860,10 @@ pump_rename (call_frame_t *frame,
default_rename_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
+ oldloc, newloc);
return 0;
}
- afr_rename (frame, this, oldloc, newloc, xdata);
+ afr_rename (frame, this, oldloc, newloc);
return 0;
}
@@ -1922,7 +1873,7 @@ static int32_t
pump_link (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1931,10 +1882,10 @@ pump_link (call_frame_t *frame,
default_link_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
+ oldloc, newloc);
return 0;
}
- afr_link (frame, this, oldloc, newloc, xdata);
+ afr_link (frame, this, oldloc, newloc);
return 0;
}
@@ -1943,7 +1894,7 @@ pump_link (call_frame_t *frame,
static int32_t
pump_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata)
+ fd_t *fd, dict_t *params)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1951,10 +1902,10 @@ pump_create (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
}
- afr_create (frame, this, loc, flags, mode, umask, fd, xdata);
+ afr_create (frame, this, loc, flags, mode, fd, params);
return 0;
}
@@ -1964,7 +1915,8 @@ static int32_t
pump_open (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+ int32_t flags, fd_t *fd,
+ int32_t wbflags)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -1973,10 +1925,10 @@ pump_open (call_frame_t *frame,
default_open_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
+ loc, flags, fd, wbflags);
return 0;
}
- afr_open (frame, this, loc, flags, fd, xdata);
+ afr_open (frame, this, loc, flags, fd, wbflags);
return 0;
}
@@ -1988,8 +1940,8 @@ pump_writev (call_frame_t *frame,
fd_t *fd,
struct iovec *vector,
int32_t count,
- off_t off, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
+ off_t off,
+ struct iobref *iobref)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2001,20 +1953,20 @@ pump_writev (call_frame_t *frame,
fd,
vector,
count,
- off, flags,
- iobref, xdata);
+ off,
+ iobref);
return 0;
}
-
- afr_writev (frame, this, fd, vector, count, off, flags, iobref, xdata);
+ afr_writev (frame, this, fd, vector, count, off, iobref);
return 0;
+
}
static int32_t
pump_flush (call_frame_t *frame,
xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2023,10 +1975,10 @@ pump_flush (call_frame_t *frame,
default_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
+ fd);
return 0;
}
- afr_flush (frame, this, fd, xdata);
+ afr_flush (frame, this, fd);
return 0;
}
@@ -2036,7 +1988,7 @@ static int32_t
pump_fsync (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2046,10 +1998,10 @@ pump_fsync (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
fd,
- flags, xdata);
+ flags);
return 0;
}
- afr_fsync (frame, this, fd, flags, xdata);
+ afr_fsync (frame, this, fd, flags);
return 0;
}
@@ -2058,7 +2010,7 @@ pump_fsync (call_frame_t *frame,
static int32_t
pump_opendir (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+ loc_t *loc, fd_t *fd)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2067,10 +2019,10 @@ pump_opendir (call_frame_t *frame,
default_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
+ loc, fd);
return 0;
}
- afr_opendir (frame, this, loc, fd, xdata);
+ afr_opendir (frame, this, loc, fd);
return 0;
}
@@ -2080,7 +2032,7 @@ static int32_t
pump_fsyncdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2090,10 +2042,10 @@ pump_fsyncdir (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsyncdir,
fd,
- flags, xdata);
+ flags);
return 0;
}
- afr_fsyncdir (frame, this, fd, flags, xdata);
+ afr_fsyncdir (frame, this, fd, flags);
return 0;
}
@@ -2104,7 +2056,7 @@ pump_xattrop (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2115,10 +2067,10 @@ pump_xattrop (call_frame_t *frame,
FIRST_CHILD(this)->fops->xattrop,
loc,
flags,
- dict, xdata);
+ dict);
return 0;
}
- afr_xattrop (frame, this, loc, flags, dict, xdata);
+ afr_xattrop (frame, this, loc, flags, dict);
return 0;
}
@@ -2128,7 +2080,7 @@ pump_fxattrop (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2139,10 +2091,10 @@ pump_fxattrop (call_frame_t *frame,
FIRST_CHILD(this)->fops->fxattrop,
fd,
flags,
- dict, xdata);
+ dict);
return 0;
}
- afr_fxattrop (frame, this, fd, flags, dict, xdata);
+ afr_fxattrop (frame, this, fd, flags, dict);
return 0;
}
@@ -2152,17 +2104,9 @@ static int32_t
pump_removexattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
- afr_private_t *priv = NULL;
- int op_errno = -1;
-
- VALIDATE_OR_GOTO (this, out);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.pump*",
- name, op_errno, out);
-
- op_errno = 0;
+ afr_private_t *priv = NULL;
priv = this->private;
if (!priv->use_afr_in_pump) {
STACK_WIND (frame,
@@ -2170,14 +2114,10 @@ pump_removexattr (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
loc,
- name, xdata);
+ name);
return 0;
}
- afr_removexattr (frame, this, loc, name, xdata);
-
- out:
- if (op_errno)
- AFR_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
+ afr_removexattr (frame, this, loc, name);
return 0;
}
@@ -2189,7 +2129,7 @@ pump_readdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t off, dict_t *xdata)
+ off_t off)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2198,18 +2138,21 @@ pump_readdir (call_frame_t *frame,
default_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
+ fd, size, off);
return 0;
}
- afr_readdir (frame, this, fd, size, off, xdata);
+ afr_readdir (frame, this, fd, size, off);
return 0;
}
static int32_t
-pump_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *dict)
+pump_readdirp (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t off)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2218,10 +2161,10 @@ pump_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
default_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, off, dict);
+ fd, size, off);
return 0;
}
- afr_readdirp (frame, this, fd, size, off, dict);
+ afr_readdirp (frame, this, fd, size, off);
return 0;
}
@@ -2252,24 +2195,13 @@ pump_release (xlator_t *this,
}
-static int32_t
-pump_forget (xlator_t *this, inode_t *inode)
-{
- afr_private_t *priv = NULL;
-
- priv = this->private;
- if (priv->use_afr_in_pump)
- afr_forget (this, inode);
-
- return 0;
-}
static int32_t
pump_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+ int32_t valid)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2278,10 +2210,10 @@ pump_setattr (call_frame_t *frame,
default_setattr_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
return 0;
}
- afr_setattr (frame, this, loc, stbuf, valid, xdata);
+ afr_setattr (frame, this, loc, stbuf, valid);
return 0;
}
@@ -2292,7 +2224,7 @@ pump_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+ int32_t valid)
{
afr_private_t *priv = NULL;
priv = this->private;
@@ -2301,10 +2233,10 @@ pump_fsetattr (call_frame_t *frame,
default_fsetattr_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
return 0;
}
- afr_fsetattr (frame, this, fd, stbuf, valid, xdata);
+ afr_fsetattr (frame, this, fd, stbuf, valid);
return 0;
}
@@ -2353,7 +2285,7 @@ notify (xlator_t *this, int32_t event,
child_xl = (xlator_t *) data;
- ret = afr_notify (this, event, data, NULL);
+ ret = afr_notify (this, event, data);
switch (event) {
case GF_EVENT_CHILD_DOWN:
@@ -2388,7 +2320,7 @@ init (xlator_t *this)
xlator_list_t * trav = NULL;
int i = 0;
int ret = -1;
- GF_UNUSED int op_errno = 0;
+ int op_errno = 0;
int source_child = 0;
@@ -2404,32 +2336,15 @@ init (xlator_t *this)
"Volume is dangling.");
}
- this->private = GF_CALLOC (1, sizeof (afr_private_t),
- gf_afr_mt_afr_private_t);
- if (!this->private)
- goto out;
+ ALLOC_OR_GOTO (this->private, afr_private_t, out);
priv = this->private;
- LOCK_INIT (&priv->lock);
- LOCK_INIT (&priv->read_child_lock);
- //lock recovery is not done in afr
- pthread_mutex_init (&priv->mutex, NULL);
- INIT_LIST_HEAD (&priv->saved_fds);
-
- child_count = xlator_subvolume_count (this);
- if (child_count != 2) {
- gf_log (this->name, GF_LOG_ERROR,
- "There should be exactly 2 children - one source "
- "and one sink");
- return -1;
- }
- priv->child_count = child_count;
priv->read_child = source_child;
priv->favorite_child = source_child;
priv->background_self_heal_count = 0;
- priv->data_self_heal = "on";
+ priv->data_self_heal = 1;
priv->metadata_self_heal = 1;
priv->entry_self_heal = 1;
@@ -2449,9 +2364,31 @@ init (xlator_t *this)
and the sink.
*/
+ priv->data_lock_server_count = 2;
+ priv->metadata_lock_server_count = 2;
+ priv->entry_lock_server_count = 2;
+
priv->strict_readdir = _gf_false;
+ trav = this->children;
+ while (trav) {
+ child_count++;
+ trav = trav->next;
+ }
+
priv->wait_count = 1;
+
+ if (child_count != 2) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "There should be exactly 2 children - one source "
+ "and one sink");
+ return -1;
+ }
+ priv->child_count = child_count;
+
+ LOCK_INIT (&priv->lock);
+ LOCK_INIT (&priv->read_child_lock);
+
priv->child_up = GF_CALLOC (sizeof (unsigned char), child_count,
gf_afr_mt_char);
if (!priv->child_up) {
@@ -2485,8 +2422,8 @@ init (xlator_t *this)
while (i < child_count) {
priv->children[i] = trav->xlator;
- ret = gf_asprintf (&priv->pending_key[i], "%s.%s", AFR_XATTR_PREFIX,
- trav->xlator->name);
+ ret = asprintf (&priv->pending_key[i], "%s.%s", AFR_XATTR_PREFIX,
+ trav->xlator->name);
if (-1 == ret) {
gf_log (this->name, GF_LOG_ERROR,
"asprintf failed to set pending key");
@@ -2501,13 +2438,6 @@ init (xlator_t *this)
priv->first_lookup = 1;
priv->root_inode = NULL;
- priv->last_event = GF_CALLOC (child_count, sizeof (*priv->last_event),
- gf_afr_mt_int32_t);
- if (!priv->last_event) {
- ret = -ENOMEM;
- goto out;
- }
-
pump_priv = GF_CALLOC (1, sizeof (*pump_priv),
gf_afr_mt_pump_priv);
if (!pump_priv) {
@@ -2537,17 +2467,11 @@ init (xlator_t *this)
goto out;
}
- /* keep more local here as we may need them for self-heal etc */
- this->local_pool = mem_pool_new (afr_local_t, 128);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
priv->pump_private = pump_priv;
+ pthread_mutex_init (&priv->mutex, NULL);
+ INIT_LIST_HEAD (&priv->saved_fds);
+
pump_change_state (this, PUMP_STATE_ABORT);
ret = 0;
@@ -2558,28 +2482,6 @@ out:
int
fini (xlator_t *this)
{
- afr_private_t * priv = NULL;
- pump_private_t *pump_priv = NULL;
-
- priv = this->private;
- this->private = NULL;
- if (!priv)
- goto out;
-
- pump_priv = priv->pump_private;
- if (!pump_priv)
- goto afr_priv;
-
- if (pump_priv->env)
- syncenv_destroy (pump_priv->env);
-
- GF_FREE (pump_priv->resume_path);
- LOCK_DESTROY (&pump_priv->resume_path_lock);
- LOCK_DESTROY (&pump_priv->pump_state_lock);
- GF_FREE (pump_priv);
-afr_priv:
- afr_priv_destroy (priv);
-out:
return 0;
}
@@ -2627,7 +2529,6 @@ struct xlator_dumpops dumpops = {
struct xlator_cbks cbks = {
.release = pump_release,
.releasedir = pump_releasedir,
- .forget = pump_forget,
};
struct volume_options options[] = {
diff --git a/xlators/cluster/afr/src/pump.h b/xlators/cluster/afr/src/pump.h
index bc4c31a78..a46f9d7a5 100644
--- a/xlators/cluster/afr/src/pump.h
+++ b/xlators/cluster/afr/src/pump.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __PUMP_H__
@@ -17,6 +26,18 @@
#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"
#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
+#define PUMP_PID 696969
+#define PUMP_LK_OWNER 696969
+
+#define IS_ROOT_PATH(path) (!strcmp (path, "/"))
+#define IS_ENTRY_CWD(entry) (!strcmp (entry, "."))
+#define IS_ENTRY_PARENT(entry) (!strcmp (entry, ".."))
+
+#define PUMP_CMD_START "trusted.glusterfs.pump.start"
+#define PUMP_CMD_ABORT "trusted.glusterfs.pump.abort"
+#define PUMP_CMD_PAUSE "trusted.glusterfs.pump.pause"
+#define PUMP_CMD_STATUS "trusted.glusterfs.pump.status"
+
#define PUMP_SOURCE_COMPLETE "trusted.glusterfs.pump-source-complete"
#define PUMP_SINK_COMPLETE "trusted.glusterfs.pump-sink-complete"
@@ -30,12 +51,11 @@ typedef enum {
PUMP_STATE_RESUME, /* Pump is resuming from a previous pause */
PUMP_STATE_PAUSE, /* Pump is paused */
PUMP_STATE_ABORT, /* Pump is aborted */
- PUMP_STATE_COMMIT, /* Pump is commited */
} pump_state_t;
typedef struct _pump_private {
struct syncenv *env; /* The env pointer to the pump synctask */
- char *resume_path; /* path to resume from the last pause */
+ const char *resume_path; /* path to resume from the last pause */
gf_lock_t resume_path_lock; /* Synchronize resume_path changes */
gf_lock_t pump_state_lock; /* Synchronize pump_state changes */
pump_state_t pump_state; /* State of pump */
@@ -44,7 +64,6 @@ typedef struct _pump_private {
gf_boolean_t pump_finished; /* Boolean to indicate pump termination */
char pump_start_pending; /* Boolean to mark start pending until
CHILD_UP */
- call_stub_t *cleaner;
} pump_private_t;
void
diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am
index e35058d65..8ebcab044 100644
--- a/xlators/cluster/dht/src/Makefile.am
+++ b/xlators/cluster/dht/src/Makefile.am
@@ -2,12 +2,12 @@
xlator_LTLIBRARIES = dht.la nufa.la switch.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
-dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c dht-rebalance.c \
- dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \
- dht-common.c dht-inode-write.c dht-inode-read.c \
- $(top_builddir)/xlators/lib/src/libxlator.c
-dht_la_SOURCES = $(dht_common_source) dht.c
+dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c \
+ dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \
+ $(top_builddir)/xlators/lib/src/libxlator.c
+
+dht_la_SOURCES = $(dht_common_source) dht.c
nufa_la_SOURCES = $(dht_common_source) nufa.c
switch_la_SOURCES = $(dht_common_source) switch.c
@@ -21,14 +21,13 @@ nufa_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
switch_la_LDFLAGS = -module -avoidversion
switch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = dht-common.h dht-mem-types.h \
- $(top_builddir)/xlators/lib/src/libxlator.h
+noinst_HEADERS = dht-common.h dht-common.c dht-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
-I$(top_srcdir)/xlators/lib/src
-CLEANFILES =
+CLEANFILES =
uninstall-local:
rm -f $(DESTDIR)$(xlatordir)/distribute.so
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 5b57552c3..35bf180f5 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -26,13 +35,13 @@
#include <sys/time.h>
#include <libgen.h>
+
void
dht_aggregate (dict_t *this, char *key, data_t *value, void *data)
{
dict_t *dst = NULL;
int64_t *ptr = 0, *size = NULL;
int32_t ret = -1;
- data_pair_t *data_pair = NULL;
dst = data;
@@ -62,20 +71,6 @@ dht_aggregate (dict_t *this, char *key, data_t *value, void *data)
}
*size = hton64 (ntoh64 (*size) + ntoh64 (*ptr));
- } else {
- /* compare user xattrs only */
- if (!strncmp (key, "user.", strlen ("user."))) {
- ret = dict_lookup (dst, key, &data_pair);
- if (!ret && data_pair && value) {
- ret = is_data_equal (data_pair->value, value);
- if (!ret)
- gf_log ("dht", GF_LOG_DEBUG,
- "xattr mismatch for %s", key);
- }
- }
- ret = dict_set (dst, key, value);
- if (ret)
- gf_log ("dht", GF_LOG_WARNING, "xattr dict set failed");
}
return;
@@ -105,7 +100,7 @@ out:
int
dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+ int op_ret, int op_errno)
{
dht_local_t *local = NULL;
dht_layout_t *layout = NULL;
@@ -123,12 +118,21 @@ dht_lookup_selfheal_cbk (call_frame_t *frame, void *cookie,
if (ret == 0) {
layout = local->selfheal.layout;
ret = dht_layout_set (this, local->inode, layout);
+
+ if (local->ia_ino) {
+ local->stbuf.ia_ino = local->ia_ino;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not find hashed subvolume for %s",
+ local->loc.path);
+ }
+
+ if (local->loc.parent)
+ local->postparent.ia_ino = local->loc.parent->ino;
}
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
-
DHT_STACK_UNWIND (lookup, frame, ret, local->op_errno, local->inode,
&local->stbuf, local->xattr, &local->postparent);
@@ -138,91 +142,18 @@ out:
int
-dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
-{
- dht_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
- int op_errno = 0;
- int ret = -1;
- dht_layout_t *layout = NULL;
-
- local = discover_frame->local;
- layout = local->layout;
-
- LOCK(&discover_frame->lock);
- {
- main_frame = local->main_frame;
- local->main_frame = NULL;
- }
- UNLOCK(&discover_frame->lock);
-
- if (!main_frame)
- return 0;
-
- if (local->file_count && local->dir_count) {
- gf_log (this->name, GF_LOG_ERROR,
- "path %s exists as a file on one subvolume "
- "and directory on another. "
- "Please fix it manually",
- local->loc.path);
- op_errno = EIO;
- goto out;
- }
-
- if (local->cached_subvol) {
- ret = dht_layout_preset (this, local->cached_subvol,
- local->inode);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set layout for subvolume %s",
- local->cached_subvol ? local->cached_subvol->name : "<nil>");
- op_errno = EINVAL;
- goto out;
- }
- } else {
- ret = dht_layout_normalize (this, &local->loc, layout);
- if ((ret < 0) || ((ret > 0) && (local->op_ret != 0))) {
- /* either the layout is incorrect or the directory is
- * not found even in one subvolume.
- */
- gf_log (this->name, GF_LOG_DEBUG,
- "normalizing failed on %s "
- "(overlaps/holes present: %s, "
- "ENOENT errors: %d)", local->loc.path,
- (ret < 0) ? "yes" : "no", (ret > 0) ? ret : 0);
- op_errno = EINVAL;
- goto out;
- }
-
- dht_layout_set (this, local->inode, layout);
- }
-
- DHT_STACK_UNWIND (lookup, main_frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf, local->xattr,
- &local->postparent);
- return 0;
-out:
- DHT_STACK_UNWIND (lookup, main_frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
-
- return ret;
-}
-
-
-int
-dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent)
+dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xattr,
+ struct iatt *postparent)
{
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
dht_layout_t *layout = NULL;
int ret = -1;
int is_dir = 0;
- int is_linkfile = 0;
- int attempt_unwind = 0;
GF_VALIDATE_OR_GOTO ("dht", frame, out);
GF_VALIDATE_OR_GOTO ("dht", this, out);
@@ -230,11 +161,15 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_VALIDATE_OR_GOTO ("dht", this->private, out);
GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+ conf = this->private;
local = frame->local;
prev = cookie;
layout = local->layout;
+ if (!op_ret && uuid_is_null (local->gfid))
+ memcpy (local->gfid, stbuf->ia_gfid, 16);
+
/* Check if the gfid is different for file from other node */
if (!op_ret && uuid_compare (local->gfid, stbuf->ia_gfid)) {
gf_log (this->name, GF_LOG_WARNING,
@@ -242,7 +177,6 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->loc.path, prev->this->name);
}
-
LOCK (&frame->lock);
{
/* TODO: assert equal mode on stbuf->st_mode and
@@ -252,12 +186,9 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, xattr);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to merge layouts", local->loc.path);
if (op_ret == -1) {
- local->op_errno = op_errno;
+ local->op_errno = ENOENT;
gf_log (this->name, GF_LOG_DEBUG,
"lookup of %s on %s returned error (%s)",
local->loc.path, prev->this->name,
@@ -266,25 +197,17 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
- is_linkfile = check_is_linkfile (inode, stbuf, xattr);
is_dir = check_is_dir (inode, stbuf, xattr);
-
- if (is_dir) {
- local->dir_count ++;
- } else {
- local->file_count ++;
-
- if (!is_linkfile) {
- /* real file */
- local->cached_subvol = prev->this;
- attempt_unwind = 1;
- } else {
- goto unlock;
- }
+ if (!is_dir) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of %s on %s returned non dir 0%o",
+ local->loc.path, prev->this->name,
+ stbuf->ia_type);
+ local->need_selfheal = 1;
+ goto unlock;
}
local->op_ret = 0;
-
if (local->xattr == NULL) {
local->xattr = dict_ref (xattr);
} else {
@@ -297,97 +220,73 @@ dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
dht_iatt_merge (this, &local->postparent, postparent,
prev->this);
+
+ if (!local->ia_ino &&
+ (prev->this == dht_first_up_subvol (this))) {
+ local->ia_ino = local->stbuf.ia_ino;
+ }
+
}
unlock:
UNLOCK (&frame->lock);
-out:
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt) || attempt_unwind) {
- dht_discover_complete (this, frame);
- }
- if (is_last_call (this_call_cnt))
- DHT_STACK_DESTROY (frame);
-
- return 0;
-}
-
-
-int
-dht_discover (call_frame_t *frame, xlator_t *this, loc_t *loc)
-{
- int ret;
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- int call_cnt = 0;
- int op_errno = EINVAL;
- int i = 0;
- call_frame_t *discover_frame = NULL;
-
-
- conf = this->private;
- local = frame->local;
-
- ret = dict_set_uint32 (local->xattr_req,
- "trusted.glusterfs.dht", 4 * 4);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set 'trusted.glusterfs.dht' key",
- loc->path);
-
- ret = dict_set_uint32 (local->xattr_req,
- "trusted.glusterfs.dht.linkto", 256);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set 'trusted.glusterfs.dht.linkto' key",
- loc->path);
+ this_call_cnt = dht_frame_return (frame);
- call_cnt = conf->subvolume_cnt;
- local->call_cnt = call_cnt;
+ if (is_last_call (this_call_cnt)) {
+ if (local->need_selfheal) {
+ local->need_selfheal = 0;
+ dht_lookup_everywhere (frame, this, &local->loc);
+ return 0;
+ }
- local->layout = dht_layout_new (this, conf->subvolume_cnt);
+ if (local->op_ret == 0) {
+ ret = dht_layout_normalize (this, &local->loc, layout);
- if (!local->layout) {
- op_errno = ENOMEM;
- goto err;
- }
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "fixing assignment on %s",
+ local->loc.path);
+ goto selfheal;
+ }
- uuid_copy (local->gfid, loc->gfid);
+ dht_layout_set (this, local->inode, layout);
- discover_frame = copy_frame (frame);
- if (!discover_frame) {
- op_errno = ENOMEM;
- goto err;
- }
+ if (local->ia_ino) {
+ local->stbuf.ia_ino = local->ia_ino;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "could not find hashed subvol for %s",
+ local->loc.path);
+ }
- discover_frame->local = local;
- frame->local = NULL;
- local->main_frame = frame;
+ if (local->loc.parent)
+ local->postparent.ia_ino =
+ local->loc.parent->ino;
+ }
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (discover_frame, dht_discover_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->lookup,
- &local->loc, local->xattr_req);
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
+ &local->postparent);
}
return 0;
-err:
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
-
- return 0;
+selfheal:
+ FRAME_SU_DO (frame, dht_local_t);
+ ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk,
+ &local->loc, layout);
+out:
+ return ret;
}
-
int
-dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent)
+dht_lookup_root_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xattr,
+ struct iatt *postparent)
{
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
@@ -401,48 +300,32 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_VALIDATE_OR_GOTO ("dht", this->private, out);
GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+ conf = this->private;
local = frame->local;
prev = cookie;
layout = local->layout;
- if (!op_ret && uuid_is_null (local->gfid))
- memcpy (local->gfid, stbuf->ia_gfid, 16);
-
- /* Check if the gfid is different for file from other node */
- if (!op_ret && uuid_compare (local->gfid, stbuf->ia_gfid)) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: gfid different on %s",
- local->loc.path, prev->this->name);
- }
-
LOCK (&frame->lock);
{
- /* TODO: assert equal mode on stbuf->st_mode and
- local->stbuf->st_mode
-
- else mkdir/chmod/chown and fix
- */
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, xattr);
if (op_ret == -1) {
- local->op_errno = ENOENT;
- gf_log (this->name, GF_LOG_DEBUG,
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_ERROR,
"lookup of %s on %s returned error (%s)",
local->loc.path, prev->this->name,
strerror (op_errno));
-
goto unlock;
}
is_dir = check_is_dir (inode, stbuf, xattr);
if (!is_dir) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_CRITICAL,
"lookup of %s on %s returned non dir 0%o",
local->loc.path, prev->this->name,
stbuf->ia_type);
- local->need_selfheal = 1;
goto unlock;
}
@@ -457,8 +340,11 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->inode = inode_ref (inode);
dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
- prev->this);
+
+ if (prev->this == dht_first_up_subvol (this)) {
+ local->ia_ino = local->stbuf.ia_ino;
+ }
+
}
unlock:
UNLOCK (&frame->lock);
@@ -467,40 +353,88 @@ unlock:
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
- if (local->need_selfheal) {
- local->need_selfheal = 0;
- dht_lookup_everywhere (frame, this, &local->loc);
- return 0;
- }
-
if (local->op_ret == 0) {
ret = dht_layout_normalize (this, &local->loc, layout);
-
if (ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log (this->name, GF_LOG_INFO,
"fixing assignment on %s",
local->loc.path);
- goto selfheal;
}
- dht_layout_set (this, local->inode, layout);
+ ret = dht_layout_set (this, local->inode, layout);
}
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf, local->xattr,
&local->postparent);
}
+out:
+ return ret;
+}
+
+static int
+dht_do_fresh_lookup_on_root (xlator_t *this, call_frame_t *frame)
+{
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ int ret = -1;
+ int call_cnt = 0;
+ int i = 0;
+ int op_errno = EINVAL;
+
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
+ GF_VALIDATE_OR_GOTO ("dht", frame, unwind);
+ GF_VALIDATE_OR_GOTO ("dht", frame->local, unwind);
+
+ local = frame->local;
+ conf = this->private;
+ if (!conf)
+ goto err;
+
+ if (local->layout) {
+ dht_layout_unref (this, local->layout);
+ local->layout = NULL;
+ }
+
+ if (local->xattr != NULL) {
+ dict_unref (local->xattr);
+ local->xattr = NULL;
+ }
+
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set the dict entry for dht");
+
+ call_cnt = local->call_cnt = conf->subvolume_cnt;
+
+ local->layout = dht_layout_new (this,
+ conf->subvolume_cnt);
+ if (!local->layout) {
+ local->op_errno = ENOMEM;
+ goto err;
+ }
+
+ for (i = 0; i < call_cnt; i++) {
+ STACK_WIND (frame, dht_lookup_root_dir_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->lookup,
+ &local->loc, local->xattr_req);
+ }
+
return 0;
+err:
+ DHT_STACK_UNWIND (lookup, frame, -1, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
+ &local->postparent);
-selfheal:
- FRAME_SU_DO (frame, dht_local_t);
- uuid_copy (local->loc.gfid, local->gfid);
- ret = dht_selfheal_directory (frame, dht_lookup_selfheal_cbk,
- &local->loc, layout);
+ return 0;
+unwind:
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
out:
- return ret;
+ return -1;
}
int
@@ -517,6 +451,7 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int ret = -1;
int is_dir = 0;
int is_linkfile = 0;
+ unsigned char root_gfid[16] = {0,};
GF_VALIDATE_OR_GOTO ("dht", frame, err);
GF_VALIDATE_OR_GOTO ("dht", this, err);
@@ -543,20 +478,12 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
strerror (op_errno));
}
if (op_errno == ESTALE) {
- /* propagate the ESTALE to parent.
- * setting local->return_estale would send
+ /* propogate the ESTALE to parent.
+ * setting local->layout_mismatch would send
* ESTALE to parent. */
- local->return_estale = 1;
+ local->layout_mismatch = 1;
}
- /* if it is ENOENT, we may have to do a
- * 'lookup_everywhere()' to make sure
- * the file is not migrated */
- if (op_errno == ENOENT) {
- if (IA_ISREG (local->loc.inode->ia_type)) {
- local->need_lookup_everywhere = 1;
- }
- }
goto unlock;
}
@@ -581,7 +508,7 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_INFO,
"linkfile found in revalidate for %s",
local->loc.path);
- local->return_estale = 1;
+ local->layout_mismatch = 1;
goto unlock;
}
@@ -606,6 +533,10 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev->this);
local->op_ret = 0;
+ local->stbuf.ia_ino = local->ia_ino;
+
+ if (local->loc.parent)
+ local->postparent.ia_ino = local->loc.parent->ino;
if (!local->xattr) {
local->xattr = dict_ref (xattr);
@@ -625,35 +556,24 @@ out:
&& (conf && conf->unhashed_sticky_bit)) {
local->stbuf.ia_prot.sticky = 1;
}
- if (local->layout_mismatch) {
- /* Found layout mismatch in the directory, need to
- fix this in the inode context */
- dht_layout_unref (this, local->layout);
- local->layout = NULL;
- dht_lookup_directory (frame, this, &local->loc);
- return 0;
- }
- if (local->need_lookup_everywhere) {
- /* As the current layout gave ENOENT error, we would
- need a new layout */
- dht_layout_unref (this, local->layout);
- local->layout = NULL;
-
- /* We know that current cached subvol is no more
- valid, get the new one */
- local->cached_subvol = NULL;
- dht_lookup_everywhere (frame, this, &local->loc);
- return 0;
- }
- if (local->return_estale) {
+ if (local->layout_mismatch) {
local->op_ret = -1;
local->op_errno = ESTALE;
+
+ /* Because for 'root' inode, there is no FRESH lookup
+ * sent from FUSE layer upon ESTALE, we need to handle
+ * that one case here */
+ root_gfid[15] = 1;
+ if (!local->loc.parent &&
+ !uuid_compare (local->loc.inode->gfid, root_gfid)) {
+ dht_do_fresh_lookup_on_root (this, frame);
+ return 0;
+ }
}
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf, local->xattr,
&local->postparent);
@@ -669,8 +589,7 @@ dht_lookup_linkfile_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
xlator_t *cached_subvol = NULL;
@@ -703,10 +622,12 @@ dht_lookup_linkfile_create_cbk (call_frame_t *frame, void *cookie,
local->stbuf.ia_prot.sticky = 1;
}
+ if (local->loc.parent)
+ local->postparent.ia_ino = local->loc.parent->ino;
+
unwind:
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (lookup, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf, local->xattr,
&local->postparent);
@@ -716,143 +637,12 @@ out:
int
-dht_lookup_everywhere_done (call_frame_t *frame, xlator_t *this)
-{
- int ret = 0;
- dht_local_t *local = NULL;
- xlator_t *hashed_subvol = NULL;
- xlator_t *cached_subvol = NULL;
- dht_layout_t *layout = NULL;
-
- local = frame->local;
- hashed_subvol = local->hashed_subvol;
- cached_subvol = local->cached_subvol;
-
- if (local->file_count && local->dir_count) {
- gf_log (this->name, GF_LOG_ERROR,
- "path %s exists as a file on one subvolume "
- "and directory on another. "
- "Please fix it manually",
- local->loc.path);
- DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL,
- NULL);
- return 0;
- }
-
- if (local->dir_count) {
- dht_lookup_directory (frame, this, &local->loc);
- return 0;
- }
-
- if (!cached_subvol) {
- DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL,
- NULL);
- return 0;
- }
-
- if (local->need_lookup_everywhere) {
- if (uuid_compare (local->gfid, local->inode->gfid)) {
- /* GFID different, return error */
- DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL,
- NULL, NULL, NULL);
- return 0;
- }
- local->op_ret = 0;
- local->op_errno = 0;
- layout = dht_layout_for_subvol (this, cached_subvol);
- if (!layout) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: no pre-set layout for subvolume %s",
- local->loc.path, (cached_subvol ?
- cached_subvol->name :
- "<nil>"));
- }
-
- ret = dht_layout_set (this, local->inode, layout);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: failed to set layout for subvol %s",
- local->loc.path, (cached_subvol ?
- cached_subvol->name :
- "<nil>"));
- }
-
- WIPE (&local->postparent);
-
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret,
- local->op_errno, local->inode,
- &local->stbuf, local->xattr,
- &local->postparent);
- return 0;
- }
-
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_INFO,
- "cannot create linkfile file for %s on %s: "
- "hashed subvolume cannot be found.",
- local->loc.path, cached_subvol->name);
-
- local->op_ret = 0;
- local->op_errno = 0;
-
- ret = dht_layout_preset (frame->this, cached_subvol,
- local->inode);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "failed to set layout for subvol %s",
- cached_subvol ? cached_subvol->name :
- "<nil>");
- local->op_ret = -1;
- local->op_errno = EINVAL;
- }
-
- WIPE (&local->postparent);
-
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (lookup, frame, local->op_ret,
- local->op_errno, local->inode,
- &local->stbuf, local->xattr,
- &local->postparent);
- return 0;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "linking file %s existing on %s to %s (hash)",
- local->loc.path, cached_subvol->name,
- hashed_subvol->name);
-
- ret = dht_linkfile_create (frame,
- dht_lookup_linkfile_create_cbk,
- cached_subvol, hashed_subvol, &local->loc);
-
- return ret;
-}
-
-
-int
-dht_lookup_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- int this_call_cnt = 0;
-
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- dht_lookup_everywhere_done (frame, this);
- }
-
- return 0;
-}
-
-
-int
dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf, dict_t *xattr,
struct iatt *postparent)
{
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
@@ -861,8 +651,9 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
xlator_t *subvol = NULL;
loc_t *loc = NULL;
xlator_t *link_subvol = NULL;
+ xlator_t *hashed_subvol = NULL;
+ xlator_t *cached_subvol = NULL;
int ret = -1;
- int32_t fd_count = 0;
GF_VALIDATE_OR_GOTO ("dht", frame, out);
GF_VALIDATE_OR_GOTO ("dht", this, out);
@@ -870,6 +661,8 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_VALIDATE_OR_GOTO ("dht", cookie, out);
GF_VALIDATE_OR_GOTO ("dht", this->private, out);
+ conf = this->private;
+
local = frame->local;
loc = &local->loc;
@@ -883,9 +676,8 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_errno = op_errno;
goto unlock;
}
-
if (uuid_is_null (local->gfid))
- uuid_copy (local->gfid, buf->ia_gfid);
+ memcpy (local->gfid, buf->ia_gfid, 16);
if (uuid_compare (local->gfid, buf->ia_gfid)) {
gf_log (this->name, GF_LOG_WARNING,
@@ -906,9 +698,6 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
- /* non linkfile GFID takes precedence */
- uuid_copy (local->gfid, buf->ia_gfid);
-
if (is_dir) {
local->dir_count++;
@@ -934,7 +723,7 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* This is where we need 'rename' both entries logic */
gf_log (this->name, GF_LOG_WARNING,
"multiple subvolumes (%s and %s) have "
- "file %s (preferably rename the file "
+ "file %s (preferrably rename the file "
"in the backend, and do a fresh lookup)",
local->cached_subvol->name,
subvol->name, local->loc.path);
@@ -945,22 +734,80 @@ unlock:
UNLOCK (&frame->lock);
if (is_linkfile) {
- ret = dict_get_int32 (xattr, GLUSTERFS_OPEN_FD_COUNT, &fd_count);
- /* Delete the linkfile only if there are no open fds on it.
- if there is a open-fd, it may be in migration */
- if (!ret && (fd_count == 0)) {
- gf_log (this->name, GF_LOG_INFO,
- "deleting stale linkfile %s on %s",
- loc->path, subvol->name);
- STACK_WIND (frame, dht_lookup_unlink_cbk,
- subvol, subvol->fops->unlink, loc, 0, NULL);
- return 0;
- }
+ gf_log (this->name, GF_LOG_INFO,
+ "deleting stale linkfile %s on %s",
+ loc->path, subvol->name);
+ dht_linkfile_unlink (frame, this, subvol, loc);
}
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
- dht_lookup_everywhere_done (frame, this);
+ hashed_subvol = local->hashed_subvol;
+ cached_subvol = local->cached_subvol;
+
+ if (local->file_count && local->dir_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "path %s exists as a file on one subvolume "
+ "and directory on another. "
+ "Please fix it manually",
+ loc->path);
+ DHT_STACK_UNWIND (lookup, frame, -1, EIO, NULL, NULL, NULL,
+ NULL);
+ return 0;
+ }
+
+ if (local->dir_count) {
+ dht_lookup_directory (frame, this, &local->loc);
+ return 0;
+ }
+
+ if (!cached_subvol) {
+ DHT_STACK_UNWIND (lookup, frame, -1, ENOENT, NULL, NULL, NULL,
+ NULL);
+ return 0;
+ }
+
+ if (!hashed_subvol) {
+ gf_log (this->name, GF_LOG_INFO,
+ "cannot create linkfile file for %s on %s: "
+ "hashed subvolume cannot be found.",
+ loc->path, cached_subvol->name);
+
+ local->op_ret = 0;
+ local->op_errno = 0;
+
+ ret = dht_layout_preset (frame->this, cached_subvol,
+ local->inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "failed to set layout for subvol %s",
+ cached_subvol ? cached_subvol->name :
+ "<nil>");
+ local->op_ret = -1;
+ local->op_errno = EINVAL;
+ }
+
+ if (local->loc.parent)
+ local->postparent.ia_ino =
+ local->loc.parent->ino;
+
+ WIPE (&local->postparent);
+
+ DHT_STACK_UNWIND (lookup, frame, local->op_ret,
+ local->op_errno, local->inode,
+ &local->stbuf, local->xattr,
+ &local->postparent);
+ return 0;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "linking file %s existing on %s to %s (hash)",
+ loc->path, cached_subvol->name,
+ hashed_subvol->name);
+
+ ret = dht_linkfile_create (frame,
+ dht_lookup_linkfile_create_cbk,
+ cached_subvol, hashed_subvol, loc);
}
out:
@@ -1056,13 +903,15 @@ dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie,
gf_log (this->name, GF_LOG_WARNING,
"%s: gfid different on data file on %s",
local->loc.path, subvol->name);
- goto err;
}
if ((stbuf->ia_nlink == 1)
&& (conf && conf->unhashed_sticky_bit)) {
stbuf->ia_prot.sticky = 1;
}
+ dht_itransform (this, prev->this, stbuf->ia_ino, &stbuf->ia_ino);
+ if (local->loc.parent)
+ postparent->ia_ino = local->loc.parent->ino;
ret = dht_layout_preset (this, prev->this, inode);
if (ret < 0) {
@@ -1076,7 +925,6 @@ dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie,
unwind:
WIPE (postparent);
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
postparent);
@@ -1096,7 +944,6 @@ dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc)
int i = 0;
dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
- int ret = 0;
GF_VALIDATE_OR_GOTO ("dht", frame, out);
GF_VALIDATE_OR_GOTO ("dht", this, unwind);
@@ -1120,14 +967,6 @@ dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc)
local->xattr = NULL;
}
- if (!uuid_is_null (local->gfid)) {
- ret = dict_set_static_bin (local->xattr_req, "gfid-req",
- local->gfid, 16);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set gfid", local->loc.path);
- }
-
for (i = 0; i < call_cnt; i++) {
STACK_WIND (frame, dht_lookup_dir_cbk,
conf->subvolumes[i],
@@ -1223,6 +1062,11 @@ dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!is_linkfile) {
/* non-directory and not a linkfile */
+ dht_itransform (this, prev->this, stbuf->ia_ino,
+ &stbuf->ia_ino);
+ if (loc->parent)
+ postparent->ia_ino = loc->parent->ino;
+
ret = dht_layout_preset (this, prev->this, inode);
if (ret < 0) {
gf_log (this->name, GF_LOG_INFO,
@@ -1260,46 +1104,12 @@ out:
WIPE (postparent);
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf, xattr,
postparent);
err:
return 0;
}
-/* For directories, check if acl xattrs have been requested (by the acl xlator),
- * if not, request for them. These xattrs are needed for dht dir self-heal to
- * perform proper self-healing of dirs
- */
-void
-dht_check_and_set_acl_xattr_req (inode_t *inode, dict_t *xattr_req)
-{
- int ret = 0;
-
- GF_ASSERT (inode);
- GF_ASSERT (xattr_req);
-
- if (inode->ia_type != IA_IFDIR)
- return;
-
- if (!dict_get (xattr_req, POSIX_ACL_ACCESS_XATTR)) {
- ret = dict_set_int8 (xattr_req, POSIX_ACL_ACCESS_XATTR, 0);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set key %s",
- POSIX_ACL_ACCESS_XATTR);
- }
-
- if (!dict_get (xattr_req, POSIX_ACL_DEFAULT_XATTR)) {
- ret = dict_set_int8 (xattr_req, POSIX_ACL_DEFAULT_XATTR, 0);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set key %s",
- POSIX_ACL_DEFAULT_XATTR);
- }
-
- return;
-}
int
dht_lookup (call_frame_t *frame, xlator_t *this,
@@ -1307,6 +1117,7 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
{
xlator_t *subvol = NULL;
xlator_t *hashed_subvol = NULL;
+ xlator_t *cached_subvol = NULL;
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int ret = -1;
@@ -1314,7 +1125,7 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
dht_layout_t *layout = NULL;
int i = 0;
int call_cnt = 0;
- loc_t new_loc = {0,};
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1326,22 +1137,14 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
if (!conf)
goto err;
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
-
- ret = dht_filter_loc_subvol_key (this, loc, &new_loc,
- &hashed_subvol);
- if (ret) {
- loc_wipe (&local->loc);
- ret = loc_dup (&new_loc, &local->loc);
-
- /* we no more need 'new_loc' entries */
- loc_wipe (&new_loc);
-
- /* check if loc_dup() is successful */
+ if (!dht_filter_loc_subvol_key (this, loc, &local->loc,
+ &hashed_subvol)) {
+ ret = loc_dup (loc, &local->loc);
if (ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_DEBUG,
@@ -1357,27 +1160,16 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
local->xattr_req = dict_new ();
}
- if (uuid_is_null (loc->pargfid) && !uuid_is_null (loc->gfid) &&
- !__is_root_gfid (loc->inode->gfid)) {
- local->cached_subvol = NULL;
- dht_discover (frame, this, loc);
- return 0;
- }
-
- if (!hashed_subvol) {
+ if (!hashed_subvol)
hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get hashed subvol for %s",
- loc->path);
- op_errno = EINVAL;
- goto err;
- }
- }
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
+
+ local->cached_subvol = cached_subvol;
local->hashed_subvol = hashed_subvol;
if (is_revalidate (loc)) {
- layout = local->layout;
+ local->layout = layout = dht_layout_get (this, loc->inode);
+
if (!layout) {
gf_log (this->name, GF_LOG_DEBUG,
"revalidate without cache. path=%s",
@@ -1386,6 +1178,8 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
goto err;
}
+ local->ia_ino = loc->inode->ino;
+
if (layout->gen && (layout->gen < conf->gen)) {
gf_log (this->name, GF_LOG_TRACE,
"incomplete layout failure for path=%s",
@@ -1393,11 +1187,13 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
dht_layout_unref (this, local->layout);
local->layout = NULL;
- local->cached_subvol = NULL;
goto do_fresh_lookup;
}
- local->inode = inode_ref (loc->inode);
+ local->inode = inode_ref (loc->inode);
+
+ local->call_cnt = layout->cnt;
+ call_cnt = local->call_cnt;
/* NOTE: we don't require 'trusted.glusterfs.dht.linkto' attribute,
* revalidates directly go to the cached-subvolume.
@@ -1405,34 +1201,15 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
ret = dict_set_uint32 (local->xattr_req,
"trusted.glusterfs.dht", 4 * 4);
- if (IA_ISDIR (local->inode->ia_type)) {
- local->call_cnt = call_cnt = conf->subvolume_cnt;
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_revalidate_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->lookup,
- loc, local->xattr_req);
- }
- return 0;
- }
-
- call_cnt = local->call_cnt = layout->cnt;
-
- /* need it for self-healing linkfiles which is
- 'in-migration' state */
- ret = dict_set_uint32 (local->xattr_req,
- GLUSTERFS_OPEN_FD_COUNT, 4);
-
- /* need it for dir self-heal */
- dht_check_and_set_acl_xattr_req (loc->inode, local->xattr_req);
-
- for (i = 0; i < call_cnt; i++) {
+ for (i = 0; i < layout->cnt; i++) {
subvol = layout->list[i].xlator;
-
+
STACK_WIND (frame, dht_revalidate_cbk,
subvol, subvol->fops->lookup,
&local->loc, local->xattr_req);
+ if (!--call_cnt)
+ break;
}
} else {
do_fresh_lookup:
@@ -1441,15 +1218,7 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
"trusted.glusterfs.dht", 4 * 4);
ret = dict_set_uint32 (local->xattr_req,
- DHT_LINKFILE_KEY, 256);
-
- /* need it for self-healing linkfiles which is
- 'in-migration' state */
- ret = dict_set_uint32 (local->xattr_req,
- GLUSTERFS_OPEN_FD_COUNT, 4);
-
- /* need it for dir self-heal */
- dht_check_and_set_acl_xattr_req (loc->inode, local->xattr_req);
+ "trusted.glusterfs.dht.linkto", 256);
if (!hashed_subvol) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -1484,8 +1253,294 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
+
+ GF_VALIDATE_OR_GOTO ("dht", frame, err);
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
+ GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
+ GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+
+ local = frame->local;
+ prev = cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ local->op_ret = -1;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s returned -1 (%s)",
+ prev->this->name, strerror (op_errno));
+ goto unlock;
+ }
+
+ dht_iatt_merge (this, &local->prebuf, prebuf, prev->this);
+ dht_iatt_merge (this, &local->stbuf, postbuf, prev->this);
+
+ if (local->inode) {
+ local->stbuf.ia_ino = local->inode->ino;
+ local->prebuf.ia_ino = local->inode->ino;
+ }
+
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+out:
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (truncate, frame, local->op_ret, local->op_errno,
+ &local->prebuf, &local->stbuf);
+err:
+ return 0;
+}
+
+
+
+int
+dht_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *stbuf)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
+
+ GF_VALIDATE_OR_GOTO ("dht", frame, err);
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
+ GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
+ GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+
+ local = frame->local;
+ prev = cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s returned -1 (%s)",
+ prev->this->name, strerror (op_errno));
+ goto unlock;
+ }
+
+ dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
+
+ if (local->inode)
+ local->stbuf.ia_ino = local->inode->ino;
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+out:
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (stat, frame, local->op_ret, local->op_errno,
+ &local->stbuf);
+err:
+ return 0;
+}
+
+
+int
+dht_stat (call_frame_t *frame, xlator_t *this,
+ loc_t *loc)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ int i = 0;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->layout = layout = dht_layout_get (this, loc->inode);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no layout for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = layout->cnt;
+
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
+
+ STACK_WIND (frame, dht_attr_cbk,
+ subvol, subvol->fops->stat,
+ loc);
+ }
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+dht_fstat (call_frame_t *frame, xlator_t *this,
+ fd_t *fd)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
+ int i = 0;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->layout = layout = dht_layout_get (this, fd->inode);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no layout for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local->inode = inode_ref (fd->inode);
+ local->call_cnt = layout->cnt;;
+
+ for (i = 0; i < layout->cnt; i++) {
+ subvol = layout->list[i].xlator;
+ STACK_WIND (frame, dht_attr_cbk,
+ subvol, subvol->fops->fstat,
+ fd);
+ }
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+dht_truncate (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, off_t offset)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
+
+ STACK_WIND (frame, dht_truncate_cbk,
+ subvol, subvol->fops->truncate,
+ loc, offset);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+dht_ftruncate (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, off_t offset)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->inode = inode_ref (fd->inode);
+ local->call_cnt = 1;
+
+ STACK_WIND (frame, dht_truncate_cbk,
+ subvol, subvol->fops->ftruncate,
+ fd, offset);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
+
return 0;
}
@@ -1493,7 +1548,7 @@ err:
int
dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -1512,6 +1567,8 @@ dht_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
+ preparent->ia_ino = local->loc.parent->ino;
+ postparent->ia_ino = local->loc.parent->ino;
local->op_ret = 0;
local->postparent = *postparent;
@@ -1524,7 +1581,7 @@ unlock:
UNLOCK (&frame->lock);
DHT_STACK_UNWIND (unlink, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
return 0;
}
@@ -1533,7 +1590,7 @@ unlock:
int
dht_unlink_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -1572,59 +1629,68 @@ unlock:
STACK_WIND (frame, dht_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink,
- &local->loc, local->flags, NULL);
+ &local->loc);
return 0;
err:
DHT_STACK_UNWIND (unlink, frame, -1, local->op_errno,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
-static int
-dht_ufo_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+
+int
+dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
+ int op_errno, struct iatt *prebuf, struct iatt *postbuf)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
+
local = frame->local;
prev = cookie;
LOCK (&frame->lock);
{
if (op_ret == -1) {
- local->op_ret = -1;
local->op_errno = op_errno;
gf_log (this->name, GF_LOG_DEBUG,
"subvolume %s returned -1 (%s)",
prev->this->name, strerror (op_errno));
goto unlock;
}
+
+ local->op_ret = 0;
}
unlock:
UNLOCK (&frame->lock);
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
- local->op_errno, NULL);
+ if (local && (op_ret == 0)) {
+ prebuf->ia_ino = local->ia_ino;
+ postbuf->ia_ino = local->ia_ino;
}
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (fsync, frame, local->op_ret, local->op_errno,
+ prebuf, postbuf);
+
return 0;
}
+
int
dht_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+ int op_ret, int op_errno)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
+
local = frame->local;
prev = cookie;
@@ -1645,13 +1711,135 @@ unlock:
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (setxattr, frame, local->op_ret,
- local->op_errno, NULL);
+ DHT_STACK_UNWIND (setxattr, frame, local->op_ret, local->op_errno);
}
return 0;
}
+
+int
+dht_access (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t mask)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->call_cnt = 1;
+
+ STACK_WIND (frame, dht_err_cbk,
+ subvol, subvol->fops->access,
+ loc, mask);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (access, frame, -1, op_errno);
+
+ return 0;
+}
+
+
+int
+dht_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, const char *path, struct iatt *sbuf)
+{
+ dht_local_t *local = NULL;
+
+ local = frame->local;
+ if (op_ret == -1)
+ goto err;
+
+ if (local) {
+ sbuf->ia_ino = local->ia_ino;
+ } else {
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
+
+err:
+ DHT_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, sbuf);
+
+ return 0;
+}
+
+
+int
+dht_readlink (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, size_t size)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->ia_ino = loc->inode->ino;
+
+ STACK_WIND (frame, dht_readlink_cbk,
+ subvol, subvol->fops->readlink,
+ loc, size);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+dht_fix_layout_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+{
+ DHT_STACK_UNWIND (getxattr, frame, -1, ENODATA, NULL);
+
+ return 0;
+}
+
static void
fill_layout_info (dht_layout_t *layout, char *buf)
{
@@ -1669,93 +1857,34 @@ fill_layout_info (dht_layout_t *layout, char *buf)
}
}
-void
-dht_fill_pathinfo_xattr (xlator_t *this, dht_local_t *local,
- char *xattr_buf, int32_t alloc_len,
- int flag, char *layout_buf)
-{
- if (flag && local->xattr_val)
- snprintf (xattr_buf, alloc_len,
- "((<"DHT_PATHINFO_HEADER"%s> %s) (%s-layout %s))",
- this->name, local->xattr_val, this->name,
- layout_buf);
- else if (local->xattr_val)
- snprintf (xattr_buf, alloc_len,
- "(<"DHT_PATHINFO_HEADER"%s> %s)",
- this->name, local->xattr_val);
- else if (flag)
- snprintf (xattr_buf, alloc_len, "(%s-layout %s)",
- this->name, layout_buf);
-}
-
int
-dht_vgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+dht_pathinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, dict_t *xattr)
{
- dht_local_t *local = NULL;
- int ret = 0;
- int flag = 0;
- int this_call_cnt = 0;
- char *value_got = NULL;
- char layout_buf[8192] = {0,};
- char *xattr_buf = NULL;
- dict_t *dict = NULL;
- int32_t alloc_len = 0;
- int32_t plen = 0;
- call_frame_t *prev = NULL;
+ dht_local_t *local = NULL;
+ int ret = 0;
+ int flag = 0;
+ int this_call_cnt = 0;
+ char *value_got = NULL;
+ char layout_buf[8192] = {0,};
+ char xattr_buf[8192 + 1024] = {0,};
+ dict_t *dict = NULL;
local = frame->local;
- prev = cookie;
- if (op_ret >= 0) {
- ret = dict_get_str (xattr, local->xsel, &value_got);
+ if (op_ret != -1) {
+ ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value_got);
if (!ret) {
- alloc_len = strlen (value_got);
-
- /**
- * allocate the buffer:- we allocate 10 bytes extra in
- * case we need to append ' Link: ' in the buffer for
- * another STACK_WIND
- */
- if (!local->xattr_val) {
- alloc_len += (strlen (DHT_PATHINFO_HEADER) + 10);
- local->xattr_val =
- GF_CALLOC (alloc_len,
- sizeof (char),
- gf_common_mt_char);
- }
-
- if (local->xattr_val) {
- plen = strlen (local->xattr_val);
- if (plen) {
- /* extra byte(s) for \0 to be safe */
- alloc_len += (plen + 2);
- local->xattr_val =
- GF_REALLOC (local->xattr_val,
- alloc_len);
- if (!local->xattr_val)
- goto out;
- }
-
- strcat (local->xattr_val, value_got);
- }
- local->op_ret = 0;
+ if (!local->pathinfo)
+ local->pathinfo = GF_CALLOC (8192, sizeof (char),
+ gf_common_mt_char);
+ if (local->pathinfo)
+ strcat (local->pathinfo, value_got);
}
- } else {
- local->op_ret = -1;
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_ERROR, "Subvolume %s returned -1 "
- "(%s)", prev->this->name, strerror (op_errno));
}
- out:
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
-
- if (local->op_ret == -1) {
- goto unwind;
- }
-
if (local->layout->cnt > 1) {
/* Set it for directory */
fill_layout_info (local->layout, layout_buf);
@@ -1764,30 +1893,24 @@ dht_vgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dict = dict_new ();
- /* we would need max this many bytes to create xattr string */
- alloc_len += (2 * strlen (this->name))
- + strlen (layout_buf)
- + 40;
- xattr_buf = GF_CALLOC (alloc_len,
- sizeof (char), gf_common_mt_char);
-
- if (XATTR_IS_PATHINFO (local->xsel)) {
- (void) dht_fill_pathinfo_xattr (this, local, xattr_buf,
- alloc_len, flag,
- layout_buf);
- } else if (XATTR_IS_NODE_UUID (local->xsel)) {
- (void) snprintf (xattr_buf, alloc_len, "%s",
- local->xattr_val);
- } else
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown local->xsel (%s)", local->xsel);
+ if (flag && local->pathinfo)
+ snprintf (xattr_buf, 9216, "((%s %s) (%s-layout %s))",
+ this->name, local->pathinfo, this->name,
+ layout_buf);
+ else if (local->pathinfo)
+ snprintf (xattr_buf, 9216, "(%s %s)",
+ this->name, local->pathinfo);
+ else if (flag)
+ snprintf (xattr_buf, 9216, "(%s-layout %s)",
+ this->name, layout_buf);
- ret = dict_set_dynstr (dict, local->xsel, xattr_buf);
+ ret = dict_set_str (dict, GF_XATTR_PATHINFO_KEY,
+ xattr_buf);
- GF_FREE (local->xattr_val);
+ if (local->pathinfo)
+ GF_FREE (local->pathinfo);
- DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict,
- xdata);
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
if (dict)
dict_unref (dict);
@@ -1795,15 +1918,27 @@ dht_vgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-unwind:
- DHT_STACK_UNWIND (getxattr, frame, -1, local->op_errno, NULL, NULL);
+ if (local->pathinfo)
+ strcat (local->pathinfo, " Link: ");
+ if (local->hashed_subvol) {
+ /* This will happen if there pending */
+ STACK_WIND (frame, dht_pathinfo_getxattr_cbk, local->hashed_subvol,
+ local->hashed_subvol->fops->getxattr,
+ &local->loc, local->key);
+
+ return 0;
+ }
+
+ gf_log ("this->name", GF_LOG_ERROR, "Unable to find hashed_subvol for path"
+ " %s", local->pathinfo);
+
+ DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, dict);
return 0;
}
int
dht_linkinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr,
- dict_t *xdata)
+ int op_ret, int op_errno, dict_t *xattr)
{
int ret = 0;
char *value = NULL;
@@ -1818,14 +1953,14 @@ dht_linkinfo_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
}
- DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr);
return 0;
}
int
dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *xattr)
{
int this_call_cnt = 0;
dht_local_t *local = NULL;
@@ -1849,33 +1984,30 @@ dht_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->xattr = dict_copy_with_ref (xattr, NULL);
} else {
/* first aggregate everything into xattr and then copy into
- * local->xattr. This is required as we want to have
- * 'local->xattr' as the proper final dictionary passed above
- * distribute xlator.
+ * local->xattr.
*/
dht_aggregate_xattr (xattr, local->xattr);
local->xattr = dict_copy (xattr, local->xattr);
}
out:
if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
- local->xattr, NULL);
+ DHT_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno, local->xattr);
}
return 0;
}
int32_t
dht_getxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *dict)
{
- DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
+ DHT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
dht_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *key, dict_t *xdata)
+ loc_t *loc, const char *key)
{
xlator_t *subvol = NULL;
xlator_t *hashed_subvol = NULL;
@@ -1885,6 +2017,8 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
dht_layout_t *layout = NULL;
xlator_t **sub_volumes = NULL;
int op_errno = -1;
+ int ret = 0;
+ int flag = 0;
int i = 0;
int cnt = 0;
@@ -1896,58 +2030,60 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this->private, err);
conf = this->private;
+ layout = dht_layout_get (this, loc->inode);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "layout is NULL");
+ op_errno = ENOENT;
+ goto err;
+ }
- local = dht_local_init (frame, loc, NULL, GF_FOP_GETXATTR);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_ERROR,
- "layout is NULL");
- op_errno = ENOENT;
- goto err;
- }
+ if (key && (strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)) {
+ hashed_subvol = dht_subvol_get_hashed (this, loc);
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (key) {
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
local->key = gf_strdup (key);
if (!local->key) {
op_errno = ENOMEM;
+
goto err;
}
- }
-
- if (key && ((strcmp (key, GF_XATTR_PATHINFO_KEY) == 0)
- || strcmp (key, GF_XATTR_NODE_UUID_KEY) == 0)) {
- cached_subvol = local->cached_subvol;
- (void) strncpy (local->xsel, key, 256);
+ local->layout = layout;
local->call_cnt = 1;
- STACK_WIND (frame, dht_vgetxattr_cbk, cached_subvol,
- cached_subvol->fops->getxattr, loc, key, NULL);
+ if (hashed_subvol != cached_subvol) {
+ local->call_cnt = 2;
+ local->hashed_subvol = hashed_subvol;
+ }
+
+ STACK_WIND (frame, dht_pathinfo_getxattr_cbk, cached_subvol,
+ cached_subvol->fops->getxattr, loc, key);
return 0;
}
if (key && (strcmp (key, GF_XATTR_LINKINFO_KEY) == 0)) {
hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get"
- "hashed subvol for %s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (!cached_subvol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get"
- "cached subvol for %s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
if (hashed_subvol == cached_subvol) {
op_errno = ENODATA;
goto err;
@@ -1955,7 +2091,41 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
if (hashed_subvol) {
STACK_WIND (frame, dht_linkinfo_getxattr_cbk, hashed_subvol,
hashed_subvol->fops->getxattr, loc,
- GF_XATTR_PATHINFO_KEY, NULL);
+ GF_XATTR_PATHINFO_KEY);
+ return 0;
+ }
+ op_errno = ENODATA;
+ goto err;
+ }
+ if (key && (strcmp (key, GF_XATTR_FIX_LAYOUT_KEY) == 0)) {
+ for (i = 0; i < layout->cnt; i++) {
+ if (layout->list[i].start == layout->list[i].stop) {
+ flag = 1;
+ break;
+ }
+ }
+ if ((layout->cnt < conf->subvolume_cnt) || flag) {
+ gf_log (this->name, GF_LOG_INFO,
+ "expanding layout of %s from %d to %d",
+ loc->path, layout->cnt, conf->subvolume_cnt);
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+ local->layout = layout;
+ //layout = dht_layout_new (this, conf->subvolume_cnt);
+
+ dht_selfheal_new_directory (frame, dht_fix_layout_cbk,
+ layout);
return 0;
}
op_errno = ENODATA;
@@ -2010,68 +2180,24 @@ dht_getxattr (call_frame_t *frame, xlator_t *this,
}
}
- if (loc->inode-> ia_type == IA_IFDIR) {
- cnt = local->call_cnt = layout->cnt;
- } else {
- cnt = local->call_cnt = 1;
- }
-
- for (i = 0; i < cnt; i++) {
- subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_getxattr_cbk,
- subvol, subvol->fops->getxattr,
- loc, key, NULL);
- }
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *key, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int op_errno = -1;
- int i = 0;
- int cnt = 0;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
- VALIDATE_OR_GOTO (fd->inode, err);
- VALIDATE_OR_GOTO (this->private, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FGETXATTR);
- if (!local) {
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
op_errno = ENOMEM;
goto err;
}
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_ERROR,
- "layout is NULL");
- op_errno = ENOENT;
- goto err;
- }
-
if (key) {
local->key = gf_strdup (key);
if (!local->key) {
op_errno = ENOMEM;
+
goto err;
}
}
+ local->layout = layout;
- if (fd->inode->ia_type == IA_IFDIR) {
+ if (loc->inode-> ia_type == IA_IFDIR) {
cnt = local->call_cnt = layout->cnt;
} else {
cnt = local->call_cnt = 1;
@@ -2080,42 +2206,32 @@ dht_fgetxattr (call_frame_t *frame, xlator_t *this,
for (i = 0; i < cnt; i++) {
subvol = layout->list[i].xlator;
STACK_WIND (frame, dht_getxattr_cbk,
- subvol, subvol->fops->fgetxattr,
- fd, key, NULL);
+ subvol, subvol->fops->getxattr,
+ loc, key);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
+ DHT_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL);
return 0;
}
int
dht_fsetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xattr, int flags, dict_t *xdata)
+ fd_t *fd, dict_t *xattr, int flags)
{
xlator_t *subvol = NULL;
dht_local_t *local = NULL;
int op_errno = EINVAL;
- data_pair_t *trav = NULL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
VALIDATE_OR_GOTO (fd->inode, err);
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.dht*", xattr,
- trav, op_errno, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FSETXATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
+ subvol = dht_subvol_get_cached (this, fd->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
"no cached subvolume for fd=%p", fd);
@@ -2123,75 +2239,31 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this,
goto err;
}
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->inode = inode_ref (fd->inode);
local->call_cnt = 1;
STACK_WIND (frame, dht_err_cbk, subvol, subvol->fops->fsetxattr,
- fd, xattr, flags, NULL);
+ fd, xattr, flags);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (fsetxattr, frame, -1, op_errno);
return 0;
}
-static int
-dht_common_setxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *xdata)
-{
- DHT_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int
-dht_checking_pathinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr,
- dict_t *xdata)
-{
- int i = -1;
- int ret = -1;
- char *value = NULL;
- dht_local_t *local = NULL;
- dht_conf_t *conf = NULL;
- call_frame_t *prev = NULL;
- int this_call_cnt = 0;
-
- local = frame->local;
- prev = cookie;
- conf = this->private;
-
- if (op_ret == -1)
- goto out;
-
-
- ret = dict_get_str (xattr, GF_XATTR_PATHINFO_KEY, &value);
- if (ret)
- goto out;
-
- if (!strcmp (value, local->key)) {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == prev->this)
- conf->decommissioned_bricks[i] = prev->this;
- }
- }
-
-out:
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (setxattr, frame, local->op_ret, ENOTSUP, NULL);
- }
- return 0;
-
-}
-
int
dht_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr, int flags, dict_t *xdata)
+ loc_t *loc, dict_t *xattr, int flags)
{
xlator_t *subvol = NULL;
dht_local_t *local = NULL;
@@ -2199,14 +2271,6 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
dht_layout_t *layout = NULL;
int i = 0;
int op_errno = EINVAL;
- int ret = -1;
- data_t *tmp = NULL;
- uint32_t dir_spread = 0;
- char value[4096] = {0,};
- gf_dht_migrate_data_type_t forced_rebalance = GF_DHT_MIGRATE_DATA;
- int call_cnt = 0;
- data_pair_t *trav = NULL;
-
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -2214,17 +2278,8 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.dht*", xattr,
- trav, op_errno, err);
-
conf = this->private;
- local = dht_local_init (frame, loc, NULL, GF_FOP_SETXATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
+ subvol = dht_subvol_get_cached (this, loc->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
"no cached subvolume for path=%s", loc->path);
@@ -2232,7 +2287,13 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
goto err;
}
- layout = local->layout;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->layout = layout = dht_layout_get (this, loc->inode);
if (!layout) {
gf_log (this->name, GF_LOG_DEBUG,
"no layout for path=%s", loc->path);
@@ -2240,151 +2301,127 @@ dht_setxattr (call_frame_t *frame, xlator_t *this,
goto err;
}
- local->call_cnt = call_cnt = layout->cnt;
+ local->call_cnt = layout->cnt;
- /* This key is sent by Unified File and Object storage
- * to test xattr support in backend.
- */
- tmp = dict_get (xattr, "user.ufo-test");
- if (tmp) {
- if (IA_ISREG (loc->inode->ia_type)) {
- op_errno = ENOTSUP;
- goto err;
- }
- local->op_ret = 0;
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_ufo_xattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->setxattr,
- loc, xattr, flags, NULL);
- }
- return 0;
+ for (i = 0; i < layout->cnt; i++) {
+ STACK_WIND (frame, dht_err_cbk,
+ layout->list[i].xlator,
+ layout->list[i].xlator->fops->setxattr,
+ loc, xattr, flags);
}
- tmp = dict_get (xattr, "distribute.migrate-data");
- if (tmp) {
- if (IA_ISDIR (loc->inode->ia_type)) {
- op_errno = ENOTSUP;
- goto err;
- }
-
- /* TODO: need to interpret the 'value' for more meaning
- (ie, 'target' subvolume given there, etc) */
- memcpy (value, tmp->data, tmp->len);
- if (strcmp (value, "force") == 0)
- forced_rebalance =
- GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS;
+ return 0;
- if (conf->decommission_in_progress)
- forced_rebalance = GF_DHT_MIGRATE_HARDLINK;
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (setxattr, frame, -1, op_errno);
- local->rebalance.target_node = dht_subvol_get_hashed (this, loc);
- if (!local->rebalance.target_node) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "hashed subvol for %s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
+ return 0;
+}
- local->rebalance.from_subvol = local->cached_subvol;
- if (local->rebalance.target_node == local->rebalance.from_subvol) {
- op_errno = EEXIST;
- goto err;
- }
- if (local->rebalance.target_node) {
- local->flags = forced_rebalance;
+int
+dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
- ret = dht_start_rebalance_task (this, frame);
- if (!ret)
- return 0;
+ local = frame->local;
+ prev = cookie;
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to create a new synctask",
- loc->path);
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s returned -1 (%s)",
+ prev->this->name, strerror (op_errno));
+ goto unlock;
}
- op_errno = EINVAL;
- goto err;
+ local->op_ret = 0;
}
+unlock:
+ UNLOCK (&frame->lock);
- tmp = dict_get (xattr, "decommission-brick");
- if (tmp) {
- /* This operation should happen only on '/' */
- if (!__is_root_gfid (loc->inode->gfid)) {
- op_errno = ENOTSUP;
- goto err;
- }
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt)) {
+ DHT_STACK_UNWIND (removexattr, frame, local->op_ret, local->op_errno);
+ }
- memcpy (value, tmp->data, ((tmp->len < 4095) ? tmp->len : 4095));
- local->key = gf_strdup (value);
- local->call_cnt = conf->subvolume_cnt;
+ return 0;
+}
- for (i = 0 ; i < conf->subvolume_cnt; i++) {
- /* Get the pathinfo, and then compare */
- STACK_WIND (frame, dht_checking_pathinfo_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->getxattr,
- loc, GF_XATTR_PATHINFO_KEY, NULL);
- }
- return 0;
- }
- tmp = dict_get (xattr, GF_XATTR_FIX_LAYOUT_KEY);
- if (tmp) {
- gf_log (this->name, GF_LOG_INFO,
- "fixing the layout of %s", loc->path);
+int
+dht_removexattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, const char *key)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+ dht_layout_t *layout = NULL;
- dht_fix_directory_layout (frame, dht_common_setxattr_cbk,
- layout);
- return 0;
+ int i;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
}
- tmp = dict_get (xattr, "distribute.directory-spread-count");
- if (tmp) {
- /* Setxattr value is packed as 'binary', not string */
- memcpy (value, tmp->data, ((tmp->len < 4095)?tmp->len:4095));
- ret = gf_string2uint32 (value, &dir_spread);
- if (!ret && ((dir_spread <= conf->subvolume_cnt) &&
- (dir_spread > 0))) {
- layout->spread_cnt = dir_spread;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
- dht_fix_directory_layout (frame,
- dht_common_setxattr_cbk,
- layout);
- return 0;
- }
- gf_log (this->name, GF_LOG_ERROR,
- "wrong 'directory-spread-count' value (%s)", value);
- op_errno = ENOTSUP;
+ local->layout = layout = dht_layout_get (this, loc->inode);
+ if (!local->layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no layout for path=%s", loc->path);
+ op_errno = EINVAL;
goto err;
}
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_err_cbk,
+ local->call_cnt = layout->cnt;
+
+ for (i = 0; i < layout->cnt; i++) {
+ STACK_WIND (frame, dht_removexattr_cbk,
layout->list[i].xlator,
- layout->list[i].xlator->fops->setxattr,
- loc, xattr, flags, xdata);
+ layout->list[i].xlator->fops->removexattr,
+ loc, key);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (removexattr, frame, -1, op_errno);
return 0;
}
int
-dht_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+dht_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, fd_t *fd)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
+
local = frame->local;
prev = cookie;
@@ -2404,170 +2441,331 @@ unlock:
UNLOCK (&frame->lock);
this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (removexattr, frame, local->op_ret,
- local->op_errno, NULL);
- }
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
+ local->fd);
return 0;
}
int
-dht_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *key, dict_t *xdata)
+dht_open (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int flags, fd_t *fd, int wbflags)
{
xlator_t *subvol = NULL;
+ int ret = -1;
int op_errno = -1;
dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int call_cnt = 0;
- int i;
+ VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.dht*",
- key, op_errno, err);
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
- local = dht_local_init (frame, loc, NULL, GF_FOP_REMOVEXATTR);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ local->fd = fd_ref (fd);
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
goto err;
}
- subvol = local->cached_subvol;
+ local->call_cnt = 1;
+
+ STACK_WIND (frame, dht_fd_cbk,
+ subvol, subvol->fops->open,
+ loc, flags, fd, wbflags);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (open, frame, -1, op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ struct iovec *vector, int count, struct iatt *stbuf,
+ struct iobref *iobref)
+{
+ dht_local_t *local = frame->local;
+
+ if (!local) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ if (op_ret != -1)
+ stbuf->ia_ino = local->ia_ino;
+out:
+ DHT_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, stbuf,
+ iobref);
+
+ return 0;
+}
+
+
+int
+dht_readv (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t off)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
+ "no cached subvolume for fd=%p", fd);
op_errno = EINVAL;
goto err;
}
- layout = local->layout;
- if (!local->layout) {
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->ia_ino = fd->inode->ino;
+ STACK_WIND (frame, dht_readv_cbk,
+ subvol, subvol->fops->readv,
+ fd, size, off);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ dht_local_t *local = NULL;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ if (!local) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ prebuf->ia_ino = local->ia_ino;
+ postbuf->ia_ino = local->ia_ino;
+
+out:
+ DHT_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
+
+ return 0;
+}
+
+
+int
+dht_writev (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, struct iovec *vector, int count, off_t off,
+ struct iobref *iobref)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
- "no layout for path=%s", loc->path);
+ "no cached subvolume for fd=%p", fd);
op_errno = EINVAL;
goto err;
}
- local->call_cnt = call_cnt = layout->cnt;
- local->key = gf_strdup (key);
+ local = dht_local_init (frame);
+ if (!local) {
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_removexattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->removexattr,
- loc, key, NULL);
+ op_errno = ENOMEM;
+ goto err;
}
+ local->ia_ino = fd->inode->ino;
+
+ STACK_WIND (frame, dht_writev_cbk,
+ subvol, subvol->fops->writev,
+ fd, vector, count, off, iobref);
+
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
+
int
-dht_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *key, dict_t *xdata)
+dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
xlator_t *subvol = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int call_cnt = 0;
- int i;
+ VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
- GF_IF_NATIVE_XATTR_GOTO ("trusted.glusterfs.dht*",
- key, op_errno, err);
-
- VALIDATE_OR_GOTO (frame, err);
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
- local = dht_local_init (frame, NULL, fd, GF_FOP_FREMOVEXATTR);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
goto err;
}
- subvol = local->cached_subvol;
+ local->fd = fd_ref (fd);
+ local->call_cnt = 1;
+
+ STACK_WIND (frame, dht_err_cbk,
+ subvol, subvol->fops->flush, fd);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (flush, frame, -1, op_errno);
+
+ return 0;
+}
+
+
+int
+dht_fsync (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int datasync)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for inode=%s",
- uuid_utoa (fd->inode->gfid));
+ "no cached subvolume for fd=%p", fd);
op_errno = EINVAL;
goto err;
}
- layout = local->layout;
- if (!local->layout) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no layout for inode=%s", uuid_utoa (fd->inode->gfid));
- op_errno = EINVAL;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
goto err;
}
+ local->call_cnt = 1;
- local->call_cnt = call_cnt = layout->cnt;
- local->key = gf_strdup (key);
+ local->ia_ino = fd->inode->ino;
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_removexattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->fremovexattr,
- fd, key, NULL);
- }
+ STACK_WIND (frame, dht_fsync_cbk,
+ subvol, subvol->fops->fsync,
+ fd, datasync);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
return 0;
}
int
-dht_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd, dict_t *xdata)
+dht_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct gf_flock *flock)
{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
+ DHT_STACK_UNWIND (lk, frame, op_ret, op_errno, flock);
- local = frame->local;
- prev = cookie;
+ return 0;
+}
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
- local->op_ret = 0;
+int
+dht_lk (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, int cmd, struct gf_flock *flock)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
}
-unlock:
- UNLOCK (&frame->lock);
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt))
- DHT_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
- local->fd, NULL);
+ STACK_WIND (frame, dht_lk_cbk,
+ subvol, subvol->fops->lk,
+ fd, cmd, flock);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (lk, frame, -1, op_errno, NULL);
return 0;
}
@@ -2597,7 +2795,7 @@ dht_normalize_stats (struct statvfs *buf, unsigned long bsize,
int
dht_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct statvfs *statvfs, dict_t *xdata)
+ int op_ret, int op_errno, struct statvfs *statvfs)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
@@ -2643,21 +2841,21 @@ unlock:
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt))
DHT_STACK_UNWIND (statfs, frame, local->op_ret, local->op_errno,
- &local->statvfs, xdata);
+ &local->statvfs);
return 0;
}
int
-dht_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+dht_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- xlator_t *subvol = NULL;
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int op_errno = -1;
int i = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
@@ -2667,56 +2865,35 @@ dht_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
conf = this->private;
- local = dht_local_init (frame, NULL, NULL, GF_FOP_STATFS);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- if (IA_ISDIR (loc->inode->ia_type)) {
- local->call_cnt = conf->subvolume_cnt;
-
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (frame, dht_statfs_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->statfs, loc,
- xdata);
- }
- return 0;
- }
+ local = dht_local_init (frame);
+ local->call_cnt = conf->subvolume_cnt;
- subvol = dht_subvol_get_cached (this, loc->inode);
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (frame, dht_statfs_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->statfs, loc);
}
- local->call_cnt = 1;
-
- STACK_WIND (frame, dht_statfs_cbk,
- subvol, subvol->fops->statfs, loc, xdata);
-
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
+ DHT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL);
return 0;
}
int
-dht_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+dht_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
+ int ret = -1;
int op_errno = -1;
int i = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
@@ -2724,27 +2901,35 @@ dht_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
conf = this->private;
- local = dht_local_init (frame, loc, fd, GF_FOP_OPENDIR);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
+ local->fd = fd_ref (fd);
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
local->call_cnt = conf->subvolume_cnt;
for (i = 0; i < conf->subvolume_cnt; i++) {
STACK_WIND (frame, dht_fd_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->opendir,
- loc, fd, xdata);
+ loc, fd);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL);
+ DHT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
return 0;
}
@@ -2752,7 +2937,7 @@ err:
int
dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
- int op_errno, gf_dirent_t *orig_entries, dict_t *xdata)
+ int op_errno, gf_dirent_t *orig_entries)
{
dht_local_t *local = NULL;
gf_dirent_t entries;
@@ -2765,7 +2950,6 @@ dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
dht_layout_t *layout = 0;
dht_conf_t *conf = NULL;
xlator_t *subvol = 0;
- int ret = 0;
INIT_LIST_HEAD (&entries.list);
prev = cookie;
@@ -2782,10 +2966,10 @@ dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
list_for_each_entry (orig_entry, (&orig_entries->list), list) {
next_offset = orig_entry->d_off;
- if ((check_is_dir (NULL, (&orig_entry->d_stat), NULL) &&
- (prev->this != dht_first_up_subvol (this))) ||
- check_is_linkfile (NULL, (&orig_entry->d_stat),
- orig_entry->dict)) {
+
+ if (check_is_linkfile (NULL, (&orig_entry->d_stat), NULL)
+ || (check_is_dir (NULL, (&orig_entry->d_stat), NULL)
+ && (prev->this != dht_first_up_subvol (this)))) {
continue;
}
@@ -2801,34 +2985,21 @@ dht_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
orig_entry->d_name);
if (!subvol || (subvol != prev->this)) {
/* TODO: Count the number of entries which need
- linkfile to prove its existence in fs */
+ linkfile to prove its existance in fs */
layout->search_unhashed++;
}
}
+ entry->d_stat = orig_entry->d_stat;
+ dht_itransform (this, prev->this, orig_entry->d_ino,
+ &entry->d_ino);
dht_itransform (this, prev->this, orig_entry->d_off,
&entry->d_off);
- entry->d_stat = orig_entry->d_stat;
- entry->d_ino = orig_entry->d_ino;
+ entry->d_stat.ia_ino = entry->d_ino;
entry->d_type = orig_entry->d_type;
entry->d_len = orig_entry->d_len;
- if (orig_entry->dict)
- entry->dict = dict_ref (orig_entry->dict);
-
- /* making sure we set the inode ctx right with layout,
- currently possible only for non-directories, so for
- directories don't set entry inodes */
- if (!IA_ISDIR(entry->d_stat.ia_type)) {
- ret = dht_layout_preset (this, prev->this,
- orig_entry->inode);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to link the layout in inode");
- entry->inode = inode_ref (orig_entry->inode);
- }
-
list_add_tail (&entry->list, &entries.list);
count++;
}
@@ -2860,8 +3031,7 @@ done:
STACK_WIND (frame, dht_readdirp_cbk,
next_subvol, next_subvol->fops->readdirp,
- local->fd, local->size, next_offset,
- local->xattr);
+ local->fd, local->size, next_offset);
return 0;
}
@@ -2869,7 +3039,7 @@ unwind:
if (op_ret < 0)
op_ret = 0;
- DHT_STACK_UNWIND (readdirp, frame, op_ret, op_errno, &entries, NULL);
+ DHT_STACK_UNWIND (readdirp, frame, op_ret, op_errno, &entries);
gf_dirent_free (&entries);
@@ -2880,8 +3050,7 @@ unwind:
int
dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *orig_entries,
- dict_t *xdata)
+ int op_ret, int op_errno, gf_dirent_t *orig_entries)
{
dht_local_t *local = NULL;
gf_dirent_t entries;
@@ -2892,11 +3061,13 @@ dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
off_t next_offset = 0;
int count = 0;
dht_layout_t *layout = 0;
+ dht_conf_t *conf = NULL;
xlator_t *subvol = 0;
INIT_LIST_HEAD (&entries.list);
prev = cookie;
local = frame->local;
+ conf = this->private;
if (op_ret < 0)
goto done;
@@ -2919,10 +3090,11 @@ dht_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unwind;
}
+ dht_itransform (this, prev->this, orig_entry->d_ino,
+ &entry->d_ino);
dht_itransform (this, prev->this, orig_entry->d_off,
&entry->d_off);
- entry->d_ino = orig_entry->d_ino;
entry->d_type = orig_entry->d_type;
entry->d_len = orig_entry->d_len;
@@ -2958,7 +3130,7 @@ done:
STACK_WIND (frame, dht_readdir_cbk,
next_subvol, next_subvol->fops->readdir,
- local->fd, local->size, next_offset, NULL);
+ local->fd, local->size, next_offset);
return 0;
}
@@ -2966,7 +3138,7 @@ unwind:
if (op_ret < 0)
op_ret = 0;
- DHT_STACK_UNWIND (readdir, frame, op_ret, op_errno, &entries, NULL);
+ DHT_STACK_UNWIND (readdir, frame, op_ret, op_errno, &entries);
gf_dirent_free (&entries);
@@ -2976,59 +3148,46 @@ unwind:
int
dht_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t yoff, int whichop, dict_t *dict)
+ off_t yoff, int whichop)
{
dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
int op_errno = -1;
xlator_t *xvol = NULL;
off_t xoff = 0;
- int ret = 0;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
- local = dht_local_init (frame, NULL, NULL, whichop);
+ conf = this->private;
+
+ local = dht_local_init (frame);
if (!local) {
+
op_errno = ENOMEM;
goto err;
}
local->fd = fd_ref (fd);
local->size = size;
- local->xattr_req = (dict)? dict_ref (dict) : NULL;
dht_deitransform (this, yoff, &xvol, (uint64_t *)&xoff);
/* TODO: do proper readdir */
- if (whichop == GF_FOP_READDIRP) {
- if (dict)
- local->xattr = dict_ref (dict);
- else
- local->xattr = dict_new ();
-
- if (local->xattr) {
- ret = dict_set_uint32 (local->xattr,
- "trusted.glusterfs.dht.linkto",
- 256);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set 'glusterfs.dht.linkto'"
- " key");
- }
-
- STACK_WIND (frame, dht_readdirp_cbk, xvol, xvol->fops->readdirp,
- fd, size, xoff, local->xattr);
- } else {
+ if (whichop == GF_FOP_READDIR)
STACK_WIND (frame, dht_readdir_cbk, xvol, xvol->fops->readdir,
- fd, size, xoff, local->xattr);
- }
+ fd, size, xoff);
+ else
+ STACK_WIND (frame, dht_readdirp_cbk, xvol, xvol->fops->readdirp,
+ fd, size, xoff);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
+ DHT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL);
return 0;
}
@@ -3036,7 +3195,7 @@ err:
int
dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t yoff, dict_t *xdata)
+ off_t yoff)
{
int op = GF_FOP_READDIR;
dht_conf_t *conf = NULL;
@@ -3057,15 +3216,15 @@ dht_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
op = GF_FOP_READDIRP;
out:
- dht_do_readdir (frame, this, fd, size, yoff, op, 0);
+ dht_do_readdir (frame, this, fd, size, yoff, op);
return 0;
}
int
dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t yoff, dict_t *dict)
+ off_t yoff)
{
- dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP, dict);
+ dht_do_readdir (frame, this, fd, size, yoff, GF_FOP_READDIRP);
return 0;
}
@@ -3073,7 +3232,7 @@ dht_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
int
dht_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+ int op_ret, int op_errno)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
@@ -3093,22 +3252,21 @@ dht_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt))
- DHT_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno, xdata);
+ DHT_STACK_UNWIND (fsyncdir, frame, local->op_ret, local->op_errno);
return 0;
}
int
-dht_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int datasync, dict_t *xdata)
+dht_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int op_errno = -1;
int i = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
@@ -3116,9 +3274,10 @@ dht_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
conf = this->private;
- local = dht_local_init (frame, NULL, NULL, GF_FOP_FSYNCDIR);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
goto err;
}
@@ -3129,14 +3288,14 @@ dht_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, dht_fsyncdir_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->fsyncdir,
- fd, datasync, xdata);
+ fd, datasync);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (fsyncdir, frame, -1, op_errno);
return 0;
}
@@ -3146,7 +3305,7 @@ int
dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
call_frame_t *prev = NULL;
int ret = -1;
@@ -3165,7 +3324,11 @@ dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
+ dht_itransform (this, prev->this, stbuf->ia_ino, &stbuf->ia_ino);
if (local->loc.parent) {
+ preparent->ia_ino = local->loc.parent->ino;
+ postparent->ia_ino = local->loc.parent->ino;
+
WIPE (preparent);
WIPE (postparent);
}
@@ -3188,9 +3351,8 @@ out:
* See dht_iatt_merge for reference.
*/
- DHT_STRIP_PHASE1_FLAGS (stbuf);
- DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, stbuf,
- preparent, postparent, xdata);
+ DHT_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, stbuf, preparent,
+ postparent);
return 0;
}
@@ -3199,8 +3361,7 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
xlator_t *cached_subvol = NULL;
@@ -3213,34 +3374,38 @@ dht_mknod_linkfile_create_cbk (call_frame_t *frame, void *cookie,
STACK_WIND (frame, dht_newfile_cbk,
cached_subvol, cached_subvol->fops->mknod,
- &local->loc, local->mode, local->rdev, local->umask,
+ &local->loc, local->mode, local->rdev,
local->params);
return 0;
err:
- DHT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL);
+ DHT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
int
dht_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params)
+ loc_t *loc, mode_t mode, dev_t rdev, dict_t *params)
{
xlator_t *subvol = NULL;
int op_errno = -1;
+ int ret = -1;
xlator_t *avail_subvol = NULL;
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
+ conf = this->private;
+
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
goto err;
}
@@ -3253,13 +3418,20 @@ dht_mknod (call_frame_t *frame, xlator_t *this,
goto err;
}
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
if (!dht_is_subvol_filled (this, subvol)) {
gf_log (this->name, GF_LOG_TRACE,
"creating %s on %s", loc->path, subvol->name);
STACK_WIND (frame, dht_newfile_cbk,
subvol, subvol->fops->mknod,
- loc, mode, rdev, umask, params);
+ loc, mode, rdev, params);
} else {
avail_subvol = dht_free_disk_available_subvol (this, subvol);
if (avail_subvol != subvol) {
@@ -3270,7 +3442,7 @@ dht_mknod (call_frame_t *frame, xlator_t *this,
local->cached_subvol = avail_subvol;
local->mode = mode;
local->rdev = rdev;
- local->umask = umask;
+
dht_linkfile_create (frame,
dht_mknod_linkfile_create_cbk,
avail_subvol, subvol, loc);
@@ -3280,7 +3452,7 @@ dht_mknod (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_newfile_cbk,
subvol, subvol->fops->mknod,
- loc, mode, rdev, umask, params);
+ loc, mode, rdev, params);
}
}
@@ -3289,7 +3461,7 @@ dht_mknod (call_frame_t *frame, xlator_t *this,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -3297,19 +3469,22 @@ err:
int
dht_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc, mode_t umask, dict_t *params)
+ const char *linkname, loc_t *loc, dict_t *params)
{
xlator_t *subvol = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
+ int ret = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
- local = dht_local_init (frame, loc, NULL, GF_FOP_SYMLINK);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
goto err;
}
@@ -3322,33 +3497,41 @@ dht_symlink (call_frame_t *frame, xlator_t *this,
goto err;
}
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "Failed to copy loc");
+ op_errno = ENOMEM;
+ goto err;
+ }
+
gf_log (this->name, GF_LOG_TRACE,
"creating %s on %s", loc->path, subvol->name);
STACK_WIND (frame, dht_newfile_cbk,
subvol, subvol->fops->symlink,
- linkname, loc, umask, params);
+ linkname, loc, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (link, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
int
-dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
xlator_t *cached_subvol = NULL;
xlator_t *hashed_subvol = NULL;
+ int ret = -1;
int op_errno = -1;
dht_local_t *local = NULL;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
@@ -3360,14 +3543,15 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
local->loc.path, cached_subvol->name, loc->path);
STACK_WIND (frame, dht_unlink_cbk,
cached_subvol, cached_subvol->fops->unlink,
- &local->loc, xflag, xdata);
+ &local->loc);
goto done;
}
- local = dht_local_init (frame, loc, NULL, GF_FOP_UNLINK);
- if (!local) {
- op_errno = ENOMEM;
-
+ cached_subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!cached_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
goto err;
}
@@ -3380,29 +3564,32 @@ dht_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
goto err;
}
- cached_subvol = local->cached_subvol;
- if (!cached_subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
goto err;
}
- local->flags = xflag;
if (hashed_subvol != cached_subvol) {
STACK_WIND (frame, dht_unlink_linkfile_cbk,
- hashed_subvol, hashed_subvol->fops->unlink, loc,
- xflag, xdata);
+ hashed_subvol, hashed_subvol->fops->unlink, loc);
} else {
STACK_WIND (frame, dht_unlink_cbk,
- cached_subvol, cached_subvol->fops->unlink, loc,
- xflag, xdata);
+ cached_subvol, cached_subvol->fops->unlink, loc);
}
done:
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
+ DHT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -3412,12 +3599,14 @@ int
dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
call_frame_t *prev = NULL;
dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
prev = cookie;
+ local = frame->local;
if (op_ret == -1)
goto out;
@@ -3432,13 +3621,17 @@ dht_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
+ stbuf->ia_ino = local->loc.inode->ino;
+
+ preparent->ia_ino = local->loc2.parent->ino;
+ postparent->ia_ino = local->loc2.parent->ino;
+
WIPE (preparent);
WIPE (postparent);
out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
- postparent, NULL);
+ postparent);
return 0;
}
@@ -3448,27 +3641,27 @@ int
dht_link_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
xlator_t *srcvol = NULL;
+
if (op_ret == -1)
goto err;
local = frame->local;
srcvol = local->linkfile.srcvol;
- STACK_WIND (frame, dht_link_cbk, srcvol, srcvol->fops->link,
- &local->loc, &local->loc2, xdata);
+ STACK_WIND (frame, dht_link_cbk,
+ srcvol, srcvol->fops->link,
+ &local->loc, &local->loc2);
return 0;
err:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (link, frame, op_ret, op_errno, inode, stbuf, preparent,
- postparent, NULL);
+ postparent);
return 0;
}
@@ -3476,7 +3669,7 @@ err:
int
dht_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
xlator_t *cached_subvol = NULL;
xlator_t *hashed_subvol = NULL;
@@ -3484,19 +3677,13 @@ dht_link (call_frame_t *frame, xlator_t *this,
int ret = -1;
dht_local_t *local = NULL;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (oldloc, err);
VALIDATE_OR_GOTO (newloc, err);
- local = dht_local_init (frame, oldloc, NULL, GF_FOP_LINK);
- if (!local) {
- op_errno = ENOMEM;
-
- goto err;
- }
-
- cached_subvol = local->cached_subvol;
+ cached_subvol = dht_subvol_get_cached (this, oldloc->inode);
if (!cached_subvol) {
gf_log (this->name, GF_LOG_DEBUG,
"no cached subvolume for path=%s", oldloc->path);
@@ -3513,27 +3700,42 @@ dht_link (call_frame_t *frame, xlator_t *this,
goto err;
}
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ ret = loc_copy (&local->loc, oldloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
ret = loc_copy (&local->loc2, newloc);
if (ret == -1) {
op_errno = ENOMEM;
+
goto err;
}
if (hashed_subvol != cached_subvol) {
- uuid_copy (local->gfid, oldloc->inode->gfid);
+ memcpy (local->gfid, oldloc->inode->gfid, 16);
dht_linkfile_create (frame, dht_link_linkfile_cbk,
cached_subvol, hashed_subvol, newloc);
} else {
STACK_WIND (frame, dht_link_cbk,
cached_subvol, cached_subvol->fops->link,
- oldloc, newloc, xdata);
+ oldloc, newloc);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ DHT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -3543,7 +3745,7 @@ int
dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
fd_t *fd, inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
call_frame_t *prev = NULL;
int ret = -1;
@@ -3561,7 +3763,11 @@ dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
+ dht_itransform (this, prev->this, stbuf->ia_ino, &stbuf->ia_ino);
if (local->loc.parent) {
+ preparent->ia_ino = local->loc.parent->ino;
+ postparent->ia_ino = local->loc.parent->ino;
+
WIPE (preparent);
WIPE (postparent);
}
@@ -3577,9 +3783,8 @@ dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
DHT_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, stbuf, preparent,
- postparent, NULL);
+ postparent);
return 0;
}
@@ -3589,8 +3794,7 @@ dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
xlator_t *cached_subvol = NULL;
@@ -3604,22 +3808,23 @@ dht_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
STACK_WIND (frame, dht_create_cbk,
cached_subvol, cached_subvol->fops->create,
&local->loc, local->flags, local->mode,
- local->umask, local->fd, local->params);
+ local->fd, local->params);
return 0;
err:
- DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
return 0;
}
int
dht_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *params)
+ fd_t *fd, dict_t *params)
{
int op_errno = -1;
+ int ret = -1;
xlator_t *subvol = NULL;
+ dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
xlator_t *avail_subvol = NULL;
@@ -3627,10 +3832,13 @@ dht_create (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
+ conf = this->private;
+
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, fd, GF_FOP_CREATE);
+ local = dht_local_init (frame);
if (!local) {
+
op_errno = ENOMEM;
goto err;
}
@@ -3642,10 +3850,16 @@ dht_create (call_frame_t *frame, xlator_t *this,
local->loc.path, subvol->name, loc->path);
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- &local->loc, flags, mode, umask, fd, params);
+ &local->loc, flags, mode, fd, params);
goto done;
}
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
subvol = dht_subvol_get_hashed (this, loc);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -3660,17 +3874,19 @@ dht_create (call_frame_t *frame, xlator_t *this,
"creating %s on %s", loc->path, subvol->name);
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
+ loc, flags, mode, fd, params);
goto done;
}
/* Choose the minimum filled volume, and create the
files there */
+ /* TODO */
avail_subvol = dht_free_disk_available_subvol (this, subvol);
if (avail_subvol != subvol) {
+ local->fd = fd_ref (fd);
local->params = dict_ref (params);
local->flags = flags;
local->mode = mode;
- local->umask = umask;
+
local->cached_subvol = avail_subvol;
local->hashed_subvol = subvol;
gf_log (this->name, GF_LOG_TRACE,
@@ -3685,14 +3901,13 @@ dht_create (call_frame_t *frame, xlator_t *this,
"creating %s on %s", loc->path, subvol->name);
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
+ loc, flags, mode, fd, params);
done:
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ DHT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -3701,17 +3916,22 @@ err:
int
dht_mkdir_selfheal_cbk (call_frame_t *frame, void *cookie,
xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
dht_local_t *local = NULL;
dht_layout_t *layout = NULL;
+
local = frame->local;
layout = local->selfheal.layout;
if (op_ret == 0) {
dht_layout_set (this, local->inode, layout);
+ local->stbuf.ia_ino = local->ia_ino;
if (local->loc.parent) {
+ local->preparent.ia_ino = local->loc.parent->ino;
+ local->postparent.ia_ino = local->loc.parent->ino;
+
WIPE (&local->preparent);
WIPE (&local->postparent);
}
@@ -3719,7 +3939,7 @@ dht_mkdir_selfheal_cbk (call_frame_t *frame, void *cookie,
DHT_STACK_UNWIND (mkdir, frame, op_ret, op_errno,
local->inode, &local->stbuf, &local->preparent,
- &local->postparent, NULL);
+ &local->postparent);
return 0;
}
@@ -3727,15 +3947,17 @@ dht_mkdir_selfheal_cbk (call_frame_t *frame, void *cookie,
int
dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
int ret = -1;
- gf_boolean_t subvol_filled = _gf_false;
+ int subvol_filled = 0;
call_frame_t *prev = NULL;
dht_layout_t *layout = NULL;
+ dht_conf_t *conf = NULL;
+ conf = this->private;
local = frame->local;
prev = cookie;
layout = local->layout;
@@ -3751,9 +3973,6 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, NULL);
}
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to merge layouts", local->loc.path);
if (op_ret == -1) {
local->op_errno = op_errno;
@@ -3763,6 +3982,11 @@ dht_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dht_iatt_merge (this, &local->preparent, preparent, prev->this);
dht_iatt_merge (this, &local->postparent, postparent,
prev->this);
+
+ if (prev->this == dht_first_up_subvol (this)) {
+ local->ia_ino = local->stbuf.ia_ino;
+ }
+
}
unlock:
UNLOCK (&frame->lock);
@@ -3780,8 +4004,7 @@ int
dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
int ret = -1;
@@ -3799,8 +4022,8 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
conf = this->private;
hashed_subvol = local->hashed_subvol;
- if (uuid_is_null (local->loc.gfid) && !op_ret)
- uuid_copy (local->loc.gfid, stbuf->ia_gfid);
+ if (uuid_is_null (local->loc.inode->gfid) && !op_ret)
+ memcpy (local->loc.inode->gfid, stbuf->ia_gfid, 16);
if (dht_is_subvol_filled (this, hashed_subvol))
ret = dht_layout_merge (this, layout, prev->this,
@@ -3809,12 +4032,6 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
ret = dht_layout_merge (this, layout, prev->this,
op_ret, op_errno, NULL);
- /* TODO: we may have to return from the function
- if layout merge fails. For now, lets just log an error */
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to merge layouts", local->loc.path);
-
if (op_ret == -1) {
local->op_errno = op_errno;
goto err;
@@ -3825,10 +4042,10 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
dht_iatt_merge (this, &local->preparent, preparent, prev->this);
dht_iatt_merge (this, &local->postparent, postparent, prev->this);
+ local->ia_ino = local->stbuf.ia_ino;
+
local->call_cnt = conf->subvolume_cnt - 1;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, stbuf->ia_gfid);
if (local->call_cnt == 0) {
dht_selfheal_directory (frame, dht_mkdir_selfheal_cbk,
&local->loc, layout);
@@ -3838,24 +4055,24 @@ dht_mkdir_hashed_cbk (call_frame_t *frame, void *cookie,
continue;
STACK_WIND (frame, dht_mkdir_cbk,
conf->subvolumes[i],
- conf->subvolumes[i]->fops->mkdir, &local->loc,
- local->mode, local->umask, local->params);
+ conf->subvolumes[i]->fops->mkdir,
+ &local->loc, local->mode, local->params);
}
return 0;
err:
- DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
- int
+int
dht_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *params)
+ loc_t *loc, mode_t mode, dict_t *params)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int op_errno = -1;
+ int ret = -1;
xlator_t *hashed_subvol = NULL;
@@ -3870,13 +4087,15 @@ dht_mkdir (call_frame_t *frame, xlator_t *this,
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKDIR);
+ local = dht_local_init (frame);
if (!local) {
+
op_errno = ENOMEM;
goto err;
}
hashed_subvol = dht_subvol_get_hashed (this, loc);
+
if (hashed_subvol == NULL) {
gf_log (this->name, GF_LOG_DEBUG,
"hashed subvol not found for %s",
@@ -3886,13 +4105,21 @@ dht_mkdir (call_frame_t *frame, xlator_t *this,
}
local->hashed_subvol = hashed_subvol;
+ local->inode = inode_ref (loc->inode);
+ ret = loc_copy (&local->loc, loc);
local->mode = mode;
- local->umask = umask;
+
+ if (ret == -1) {
+
+ op_errno = ENOMEM;
+ goto err;
+ }
+
local->params = dict_ref (params);
- local->inode = inode_ref (loc->inode);
local->layout = dht_layout_new (this, conf->subvolume_cnt);
if (!local->layout) {
+
op_errno = ENOMEM;
goto err;
}
@@ -3900,14 +4127,13 @@ dht_mkdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_mkdir_hashed_cbk,
hashed_subvol,
hashed_subvol->fops->mkdir,
- loc, mode, umask, params);
+ loc, mode, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ DHT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -3915,80 +4141,19 @@ err:
int
dht_rmdir_selfheal_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+ int op_ret, int op_errno)
{
dht_local_t *local = NULL;
local = frame->local;
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
-
- return 0;
-}
-
-
-int
-dht_rmdir_hashed_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
-
- local = frame->local;
- prev = cookie;
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- if (op_errno != ENOENT && op_errno != EACCES) {
- local->need_selfheal = 1;
- }
-
-
- gf_log (this->name, GF_LOG_DEBUG,
- "rmdir on %s for %s failed (%s)",
- prev->this->name, local->loc.path,
- strerror (op_errno));
- goto unlock;
- }
-
- dht_iatt_merge (this, &local->preparent, preparent, prev->this);
- dht_iatt_merge (this, &local->postparent, postparent,
- prev->this);
-
+ if (local->loc.parent) {
+ local->preparent.ia_ino = local->loc.parent->ino;
+ local->postparent.ia_ino = local->loc.parent->ino;
}
-unlock:
- UNLOCK (&frame->lock);
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- if (local->need_selfheal) {
- local->layout =
- dht_layout_get (this, local->loc.inode);
-
- /* TODO: neater interface needed below */
- local->stbuf.ia_type = local->loc.inode->ia_type;
-
- uuid_copy (local->gfid, local->loc.inode->gfid);
- dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
- &local->loc, local->layout);
- } else {
-
- if (local->loc.parent) {
- WIPE (&local->preparent);
- WIPE (&local->postparent);
- }
-
- DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
- local->op_errno, &local->preparent,
- &local->postparent, NULL);
- }
- }
+ DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
+ &local->preparent, &local->postparent);
return 0;
}
@@ -3997,12 +4162,11 @@ unlock:
int
dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
call_frame_t *prev = NULL;
- int done = 0;
local = frame->local;
prev = cookie;
@@ -4013,9 +4177,8 @@ dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_errno = op_errno;
local->op_ret = -1;
- if (op_errno != ENOENT && op_errno != EACCES) {
+ if (op_errno != ENOENT)
local->need_selfheal = 1;
- }
gf_log (this->name, GF_LOG_DEBUG,
"rmdir on %s for %s failed (%s)",
@@ -4024,8 +4187,6 @@ dht_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
- /* Track if rmdir succeeded on atleast one subvol*/
- local->fop_succeeded = 1;
dht_iatt_merge (this, &local->preparent, preparent, prev->this);
dht_iatt_merge (this, &local->postparent, postparent,
prev->this);
@@ -4035,45 +4196,30 @@ unlock:
this_call_cnt = dht_frame_return (frame);
-
- /* if local->hashed_subvol, we are yet to wind to hashed_subvol. */
- if (local->hashed_subvol && (this_call_cnt == 1)) {
- done = 1;
- } else if (!local->hashed_subvol && !this_call_cnt) {
- done = 1;
- }
-
-
- if (done) {
- if (local->need_selfheal && local->fop_succeeded) {
+ if (is_last_call (this_call_cnt)) {
+ if (local->need_selfheal) {
local->layout =
dht_layout_get (this, local->loc.inode);
/* TODO: neater interface needed below */
local->stbuf.ia_type = local->loc.inode->ia_type;
- uuid_copy (local->gfid, local->loc.inode->gfid);
dht_selfheal_restore (frame, dht_rmdir_selfheal_cbk,
&local->loc, local->layout);
- } else if (this_call_cnt) {
- /* If non-hashed subvol's have responded, proceed */
-
- local->need_selfheal = 0;
- STACK_WIND (frame, dht_rmdir_hashed_subvol_cbk,
- local->hashed_subvol,
- local->hashed_subvol->fops->rmdir,
- &local->loc, local->flags, NULL);
- } else if (!this_call_cnt) {
- /* All subvol's have responded, proceed */
-
+ } else {
if (local->loc.parent) {
+ local->preparent.ia_ino =
+ local->loc.parent->ino;
+ local->postparent.ia_ino =
+ local->loc.parent->ino;
+
WIPE (&local->preparent);
WIPE (&local->postparent);
}
DHT_STACK_UNWIND (rmdir, frame, local->op_ret,
local->op_errno, &local->preparent,
- &local->postparent, NULL);
+ &local->postparent);
}
}
@@ -4087,7 +4233,6 @@ dht_rmdir_do (call_frame_t *frame, xlator_t *this)
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int i = 0;
- xlator_t *hashed_subvol = NULL;
VALIDATE_OR_GOTO (this->private, err);
@@ -4099,41 +4244,18 @@ dht_rmdir_do (call_frame_t *frame, xlator_t *this)
local->call_cnt = conf->subvolume_cnt;
- /* first remove from non-hashed_subvol */
- hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
-
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_WARNING, "failed to get hashed "
- "subvol for %s",local->loc.path);
- } else {
- local->hashed_subvol = hashed_subvol;
- }
-
- /* When DHT has only 1 child */
- if (conf->subvolume_cnt == 1) {
- STACK_WIND (frame, dht_rmdir_hashed_subvol_cbk,
- conf->subvolumes[0],
- conf->subvolumes[0]->fops->rmdir,
- &local->loc, local->flags, NULL);
- return 0;
- }
-
for (i = 0; i < conf->subvolume_cnt; i++) {
- if (hashed_subvol &&
- (hashed_subvol == conf->subvolumes[i]))
- continue;
-
STACK_WIND (frame, dht_rmdir_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->rmdir,
- &local->loc, local->flags, NULL);
+ &local->loc, local->flags);
}
return 0;
err:
DHT_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
return 0;
}
@@ -4141,7 +4263,7 @@ err:
int
dht_rmdir_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -4211,7 +4333,7 @@ dht_rmdir_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_WIND (frame, dht_rmdir_linkfile_unlink_cbk,
- src, src->fops->unlink, &local->loc, 0, NULL);
+ src, src->fops->unlink, &local->loc);
return 0;
err:
@@ -4234,7 +4356,6 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
call_frame_t *lookup_frame = NULL;
dht_local_t *lookup_local = NULL;
dht_local_t *local = NULL;
- dict_t *xattrs = NULL;
local = frame->local;
@@ -4243,7 +4364,7 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
continue;
if (strcmp (trav->d_name, "..") == 0)
continue;
- if (check_is_linkfile (NULL, (&trav->d_stat), trav->dict)) {
+ if (check_is_linkfile (NULL, (&trav->d_stat), NULL) == 1) {
ret++;
continue;
}
@@ -4255,21 +4376,6 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
return 0;
}
- xattrs = dict_new ();
- if (!xattrs) {
- gf_log (this->name, GF_LOG_ERROR, "dict_new failed");
- return -1;
- }
-
- ret = dict_set_uint32 (xattrs, DHT_LINKFILE_KEY, 256);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to set linkto key"
- " in dict");
- if (xattrs)
- dict_unref (xattrs);
- return -1;
- }
-
list_for_each_entry (trav, &entries->list, list) {
if (strcmp (trav->d_name, ".") == 0)
continue;
@@ -4286,7 +4392,8 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
goto err;
}
- lookup_local = mem_get0 (this->local_pool);
+ lookup_local = GF_CALLOC (sizeof (*local), 1,
+ gf_dht_mt_dht_local_t);
if (!lookup_local) {
goto err;
}
@@ -4299,8 +4406,6 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
if (build_ret != 0)
goto err;
- uuid_copy (lookup_local->loc.gfid, trav->d_stat.ia_gfid);
-
gf_log (this->name, GF_LOG_TRACE,
"looking up %s on %s",
lookup_local->loc.path, src->name);
@@ -4313,18 +4418,12 @@ dht_rmdir_is_subvol_empty (call_frame_t *frame, xlator_t *this,
STACK_WIND (lookup_frame, dht_rmdir_lookup_cbk,
src, src->fops->lookup,
- &lookup_local->loc, xattrs);
+ &lookup_local->loc, NULL);
ret++;
}
- if (xattrs)
- dict_unref (xattrs);
-
return ret;
err:
- if (xattrs)
- dict_unref (xattrs);
-
DHT_STACK_DESTROY (lookup_frame);
return 0;
}
@@ -4332,8 +4431,7 @@ err:
int
dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int op_ret, int op_errno, gf_dirent_t *entries)
{
dht_local_t *local = NULL;
int this_call_cnt = -1;
@@ -4377,13 +4475,12 @@ dht_rmdir_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd, dict_t *xdata)
+ int op_ret, int op_errno, fd_t *fd)
{
dht_local_t *local = NULL;
int this_call_cnt = -1;
call_frame_t *prev = NULL;
- dict_t *dict = NULL;
- int ret = 0;
+
local = frame->local;
prev = cookie;
@@ -4393,33 +4490,14 @@ dht_rmdir_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"opendir on %s for %s failed (%s)",
prev->this->name, local->loc.path,
strerror (op_errno));
- if (op_errno != ENOENT) {
- local->op_ret = -1;
- local->op_errno = op_errno;
- }
- goto err;
- }
-
- dict = dict_new ();
- if (!dict) {
local->op_ret = -1;
- local->op_errno = ENOMEM;
+ local->op_errno = op_errno;
goto err;
}
- ret = dict_set_uint32 (dict,
- "trusted.glusterfs.dht.linkto", 256);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set 'trusted.glusterfs.dht.linkto' key",
- local->loc.path);
-
STACK_WIND (frame, dht_rmdir_readdirp_cbk,
prev->this, prev->this->fops->readdirp,
- local->fd, 4096, 0, dict);
-
- if (dict)
- dict_unref (dict);
+ local->fd, 4096, 0);
return 0;
@@ -4435,13 +4513,14 @@ err:
int
-dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
int op_errno = -1;
int i = -1;
+ int ret = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -4452,15 +4531,22 @@ dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
conf = this->private;
- local = dht_local_init (frame, loc, NULL, GF_FOP_RMDIR);
+ local = dht_local_init (frame);
if (!local) {
+
op_errno = ENOMEM;
goto err;
}
local->call_cnt = conf->subvolume_cnt;
local->op_ret = 0;
- local->fop_succeeded = 0;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+
+ op_errno = ENOMEM;
+ goto err;
+ }
local->flags = flags;
@@ -4475,7 +4561,7 @@ dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
STACK_WIND (frame, dht_rmdir_opendir_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->opendir,
- loc, local->fd, NULL);
+ loc, local->fd);
}
return 0;
@@ -4483,43 +4569,240 @@ dht_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (rmdir, frame, -1, op_errno,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
+
int
-dht_entrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+dht_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+int
+dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
{
- DHT_STACK_UNWIND (entrylk, frame, op_ret, op_errno, xdata);
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
+
+ STACK_WIND (frame,
+ dht_xattrop_cbk,
+ subvol, subvol->fops->xattrop,
+ loc, flags, dict);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
+
return 0;
}
int
-dht_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+dht_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ DHT_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+
+int
+dht_fxattrop (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ STACK_WIND (frame,
+ dht_fxattrop_cbk,
+ subvol, subvol->fops->fxattrop,
+ fd, flags, dict);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL);
+
+ return 0;
+}
+
+
+int
+dht_inodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
+{
+ DHT_STACK_UNWIND (inodelk, frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+dht_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
{
xlator_t *subvol = NULL;
int op_errno = -1;
dht_local_t *local = NULL;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (loc, err);
VALIDATE_OR_GOTO (loc->inode, err);
VALIDATE_OR_GOTO (loc->path, err);
- local = dht_local_init (frame, loc, NULL, GF_FOP_ENTRYLK);
+ subvol = dht_subvol_get_cached (this, loc->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
+
goto err;
}
- subvol = local->cached_subvol;
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = 1;
+
+ STACK_WIND (frame,
+ dht_inodelk_cbk,
+ subvol, subvol->fops->inodelk,
+ volume, loc, cmd, lock);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (inodelk, frame, -1, op_errno);
+
+ return 0;
+}
+
+
+int
+dht_finodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
+{
+ DHT_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int
+dht_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ subvol = dht_subvol_get_cached (this, fd->inode);
+ if (!subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no cached subvolume for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+
+ STACK_WIND (frame,
+ dht_finodelk_cbk,
+ subvol, subvol->fops->finodelk,
+ volume, fd, cmd, lock);
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (finodelk, frame, -1, op_errno);
+
+ return 0;
+}
+
+
+int
+dht_entrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
+{
+ DHT_STACK_UNWIND (entrylk, frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int
+dht_entrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+{
+ xlator_t *subvol = NULL;
+ int op_errno = -1;
+ dht_local_t *local = NULL;
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ subvol = dht_subvol_get_cached (this, loc->inode);
if (!subvol) {
gf_log (this->name, GF_LOG_DEBUG,
"no cached subvolume for path=%s", loc->path);
@@ -4527,17 +4810,25 @@ dht_entrylk (call_frame_t *frame, xlator_t *this,
goto err;
}
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ local->inode = inode_ref (loc->inode);
local->call_cnt = 1;
STACK_WIND (frame, dht_entrylk_cbk,
subvol, subvol->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
+ volume, loc, basename, cmd, type);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (entrylk, frame, -1, op_errno);
return 0;
}
@@ -4545,10 +4836,10 @@ err:
int
dht_fentrylk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, NULL);
+ DHT_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
return 0;
}
@@ -4556,7 +4847,7 @@ dht_fentrylk_cbk (call_frame_t *frame, void *cookie,
int
dht_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
xlator_t *subvol = NULL;
int op_errno = -1;
@@ -4575,13 +4866,173 @@ dht_fentrylk (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_fentrylk_cbk,
subvol, subvol->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
+ volume, fd, basename, cmd, type);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
+ DHT_STACK_UNWIND (fentrylk, frame, -1, op_errno);
+
+ return 0;
+}
+
+
+int
+dht_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
+
+
+ local = frame->local;
+ prev = cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "subvolume %s returned -1 (%s)",
+ prev->this->name, strerror (op_errno));
+ goto unlock;
+ }
+
+ dht_iatt_merge (this, &local->prebuf, statpre, prev->this);
+ dht_iatt_merge (this, &local->stbuf, statpost, prev->this);
+
+ if (local->inode) {
+ local->prebuf.ia_ino = local->inode->ino;
+ local->stbuf.ia_ino = local->inode->ino;
+ }
+
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_UNWIND (setattr, frame, local->op_ret, local->op_errno,
+ &local->prebuf, &local->stbuf);
+
+ return 0;
+}
+
+
+int
+dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid)
+{
+ dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
+ int op_errno = -1;
+ int i = -1;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (loc, err);
+ VALIDATE_OR_GOTO (loc->inode, err);
+ VALIDATE_OR_GOTO (loc->path, err);
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "memory allocation failed :(");
+ goto err;
+ }
+
+ local->layout = layout = dht_layout_get (this, loc->inode);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no layout for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ if (!layout_is_sane (layout)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "layout is not sane for path=%s", loc->path);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local->inode = inode_ref (loc->inode);
+ local->call_cnt = layout->cnt;
+
+ for (i = 0; i < layout->cnt; i++) {
+ STACK_WIND (frame, dht_setattr_cbk,
+ layout->list[i].xlator,
+ layout->list[i].xlator->fops->setattr,
+ loc, stbuf, valid);
+ }
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+int
+dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
+ int32_t valid)
+{
+ dht_layout_t *layout = NULL;
+ dht_local_t *local = NULL;
+ int op_errno = -1;
+ int i = -1;
+
+
+ VALIDATE_OR_GOTO (frame, err);
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (fd, err);
+
+ local = dht_local_init (frame);
+ if (!local) {
+ op_errno = ENOMEM;
+
+ goto err;
+ }
+
+ local->layout = layout = dht_layout_get (this, fd->inode);
+ if (!layout) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no layout for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ if (!layout_is_sane (layout)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "layout is not sane for fd=%p", fd);
+ op_errno = EINVAL;
+ goto err;
+ }
+
+ local->inode = inode_ref (fd->inode);
+ local->call_cnt = layout->cnt;
+
+ for (i = 0; i < layout->cnt; i++) {
+ STACK_WIND (frame, dht_setattr_cbk,
+ layout->list[i].xlator,
+ layout->list[i].xlator->fops->fsetattr,
+ fd, stbuf, valid);
+ }
+
+ return 0;
+
+err:
+ op_errno = (op_errno == -1) ? errno : op_errno;
+ DHT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -4593,7 +5044,7 @@ dht_forget (xlator_t *this, inode_t *inode)
uint64_t tmp_layout = 0;
dht_layout_t *layout = NULL;
- inode_ctx_del (inode, this, &tmp_layout);
+ inode_ctx_get (inode, this, &tmp_layout);
if (!tmp_layout)
return 0;
@@ -4605,24 +5056,60 @@ dht_forget (xlator_t *this, inode_t *inode)
}
+
+int
+dht_init_subvolumes (xlator_t *this, dht_conf_t *conf)
+{
+ xlator_list_t *subvols = NULL;
+ int cnt = 0;
+
+ if (!conf)
+ return -1;
+
+ for (subvols = this->children; subvols; subvols = subvols->next)
+ cnt++;
+
+ conf->subvolumes = GF_CALLOC (cnt, sizeof (xlator_t *),
+ gf_dht_mt_xlator_t);
+ if (!conf->subvolumes) {
+
+ return -1;
+ }
+ conf->subvolume_cnt = cnt;
+
+ cnt = 0;
+ for (subvols = this->children; subvols; subvols = subvols->next)
+ conf->subvolumes[cnt++] = subvols->xlator;
+
+ conf->subvolume_status = GF_CALLOC (cnt, sizeof (char),
+ gf_dht_mt_char);
+ if (!conf->subvolume_status) {
+
+ return -1;
+ }
+
+ conf->last_event = GF_CALLOC (cnt, sizeof (int),
+ gf_dht_mt_char);
+ if (!conf->last_event) {
+
+ return -1;
+ }
+ return 0;
+}
+
+
int
dht_notify (xlator_t *this, int event, void *data, ...)
{
- xlator_t *subvol = NULL;
- int cnt = -1;
- int i = -1;
- dht_conf_t *conf = NULL;
- int ret = -1;
- int propagate = 0;
-
- int had_heard_from_all = 0;
- int have_heard_from_all = 0;
- struct timeval time = {0,};
- gf_defrag_info_t *defrag = NULL;
- dict_t *dict = NULL;
- gf_defrag_type cmd = 0;
- dict_t *output = NULL;
- va_list ap;
+ xlator_t *subvol = NULL;
+ int cnt = -1;
+ int i = -1;
+ dht_conf_t *conf = NULL;
+ int ret = -1;
+ int propagate = 0;
+
+ int had_heard_from_all = 0;
+ int have_heard_from_all = 0;
conf = this->private;
@@ -4657,12 +5144,10 @@ dht_notify (xlator_t *this, int event, void *data, ...)
break;
}
- gettimeofday (&time, NULL);
LOCK (&conf->subvolume_lock);
{
conf->subvolume_status[cnt] = 1;
conf->last_event[cnt] = event;
- conf->subvol_up_time[cnt] = time.tv_sec;
}
UNLOCK (&conf->subvolume_lock);
@@ -4675,7 +5160,6 @@ dht_notify (xlator_t *this, int event, void *data, ...)
subvol = data;
conf->gen++;
- propagate = 1;
break;
@@ -4685,11 +5169,7 @@ dht_notify (xlator_t *this, int event, void *data, ...)
if (conf->assert_no_child_down) {
gf_log (this->name, GF_LOG_WARNING,
"Received CHILD_DOWN. Exiting");
- if (conf->defrag) {
- gf_defrag_stop (conf->defrag, NULL);
- } else {
- kill (getpid(), SIGTERM);
- }
+ exit(0);
}
for (i = 0; i < conf->subvolume_cnt; i++) {
@@ -4710,7 +5190,6 @@ dht_notify (xlator_t *this, int event, void *data, ...)
{
conf->subvolume_status[cnt] = 0;
conf->last_event[cnt] = event;
- conf->subvol_up_time[cnt] = 0;
}
UNLOCK (&conf->subvolume_lock);
@@ -4740,36 +5219,6 @@ dht_notify (xlator_t *this, int event, void *data, ...)
UNLOCK (&conf->subvolume_lock);
break;
- case GF_EVENT_VOLUME_DEFRAG:
- {
- if (!conf->defrag) {
- return ret;
- }
- defrag = conf->defrag;
-
- dict = data;
- va_start (ap, data);
- output = va_arg (ap, dict_t*);
-
- ret = dict_get_int32 (dict, "rebalance-command",
- (int32_t*)&cmd);
- if (ret)
- return ret;
- LOCK (&defrag->lock);
- {
- if (defrag->is_exiting)
- goto unlock;
- if (cmd == GF_DEFRAG_CMD_STATUS)
- gf_defrag_status_get (defrag, output);
- else if (cmd == GF_DEFRAG_CMD_STOP)
- gf_defrag_stop (defrag, output);
- }
-unlock:
- UNLOCK (&defrag->lock);
- return 0;
- break;
- }
-
default:
propagate = 1;
break;
@@ -4785,19 +5234,8 @@ unlock:
/* if all subvols have reported status, no need to hide anything
or wait for anything else. Just propagate blindly */
- if (have_heard_from_all) {
+ if (have_heard_from_all)
propagate = 1;
- if (conf->defrag) {
- ret = pthread_create (&conf->defrag->th, NULL,
- gf_defrag_start, this);
- if (ret) {
- conf->defrag = NULL;
- GF_FREE (conf->defrag);
- kill (getpid(), SIGTERM);
- }
- }
- }
-
if (!had_heard_from_all && have_heard_from_all) {
/* This is the first event which completes aggregation
@@ -4819,8 +5257,7 @@ unlock:
}
}
- ret = 0;
- if (propagate)
+ if (propagate || event == GF_EVENT_CHILD_MODIFIED)
ret = default_notify (this, event, data);
return ret;
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index d3ccacdb8..67cc16e43 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -15,68 +24,45 @@
#include "dht-mem-types.h"
#include "libxlator.h"
-#include "syncop.h"
#ifndef _DHT_H
#define _DHT_H
-#define GF_XATTR_FIX_LAYOUT_KEY "distribute.fix.layout"
+#define GF_XATTR_FIX_LAYOUT_KEY "trusted.distribute.fix.layout"
#define GF_DHT_LOOKUP_UNHASHED_ON 1
#define GF_DHT_LOOKUP_UNHASHED_AUTO 2
-#define DHT_PATHINFO_HEADER "DISTRIBUTE:"
#include <fnmatch.h>
typedef int (*dht_selfheal_dir_cbk_t) (call_frame_t *frame, void *cookie,
- xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- dict_t *xdata);
-typedef int (*dht_defrag_cbk_fn_t) (xlator_t *this, call_frame_t *frame,
- int ret);
+ xlator_t *this,
+ int32_t op_ret, int32_t op_errno);
struct dht_layout {
- int spread_cnt; /* layout spread count per directory,
- is controlled by 'setxattr()' with
- special key */
- int cnt;
- int preset;
- int gen;
- int type;
- int ref; /* use with dht_conf_t->layout_lock */
- int search_unhashed;
+ int cnt;
+ int preset;
+ int gen;
+ int type;
+ int ref; /* use with dht_conf_t->layout_lock */
+ int search_unhashed;
struct {
- int err; /* 0 = normal
- -1 = dir exists and no xattr
- >0 = dir lookup failed with errno
- */
- uint32_t start;
- uint32_t stop;
- xlator_t *xlator;
+ int err; /* 0 = normal
+ -1 = dir exists and no xattr
+ >0 = dir lookup failed with errno
+ */
+ uint32_t start;
+ uint32_t stop;
+ xlator_t *xlator;
} list[0];
};
-typedef struct dht_layout dht_layout_t;
+typedef struct dht_layout dht_layout_t;
typedef enum {
DHT_HASH_TYPE_DM,
- DHT_HASH_TYPE_DM_USER,
} dht_hashfn_type_t;
-/* rebalance related */
-struct dht_rebalance_ {
- xlator_t *from_subvol;
- xlator_t *target_node;
- off_t offset;
- size_t size;
- int32_t flags;
- int count;
- struct iobref *iobref;
- struct iovec *vector;
- struct iatt stbuf;
- dht_defrag_cbk_fn_t target_op_fn;
- dict_t *xdata;
-};
struct dht_local {
int call_cnt;
@@ -110,7 +96,6 @@ struct dht_local {
int file_count;
int dir_count;
call_frame_t *main_frame;
- int fop_succeeded;
struct {
fop_mknod_cbk_t linkfile_cbk;
struct iatt stbuf;
@@ -135,15 +120,11 @@ struct dht_local {
int32_t flags;
mode_t mode;
dev_t rdev;
- mode_t umask;
/* need for file-info */
- char *xattr_val;
+ char *pathinfo;
char *key;
- /* which xattr request? */
- char xsel[256];
-
char *newpath;
/* gfid related */
@@ -151,69 +132,17 @@ struct dht_local {
/*Marker Related*/
struct marker_str marker;
-
- /* flag used to make sure we need to return estale in
- {lookup,revalidate}_cbk */
- char return_estale;
- char need_lookup_everywhere;
-
- glusterfs_fop_t fop;
-
- struct dht_rebalance_ rebalance;
-
};
typedef struct dht_local dht_local_t;
/* du - disk-usage */
struct dht_du {
double avail_percent;
- double avail_inodes;
uint64_t avail_space;
uint32_t log;
};
typedef struct dht_du dht_du_t;
-enum gf_defrag_type {
- GF_DEFRAG_CMD_START = 1,
- GF_DEFRAG_CMD_STOP = 1 + 1,
- GF_DEFRAG_CMD_STATUS = 1 + 2,
- GF_DEFRAG_CMD_START_LAYOUT_FIX = 1 + 3,
- GF_DEFRAG_CMD_START_FORCE = 1 + 4,
-};
-typedef enum gf_defrag_type gf_defrag_type;
-
-enum gf_defrag_status_t {
- GF_DEFRAG_STATUS_NOT_STARTED,
- GF_DEFRAG_STATUS_STARTED,
- GF_DEFRAG_STATUS_STOPPED,
- GF_DEFRAG_STATUS_COMPLETE,
- GF_DEFRAG_STATUS_FAILED,
-};
-typedef enum gf_defrag_status_t gf_defrag_status_t;
-
-
-struct gf_defrag_info_ {
- uint64_t total_files;
- uint64_t total_data;
- uint64_t num_files_lookedup;
- uint64_t total_failures;
- gf_lock_t lock;
- int cmd;
- pthread_t th;
- gf_defrag_status_t defrag_status;
- struct rpc_clnt *rpc;
- uint32_t connected;
- uint32_t is_exiting;
- pid_t pid;
- inode_t *root_inode;
- uuid_t node_uuid;
- struct timeval start_time;
- gf_boolean_t stats;
-
-};
-
-typedef struct gf_defrag_info_ gf_defrag_info_t;
-
struct dht_conf {
gf_lock_t subvolume_lock;
int subvolume_cnt;
@@ -222,11 +151,11 @@ struct dht_conf {
int *last_event;
dht_layout_t **file_layouts;
dht_layout_t **dir_layouts;
+ dht_layout_t *default_dir_layout;
gf_boolean_t search_unhashed;
int gen;
dht_du_t *du_stats;
uint64_t min_free_disk;
- uint32_t min_free_inodes;
char disk_unit;
int32_t refresh_interval;
gf_boolean_t unhashed_sticky_bit;
@@ -237,18 +166,6 @@ struct dht_conf {
gf_boolean_t use_readdirp;
char vol_uuid[UUID_SIZE + 1];
gf_boolean_t assert_no_child_down;
- time_t *subvol_up_time;
-
- /* This is the count used as the distribute layout for a directory */
- /* Will be a global flag to control the layout spread count */
- uint32_t dir_spread_cnt;
-
- /* to keep track of nodes which are decomissioned */
- xlator_t **decommissioned_bricks;
- int decommission_in_progress;
-
- /* defrag related */
- gf_defrag_info_t *defrag;
};
typedef struct dht_conf dht_conf_t;
@@ -263,46 +180,21 @@ struct dht_disk_layout {
};
typedef struct dht_disk_layout dht_disk_layout_t;
-typedef enum {
- GF_DHT_MIGRATE_DATA,
- GF_DHT_MIGRATE_DATA_EVEN_IF_LINK_EXISTS,
- GF_DHT_MIGRATE_HARDLINK,
- GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS
-} gf_dht_migrate_data_type_t;
+#define WIPE(statp) do { typeof(*statp) z = {0,}; if (statp) *statp = z; } while (0)
#define ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT)
+#define is_fs_root(loc) (strcmp (loc->path, "/") == 0)
+
#define is_revalidate(loc) (inode_ctx_get (loc->inode, this, NULL) == 0)
#define is_last_call(cnt) (cnt == 0)
-#define DHT_MIGRATION_IN_PROGRESS 1
-#define DHT_MIGRATION_COMPLETED 2
-
-#define DHT_LINKFILE_KEY "trusted.glusterfs.dht.linkto"
-#define DHT_LINKFILE_MODE (S_ISVTX)
-
+#define DHT_LINKFILE_MODE (S_ISVTX)
#define check_is_linkfile(i,s,x) ( \
- ((st_mode_from_ia ((s)->ia_prot, (s)->ia_type) & ~S_IFMT) \
+ ((st_mode_from_ia (s->ia_prot, s->ia_type) & ~S_IFMT) \
== DHT_LINKFILE_MODE) && \
- dict_get (x, DHT_LINKFILE_KEY))
-
-#define IS_DHT_MIGRATION_PHASE2(buf) ( \
- IA_ISREG ((buf)->ia_type) && \
- ((st_mode_from_ia ((buf)->ia_prot, (buf)->ia_type) & \
- ~S_IFMT) == DHT_LINKFILE_MODE))
-
-#define IS_DHT_MIGRATION_PHASE1(buf) ( \
- IA_ISREG ((buf)->ia_type) && \
- ((buf)->ia_prot.sticky == 1) && \
- ((buf)->ia_prot.sgid == 1))
-
-#define DHT_STRIP_PHASE1_FLAGS(buf) do { \
- if ((buf) && IS_DHT_MIGRATION_PHASE1(buf)) { \
- (buf)->ia_prot.sticky = 0; \
- (buf)->ia_prot.sgid = 0; \
- } \
- } while (0)
+ (s->ia_size == 0))
#define check_is_dir(i,s,x) (IA_ISDIR(s->ia_type))
@@ -310,357 +202,107 @@ typedef enum {
#define DHT_STACK_UNWIND(fop, frame, params ...) do { \
dht_local_t *__local = NULL; \
- xlator_t *__xl = NULL; \
+ xlator_t *__xl = NULL; \
if (frame) { \
- __xl = frame->this; \
- __local = frame->local; \
+ __xl = frame->this; \
+ __local = frame->local; \
frame->local = NULL; \
} \
STACK_UNWIND_STRICT (fop, frame, params); \
dht_local_wipe (__xl, __local); \
} while (0)
-#define DHT_STACK_DESTROY(frame) do { \
- dht_local_t *__local = NULL; \
- xlator_t *__xl = NULL; \
- __xl = frame->this; \
- __local = frame->local; \
- frame->local = NULL; \
- STACK_DESTROY (frame->root); \
- dht_local_wipe (__xl, __local); \
+#define DHT_STACK_DESTROY(frame) do { \
+ dht_local_t *__local = NULL; \
+ xlator_t *__xl = NULL; \
+ __xl = frame->this; \
+ __local = frame->local; \
+ frame->local = NULL; \
+ STACK_DESTROY (frame->root); \
+ dht_local_wipe (__xl, __local); \
} while (0)
-dht_layout_t *dht_layout_new (xlator_t *this, int cnt);
-dht_layout_t *dht_layout_get (xlator_t *this, inode_t *inode);
-dht_layout_t *dht_layout_for_subvol (xlator_t *this, xlator_t *subvol);
-xlator_t *dht_layout_search (xlator_t *this, dht_layout_t *layout,
+dht_layout_t *dht_layout_new (xlator_t *this, int cnt);
+dht_layout_t *dht_layout_get (xlator_t *this, inode_t *inode);
+dht_layout_t *dht_layout_for_subvol (xlator_t *this, xlator_t *subvol);
+xlator_t *dht_layout_search (xlator_t *this, dht_layout_t *layout,
const char *name);
-int dht_layout_normalize (xlator_t *this, loc_t *loc, dht_layout_t *layout);
-int dht_layout_anomalies (xlator_t *this, loc_t *loc, dht_layout_t *layout,
- uint32_t *holes_p, uint32_t *overlaps_p,
- uint32_t *missing_p, uint32_t *down_p,
- uint32_t *misc_p);
-int dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout,
- xlator_t *subvol, loc_t *loc, dict_t *xattr);
+int dht_layout_normalize (xlator_t *this, loc_t *loc, dht_layout_t *layout);
+int dht_layout_anomalies (xlator_t *this, loc_t *loc, dht_layout_t *layout,
+ uint32_t *holes_p, uint32_t *overlaps_p,
+ uint32_t *missing_p, uint32_t *down_p,
+ uint32_t *misc_p);
+int dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout,
+ xlator_t *subvol, loc_t *loc, dict_t *xattr);
xlator_t *dht_linkfile_subvol (xlator_t *this, inode_t *inode,
struct iatt *buf, dict_t *xattr);
-int dht_linkfile_unlink (call_frame_t *frame, xlator_t *this,
- xlator_t *subvol, loc_t *loc);
+int dht_linkfile_unlink (call_frame_t *frame, xlator_t *this,
+ xlator_t *subvol, loc_t *loc);
int dht_layouts_init (xlator_t *this, dht_conf_t *conf);
int dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
- int op_ret, int op_errno, dict_t *xattr);
+ int op_ret, int op_errno, dict_t *xattr);
int dht_disk_layout_extract (xlator_t *this, dht_layout_t *layout,
- int pos, int32_t **disk_layout_p);
-int dht_disk_layout_merge (xlator_t *this, dht_layout_t *layout,
- int pos, void *disk_layout_raw, int disk_layout_len);
+ int pos, int32_t **disk_layout_p);
+int dht_disk_layout_merge (xlator_t *this, dht_layout_t *layout,
+ int pos, void *disk_layout_raw);
int dht_frame_return (call_frame_t *frame);
-int dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y);
+int dht_itransform (xlator_t *this, xlator_t *subvol, uint64_t x, uint64_t *y);
int dht_deitransform (xlator_t *this, uint64_t y, xlator_t **subvol,
uint64_t *x);
void dht_local_wipe (xlator_t *this, dht_local_t *local);
-dht_local_t *dht_local_init (call_frame_t *frame, loc_t *loc, fd_t *fd,
- glusterfs_fop_t fop);
-int dht_iatt_merge (xlator_t *this, struct iatt *to, struct iatt *from,
- xlator_t *subvol);
+dht_local_t *dht_local_init (call_frame_t *frame);
+int dht_iatt_merge (xlator_t *this, struct iatt *to, struct iatt *from,
+ xlator_t *subvol);
xlator_t *dht_subvol_get_hashed (xlator_t *this, loc_t *loc);
xlator_t *dht_subvol_get_cached (xlator_t *this, inode_t *inode);
xlator_t *dht_subvol_next (xlator_t *this, xlator_t *prev);
-int dht_subvol_cnt (xlator_t *this, xlator_t *subvol);
+int dht_subvol_cnt (xlator_t *this, xlator_t *subvol);
int dht_hash_compute (int type, const char *name, uint32_t *hash_p);
-int dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,
- xlator_t *tovol, xlator_t *fromvol, loc_t *loc);
-int dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc);
-int dht_lookup_everywhere (call_frame_t *frame, xlator_t *this, loc_t *loc);
+int dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,
+ xlator_t *tovol, xlator_t *fromvol, loc_t *loc);
+int dht_lookup_directory (call_frame_t *frame, xlator_t *this, loc_t *loc);
+int dht_lookup_everywhere (call_frame_t *frame, xlator_t *this, loc_t *loc);
int
-dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t cbk,
- loc_t *loc, dht_layout_t *layout);
+dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t cbk,
+ loc_t *loc, dht_layout_t *layout);
int
dht_selfheal_new_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t cbk,
dht_layout_t *layout);
int
-dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t cbk,
- loc_t *loc, dht_layout_t *layout);
+dht_selfheal_restore (call_frame_t *frame, dht_selfheal_dir_cbk_t cbk,
+ loc_t *loc, dht_layout_t *layout);
int
dht_layout_sort_volname (dht_layout_t *layout);
+int dht_rename (call_frame_t *frame, xlator_t *this,
+ loc_t *oldloc, loc_t *newloc);
+
int dht_get_du_info (call_frame_t *frame, xlator_t *this, loc_t *loc);
-gf_boolean_t dht_is_subvol_filled (xlator_t *this, xlator_t *subvol);
+int dht_is_subvol_filled (xlator_t *this, xlator_t *subvol);
xlator_t *dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol);
-int dht_get_du_info_for_subvol (xlator_t *this, int subvol_idx);
+int dht_get_du_info_for_subvol (xlator_t *this, int subvol_idx);
int dht_layout_preset (xlator_t *this, xlator_t *subvol, inode_t *inode);
-int dht_layout_set (xlator_t *this, inode_t *inode, dht_layout_t *layout);;
-void dht_layout_unref (xlator_t *this, dht_layout_t *layout);
+int dht_layout_set (xlator_t *this, inode_t *inode, dht_layout_t *layout);
+void dht_layout_unref (xlator_t *this, dht_layout_t *layout);
dht_layout_t *dht_layout_ref (xlator_t *this, dht_layout_t *layout);
-xlator_t *dht_first_up_subvol (xlator_t *this);
-xlator_t *dht_last_up_subvol (xlator_t *this);
+xlator_t *dht_first_up_subvol (xlator_t *this);
+xlator_t *dht_last_up_subvol (xlator_t *this);
int dht_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent, char *name);
-int dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
+int dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
xlator_t **subvol);
-int dht_rename_cleanup (call_frame_t *frame);
-int dht_rename_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-
-int dht_fix_directory_layout (call_frame_t *frame,
- dht_selfheal_dir_cbk_t dir_cbk,
- dht_layout_t *layout);
-
-int dht_init_subvolumes (xlator_t *this, dht_conf_t *conf);
-
-/* migration/rebalance */
-int dht_start_rebalance_task (xlator_t *this, call_frame_t *frame);
-
-int dht_rebalance_in_progress_check (xlator_t *this, call_frame_t *frame);
-int dht_rebalance_complete_check (xlator_t *this, call_frame_t *frame);
-
-
-/* FOPS */
-int32_t dht_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xattr_req);
-
-int32_t dht_stat (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata);
-
-int32_t dht_fstat (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t dht_truncate (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- off_t offset, dict_t *xdata);
-
-int32_t dht_ftruncate (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- off_t offset, dict_t *xdata);
-
-int32_t dht_access (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t mask, dict_t *xdata);
-
-int32_t dht_readlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- size_t size, dict_t *xdata);
-
-int32_t dht_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata);
-
-int32_t dht_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata);
-
-int32_t dht_unlink (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata);
-
-int32_t dht_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata);
-
-int32_t dht_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask,
- dict_t *xdata);
-
-int32_t dht_rename (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata);
-
-int32_t dht_link (call_frame_t *frame,
- xlator_t *this,
- loc_t *oldloc,
- loc_t *newloc, dict_t *xdata);
-
-int32_t dht_create (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *params);
-
-int32_t dht_open (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata);
-
-int32_t dht_readv (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size,
- off_t offset, uint32_t flags, dict_t *xdata);
-
-int32_t dht_writev (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset,
- uint32_t flags,
- struct iobref *iobref, dict_t *xdata);
-
-int32_t dht_flush (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd, dict_t *xdata);
-
-int32_t dht_fsync (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync, dict_t *xdata);
-
-int32_t dht_opendir (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata);
-
-int32_t dht_fsyncdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t datasync, dict_t *xdata);
-
-int32_t dht_statfs (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc, dict_t *xdata);
-
-int32_t dht_setxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- int32_t flags, dict_t *xdata);
-
-int32_t dht_getxattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name, dict_t *xdata);
-
-int32_t dht_fsetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- dict_t *dict,
- int32_t flags, dict_t *xdata);
-
-int32_t dht_fgetxattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name, dict_t *xdata);
-
-int32_t dht_removexattr (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- const char *name, dict_t *xdata);
-int32_t dht_fremovexattr (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- const char *name, dict_t *xdata);
-
-int32_t dht_lk (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- int32_t cmd,
- struct gf_flock *flock, dict_t *xdata);
-
-int32_t dht_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *flock, dict_t *xdata);
-
-int32_t dht_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *flock, dict_t *xdata);
-
-int32_t dht_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
-
-int32_t dht_fentrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
-
-int32_t dht_readdir (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off, dict_t *xdata);
-
-int32_t dht_readdirp (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- size_t size, off_t off, dict_t *dict);
-
-int32_t dht_xattrop (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata);
-
-int32_t dht_fxattrop (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata);
-
-int32_t dht_forget (xlator_t *this, inode_t *inode);
-int32_t dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-int32_t dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-
-int32_t dht_notify (xlator_t *this, int32_t event, void *data, ...);
-
-/* definitions for nufa/switch */
-int dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode,
- struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent);
-int dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode,
- struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent);
-int dht_lookup_linkfile_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent);
-int dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *xattr,
- struct iatt *postparent);
-int dht_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- fd_t *fd, inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata);
-int dht_newfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata);
-
-int
-gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict);
-
-int
-gf_defrag_stop (gf_defrag_info_t *defrag, dict_t *output);
-
-void*
-gf_defrag_start (void *this);
-
-int32_t
-gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
- struct iatt *stbuf);
-int
-dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
- int flag);
-#endif/* _DHT_H */
+#endif /* _DHT_H */
diff --git a/xlators/cluster/dht/src/dht-diskusage.c b/xlators/cluster/dht/src/dht-diskusage.c
index 52ea3a32a..75953781e 100644
--- a/xlators/cluster/dht/src/dht-diskusage.c
+++ b/xlators/cluster/dht/src/dht-diskusage.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -26,272 +35,224 @@
int
dht_du_info_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct statvfs *statvfs,
- dict_t *xdata)
+ int op_ret, int op_errno, struct statvfs *statvfs)
{
- dht_conf_t *conf = NULL;
- call_frame_t *prev = NULL;
- int this_call_cnt = 0;
- int i = 0;
- double percent = 0;
- double percent_inodes = 0;
- uint64_t bytes = 0;
-
- conf = this->private;
- prev = cookie;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to get disk info from %s", prev->this->name);
- goto out;
- }
-
- if (statvfs && statvfs->f_blocks) {
- percent = (statvfs->f_bavail * 100) / statvfs->f_blocks;
- bytes = (statvfs->f_bavail * statvfs->f_frsize);
- }
-
- if (statvfs && statvfs->f_files) {
- percent_inodes = (statvfs->f_ffree * 100) / statvfs->f_files;
- } else {
- /* set percent inodes to 100 for dynamically allocated inode filesystems
- this logic holds good so that, distribute has nothing to worry about
- total inodes rather let the 'create()' to be scheduled on the hashed
- subvol regardless of the total inodes. since we have no awareness on
- loosing inodes this logic fits well
- */
- percent_inodes = 100;
- }
-
- LOCK (&conf->subvolume_lock);
- {
- for (i = 0; i < conf->subvolume_cnt; i++)
- if (prev->this == conf->subvolumes[i]) {
- conf->du_stats[i].avail_percent = percent;
- conf->du_stats[i].avail_space = bytes;
- conf->du_stats[i].avail_inodes = percent_inodes;
- gf_log (this->name, GF_LOG_DEBUG,
- "on subvolume '%s': avail_percent is: "
- "%.2f and avail_space is: %"PRIu64" "
- "and avail_inodes is: %.2f",
- prev->this->name,
- conf->du_stats[i].avail_percent,
- conf->du_stats[i].avail_space,
- conf->du_stats[i].avail_inodes);
- }
- }
- UNLOCK (&conf->subvolume_lock);
+ dht_conf_t *conf = NULL;
+ call_frame_t *prev = NULL;
+ int this_call_cnt = 0;
+ int i = 0;
+ double percent = 0;
+ uint64_t bytes = 0;
+
+ conf = this->private;
+ prev = cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get disk info from %s", prev->this->name);
+ goto out;
+ }
+
+ if (statvfs && statvfs->f_blocks) {
+ percent = (statvfs->f_bfree * 100) / statvfs->f_blocks;
+ bytes = (statvfs->f_bfree * statvfs->f_frsize);
+ }
+
+ LOCK (&conf->subvolume_lock);
+ {
+ for (i = 0; i < conf->subvolume_cnt; i++)
+ if (prev->this == conf->subvolumes[i]) {
+ conf->du_stats[i].avail_percent = percent;
+ conf->du_stats[i].avail_space = bytes;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "on subvolume '%s': avail_percent is: "
+ "%.2f and avail_space is: %"PRIu64"",
+ prev->this->name,
+ conf->du_stats[i].avail_percent,
+ conf->du_stats[i].avail_space);
+ }
+ }
+ UNLOCK (&conf->subvolume_lock);
out:
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt))
- DHT_STACK_DESTROY (frame);
+ this_call_cnt = dht_frame_return (frame);
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_DESTROY (frame);
- return 0;
+ return 0;
}
int
dht_get_du_info_for_subvol (xlator_t *this, int subvol_idx)
{
- dht_conf_t *conf = NULL;
- call_frame_t *statfs_frame = NULL;
- dht_local_t *statfs_local = NULL;
- call_pool_t *pool = NULL;
- loc_t tmp_loc = {0,};
-
- conf = this->private;
- pool = this->ctx->pool;
-
- statfs_frame = create_frame (this, pool);
- if (!statfs_frame) {
- goto err;
- }
-
- /* local->fop value is not used in this case */
- statfs_local = dht_local_init (statfs_frame, NULL, NULL,
- GF_FOP_MAXVALUE);
- if (!statfs_local) {
- goto err;
- }
-
- /* make it root gfid, should be enough to get the proper info back */
- tmp_loc.gfid[15] = 1;
-
- statfs_local->call_cnt = 1;
- STACK_WIND (statfs_frame, dht_du_info_cbk,
- conf->subvolumes[subvol_idx],
- conf->subvolumes[subvol_idx]->fops->statfs,
- &tmp_loc, NULL);
-
- return 0;
+ dht_conf_t *conf = NULL;
+ call_frame_t *statfs_frame = NULL;
+ dht_local_t *statfs_local = NULL;
+ call_pool_t *pool = NULL;
+
+ conf = this->private;
+ pool = this->ctx->pool;
+
+ statfs_frame = create_frame (this, pool);
+ if (!statfs_frame) {
+ goto err;
+ }
+
+ statfs_local = dht_local_init (statfs_frame);
+ if (!statfs_local) {
+ goto err;
+ }
+
+ loc_t tmp_loc = { .inode = NULL,
+ .path = "/",
+ };
+
+ statfs_local->call_cnt = 1;
+ STACK_WIND (statfs_frame, dht_du_info_cbk,
+ conf->subvolumes[subvol_idx],
+ conf->subvolumes[subvol_idx]->fops->statfs,
+ &tmp_loc);
+
+ return 0;
err:
- if (statfs_frame)
- DHT_STACK_DESTROY (statfs_frame);
+ if (statfs_frame)
+ DHT_STACK_DESTROY (statfs_frame);
- return -1;
+ return -1;
}
int
dht_get_du_info (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- int i = 0;
- dht_conf_t *conf = NULL;
- call_frame_t *statfs_frame = NULL;
- dht_local_t *statfs_local = NULL;
- struct timeval tv = {0,};
- loc_t tmp_loc = {0,};
-
- conf = this->private;
-
- gettimeofday (&tv, NULL);
-
- /* make it root gfid, should be enough to get the proper
- info back */
- tmp_loc.gfid[15] = 1;
-
- if (tv.tv_sec > (conf->refresh_interval
- + conf->last_stat_fetch.tv_sec)) {
-
- statfs_frame = copy_frame (frame);
- if (!statfs_frame) {
- goto err;
- }
-
- /* In this case, 'local->fop' is not used */
- statfs_local = dht_local_init (statfs_frame, loc, NULL,
- GF_FOP_MAXVALUE);
- if (!statfs_local) {
- goto err;
- }
-
- statfs_local->call_cnt = conf->subvolume_cnt;
- for (i = 0; i < conf->subvolume_cnt; i++) {
- STACK_WIND (statfs_frame, dht_du_info_cbk,
- conf->subvolumes[i],
- conf->subvolumes[i]->fops->statfs,
- &tmp_loc, NULL);
- }
-
- conf->last_stat_fetch.tv_sec = tv.tv_sec;
- }
- return 0;
+ int i = 0;
+ dht_conf_t *conf = NULL;
+ call_frame_t *statfs_frame = NULL;
+ dht_local_t *statfs_local = NULL;
+ struct timeval tv = {0,};
+
+ conf = this->private;
+
+ gettimeofday (&tv, NULL);
+ if (tv.tv_sec > (conf->refresh_interval
+ + conf->last_stat_fetch.tv_sec)) {
+
+ statfs_frame = copy_frame (frame);
+ if (!statfs_frame) {
+ goto err;
+ }
+
+ statfs_local = dht_local_init (statfs_frame);
+ if (!statfs_local) {
+ goto err;
+ }
+
+ loc_copy (&statfs_local->loc, loc);
+ loc_t tmp_loc = { .inode = NULL,
+ .path = "/",
+ };
+
+ statfs_local->call_cnt = conf->subvolume_cnt;
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ STACK_WIND (statfs_frame, dht_du_info_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->statfs,
+ &tmp_loc);
+ }
+
+ conf->last_stat_fetch.tv_sec = tv.tv_sec;
+ }
+ return 0;
err:
- if (statfs_frame)
- DHT_STACK_DESTROY (statfs_frame);
+ if (statfs_frame)
+ DHT_STACK_DESTROY (statfs_frame);
- return -1;
+ return -1;
}
-gf_boolean_t
+int
dht_is_subvol_filled (xlator_t *this, xlator_t *subvol)
{
- int i = 0;
- dht_conf_t *conf = NULL;
- gf_boolean_t subvol_filled_inodes = _gf_false;
- gf_boolean_t subvol_filled_space = _gf_false;
- gf_boolean_t is_subvol_filled = _gf_false;
-
- conf = this->private;
-
- /* Check for values above specified percent or free disk */
- LOCK (&conf->subvolume_lock);
- {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (subvol == conf->subvolumes[i]) {
- if (conf->disk_unit == 'p') {
- if (conf->du_stats[i].avail_percent <
- conf->min_free_disk) {
- subvol_filled_space = _gf_true;
- break;
- }
-
- } else {
- if (conf->du_stats[i].avail_space <
- conf->min_free_disk) {
- subvol_filled_space = _gf_true;
- break;
- }
- }
- if (conf->du_stats[i].avail_inodes <
- conf->min_free_inodes) {
- subvol_filled_inodes = _gf_true;
- break;
- }
- }
- }
- }
- UNLOCK (&conf->subvolume_lock);
-
- if (subvol_filled_space && conf->subvolume_status[i]) {
- if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) {
- gf_log (this->name, GF_LOG_WARNING,
- "disk space on subvolume '%s' is getting "
- "full (%.2f %%), consider adding more nodes",
- subvol->name,
- (100 - conf->du_stats[i].avail_percent));
- }
- }
-
- if (subvol_filled_inodes && conf->subvolume_status[i]) {
- if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "inodes on subvolume '%s' are at "
- "(%.2f %%), consider adding more nodes",
- subvol->name,
- (100 - conf->du_stats[i].avail_inodes));
- }
- }
-
- is_subvol_filled = (subvol_filled_space || subvol_filled_inodes);
-
- return is_subvol_filled;
+ int i = 0;
+ int subvol_filled = 0;
+ dht_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ /* Check for values above specified percent or free disk */
+ LOCK (&conf->subvolume_lock);
+ {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (subvol == conf->subvolumes[i]) {
+ if (conf->disk_unit == 'p') {
+ if (conf->du_stats[i].avail_percent <
+ conf->min_free_disk) {
+ subvol_filled = 1;
+ break;
+ }
+ } else {
+ if (conf->du_stats[i].avail_space <
+ conf->min_free_disk) {
+ subvol_filled = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ UNLOCK (&conf->subvolume_lock);
+
+ if (subvol_filled && conf->subvolume_status[i]) {
+ if (!(conf->du_stats[i].log++ % (GF_UNIVERSAL_ANSWER * 10))) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "disk space on subvolume '%s' is getting "
+ "full (%.2f %%), consider adding more nodes",
+ subvol->name,
+ (100 - conf->du_stats[i].avail_percent));
+ }
+ }
+
+ return subvol_filled;
}
xlator_t *
dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol)
{
- int i = 0;
- double max = 0;
- double max_inodes = 0;
- xlator_t *avail_subvol = NULL;
- dht_conf_t *conf = NULL;
-
- conf = this->private;
-
- LOCK (&conf->subvolume_lock);
- {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->disk_unit == 'p') {
- if ((conf->du_stats[i].avail_percent > max)
- && (conf->du_stats[i].avail_inodes > max_inodes)) {
- max = conf->du_stats[i].avail_percent;
- max_inodes = conf->du_stats[i].avail_inodes;
- avail_subvol = conf->subvolumes[i];
- }
- } else {
- if ((conf->du_stats[i].avail_space > max)
- && (conf->du_stats[i].avail_inodes > max_inodes)) {
- max = conf->du_stats[i].avail_space;
- max_inodes = conf->du_stats[i].avail_inodes;
- avail_subvol = conf->subvolumes[i];
- }
-
- }
- }
- }
- UNLOCK (&conf->subvolume_lock);
-
- if (!avail_subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no subvolume has enough free space and inodes to create");
- }
-
- if ((max < conf->min_free_disk) && (max_inodes < conf->min_free_inodes))
- avail_subvol = subvol;
-
- if (!avail_subvol)
- avail_subvol = subvol;
-
- return avail_subvol;
+ int i = 0;
+ double max= 0;
+ xlator_t *avail_subvol = NULL;
+ dht_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ LOCK (&conf->subvolume_lock);
+ {
+ for (i = 0; i < conf->subvolume_cnt; i++) {
+ if (conf->disk_unit == 'p') {
+ if (conf->du_stats[i].avail_percent > max) {
+ max = conf->du_stats[i].avail_percent;
+ avail_subvol = conf->subvolumes[i];
+ }
+ } else {
+ if (conf->du_stats[i].avail_space > max) {
+ max = conf->du_stats[i].avail_space;
+ avail_subvol = conf->subvolumes[i];
+ }
+ }
+ }
+ }
+ UNLOCK (&conf->subvolume_lock);
+
+ if (!avail_subvol) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no subvolume has enough free space to create");
+ }
+
+ if (max < conf->min_free_disk)
+ avail_subvol = subvol;
+
+ if (!avail_subvol)
+ avail_subvol = subvol;
+
+ return avail_subvol;
}
diff --git a/xlators/cluster/dht/src/dht-hashfn.c b/xlators/cluster/dht/src/dht-hashfn.c
index 97eb1f05f..99bb13265 100644
--- a/xlators/cluster/dht/src/dht-hashfn.c
+++ b/xlators/cluster/dht/src/dht-hashfn.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -28,7 +37,6 @@ dht_hash_compute_internal (int type, const char *name, uint32_t *hash_p)
switch (type) {
case DHT_HASH_TYPE_DM:
- case DHT_HASH_TYPE_DM_USER:
hash = gf_dm_hashfn (name, strlen (name));
break;
default:
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index f0e74a154..cd57b9ea0 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -80,7 +89,7 @@ dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
int ret = 0; /* not found */
/* Why do other tasks if first required 'char' itself is not there */
- if (!new_loc || !loc || !loc->name || !strchr (loc->name, '@'))
+ if (loc->name && !strchr (loc->name, '@'))
goto out;
trav = this->children;
@@ -108,6 +117,7 @@ dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
new_loc->path = ((new_path) ? new_path:
gf_strdup (loc->path));
new_loc->name = new_name;
+ new_loc->ino = loc->ino;
new_loc->inode = inode_ref (loc->inode);
new_loc->parent = inode_ref (loc->parent);
}
@@ -120,8 +130,10 @@ dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
out:
if (!ret) {
/* !success */
- GF_FREE (new_path);
- GF_FREE (new_name);
+ if (new_path)
+ GF_FREE (new_path);
+ if (new_name)
+ GF_FREE (new_name);
}
return ret;
}
@@ -204,62 +216,35 @@ dht_local_wipe (xlator_t *this, dht_local_t *local)
local->selfheal.layout = NULL;
}
- GF_FREE (local->newpath);
-
- GF_FREE (local->key);
-
- GF_FREE (local->rebalance.vector);
+ if (local->newpath) {
+ GF_FREE (local->newpath);
+ }
- if (local->rebalance.iobref)
- iobref_unref (local->rebalance.iobref);
+ if (local->key) {
+ GF_FREE (local->key);
+ }
- mem_put (local);
+ GF_FREE (local);
}
dht_local_t *
-dht_local_init (call_frame_t *frame, loc_t *loc, fd_t *fd, glusterfs_fop_t fop)
+dht_local_init (call_frame_t *frame)
{
dht_local_t *local = NULL;
- inode_t *inode = NULL;
- int ret = 0;
- local = mem_get0 (THIS->local_pool);
- if (!local)
- goto out;
-
- if (loc) {
- ret = loc_copy (&local->loc, loc);
- if (ret)
- goto out;
-
- inode = loc->inode;
- }
+ /* TODO: use mem-pool */
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_dht_mt_dht_local_t);
- if (fd) {
- local->fd = fd_ref (fd);
- if (!inode)
- inode = fd->inode;
- }
+ if (!local)
+ return NULL;
- local->op_ret = -1;
+ local->op_ret = -1;
local->op_errno = EUCLEAN;
- local->fop = fop;
-
- if (inode) {
- local->layout = dht_layout_get (frame->this, inode);
- local->cached_subvol = dht_subvol_get_cached (frame->this,
- inode);
- }
frame->local = local;
-out:
- if (ret) {
- if (local)
- mem_put (local);
- local = NULL;
- }
return local;
}
@@ -283,7 +268,6 @@ dht_first_up_subvol (xlator_t *this)
dht_conf_t *conf = NULL;
xlator_t *child = NULL;
int i = 0;
- time_t time = 0;
conf = this->private;
if (!conf)
@@ -292,14 +276,9 @@ dht_first_up_subvol (xlator_t *this)
LOCK (&conf->subvolume_lock);
{
for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvol_up_time[i]) {
- if (!time) {
- time = conf->subvol_up_time[i];
- child = conf->subvolumes[i];
- } else if (time > conf->subvol_up_time[i]) {
- time = conf->subvol_up_time[i];
- child = conf->subvolumes[i];
- }
+ if (conf->subvolume_status[i]) {
+ child = conf->subvolumes[i];
+ break;
}
}
}
@@ -341,23 +320,17 @@ dht_subvol_get_hashed (xlator_t *this, loc_t *loc)
dht_layout_t *layout = NULL;
xlator_t *subvol = NULL;
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO (this->name, loc, out);
-
- if (__is_root_gfid (loc->gfid)) {
+ if (is_fs_root (loc)) {
subvol = dht_first_up_subvol (this);
goto out;
}
- GF_VALIDATE_OR_GOTO (this->name, loc->parent, out);
- GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
-
layout = dht_layout_get (this, loc->parent);
if (!layout) {
gf_log (this->name, GF_LOG_DEBUG,
- "layout missing path=%s parent=%s",
- loc->path, uuid_utoa (loc->parent->gfid));
+ "layout missing path=%s parent=%"PRId64,
+ loc->path, loc->parent->ino);
goto out;
}
@@ -385,8 +358,6 @@ dht_subvol_get_cached (xlator_t *this, inode_t *inode)
dht_layout_t *layout = NULL;
xlator_t *subvol = NULL;
- GF_VALIDATE_OR_GOTO (this->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
layout = dht_layout_get (this, inode);
@@ -457,15 +428,6 @@ out:
(a) = (b); \
} while (0)
-
-#define set_if_greater_time(a, an, b, bn) do { \
- if (((a) < (b)) || (((a) == (b)) && ((an) < (bn)))){ \
- (a) = (b); \
- (an) = (bn); \
- } \
- } while (0) \
-
-
int
dht_iatt_merge (xlator_t *this, struct iatt *to,
struct iatt *from, xlator_t *subvol)
@@ -477,7 +439,8 @@ dht_iatt_merge (xlator_t *this, struct iatt *to,
uuid_copy (to->ia_gfid, from->ia_gfid);
- to->ia_ino = from->ia_ino;
+ dht_itransform (this, subvol, from->ia_ino, &to->ia_ino);
+
to->ia_prot = from->ia_prot;
to->ia_type = from->ia_type;
to->ia_nlink = from->ia_nlink;
@@ -489,12 +452,9 @@ dht_iatt_merge (xlator_t *this, struct iatt *to,
set_if_greater (to->ia_uid, from->ia_uid);
set_if_greater (to->ia_gid, from->ia_gid);
- set_if_greater_time(to->ia_atime, to->ia_atime_nsec,
- from->ia_atime, from->ia_atime_nsec);
- set_if_greater_time (to->ia_mtime, to->ia_mtime_nsec,
- from->ia_mtime, from->ia_mtime_nsec);
- set_if_greater_time (to->ia_ctime, to->ia_ctime_nsec,
- from->ia_ctime, from->ia_ctime_nsec);
+ set_if_greater (to->ia_atime, from->ia_atime);
+ set_if_greater (to->ia_mtime, from->ia_mtime);
+ set_if_greater (to->ia_ctime, from->ia_ctime);
return 0;
}
@@ -531,372 +491,3 @@ err:
loc_wipe (child);
return -1;
}
-
-
-
-int
-dht_init_subvolumes (xlator_t *this, dht_conf_t *conf)
-{
- xlator_list_t *subvols = NULL;
- int cnt = 0;
-
- if (!conf)
- return -1;
-
- for (subvols = this->children; subvols; subvols = subvols->next)
- cnt++;
-
- conf->subvolumes = GF_CALLOC (cnt, sizeof (xlator_t *),
- gf_dht_mt_xlator_t);
- if (!conf->subvolumes) {
- return -1;
- }
- conf->subvolume_cnt = cnt;
-
- cnt = 0;
- for (subvols = this->children; subvols; subvols = subvols->next)
- conf->subvolumes[cnt++] = subvols->xlator;
-
- conf->subvolume_status = GF_CALLOC (cnt, sizeof (char),
- gf_dht_mt_char);
- if (!conf->subvolume_status) {
- return -1;
- }
-
- conf->last_event = GF_CALLOC (cnt, sizeof (int),
- gf_dht_mt_char);
- if (!conf->last_event) {
- return -1;
- }
-
- conf->subvol_up_time = GF_CALLOC (cnt, sizeof (time_t),
- gf_dht_mt_subvol_time);
- if (!conf->subvol_up_time) {
- return -1;
- }
-
- conf->du_stats = GF_CALLOC (conf->subvolume_cnt, sizeof (dht_du_t),
- gf_dht_mt_dht_du_t);
- if (!conf->du_stats) {
- return -1;
- }
-
- conf->decommissioned_bricks = GF_CALLOC (cnt, sizeof (xlator_t *),
- gf_dht_mt_xlator_t);
- if (!conf->decommissioned_bricks) {
- return -1;
- }
-
- return 0;
-}
-
-
-
-
-static int
-dht_migration_complete_check_done (int op_ret, call_frame_t *frame, void *data)
-{
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- local->rebalance.target_op_fn (THIS, frame, op_ret);
-
- return 0;
-}
-
-
-int
-dht_migration_complete_check_task (void *data)
-{
- int ret = -1;
- xlator_t *src_node = NULL;
- xlator_t *dst_node = NULL;
- dht_local_t *local = NULL;
- dict_t *dict = NULL;
- dht_layout_t *layout = NULL;
- struct iatt stbuf = {0,};
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- loc_t tmp_loc = {0,};
- char *path = NULL;
-
- this = THIS;
- frame = data;
- local = frame->local;
-
- src_node = local->cached_subvol;
-
- /* getxattr on cached_subvol for 'linkto' value */
- if (!local->loc.inode)
- ret = syncop_fgetxattr (src_node, local->fd, &dict,
- DHT_LINKFILE_KEY);
- else
- ret = syncop_getxattr (src_node, &local->loc, &dict,
- DHT_LINKFILE_KEY);
-
- if (!ret)
- dst_node = dht_linkfile_subvol (this, NULL, NULL, dict);
-
- if (ret) {
- if ((errno != ENOENT) || (!local->loc.inode)) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the 'linkto' xattr %s",
- local->loc.path, strerror (errno));
- goto out;
- }
- /* Need to do lookup on hashed subvol, then get the file */
- ret = syncop_lookup (this, &local->loc, NULL, &stbuf, NULL,
- NULL);
- if (ret)
- goto out;
- dst_node = dht_subvol_get_cached (this, local->loc.inode);
- }
-
- if (!dst_node) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the destination node",
- local->loc.path);
- ret = -1;
- goto out;
- }
-
- /* lookup on dst */
- if (local->loc.inode) {
- ret = syncop_lookup (dst_node, &local->loc, NULL, &stbuf, NULL, NULL);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to lookup the file on %s",
- local->loc.path, dst_node->name);
- goto out;
- }
-
- if (uuid_compare (stbuf.ia_gfid, local->loc.inode->gfid)) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: gfid different on the target file on %s",
- local->loc.path, dst_node->name);
- ret = -1;
- goto out;
- }
- }
-
- /* update inode ctx (the layout) */
- dht_layout_unref (this, local->layout);
-
- if (!local->loc.inode)
- ret = dht_layout_preset (this, dst_node, local->fd->inode);
- else
- ret = dht_layout_preset (this, dst_node, local->loc.inode);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: could not set preset layout for subvol %s",
- local->loc.path, dst_node->name);
- ret = -1;
- goto out;
- }
-
- layout = dht_layout_for_subvol (this, dst_node);
- if (!layout) {
- gf_log (this->name, GF_LOG_INFO,
- "%s: no pre-set layout for subvolume %s",
- local->loc.path, dst_node ? dst_node->name : "<nil>");
- ret = -1;
- goto out;
- }
-
- if (!local->loc.inode)
- ret = dht_layout_set (this, local->fd->inode, layout);
- else
- ret = dht_layout_set (this, local->loc.inode, layout);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set the new layout",
- local->loc.path);
- goto out;
- }
-
- local->cached_subvol = dst_node;
- ret = 0;
-
- if (!local->fd)
- goto out;
-
- /* once we detect the migration complete, the fd-ctx is no more
- required.. delete the ctx, and do one extra 'fd_unref' for open fd */
- ret = fd_ctx_del (local->fd, this, NULL);
- if (!ret) {
- fd_unref (local->fd);
- ret = 0;
- goto out;
- }
-
- /* if 'local->fd' (ie, fd based operation), send a 'open()' on
- destination if not already done */
- if (local->loc.inode) {
- ret = syncop_open (dst_node, &local->loc,
- local->fd->flags, local->fd);
- } else {
- tmp_loc.inode = local->fd->inode;
- inode_path (local->fd->inode, NULL, &path);
- if (path)
- tmp_loc.path = path;
- ret = syncop_open (dst_node, &tmp_loc,
- local->fd->flags, local->fd);
- GF_FREE (path);
-
- }
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to send open() on target file at %s",
- local->loc.path, dst_node->name);
- goto out;
- }
-
- /* need this unref for the fd on src_node */
- fd_unref (local->fd);
- ret = 0;
-out:
-
- return ret;
-}
-
-int
-dht_rebalance_complete_check (xlator_t *this, call_frame_t *frame)
-{
- int ret = -1;
-
- ret = synctask_new (this->ctx->env, dht_migration_complete_check_task,
- dht_migration_complete_check_done,
- frame, frame);
- return ret;
-}
-
-/* During 'in-progress' state, both nodes should have the file */
-static int
-dht_inprogress_check_done (int op_ret, call_frame_t *sync_frame, void *data)
-{
- dht_local_t *local = NULL;
-
- local = sync_frame->local;
-
- local->rebalance.target_op_fn (THIS, sync_frame, op_ret);
-
- return 0;
-}
-
-static int
-dht_rebalance_inprogress_task (void *data)
-{
- int ret = -1;
- xlator_t *src_node = NULL;
- xlator_t *dst_node = NULL;
- dht_local_t *local = NULL;
- dict_t *dict = NULL;
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- char *path = NULL;
- struct iatt stbuf = {0,};
- loc_t tmp_loc = {0,};
-
- this = THIS;
- frame = data;
- local = frame->local;
-
- src_node = local->cached_subvol;
-
- /* getxattr on cached_subvol for 'linkto' value */
- if (local->loc.inode)
- ret = syncop_getxattr (src_node, &local->loc, &dict,
- DHT_LINKFILE_KEY);
- else
- ret = syncop_fgetxattr (src_node, local->fd, &dict,
- DHT_LINKFILE_KEY);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the 'linkto' xattr %s",
- local->loc.path, strerror (errno));
- goto out;
- }
-
- dst_node = dht_linkfile_subvol (this, NULL, NULL, dict);
- if (!dst_node) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to get the 'linkto' xattr from dict",
- local->loc.path);
- ret = -1;
- goto out;
- }
-
- local->rebalance.target_node = dst_node;
-
- if (local->loc.inode) {
- /* lookup on dst */
- ret = syncop_lookup (dst_node, &local->loc, NULL,
- &stbuf, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to lookup the file on %s",
- local->loc.path, dst_node->name);
- goto out;
- }
-
- if (uuid_compare (stbuf.ia_gfid, local->loc.inode->gfid)) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: gfid different on the target file on %s",
- local->loc.path, dst_node->name);
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-
- if (!local->fd)
- goto out;
-
- if (local->loc.inode) {
- ret = syncop_open (dst_node, &local->loc,
- local->fd->flags, local->fd);
- } else {
- tmp_loc.inode = local->fd->inode;
- inode_path (local->fd->inode, NULL, &path);
- if (path)
- tmp_loc.path = path;
- ret = syncop_open (dst_node, &tmp_loc,
- local->fd->flags, local->fd);
- GF_FREE (path);
- }
-
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to send open() on target file at %s",
- local->loc.path, dst_node->name);
- goto out;
- }
-
- ret = fd_ctx_set (local->fd, this, (uint64_t)(long)dst_node);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set fd-ctx target file at %s",
- local->loc.path, dst_node->name);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-dht_rebalance_in_progress_check (xlator_t *this, call_frame_t *frame)
-{
-
- int ret = -1;
-
- ret = synctask_new (this->ctx->env, dht_rebalance_inprogress_task,
- dht_inprogress_check_done,
- frame, frame);
- return ret;
-}
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
deleted file mode 100644
index 7e29a7a8c..000000000
--- a/xlators/cluster/dht/src/dht-inode-read.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dht-common.h"
-
-int dht_access2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_readv2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_attr2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_open2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_flush2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_lk2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_fsync2 (xlator_t *this, call_frame_t *frame, int ret);
-
-int
-dht_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = 0;
-
- local = frame->local;
- prev = cookie;
-
- local->op_errno = op_errno;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto out;
- }
-
- if (!op_ret || (local->call_cnt != 1))
- goto out;
-
- /* rebalance would have happened */
- local->rebalance.target_op_fn = dht_open2;
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
-
-out:
- DHT_STACK_UNWIND (open, frame, op_ret, op_errno, local->fd, xdata);
-
- return 0;
-}
-
-int
-dht_open2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- int op_errno = EINVAL;
-
- local = frame->local;
- if (!local)
- goto out;
-
- op_errno = ENOENT;
- if (op_ret)
- goto out;
-
- local->call_cnt = 2;
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_open_cbk, subvol, subvol->fops->open,
- &local->loc, local->rebalance.flags, local->fd,
- NULL);
- return 0;
-
-out:
- DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int
-dht_open (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, fd_t *fd, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, loc, fd, GF_FOP_OPEN);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- local->rebalance.flags = flags;
- local->call_cnt = 1;
-
- STACK_WIND (frame, dht_open_cbk, subvol, subvol->fops->open,
- loc, flags, fd, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata)
-{
- uint64_t tmp_subvol = 0;
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("dht", frame, err);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
-
- local = frame->local;
- prev = cookie;
-
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto out;
- }
-
- if (local->call_cnt != 1)
- goto out;
-
- /* Check if the rebalance phase2 is true */
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
- if (local->fd)
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (ret) {
- /* Phase 2 of migration */
- local->rebalance.target_op_fn = dht_attr2;
- ret = dht_rebalance_complete_check (this, frame);
- } else {
- /* value is already set in fd_ctx, that means no need
- to check for whether its complete or not. */
- dht_attr2 (this, frame, 0);
- }
- if (!ret)
- return 0;
- }
-
-out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
- DHT_STACK_UNWIND (stat, frame, op_ret, op_errno, stbuf, xdata);
-err:
- return 0;
-}
-
-int
-dht_attr2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- int op_errno = EINVAL;
-
- local = frame->local;
- if (!local)
- goto out;
-
- op_errno = local->op_errno;
- if (op_ret == -1)
- goto out;
-
- subvol = local->cached_subvol;
- local->call_cnt = 2;
-
- if (local->fop == GF_FOP_FSTAT) {
- STACK_WIND (frame, dht_file_attr_cbk, subvol,
- subvol->fops->fstat, local->fd, NULL);
- } else {
- STACK_WIND (frame, dht_file_attr_cbk, subvol,
- subvol->fops->stat, &local->loc, NULL);
- }
- return 0;
-
-out:
- DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-int
-dht_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *stbuf, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
-
- GF_VALIDATE_OR_GOTO ("dht", frame, err);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
-
- local = frame->local;
- prev = cookie;
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
-
- goto unlock;
- }
-
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
-
- local->op_ret = 0;
- }
-unlock:
- UNLOCK (&frame->lock);
-out:
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt)) {
- DHT_STACK_UNWIND (stat, frame, local->op_ret, local->op_errno,
- &local->stbuf, xdata);
- }
-err:
- return 0;
-}
-
-int
-dht_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int i = 0;
- int call_cnt = 0;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_STAT);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no layout for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- if (IA_ISREG (loc->inode->ia_type)) {
- local->call_cnt = 1;
-
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_file_attr_cbk, subvol,
- subvol->fops->stat, loc, xdata);
-
- return 0;
- }
-
- local->call_cnt = call_cnt = layout->cnt;
-
- for (i = 0; i < call_cnt; i++) {
- subvol = layout->list[i].xlator;
-
- STACK_WIND (frame, dht_attr_cbk,
- subvol, subvol->fops->stat,
- loc, xdata);
- }
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-
-int
-dht_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
- dht_layout_t *layout = NULL;
- int i = 0;
- int call_cnt = 0;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FSTAT);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no layout for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- if (IA_ISREG (fd->inode->ia_type)) {
- local->call_cnt = 1;
-
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_file_attr_cbk, subvol,
- subvol->fops->fstat, fd, xdata);
-
- return 0;
- }
-
- local->call_cnt = call_cnt = layout->cnt;
-
- for (i = 0; i < call_cnt; i++) {
- subvol = layout->list[i].xlator;
- STACK_WIND (frame, dht_attr_cbk,
- subvol, subvol->fops->fstat,
- fd, xdata);
- }
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno,
- struct iovec *vector, int count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int ret = 0;
-
- local = frame->local;
- if (!local) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- /* This is already second try, no need for re-check */
- if (local->call_cnt != 1)
- goto out;
-
- if ((op_ret == -1) && (op_errno != ENOENT))
- goto out;
-
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
- /* File would be migrated to other node */
- ret = fd_ctx_get (local->fd, this, NULL);
- if (ret) {
- local->rebalance.target_op_fn = dht_readv2;
- ret = dht_rebalance_complete_check (this, frame);
- } else {
- /* value is already set in fd_ctx, that means no need
- to check for whether its complete or not. */
- dht_readv2 (this, frame, 0);
- }
- if (!ret)
- return 0;
- }
-
-out:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
- DHT_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, stbuf,
- iobref, xdata);
-
- return 0;
-}
-
-int
-dht_readv2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- int op_errno = EINVAL;
-
- local = frame->local;
- if (!local)
- goto out;
-
- op_errno = local->op_errno;
- if (op_ret == -1)
- goto out;
-
- local->call_cnt = 2;
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_readv_cbk, subvol, subvol->fops->readv,
- local->fd, local->rebalance.size, local->rebalance.offset,
- local->rebalance.flags, NULL);
-
- return 0;
-
-out:
- DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
- return 0;
-}
-
-int
-dht_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t off, uint32_t flags, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_READ);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- local->rebalance.offset = off;
- local->rebalance.size = size;
- local->rebalance.flags = flags;
- local->call_cnt = 1;
-
- STACK_WIND (frame, dht_readv_cbk,
- subvol, subvol->fops->readv,
- fd, size, off, flags, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
-{
- int ret = -1;
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- if (local->call_cnt != 1)
- goto out;
-
- if ((op_ret == -1) && (op_errno == ENOENT)) {
- /* File would be migrated to other node */
- local->rebalance.target_op_fn = dht_access2;
- ret = dht_rebalance_complete_check (frame->this, frame);
- if (!ret)
- return 0;
- }
-
-out:
- DHT_STACK_UNWIND (access, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-dht_access2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- int op_errno = EINVAL;
-
- local = frame->local;
- if (!local)
- goto out;
-
- op_errno = local->op_errno;
- if (op_ret == -1)
- goto out;
-
- local->call_cnt = 2;
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access,
- &local->loc, local->rebalance.flags, NULL);
-
- return 0;
-
-out:
- DHT_STACK_UNWIND (access, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int
-dht_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_ACCESS);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.flags = mask;
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_access_cbk, subvol, subvol->fops->access,
- loc, mask, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (access, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-int
-dht_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int ret = -1;
-
- local = frame->local;
-
- local->op_errno = op_errno;
-
- if (local->call_cnt != 1)
- goto out;
-
- /* If context is set, then send flush() it to the destination */
- ret = fd_ctx_get (local->fd, this, NULL);
- if (!ret) {
- dht_flush2 (this, frame, 0);
- return 0;
- }
-
-out:
- DHT_STACK_UNWIND (flush, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-int
-dht_flush2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- uint64_t tmp_subvol = 0;
- int ret = -1;
-
- local = frame->local;
-
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (!ret)
- subvol = (xlator_t *)(long)tmp_subvol;
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- STACK_WIND (frame, dht_flush_cbk,
- subvol, subvol->fops->flush, local->fd, NULL);
-
- return 0;
-}
-
-
-int
-dht_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FLUSH);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- local->call_cnt = 1;
-
- STACK_WIND (frame, dht_flush_cbk,
- subvol, subvol->fops->flush, fd, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-int
-dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
- int op_errno, struct iatt *prebuf, struct iatt *postbuf,
- dict_t *xdata)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = -1;
-
- local = frame->local;
- prev = cookie;
-
- local->op_errno = op_errno;
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto out;
- }
-
- if (local->call_cnt != 1) {
- if (local->stbuf.ia_blocks) {
- dht_iatt_merge (this, postbuf, &local->stbuf, NULL);
- dht_iatt_merge (this, prebuf, &local->prebuf, NULL);
- }
- goto out;
- }
-
- ret = fd_ctx_get (local->fd, this, NULL);
- if (ret) {
- local->rebalance.target_op_fn = dht_fsync2;
-
- /* Check if the rebalance phase1 is true */
- if (IS_DHT_MIGRATION_PHASE1 (postbuf)) {
- dht_iatt_merge (this, &local->stbuf, postbuf, NULL);
- dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
-
- ret = dht_rebalance_in_progress_check (this, frame);
- }
-
- /* Check if the rebalance phase2 is true */
- if (IS_DHT_MIGRATION_PHASE2 (postbuf)) {
- ret = dht_rebalance_complete_check (this, frame);
- }
- } else {
- dht_fsync2 (this, frame, 0);
- }
- if (!ret)
- return 0;
-
-out:
- DHT_STRIP_PHASE1_FLAGS (postbuf);
- DHT_STRIP_PHASE1_FLAGS (prebuf);
- DHT_STACK_UNWIND (fsync, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-
- return 0;
-}
-
-int
-dht_fsync2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- uint64_t tmp_subvol = 0;
- int ret = -1;
-
- local = frame->local;
-
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (!ret)
- subvol = (xlator_t *)(long)tmp_subvol;
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- STACK_WIND (frame, dht_fsync_cbk, subvol, subvol->fops->fsync,
- local->fd, local->rebalance.flags, NULL);
-
- return 0;
-}
-
-int
-dht_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
- dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FSYNC);
- if (!local) {
- op_errno = ENOMEM;
-
- goto err;
- }
-
- local->call_cnt = 1;
- local->rebalance.flags = datasync;
-
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_fsync_cbk, subvol, subvol->fops->fsync,
- fd, datasync, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-/* TODO: for 'lk()' call, we need some other special error, may be ESTALE to
- indicate that lock migration happened on the fd, so we can consider it as
- phase 2 of migration */
-int
-dht_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct gf_flock *flock, dict_t *xdata)
-{
- DHT_STACK_UNWIND (lk, frame, op_ret, op_errno, flock, xdata);
-
- return 0;
-}
-
-
-int
-dht_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int cmd, struct gf_flock *flock, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- subvol = dht_subvol_get_cached (this, fd->inode);
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- /* TODO: for rebalance, we need to preserve the fop arguments */
- STACK_WIND (frame, dht_lk_cbk, subvol, subvol->fops->lk, fd,
- cmd, flock, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-/* Symlinks are currently not migrated, so no need for any check here */
-int
-dht_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, const char *path,
- struct iatt *stbuf, dict_t *xdata)
-{
- dht_local_t *local = NULL;
-
- local = frame->local;
- if (op_ret == -1)
- goto err;
-
- if (!local) {
- op_ret = -1;
- op_errno = EINVAL;
- }
-
-err:
- DHT_STRIP_PHASE1_FLAGS (stbuf);
- DHT_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, stbuf, xdata);
-
- return 0;
-}
-
-
-int
-dht_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_READLINK);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_readlink_cbk,
- subvol, subvol->fops->readlink,
- loc, size, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-/* Currently no translators on top of 'distribute' will be using
- * below fops, hence not implementing 'migration' related checks
- */
-
-int
-dht_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- DHT_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int
-dht_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_XATTROP);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- local->call_cnt = 1;
-
- STACK_WIND (frame,
- dht_xattrop_cbk,
- subvol, subvol->fops->xattrop,
- loc, flags, dict, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-
-int
-dht_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- DHT_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int
-dht_fxattrop (call_frame_t *frame, xlator_t *this,
- fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- subvol = dht_subvol_get_cached (this, fd->inode);
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame,
- dht_fxattrop_cbk,
- subvol, subvol->fops->fxattrop,
- fd, flags, dict, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
-
- return 0;
-}
-
-
-int
-dht_inodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
-
-{
- DHT_STACK_UNWIND (inodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int32_t
-dht_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_INODELK);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- local->call_cnt = 1;
-
- STACK_WIND (frame,
- dht_inodelk_cbk,
- subvol, subvol->fops->inodelk,
- volume, loc, cmd, lock, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
-
- return 0;
-}
-
-
-int
-dht_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-
-{
- DHT_STACK_UNWIND (finodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-dht_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- subvol = dht_subvol_get_cached (this, fd->inode);
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
-
- STACK_WIND (frame, dht_finodelk_cbk, subvol, subvol->fops->finodelk,
- volume, fd, cmd, lock, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
-
- return 0;
-}
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
deleted file mode 100644
index d4a3ecc39..000000000
--- a/xlators/cluster/dht/src/dht-inode-write.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dht-common.h"
-
-int dht_writev2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_truncate2 (xlator_t *this, call_frame_t *frame, int ret);
-int dht_setattr2 (xlator_t *this, call_frame_t *frame, int ret);
-
-int
-dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int ret = -1;
-
- if (op_ret == -1) {
- goto out;
- }
-
- local = frame->local;
- if (!local) {
- op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- if (local->call_cnt != 1) {
- /* preserve the modes of source */
- if (local->stbuf.ia_blocks) {
- dht_iatt_merge (this, postbuf, &local->stbuf, NULL);
- dht_iatt_merge (this, prebuf, &local->prebuf, NULL);
- }
- goto out;
- }
-
- local->rebalance.target_op_fn = dht_writev2;
-
- /* Phase 2 of migration */
- if (IS_DHT_MIGRATION_PHASE2 (postbuf)) {
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
- }
-
- /* Check if the rebalance phase1 is true */
- if (IS_DHT_MIGRATION_PHASE1 (postbuf)) {
- dht_iatt_merge (this, &local->stbuf, postbuf, NULL);
- dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
-
- ret = fd_ctx_get (local->fd, this, NULL);
- if (!ret) {
- dht_writev2 (this, frame, 0);
- return 0;
- }
- ret = dht_rebalance_in_progress_check (this, frame);
- if (!ret)
- return 0;
- }
-
-out:
- DHT_STRIP_PHASE1_FLAGS (postbuf);
- DHT_STRIP_PHASE1_FLAGS (prebuf);
-
- DHT_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-int
-dht_writev2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- uint64_t tmp_subvol = 0;
- int ret = -1;
-
- local = frame->local;
-
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (!ret)
- subvol = (xlator_t *)(long)tmp_subvol;
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- STACK_WIND (frame, dht_writev_cbk,
- subvol, subvol->fops->writev,
- local->fd, local->rebalance.vector, local->rebalance.count,
- local->rebalance.offset, local->rebalance.flags,
- local->rebalance.iobref, NULL);
-
- return 0;
-}
-
-int
-dht_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int count, off_t off, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_WRITE);
- if (!local) {
-
- op_errno = ENOMEM;
- goto err;
- }
-
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
-
- local->rebalance.vector = iov_dup (vector, count);
- local->rebalance.offset = off;
- local->rebalance.count = count;
- local->rebalance.flags = flags;
- local->rebalance.iobref = iobref_ref (iobref);
- local->call_cnt = 1;
-
- STACK_WIND (frame, dht_writev_cbk,
- subvol, subvol->fops->writev,
- fd, vector, count, off, flags, iobref, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-
-int
-dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("dht", frame, err);
- GF_VALIDATE_OR_GOTO ("dht", this, out);
- GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
- GF_VALIDATE_OR_GOTO ("dht", cookie, out);
-
- local = frame->local;
- prev = cookie;
-
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- local->op_errno = op_errno;
- local->op_ret = -1;
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
-
- goto out;
- }
-
- if (local->call_cnt != 1) {
- if (local->stbuf.ia_blocks) {
- dht_iatt_merge (this, postbuf, &local->stbuf, NULL);
- dht_iatt_merge (this, prebuf, &local->prebuf, NULL);
- }
- goto out;
- }
-
- local->rebalance.target_op_fn = dht_truncate2;
-
- /* Phase 2 of migration */
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (postbuf)) {
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
- }
-
- /* Check if the rebalance phase1 is true */
- if (IS_DHT_MIGRATION_PHASE1 (postbuf)) {
- dht_iatt_merge (this, &local->stbuf, postbuf, NULL);
- dht_iatt_merge (this, &local->prebuf, prebuf, NULL);
- ret = fd_ctx_get (local->fd, this, NULL);
- if (!ret) {
- dht_truncate2 (this, frame, 0);
- return 0;
- }
- ret = dht_rebalance_in_progress_check (this, frame);
- if (!ret)
- return 0;
- }
-
-out:
- DHT_STRIP_PHASE1_FLAGS (postbuf);
- DHT_STRIP_PHASE1_FLAGS (prebuf);
- DHT_STACK_UNWIND (truncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-err:
- return 0;
-}
-
-
-int
-dht_truncate2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- uint64_t tmp_subvol = 0;
- int ret = -1;
-
- local = frame->local;
-
- if (local->fd)
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (!ret)
- subvol = (xlator_t *)(long)tmp_subvol;
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- if (local->fop == GF_FOP_TRUNCATE) {
- STACK_WIND (frame, dht_truncate_cbk, subvol,
- subvol->fops->truncate, &local->loc,
- local->rebalance.offset, NULL);
- } else {
- STACK_WIND (frame, dht_truncate_cbk, subvol,
- subvol->fops->ftruncate, local->fd,
- local->rebalance.offset, NULL);
- }
-
- return 0;
-}
-
-int
-dht_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_TRUNCATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.offset = offset;
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_truncate_cbk,
- subvol, subvol->fops->truncate,
- loc, offset, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-int
-dht_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- int op_errno = -1;
- dht_local_t *local = NULL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FTRUNCATE);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- local->rebalance.offset = offset;
- local->call_cnt = 1;
- subvol = local->cached_subvol;
- if (!subvol) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no cached subvolume for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- STACK_WIND (frame, dht_truncate_cbk,
- subvol, subvol->fops->ftruncate,
- fd, offset, xdata);
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-/* handle cases of migration here for 'setattr()' calls */
-int
-dht_file_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = -1;
-
- local = frame->local;
- prev = cookie;
-
- local->op_errno = op_errno;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto out;
- }
-
- if (local->call_cnt != 1)
- goto out;
-
- local->rebalance.target_op_fn = dht_setattr2;
-
- /* Phase 2 of migration */
- if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (postbuf)) {
- ret = dht_rebalance_complete_check (this, frame);
- if (!ret)
- return 0;
- }
-
- /* At the end of the migration process, whatever 'attr' we
- have on source file will be migrated to destination file
- in one shot, hence we don't need to check for in progress
- state here (ie, PHASE1) */
-out:
- DHT_STRIP_PHASE1_FLAGS (postbuf);
- DHT_STRIP_PHASE1_FLAGS (prebuf);
- DHT_STACK_UNWIND (setattr, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
-
- return 0;
-}
-
-int
-dht_setattr2 (xlator_t *this, call_frame_t *frame, int op_ret)
-{
- dht_local_t *local = NULL;
- xlator_t *subvol = NULL;
- uint64_t tmp_subvol = 0;
- int ret = -1;
-
- local = frame->local;
-
- if (local->fd)
- ret = fd_ctx_get (local->fd, this, &tmp_subvol);
- if (!ret)
- subvol = (xlator_t *)(long)tmp_subvol;
-
- if (!subvol)
- subvol = local->cached_subvol;
-
- local->call_cnt = 2; /* This is the second attempt */
-
- if (local->fop == GF_FOP_SETATTR) {
- STACK_WIND (frame, dht_file_setattr_cbk, subvol,
- subvol->fops->setattr, &local->loc,
- &local->rebalance.stbuf, local->rebalance.flags,
- NULL);
- } else {
- STACK_WIND (frame, dht_file_setattr_cbk, subvol,
- subvol->fops->fsetattr, local->fd,
- &local->rebalance.stbuf, local->rebalance.flags,
- NULL);
- }
-
- return 0;
-}
-
-
-/* Keep the existing code same for all the cases other than regular file */
-int
-dht_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
-{
- dht_local_t *local = NULL;
- int this_call_cnt = 0;
- call_frame_t *prev = NULL;
-
-
- local = frame->local;
- prev = cookie;
-
- LOCK (&frame->lock);
- {
- if (op_ret == -1) {
- local->op_errno = op_errno;
- gf_log (this->name, GF_LOG_DEBUG,
- "subvolume %s returned -1 (%s)",
- prev->this->name, strerror (op_errno));
- goto unlock;
- }
-
- dht_iatt_merge (this, &local->prebuf, statpre, prev->this);
- dht_iatt_merge (this, &local->stbuf, statpost, prev->this);
-
- local->op_ret = 0;
- }
-unlock:
- UNLOCK (&frame->lock);
-
- this_call_cnt = dht_frame_return (frame);
- if (is_last_call (this_call_cnt))
- DHT_STACK_UNWIND (setattr, frame, local->op_ret, local->op_errno,
- &local->prebuf, &local->stbuf, xdata);
-
- return 0;
-}
-
-
-int
-dht_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- dht_layout_t *layout = NULL;
- dht_local_t *local = NULL;
- int op_errno = -1;
- int i = -1;
- int call_cnt = 0;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
- VALIDATE_OR_GOTO (loc->path, err);
-
- local = dht_local_init (frame, loc, NULL, GF_FOP_SETATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no layout for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- if (!layout_is_sane (layout)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "layout is not sane for path=%s", loc->path);
- op_errno = EINVAL;
- goto err;
- }
-
- if (IA_ISREG (loc->inode->ia_type)) {
- /* in the regular file _cbk(), we need to check for
- migration possibilities */
- local->rebalance.stbuf = *stbuf;
- local->rebalance.flags = valid;
- local->call_cnt = 1;
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_file_setattr_cbk, subvol,
- subvol->fops->setattr,
- loc, stbuf, valid, xdata);
-
- return 0;
- }
-
- local->call_cnt = call_cnt = layout->cnt;
-
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_setattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->setattr,
- loc, stbuf, valid, xdata);
- }
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
-
-
-int
-dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
-{
- xlator_t *subvol = NULL;
- dht_layout_t *layout = NULL;
- dht_local_t *local = NULL;
- int op_errno = -1;
- int i = -1;
- int call_cnt = 0;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- local = dht_local_init (frame, NULL, fd, GF_FOP_FSETATTR);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
-
- layout = local->layout;
- if (!layout) {
- gf_log (this->name, GF_LOG_DEBUG,
- "no layout for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- if (!layout_is_sane (layout)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "layout is not sane for fd=%p", fd);
- op_errno = EINVAL;
- goto err;
- }
-
- if (IA_ISREG (fd->inode->ia_type)) {
- /* in the regular file _cbk(), we need to check for
- migration possibilities */
- local->rebalance.stbuf = *stbuf;
- local->rebalance.flags = valid;
- local->call_cnt = 1;
- subvol = local->cached_subvol;
-
- STACK_WIND (frame, dht_file_setattr_cbk, subvol,
- subvol->fops->fsetattr,
- fd, stbuf, valid, xdata);
-
- return 0;
- }
-
- local->call_cnt = call_cnt = layout->cnt;
-
- for (i = 0; i < call_cnt; i++) {
- STACK_WIND (frame, dht_setattr_cbk,
- layout->list[i].xlator,
- layout->list[i].xlator->fops->fsetattr,
- fd, stbuf, valid, xdata);
- }
-
- return 0;
-
-err:
- op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
-
- return 0;
-}
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
index 97bbe987f..16767adb9 100644
--- a/xlators/cluster/dht/src/dht-layout.c
+++ b/xlators/cluster/dht/src/dht-layout.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -43,11 +52,8 @@ dht_layout_new (xlator_t *this, int cnt)
layout->type = DHT_HASH_TYPE_DM;
layout->cnt = cnt;
-
- if (conf) {
- layout->spread_cnt = conf->dir_spread_cnt;
+ if (conf)
layout->gen = conf->gen;
- }
layout->ref = 1;
out:
@@ -167,7 +173,7 @@ dht_layout_search (xlator_t *this, dht_layout_t *layout, const char *name)
ret = dht_hash_compute (layout->type, name, &hash);
if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"hash computation failed for type=%d name=%s",
layout->type, name);
goto out;
@@ -182,7 +188,7 @@ dht_layout_search (xlator_t *this, dht_layout_t *layout, const char *name)
}
if (!subvol) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"no subvolume for hash (value) = %u", hash);
}
@@ -271,9 +277,6 @@ dht_disk_layout_extract (xlator_t *this, dht_layout_t *layout,
if (disk_layout_p)
*disk_layout_p = disk_layout;
- else
- GF_FREE (disk_layout);
-
ret = 0;
out:
@@ -283,7 +286,7 @@ out:
int
dht_disk_layout_merge (xlator_t *this, dht_layout_t *layout,
- int pos, void *disk_layout_raw, int disk_layout_len)
+ int pos, void *disk_layout_raw)
{
int cnt = 0;
int type = 0;
@@ -291,38 +294,19 @@ dht_disk_layout_merge (xlator_t *this, dht_layout_t *layout,
int stop_off = 0;
int disk_layout[4];
- if (!disk_layout_raw) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "error no layout on disk for merge");
- return -1;
- }
-
- GF_ASSERT (disk_layout_len == sizeof (disk_layout));
+ /* TODO: assert disk_layout_ptr is of required length */
- memcpy (disk_layout, disk_layout_raw, disk_layout_len);
+ memcpy (disk_layout, disk_layout_raw, sizeof (disk_layout));
cnt = ntoh32 (disk_layout[0]);
if (cnt != 1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"disk layout has invalid count %d", cnt);
return -1;
}
- type = ntoh32 (disk_layout[1]);
- switch (type) {
- case DHT_HASH_TYPE_DM_USER:
- gf_log (this->name, GF_LOG_DEBUG, "found user-set layout");
- layout->type = type;
- /* Fall through. */
- case DHT_HASH_TYPE_DM:
- break;
- default:
- gf_log (this->name, GF_LOG_CRITICAL,
- "Catastrophic error layout with unknown type found %d",
- disk_layout[1]);
- return -1;
- }
-
+ /* TODO: assert type is compatible */
+ type = ntoh32 (disk_layout[1]);
start_off = ntoh32 (disk_layout[2]);
stop_off = ntoh32 (disk_layout[3]);
@@ -346,7 +330,7 @@ dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
int ret = -1;
int err = -1;
void *disk_layout_raw = NULL;
- int disk_layout_len = 0;
+
if (op_ret != 0) {
err = op_errno;
@@ -367,8 +351,8 @@ dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
if (xattr) {
/* during lookup and not mkdir */
- ret = dict_get_ptr_and_len (xattr, "trusted.glusterfs.dht",
- &disk_layout_raw, &disk_layout_len);
+ ret = dict_get_ptr (xattr, "trusted.glusterfs.dht",
+ &disk_layout_raw);
}
if (ret != 0) {
@@ -380,10 +364,9 @@ dht_layout_merge (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
goto out;
}
- ret = dht_disk_layout_merge (this, layout, i, disk_layout_raw,
- disk_layout_len);
+ ret = dht_disk_layout_merge (this, layout, i, disk_layout_raw);
if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_DEBUG,
"layout merge from subvolume %s failed",
subvol->name);
goto out;
@@ -499,7 +482,7 @@ dht_layout_anomalies (xlator_t *this, loc_t *loc, dht_layout_t *layout,
uint32_t last_stop = 0;
char is_virgin = 1;
- /* TODO: explain what is happening */
+ /* TODO: explain WTF is happening */
last_stop = layout->list[0].start - 1;
prev_stop = last_stop;
@@ -569,6 +552,7 @@ dht_layout_normalize (xlator_t *this, loc_t *loc, dht_layout_t *layout)
uint32_t down = 0;
uint32_t misc = 0;
+
ret = dht_layout_sort (layout);
if (ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
@@ -596,28 +580,24 @@ dht_layout_normalize (xlator_t *this, loc_t *loc, dht_layout_t *layout)
"found anomalies in %s. holes=%d overlaps=%d",
loc->path, holes, overlaps);
}
- ret = -1;
+ ret = 1;
}
for (i = 0; i < layout->cnt; i++) {
- /* TODO During DHT selfheal rewrite (almost) find a better place
- * to detect this - probably in dht_layout_anomalies()
+ /* TODO During DHT selfheal rewrite (almost) find a better place to
+ * detect this - probably in dht_layout_anomalies()
*/
if (layout->list[i].err > 0) {
- gf_log_callingfn (this->name, GF_LOG_DEBUG,
- "path=%s err=%s on subvol=%s",
- loc->path,
- strerror (layout->list[i].err),
- (layout->list[i].xlator ?
- layout->list[i].xlator->name
- : "<>"));
- if ((layout->list[i].err == ENOENT) && (ret >= 0)) {
- ret++;
- }
+ gf_log (this->name, GF_LOG_DEBUG,
+ "path=%s err=%s on subvol=%s",
+ loc->path, strerror (layout->list[i].err),
+ (layout->list[i].xlator ?
+ layout->list[i].xlator->name : "<>"));
+ if (layout->list[i].err == ENOENT)
+ ret = 1;
}
}
-
out:
return ret;
}
@@ -682,7 +662,7 @@ dht_layout_dir_mismatch (xlator_t *this, dht_layout_t *layout, xlator_t *subvol,
count = ntoh32 (disk_layout[0]);
if (count != 1) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log (this->name, GF_LOG_INFO,
"%s - disk layout has invalid count %d",
loc->path, count);
ret = -1;
diff --git a/xlators/cluster/dht/src/dht-linkfile.c b/xlators/cluster/dht/src/dht-linkfile.c
index 803f344af..9dd487bc8 100644
--- a/xlators/cluster/dht/src/dht-linkfile.c
+++ b/xlators/cluster/dht/src/dht-linkfile.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -22,18 +31,81 @@
int
+dht_linkfile_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno)
+{
+ dht_local_t *local = NULL;
+
+ local = frame->local;
+ local->linkfile.linkfile_cbk (frame, cookie, this, op_ret, op_errno,
+ local->linkfile.inode,
+ &local->linkfile.stbuf, NULL, NULL);
+
+ return 0;
+}
+
+
+int
dht_linkfile_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
+ call_frame_t *prev = NULL;
+ dict_t *xattr = NULL;
+ data_t *str_data = NULL;
+ int ret = -1;
local = frame->local;
+ prev = cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: failed to create link file (%s)",
+ local->linkfile.loc.path, strerror (op_errno));
+ goto err;
+ }
+
+ xattr = get_new_dict ();
+ if (!xattr) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->linkfile.xattr = dict_ref (xattr);
+ local->linkfile.inode = inode_ref (inode);
+
+ str_data = str_to_data (local->linkfile.srcvol->name);
+ if (!str_data) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ ret = dict_set (xattr, "trusted.glusterfs.dht.linkto", str_data);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%s: failed to initialize linkfile data",
+ local->linkfile.loc.path);
+ }
+ str_data = NULL;
+
+ local->linkfile.stbuf = *stbuf;
+
+ STACK_WIND (frame, dht_linkfile_xattr_cbk,
+ prev->this, prev->this->fops->setxattr,
+ &local->linkfile.loc, local->linkfile.xattr, 0);
+
+ return 0;
+
+err:
+ if (str_data) {
+ data_destroy (str_data);
+ str_data = NULL;
+ }
local->linkfile.linkfile_cbk (frame, cookie, this, op_ret, op_errno,
- inode, stbuf, preparent, postparent,
- xdata);
+ inode, stbuf, preparent, postparent);
return 0;
}
@@ -44,58 +116,39 @@ dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,
{
dht_local_t *local = NULL;
dict_t *dict = NULL;
- int need_unref = 0;
int ret = 0;
local = frame->local;
local->linkfile.linkfile_cbk = linkfile_cbk;
local->linkfile.srcvol = tovol;
+ loc_copy (&local->linkfile.loc, loc);
- dict = local->params;
- if (!dict) {
+ if (!uuid_is_null (local->gfid)) {
dict = dict_new ();
if (!dict)
goto out;
- need_unref = 1;
- }
-
- if (!uuid_is_null (local->gfid)) {
ret = dict_set_static_bin (dict, "gfid-req", local->gfid, 16);
if (ret)
gf_log ("dht-linkfile", GF_LOG_INFO,
"%s: gfid set failed", loc->path);
+ } else if (local->params) {
+ dict = dict_ref (local->params);
}
-
- ret = dict_set_str (dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes");
- if (ret)
- gf_log ("dht-linkfile", GF_LOG_INFO,
- "%s: internal-fop set failed", loc->path);
-
- ret = dict_set_str (dict, "trusted.glusterfs.dht.linkto",
- tovol->name);
-
- if (ret < 0) {
+ if (!dict)
gf_log (frame->this->name, GF_LOG_INFO,
- "%s: failed to initialize linkfile data",
- loc->path);
- goto out;
- }
+ "dict is NULL, need to make sure gfid's are same");
STACK_WIND (frame, dht_linkfile_create_cbk,
fromvol, fromvol->fops->mknod, loc,
- S_IFREG | DHT_LINKFILE_MODE, 0, 0, dict);
+ S_IFREG | DHT_LINKFILE_MODE, 0, dict);
- if (need_unref && dict)
+ if (dict)
dict_unref (dict);
return 0;
out:
local->linkfile.linkfile_cbk (frame, NULL, frame->this, -1, ENOMEM,
- loc->inode, NULL, NULL, NULL, NULL);
-
- if (need_unref && dict)
- dict_unref (dict);
-
+ loc->inode, NULL, NULL, NULL);
return 0;
}
@@ -103,8 +156,7 @@ out:
int
dht_linkfile_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -138,17 +190,16 @@ dht_linkfile_unlink (call_frame_t *frame, xlator_t *this,
goto err;
}
- /* Using non-fop value here, as anyways, 'local->fop' is not used in
- this particular case */
- unlink_local = dht_local_init (unlink_frame, loc, NULL,
- GF_FOP_MAXVALUE);
+ unlink_local = dht_local_init (unlink_frame);
if (!unlink_local) {
goto err;
}
+ loc_copy (&unlink_local->loc, loc);
+
STACK_WIND (unlink_frame, dht_linkfile_unlink_cbk,
subvol, subvol->fops->unlink,
- &unlink_local->loc, 0, NULL);
+ &unlink_local->loc);
return 0;
err:
diff --git a/xlators/cluster/dht/src/dht-mem-types.h b/xlators/cluster/dht/src/dht-mem-types.h
index 4f3a90e91..af31c8b07 100644
--- a/xlators/cluster/dht/src/dht-mem-types.h
+++ b/xlators/cluster/dht/src/dht-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -19,15 +28,13 @@ enum gf_dht_mem_types_ {
gf_dht_mt_dht_conf_t,
gf_dht_mt_char,
gf_dht_mt_int32_t,
+ gf_dht_mt_dht_local_t,
gf_dht_mt_xlator_t,
gf_dht_mt_dht_layout_t,
gf_switch_mt_dht_conf_t,
gf_switch_mt_dht_du_t,
gf_switch_mt_switch_sched_array,
gf_switch_mt_switch_struct,
- gf_dht_mt_subvol_time,
- gf_dht_mt_loc_t,
- gf_defrag_info_mt,
gf_dht_mt_end
};
#endif
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
deleted file mode 100644
index 8f2f0adb2..000000000
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ /dev/null
@@ -1,1684 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "dht-common.h"
-#include "xlator.h"
-
-#define GF_DISK_SECTOR_SIZE 512
-#define DHT_REBALANCE_PID 4242 /* Change it if required */
-#define DHT_REBALANCE_BLKSIZE (128 * 1024)
-
-static int
-dht_write_with_holes (xlator_t *to, fd_t *fd, struct iovec *vec, int count,
- int32_t size, off_t offset, struct iobref *iobref)
-{
- int i = 0;
- int ret = -1;
- int start_idx = 0;
- int tmp_offset = 0;
- int write_needed = 0;
- int buf_len = 0;
- int size_pending = 0;
- char *buf = NULL;
-
- /* loop through each vector */
- for (i = 0; i < count; i++) {
- buf = vec[i].iov_base;
- buf_len = vec[i].iov_len;
-
- for (start_idx = 0; (start_idx + GF_DISK_SECTOR_SIZE) <= buf_len;
- start_idx += GF_DISK_SECTOR_SIZE) {
-
- if (mem_0filled (buf + start_idx, GF_DISK_SECTOR_SIZE) != 0) {
- write_needed = 1;
- continue;
- }
-
- if (write_needed) {
- ret = syncop_write (to, fd, (buf + tmp_offset),
- (start_idx - tmp_offset),
- (offset + tmp_offset),
- iobref, 0);
- /* 'path' will be logged in calling function */
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to write (%s)",
- strerror (errno));
- goto out;
- }
-
- write_needed = 0;
- }
- tmp_offset = start_idx + GF_DISK_SECTOR_SIZE;
- }
-
- if ((start_idx < buf_len) || write_needed) {
- /* This means, last chunk is not yet written.. write it */
- ret = syncop_write (to, fd, (buf + tmp_offset),
- (buf_len - tmp_offset),
- (offset + tmp_offset), iobref, 0);
- if (ret < 0) {
- /* 'path' will be logged in calling function */
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to write (%s)",
- strerror (errno));
- goto out;
- }
- }
-
- size_pending = (size - buf_len);
- if (!size_pending)
- break;
- }
-
- ret = size;
-out:
- return ret;
-
-}
-
-int32_t
-gf_defrag_handle_hardlink (xlator_t *this, loc_t *loc, dict_t *xattrs,
- struct iatt *stbuf)
-{
- int32_t ret = -1;
- xlator_t *cached_subvol = NULL;
- xlator_t *hashed_subvol = NULL;
- xlator_t *linkto_subvol = NULL;
- data_t *data = NULL;
- struct iatt iatt = {0,};
- int32_t op_errno = 0;
-
- GF_VALIDATE_OR_GOTO ("defrag", loc, out);
- GF_VALIDATE_OR_GOTO ("defrag", loc->name, out);
- GF_VALIDATE_OR_GOTO ("defrag", stbuf, out);
- GF_VALIDATE_OR_GOTO ("defrag", this, out);
- GF_VALIDATE_OR_GOTO ("defrag", xattrs, out);
-
- if (uuid_is_null (loc->pargfid)) {
- gf_log ("", GF_LOG_ERROR, "loc->pargfid is NULL for "
- "%s", loc->path);
- goto out;
- }
-
- if (uuid_is_null (loc->gfid)) {
- gf_log ("", GF_LOG_ERROR, "loc->gfid is NULL for "
- "%s", loc->path);
- goto out;
- }
-
- cached_subvol = dht_subvol_get_cached (this, loc->inode);
- if (!cached_subvol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get cached subvol"
- " for %s on %s", loc->name, this->name);
- goto out;
- }
-
- hashed_subvol = dht_subvol_get_hashed (this, loc);
- if (!hashed_subvol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get hashed subvol"
- " for %s on %s", loc->name, this->name);
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Attempting to migrate hardlink %s "
- "with gfid %s from %s -> %s", loc->name, uuid_utoa (loc->gfid),
- cached_subvol->name, hashed_subvol->name);
- data = dict_get (xattrs, DHT_LINKFILE_KEY);
- /* set linkto on cached -> hashed if not present, else link it */
- if (!data) {
- ret = dict_set_str (xattrs, DHT_LINKFILE_KEY,
- hashed_subvol->name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set "
- "linkto xattr in dict for %s", loc->name);
- goto out;
- }
-
- ret = syncop_setxattr (cached_subvol, loc, xattrs, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Linkto setxattr "
- "failed %s -> %s (%s)", cached_subvol->name,
- loc->name, strerror (errno));
- goto out;
- }
- goto out;
- } else {
- linkto_subvol = dht_linkfile_subvol (this, NULL, NULL, xattrs);
- if (!linkto_subvol) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to get "
- "linkto subvol for %s", loc->name);
- } else {
- hashed_subvol = linkto_subvol;
- }
-
- ret = syncop_link (hashed_subvol, loc, loc);
- if (ret) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "link of %s -> %s"
- " failed on subvol %s (%s)", loc->name,
- uuid_utoa(loc->gfid),
- hashed_subvol->name, strerror (op_errno));
- if (op_errno != EEXIST)
- goto out;
- }
- }
- ret = syncop_lookup (hashed_subvol, loc, NULL, &iatt, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed lookup %s on %s (%s)"
- , loc->name, hashed_subvol->name, strerror (errno));
- goto out;
- }
-
- if (iatt.ia_nlink == stbuf->ia_nlink) {
- ret = dht_migrate_file (this, loc, cached_subvol, hashed_subvol,
- GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS);
- if (ret)
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-
-static inline int
-__is_file_migratable (xlator_t *this, loc_t *loc,
- struct iatt *stbuf, dict_t *xattrs, int flags)
-{
- int ret = -1;
-
- if (IA_ISDIR (stbuf->ia_type)) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: migrate-file called on directory", loc->path);
- ret = -1;
- goto out;
- }
-
- if (flags == GF_DHT_MIGRATE_HARDLINK_IN_PROGRESS) {
- ret = 0;
- goto out;
- }
- if (stbuf->ia_nlink > 1) {
- /* support for decomission */
- if (flags == GF_DHT_MIGRATE_HARDLINK) {
- ret = gf_defrag_handle_hardlink (this, loc,
- xattrs, stbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to migrate file with link",
- loc->path);
- }
- } else {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: file has hardlinks", loc->path);
- }
- ret = ENOTSUP;
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static inline int
-__dht_rebalance_create_dst_file (xlator_t *to, xlator_t *from, loc_t *loc, struct iatt *stbuf,
- dict_t *dict, fd_t **dst_fd)
-{
- xlator_t *this = NULL;
- int ret = -1;
- fd_t *fd = NULL;
- struct iatt new_stbuf = {0,};
-
- this = THIS;
-
- ret = dict_set_static_bin (dict, "gfid-req", stbuf->ia_gfid, 16);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set gfid in dict for create", loc->path);
- goto out;
- }
-
- ret = dict_set_str (dict, DHT_LINKFILE_KEY, from->name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set gfid in dict for create", loc->path);
- goto out;
- }
-
- fd = fd_create (loc->inode, DHT_REBALANCE_PID);
- if (!fd) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: fd create failed (destination) (%s)",
- loc->path, strerror (errno));
- ret = -1;
- goto out;
- }
-
- ret = syncop_lookup (to, loc, NULL, &new_stbuf, NULL, NULL);
- if (!ret) {
- /* File exits in the destination, check if gfid matches */
- if (uuid_compare (stbuf->ia_gfid, new_stbuf.ia_gfid) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "file %s exits in %s with different gfid",
- loc->path, to->name);
- fd_unref (fd);
- goto out;
- }
- }
- if ((ret == -1) && (errno != ENOENT)) {
- /* File exists in destination, but not accessible */
- gf_log (THIS->name, GF_LOG_WARNING,
- "%s: failed to lookup file (%s)",
- loc->path, strerror (errno));
- goto out;
- }
-
- /* Create the destination with LINKFILE mode, and linkto xattr,
- if the linkfile already exists, it will just open the file */
- ret = syncop_create (to, loc, O_RDWR, DHT_LINKFILE_MODE, fd,
- dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create %s on %s (%s)",
- loc->path, to->name, strerror (errno));
- goto out;
- }
-
- if (dst_fd)
- *dst_fd = fd;
-
- /* success */
- ret = 0;
-
-out:
- return ret;
-}
-
-static inline int
-__dht_check_free_space (xlator_t *to, xlator_t *from, loc_t *loc,
- struct iatt *stbuf, int flag)
-{
- struct statvfs src_statfs = {0,};
- struct statvfs dst_statfs = {0,};
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = syncop_statfs (from, loc, &src_statfs);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get statfs of %s on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- ret = syncop_statfs (to, loc, &dst_statfs);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to get statfs of %s on %s (%s)",
- loc->path, to->name, strerror (errno));
- goto out;
- }
-
- /* if force option is given, do not check for space @ dst.
- * Check only if space is avail for the file */
- if (flag != GF_DHT_MIGRATE_DATA)
- goto check_avail_space;
-
- if (((dst_statfs.f_bavail *
- dst_statfs.f_bsize) / GF_DISK_SECTOR_SIZE) <
- (((src_statfs.f_bavail * src_statfs.f_bsize) /
- GF_DISK_SECTOR_SIZE) - stbuf->ia_blocks)) {
- gf_log (this->name, GF_LOG_WARNING,
- "data movement attempted from node (%s) with"
- " higher disk space to a node (%s) with "
- "lesser disk space (%s)", from->name,
- to->name, loc->path);
-
- /* this is not a 'failure', but we don't want to
- consider this as 'success' too :-/ */
- ret = 1;
- goto out;
- }
-
-check_avail_space:
- if (((dst_statfs.f_bavail * dst_statfs.f_bsize) /
- GF_DISK_SECTOR_SIZE) < stbuf->ia_blocks) {
- gf_log (this->name, GF_LOG_ERROR,
- "data movement attempted from node (%s) with "
- "to node (%s) which does not have required free space"
- " for %s", from->name, to->name, loc->path);
- ret = 1;
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static inline int
-__dht_rebalance_migrate_data (xlator_t *from, xlator_t *to, fd_t *src, fd_t *dst,
- uint64_t ia_size, int hole_exists)
-{
- int ret = 0;
- int count = 0;
- off_t offset = 0;
- struct iovec *vector = NULL;
- struct iobref *iobref = NULL;
- uint64_t total = 0;
- size_t read_size = 0;
-
- /* if file size is '0', no need to enter this loop */
- while (total < ia_size) {
- read_size = (((ia_size - total) > DHT_REBALANCE_BLKSIZE) ?
- DHT_REBALANCE_BLKSIZE : (ia_size - total));
- ret = syncop_readv (from, src, read_size,
- offset, 0, &vector, &count, &iobref);
- if (!ret || (ret < 0)) {
- break;
- }
-
- if (hole_exists)
- ret = dht_write_with_holes (to, dst, vector, count,
- ret, offset, iobref);
- else
- ret = syncop_writev (to, dst, vector, count,
- offset, iobref, 0);
- if (ret < 0) {
- break;
- }
- offset += ret;
- total += ret;
-
- GF_FREE (vector);
- if (iobref)
- iobref_unref (iobref);
- iobref = NULL;
- vector = NULL;
- }
- if (iobref)
- iobref_unref (iobref);
- GF_FREE (vector);
-
- if (ret >= 0)
- ret = 0;
-
- return ret;
-}
-
-
-static inline int
-__dht_rebalance_open_src_file (xlator_t *from, xlator_t *to, loc_t *loc,
- struct iatt *stbuf, fd_t **src_fd)
-{
- int ret = 0;
- fd_t *fd = NULL;
- dict_t *dict = NULL;
- xlator_t *this = NULL;
- struct iatt iatt = {0,};
-
- this = THIS;
-
- fd = fd_create (loc->inode, DHT_REBALANCE_PID);
- if (!fd) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: fd create failed (source)", loc->path);
- ret = -1;
- goto out;
- }
-
- ret = syncop_open (from, loc, O_RDWR, fd);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to open file %s on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- ret = -1;
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_str (dict, DHT_LINKFILE_KEY, to->name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set xattr in dict for %s (linkto:%s)",
- loc->path, to->name);
- goto out;
- }
-
- /* Once the migration starts, the source should have 'linkto' key set
- to show which is the target, so other clients can work around it */
- ret = syncop_setxattr (from, loc, dict, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set xattr on %s in %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- /* mode should be (+S+T) to indicate migration is in progress */
- iatt.ia_prot = stbuf->ia_prot;
- iatt.ia_type = stbuf->ia_type;
- iatt.ia_prot.sticky = 1;
- iatt.ia_prot.sgid = 1;
-
- ret = syncop_setattr (from, loc, &iatt, GF_SET_ATTR_MODE, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to set mode on %s in %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- if (src_fd)
- *src_fd = fd;
-
- /* success */
- ret = 0;
-out:
- if (dict)
- dict_unref (dict);
-
- return ret;
-}
-
-int
-migrate_special_files (xlator_t *this, xlator_t *from, xlator_t *to, loc_t *loc,
- struct iatt *buf)
-{
- int ret = -1;
- dict_t *rsp_dict = NULL;
- dict_t *dict = NULL;
- char *link = NULL;
- struct iatt stbuf = {0,};
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_int32 (dict, DHT_LINKFILE_KEY, 256);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set 'linkto' key in dict", loc->path);
- goto out;
- }
-
- /* check in the destination if the file is link file */
- ret = syncop_lookup (to, loc, dict, &stbuf, &rsp_dict, NULL);
- if ((ret == -1) && (errno != ENOENT)) {
- gf_log (this->name, GF_LOG_WARNING, "%s: lookup failed (%s)",
- loc->path, strerror (errno));
- goto out;
- }
-
- /* we no more require this key */
- dict_del (dict, DHT_LINKFILE_KEY);
-
- /* file exists in target node, only if it is 'linkfile' its valid,
- otherwise, error out */
- if (!ret) {
- if (!check_is_linkfile (loc->inode, &stbuf, rsp_dict)) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: file exists in destination", loc->path);
- ret = -1;
- goto out;
- }
-
- /* as file is linkfile, delete it */
- ret = syncop_unlink (to, loc);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to delete the linkfile (%s)",
- loc->path, strerror (errno));
- goto out;
- }
- }
-
- /* Set the gfid of the source file in dict */
- ret = dict_set_static_bin (dict, "gfid-req", buf->ia_gfid, 16);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set gfid in dict for create", loc->path);
- goto out;
- }
-
- /* Create the file in target */
- if (IA_ISLNK (buf->ia_type)) {
- /* Handle symlinks separately */
- ret = syncop_readlink (from, loc, &link, buf->ia_size);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: readlink on symlink failed (%s)",
- loc->path, strerror (errno));
- goto out;
- }
-
- ret = syncop_symlink (to, loc, link, dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: creating symlink failed (%s)",
- loc->path, strerror (errno));
- goto out;
- }
-
- goto done;
- }
-
- ret = syncop_mknod (to, loc, st_mode_from_ia (buf->ia_prot,
- buf->ia_type),
- makedev (ia_major (buf->ia_rdev),
- ia_minor (buf->ia_rdev)), dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "%s: mknod failed (%s)",
- loc->path, strerror (errno));
- goto out;
- }
-
-done:
- ret = syncop_unlink (from, loc);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "%s: unlink failed (%s)",
- loc->path, strerror (errno));
-
-out:
- if (dict)
- dict_unref (dict);
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- return ret;
-}
-
-/*
- return values:
-
- -1 : failure
- 0 : successfully migrated data
- 1 : not a failure, but we can't migrate data as of now
-*/
-int
-dht_migrate_file (xlator_t *this, loc_t *loc, xlator_t *from, xlator_t *to,
- int flag)
-{
- int ret = -1;
- struct iatt new_stbuf = {0,};
- struct iatt stbuf = {0,};
- struct iatt empty_iatt = {0,};
- ia_prot_t src_ia_prot = {0,};
- fd_t *src_fd = NULL;
- fd_t *dst_fd = NULL;
- dict_t *dict = NULL;
- dict_t *xattr = NULL;
- dict_t *xattr_rsp = NULL;
- int file_has_holes = 0;
-
- gf_log (this->name, GF_LOG_INFO, "%s: attempting to move from %s to %s",
- loc->path, from->name, to->name);
-
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_set_int32 (dict, DHT_LINKFILE_KEY, 256);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to set 'linkto' key in dict", loc->path);
- goto out;
- }
-
- /* Phase 1 - Data migration is in progress from now on */
- ret = syncop_lookup (from, loc, dict, &stbuf, &xattr_rsp, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: lookup failed on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- /* we no more require this key */
- dict_del (dict, DHT_LINKFILE_KEY);
-
- /* preserve source mode, so set the same to the destination */
- src_ia_prot = stbuf.ia_prot;
-
- /* Check if file can be migrated */
- ret = __is_file_migratable (this, loc, &stbuf, xattr_rsp, flag);
- if (ret)
- goto out;
-
- /* Take care of the special files */
- if (!IA_ISREG (stbuf.ia_type)) {
- /* Special files */
- ret = migrate_special_files (this, from, to, loc, &stbuf);
- goto out;
- }
-
- /* create the destination, with required modes/xattr */
- ret = __dht_rebalance_create_dst_file (to, from, loc, &stbuf,
- dict, &dst_fd);
- if (ret)
- goto out;
-
- ret = __dht_check_free_space (to, from, loc, &stbuf, flag);
- if (ret) {
- goto out;
- }
-
- /* Open the source, and also update mode/xattr */
- ret = __dht_rebalance_open_src_file (from, to, loc, &stbuf, &src_fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to open %s on %s",
- loc->path, from->name);
- goto out;
- }
-
- ret = syncop_fstat (from, src_fd, &stbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to lookup %s on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- /* Try to preserve 'holes' while migrating data */
- if (stbuf.ia_size > (stbuf.ia_blocks * GF_DISK_SECTOR_SIZE))
- file_has_holes = 1;
-
- /* All I/O happens in this function */
- ret = __dht_rebalance_migrate_data (from, to, src_fd, dst_fd,
- stbuf.ia_size, file_has_holes);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s: failed to migrate data",
- loc->path);
- /* reset the destination back to 0 */
- ret = syncop_ftruncate (to, dst_fd, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to reset target size back to 0 (%s)",
- loc->path, strerror (errno));
- }
-
- ret = -1;
- goto out;
- }
-
- /* TODO: move all xattr related operations to fd based operations */
- ret = syncop_listxattr (from, loc, &xattr);
- if (ret == -1)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to get xattr from %s (%s)",
- loc->path, from->name, strerror (errno));
-
- ret = syncop_setxattr (to, loc, xattr, 0);
- if (ret == -1)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set xattr on %s (%s)",
- loc->path, to->name, strerror (errno));
-
- /* TODO: Sync the locks */
-
- ret = syncop_fsync (to, dst_fd);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to fsync on %s (%s)",
- loc->path, to->name, strerror (errno));
-
-
- /* Phase 2 - Data-Migration Complete, Housekeeping updates pending */
-
- ret = syncop_fstat (from, src_fd, &new_stbuf);
- if (ret < 0) {
- /* Failed to get the stat info */
- gf_log (this->name, GF_LOG_ERROR,
- "failed to fstat file %s on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- /* source would have both sticky bit and sgid bit set, reset it to 0,
- and set the source permission on destination, if it was not set
- prior to setting rebalance-modes in source */
- if (!src_ia_prot.sticky)
- new_stbuf.ia_prot.sticky = 0;
-
- if (!src_ia_prot.sgid)
- new_stbuf.ia_prot.sgid = 0;
-
- /* TODO: if the source actually had sticky bit, or sgid bit set,
- we are not handling it */
-
- ret = syncop_fsetattr (to, dst_fd, &new_stbuf,
- (GF_SET_ATTR_UID | GF_SET_ATTR_GID |
- GF_SET_ATTR_MODE), NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform setattr on %s (%s)",
- loc->path, to->name, strerror (errno));
- goto out;
- }
-
- /* Because 'futimes' is not portable */
- ret = syncop_setattr (to, loc, &new_stbuf,
- (GF_SET_ATTR_MTIME | GF_SET_ATTR_ATIME),
- NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform setattr on %s (%s)",
- loc->path, to->name, strerror (errno));
- }
-
- /* Make the source as a linkfile first before deleting it */
- empty_iatt.ia_prot.sticky = 1;
- ret = syncop_fsetattr (from, src_fd, &empty_iatt,
- GF_SET_ATTR_MODE, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, \
- "%s: failed to perform setattr on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- /* Do a stat and check the gfid before unlink */
- ret = syncop_stat (from, loc, &empty_iatt);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to do a stat on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
-
- if (uuid_compare (empty_iatt.ia_gfid, loc->gfid) == 0) {
- /* take out the source from namespace */
- ret = syncop_unlink (from, loc);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform unlink on %s (%s)",
- loc->path, from->name, strerror (errno));
- goto out;
- }
- }
-
- /* Free up the data blocks on the source node, as the whole
- file is migrated */
- ret = syncop_ftruncate (from, src_fd, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform truncate on %s (%s)",
- loc->path, from->name, strerror (errno));
- }
-
- /* remove the 'linkto' xattr from the destination */
- ret = syncop_fremovexattr (to, dst_fd, DHT_LINKFILE_KEY);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to perform removexattr on %s (%s)",
- loc->path, to->name, strerror (errno));
- }
-
- ret = syncop_lookup (this, loc, NULL, NULL, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "%s: failed to lookup the file on subvolumes (%s)",
- loc->path, strerror (errno));
- }
-
- gf_log (this->name, GF_LOG_INFO,
- "completed migration of %s from subvolume %s to %s",
- loc->path, from->name, to->name);
-
- ret = 0;
-out:
- if (dict)
- dict_unref (dict);
-
- if (xattr)
- dict_unref (xattr);
- if (xattr_rsp)
- dict_unref (xattr_rsp);
-
- if (dst_fd)
- syncop_close (dst_fd);
- if (src_fd)
- syncop_close (src_fd);
-
- return ret;
-}
-
-static int
-rebalance_task (void *data)
-{
- int ret = -1;
- dht_local_t *local = NULL;
- call_frame_t *frame = NULL;
-
- frame = data;
-
- local = frame->local;
-
- /* This function is 'synchrounous', hence if it returns,
- we are done with the task */
- ret = dht_migrate_file (THIS, &local->loc, local->rebalance.from_subvol,
- local->rebalance.target_node, local->flags);
-
- return ret;
-}
-
-static int
-rebalance_task_completion (int op_ret, call_frame_t *sync_frame, void *data)
-{
- int ret = -1;
- uint64_t layout_int = 0;
- dht_layout_t *layout = 0;
- xlator_t *this = NULL;
- dht_local_t *local = NULL;
- int32_t op_errno = EINVAL;
-
- this = THIS;
- local = sync_frame->local;
-
- if (!op_ret) {
- /* Make sure we have valid 'layout' in inode ctx
- after the operation */
- ret = inode_ctx_del (local->loc.inode, this, &layout_int);
- if (!ret && layout_int) {
- layout = (dht_layout_t *)(long)layout_int;
- dht_layout_unref (this, layout);
- }
-
- ret = dht_layout_preset (this, local->rebalance.target_node,
- local->loc.inode);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set inode ctx", local->loc.path);
- }
-
- if (op_ret == -1) {
- /* Failure of migration process, mostly due to write process.
- as we can't preserve the exact errno, lets say there was
- no space to migrate-data
- */
- op_errno = ENOSPC;
- }
-
- if (op_ret == 1) {
- /* migration didn't happen, but is not a failure, let the user
- understand that he doesn't have permission to migrate the
- file.
- */
- op_ret = -1;
- op_errno = EPERM;
- }
-
- DHT_STACK_UNWIND (setxattr, sync_frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-int
-dht_start_rebalance_task (xlator_t *this, call_frame_t *frame)
-{
- int ret = -1;
-
- ret = synctask_new (this->ctx->env, rebalance_task,
- rebalance_task_completion,
- frame, frame);
- return ret;
-}
-
-int
-gf_listener_stop (xlator_t *this)
-{
- glusterfs_ctx_t *ctx = NULL;
- cmd_args_t *cmd_args = NULL;
- int ret = 0;
-
- ctx = this->ctx;
- GF_ASSERT (ctx);
- cmd_args = &ctx->cmd_args;
- if (cmd_args->sock_file) {
- ret = unlink (cmd_args->sock_file);
- if (ret && (ENOENT == errno)) {
- ret = 0;
- }
- }
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to unlink listener "
- "socket %s, error: %s", cmd_args->sock_file,
- strerror (errno));
- }
- return ret;
-}
-
-void
-dht_build_root_inode (xlator_t *this, inode_t **inode)
-{
- inode_table_t *itable = NULL;
- uuid_t root_gfid = {0, };
-
- itable = inode_table_new (0, this);
- if (!itable)
- return;
-
- root_gfid[15] = 1;
- *inode = inode_find (itable, root_gfid);
-}
-
-void
-dht_build_root_loc (inode_t *inode, loc_t *loc)
-{
- loc->path = "/";
- loc->inode = inode;
- loc->inode->ia_type = IA_IFDIR;
- memset (loc->gfid, 0, 16);
- loc->gfid[15] = 1;
-}
-
-
-/* return values: 1 -> error, bug ignore and continue
- 0 -> proceed
- -1 -> error, handle it */
-int32_t
-gf_defrag_handle_migrate_error (int32_t op_errno, gf_defrag_info_t *defrag)
-{
- /* if errno is not ENOSPC or ENOTCONN, we can still continue
- with rebalance process */
- if ((errno != ENOSPC) || (errno != ENOTCONN))
- return 1;
-
- if (errno == ENOTCONN) {
- /* Most probably mount point went missing (mostly due
- to a brick down), say rebalance failure to user,
- let him restart it if everything is fine */
- defrag->defrag_status = GF_DEFRAG_STATUS_FAILED;
- return -1;
- }
-
- if (errno == ENOSPC) {
- /* rebalance process itself failed, may be
- remote brick went down, or write failed due to
- disk full etc etc.. */
- defrag->defrag_status = GF_DEFRAG_STATUS_FAILED;
- return -1;
- }
-
- return 0;
-}
-
-/* We do a depth first traversal of directories. But before we move into
- * subdirs, we complete the data migration of those directories whose layouts
- * have been fixed
- */
-
-int
-gf_defrag_migrate_data (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
- dict_t *migrate_data)
-{
- int ret = -1;
- loc_t entry_loc = {0,};
- fd_t *fd = NULL;
- gf_dirent_t entries;
- gf_dirent_t *tmp = NULL;
- gf_dirent_t *entry = NULL;
- gf_boolean_t free_entries = _gf_false;
- off_t offset = 0;
- dict_t *dict = NULL;
- struct iatt iatt = {0,};
- int32_t op_errno = 0;
- char *uuid_str = NULL;
- uuid_t node_uuid = {0,};
- int readdir_operrno = 0;
- struct timeval dir_start = {0,};
- struct timeval end = {0,};
- double elapsed = {0,};
- struct timeval start = {0,};
-
- gf_log (this->name, GF_LOG_INFO, "migrate data called on %s",
- loc->path);
- gettimeofday (&dir_start, NULL);
-
- fd = fd_create (loc->inode, defrag->pid);
- if (!fd) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create fd");
- goto out;
- }
-
- ret = syncop_opendir (this, loc, fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s",
- loc->path);
- goto out;
- }
-
- INIT_LIST_HEAD (&entries.list);
-
- while ((ret = syncop_readdirp (this, fd, 131072, offset, NULL,
- &entries)) != 0) {
- if (ret < 0)
- break;
-
- /* Need to keep track of ENOENT errno, that means, there is no
- need to send more readdirp() */
- readdir_operrno = errno;
-
- free_entries = _gf_true;
-
- if (list_empty (&entries.list))
- break;
- list_for_each_entry_safe (entry, tmp, &entries.list, list) {
- if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) {
- ret = 1;
- goto out;
- }
-
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- if (IA_ISDIR (entry->d_stat.ia_type))
- continue;
-
- defrag->num_files_lookedup++;
- if (defrag->stats == _gf_true) {
- gettimeofday (&start, NULL);
- }
- loc_wipe (&entry_loc);
- ret =dht_build_child_loc (this, &entry_loc, loc,
- entry->d_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Child loc"
- " build failed");
- goto out;
- }
-
- if (uuid_is_null (entry->d_stat.ia_gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s"
- " gfid not present", loc->path,
- entry->d_name);
- continue;
- }
-
- uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid);
-
- if (uuid_is_null (loc->gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s"
- " gfid not present", loc->path,
- entry->d_name);
- continue;
- }
-
- uuid_copy (entry_loc.pargfid, loc->gfid);
-
- entry_loc.inode->ia_type = entry->d_stat.ia_type;
-
- ret = syncop_lookup (this, &entry_loc, NULL, &iatt,
- NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s"
- " lookup failed", entry_loc.path);
- continue;
- }
-
- ret = syncop_getxattr (this, &entry_loc, &dict,
- GF_XATTR_NODE_UUID_KEY);
- if(ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get node-uuid for %s", entry_loc.path);
- continue;
- }
-
- ret = dict_get_str (dict, GF_XATTR_NODE_UUID_KEY,
- &uuid_str);
- if(ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to "
- "get node-uuid from dict for %s",
- entry_loc.path);
- continue;
- }
-
- if (uuid_parse (uuid_str, node_uuid)) {
- gf_log (this->name, GF_LOG_ERROR, "uuid_parse "
- "failed for %s", entry_loc.path);
- continue;
- }
-
- /* if file belongs to different node, skip migration
- * the other node will take responsibility of migration
- */
- if (uuid_compare (node_uuid, defrag->node_uuid)) {
- gf_log (this->name, GF_LOG_TRACE, "%s does not"
- "belong to this node", entry_loc.path);
- continue;
- }
-
- uuid_str = NULL;
-
- dict_del (dict, GF_XATTR_NODE_UUID_KEY);
-
-
- /* if distribute is present, it will honor this key.
- * -1 is returned if distribute is not present or file
- * doesn't have a link-file. If file has link-file, the
- * path of link-file will be the value, and also that
- * guarantees that file has to be mostly migrated */
-
- ret = syncop_getxattr (this, &entry_loc, &dict,
- GF_XATTR_LINKINFO_KEY);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_TRACE, "failed to "
- "get link-to key for %s",
- entry_loc.path);
- continue;
- }
-
- ret = syncop_setxattr (this, &entry_loc, migrate_data,
- 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "migrate-data"
- " failed for %s", entry_loc.path);
- defrag->total_failures +=1;
- }
-
- if (ret == -1) {
- op_errno = errno;
- ret = gf_defrag_handle_migrate_error (op_errno,
- defrag);
-
- if (!ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "migrate-data on %s failed: %s",
- entry_loc.path,
- strerror (op_errno));
- else if (ret == 1)
- continue;
- else if (ret == -1)
- goto out;
- }
-
- LOCK (&defrag->lock);
- {
- defrag->total_files += 1;
- defrag->total_data += iatt.ia_size;
- }
- UNLOCK (&defrag->lock);
- if (defrag->stats == _gf_true) {
- gettimeofday (&end, NULL);
- elapsed = (end.tv_sec - start.tv_sec) * 1e6 +
- (end.tv_usec - start.tv_usec);
- gf_log (this->name, GF_LOG_INFO, "Migration of "
- "file:%s size:%"PRIu64" bytes took %.2f"
- "secs", entry_loc.path, iatt.ia_size,
- elapsed/1e6);
- }
- }
-
- gf_dirent_free (&entries);
- free_entries = _gf_false;
- INIT_LIST_HEAD (&entries.list);
-
- if (readdir_operrno == ENOENT)
- break;
- }
-
- gettimeofday (&end, NULL);
- elapsed = (end.tv_sec - dir_start.tv_sec) * 1e6 +
- (end.tv_usec - dir_start.tv_usec);
- gf_log (this->name, GF_LOG_INFO, "Migration operation on dir %s took "
- "%.2f secs", loc->path, elapsed/1e6);
- ret = 0;
-out:
- if (free_entries)
- gf_dirent_free (&entries);
-
- loc_wipe (&entry_loc);
-
- if (dict)
- dict_unref(dict);
-
- if (fd)
- fd_unref (fd);
- return ret;
-
-}
-
-
-int
-gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc,
- dict_t *fix_layout, dict_t *migrate_data)
-{
- int ret = -1;
- loc_t entry_loc = {0,};
- fd_t *fd = NULL;
- gf_dirent_t entries;
- gf_dirent_t *tmp = NULL;
- gf_dirent_t *entry = NULL;
- gf_boolean_t free_entries = _gf_false;
- dict_t *dict = NULL;
- off_t offset = 0;
- struct iatt iatt = {0,};
-
- ret = syncop_lookup (this, loc, NULL, &iatt, NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Lookup failed on %s",
- loc->path);
- goto out;
- }
-
- if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) {
- ret = gf_defrag_migrate_data (this, defrag, loc, migrate_data);
- if (ret)
- goto out;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "fix layout called on %s", loc->path);
-
- fd = fd_create (loc->inode, defrag->pid);
- if (!fd) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to create fd");
- ret = -1;
- goto out;
- }
-
- ret = syncop_opendir (this, loc, fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s",
- loc->path);
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&entries.list);
- while ((ret = syncop_readdirp (this, fd, 131072, offset, NULL,
- &entries)) != 0)
- {
- if ((ret < 0) || (ret && (errno == ENOENT)))
- break;
- free_entries = _gf_true;
-
- if (list_empty (&entries.list))
- break;
- list_for_each_entry_safe (entry, tmp, &entries.list, list) {
- if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED) {
- ret = 1;
- goto out;
- }
-
- offset = entry->d_off;
-
- if (!strcmp (entry->d_name, ".") ||
- !strcmp (entry->d_name, ".."))
- continue;
-
- if (!IA_ISDIR (entry->d_stat.ia_type))
- continue;
-
- loc_wipe (&entry_loc);
- ret =dht_build_child_loc (this, &entry_loc, loc,
- entry->d_name);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Child loc"
- " build failed");
- goto out;
- }
-
- if (uuid_is_null (entry->d_stat.ia_gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s"
- "gfid not present", loc->path,
- entry->d_name);
- continue;
- }
-
- entry_loc.inode->ia_type = entry->d_stat.ia_type;
-
- uuid_copy (entry_loc.gfid, entry->d_stat.ia_gfid);
- if (uuid_is_null (loc->gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s"
- "gfid not present", loc->path,
- entry->d_name);
- continue;
- }
-
- uuid_copy (entry_loc.pargfid, loc->gfid);
-
- ret = syncop_lookup (this, &entry_loc, NULL, &iatt,
- NULL, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "%s"
- " lookup failed", entry_loc.path);
- continue;
- }
-
- ret = syncop_setxattr (this, &entry_loc, fix_layout,
- 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Setxattr "
- "failed for %s", entry_loc.path);
- defrag->defrag_status =
- GF_DEFRAG_STATUS_FAILED;
- goto out;
- }
- ret = gf_defrag_fix_layout (this, defrag, &entry_loc,
- fix_layout, migrate_data);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Fix layout "
- "failed for %s", entry_loc.path);
- goto out;
- }
-
- }
- gf_dirent_free (&entries);
- free_entries = _gf_false;
- INIT_LIST_HEAD (&entries.list);
- }
-
- ret = 0;
-out:
- if (free_entries)
- gf_dirent_free (&entries);
-
- loc_wipe (&entry_loc);
-
- if (dict)
- dict_unref(dict);
-
- if (fd)
- fd_unref (fd);
-
- return ret;
-
-}
-
-
-int
-gf_defrag_start_crawl (void *data)
-{
- xlator_t *this = NULL;
- dht_conf_t *conf = NULL;
- gf_defrag_info_t *defrag = NULL;
- int ret = -1;
- loc_t loc = {0,};
- struct iatt iatt = {0,};
- struct iatt parent = {0,};
- dict_t *fix_layout = NULL;
- dict_t *migrate_data = NULL;
- dict_t *status = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- this = data;
- if (!this)
- goto out;
-
- ctx = this->ctx;
- if (!ctx)
- goto out;
-
- conf = this->private;
- if (!conf)
- goto out;
-
- defrag = conf->defrag;
- if (!defrag)
- goto out;
-
- gettimeofday (&defrag->start_time, NULL);
- dht_build_root_inode (this, &defrag->root_inode);
- if (!defrag->root_inode)
- goto out;
-
- dht_build_root_loc (defrag->root_inode, &loc);
-
- /* fix-layout on '/' first */
-
- ret = syncop_lookup (this, &loc, NULL, &iatt, NULL, &parent);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "look up on / failed");
- goto out;
- }
-
- fix_layout = dict_new ();
- if (!fix_layout) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_str (fix_layout, GF_XATTR_FIX_LAYOUT_KEY, "yes");
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to set dict str");
- goto out;
- }
-
- ret = syncop_setxattr (this, &loc, fix_layout, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "fix layout on %s failed",
- loc.path);
- goto out;
- }
-
- if (defrag->cmd != GF_DEFRAG_CMD_START_LAYOUT_FIX) {
- migrate_data = dict_new ();
- if (!migrate_data) {
- ret = -1;
- goto out;
- }
- if (defrag->cmd == GF_DEFRAG_CMD_START_FORCE)
- ret = dict_set_str (migrate_data,
- "distribute.migrate-data", "force");
- else
- ret = dict_set_str (migrate_data,
- "distribute.migrate-data",
- "non-force");
- if (ret)
- goto out;
- }
- ret = gf_defrag_fix_layout (this, defrag, &loc, fix_layout,
- migrate_data);
- if ((defrag->defrag_status != GF_DEFRAG_STATUS_STOPPED) &&
- (defrag->defrag_status != GF_DEFRAG_STATUS_FAILED)) {
- defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE;
- }
-
-
-
-out:
- LOCK (&defrag->lock);
- {
- status = dict_new ();
- gf_defrag_status_get (defrag, status);
- if (ctx->notify)
- ctx->notify (GF_EN_DEFRAG_STATUS, status);
- if (status)
- dict_unref (status);
- defrag->is_exiting = 1;
- }
- UNLOCK (&defrag->lock);
-
- if (defrag) {
- GF_FREE (defrag);
- conf->defrag = NULL;
- }
-
- return ret;
-}
-
-
-static int
-gf_defrag_done (int ret, call_frame_t *sync_frame, void *data)
-{
- gf_listener_stop (sync_frame->this);
-
- STACK_DESTROY (sync_frame->root);
- kill (getpid(), SIGTERM);
- return 0;
-}
-
-void *
-gf_defrag_start (void *data)
-{
- int ret = -1;
- call_frame_t *frame = NULL;
- dht_conf_t *conf = NULL;
- gf_defrag_info_t *defrag = NULL;
- xlator_t *this = NULL;
-
- this = data;
- conf = this->private;
- if (!conf)
- goto out;
-
- defrag = conf->defrag;
- if (!defrag)
- goto out;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- frame->root->pid = GF_CLIENT_PID_DEFRAG;
-
- defrag->pid = frame->root->pid;
-
- defrag->defrag_status = GF_DEFRAG_STATUS_STARTED;
-
- ret = synctask_new (this->ctx->env, gf_defrag_start_crawl,
- gf_defrag_done, frame, this);
-
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Could not create"
- " task for rebalance");
-out:
- return NULL;
-}
-
-int
-gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict)
-{
- int ret = 0;
- uint64_t files = 0;
- uint64_t size = 0;
- uint64_t lookup = 0;
- uint64_t failures = 0;
- char *status = "";
- double elapsed = 0;
- struct timeval end = {0,};
-
-
- if (!defrag)
- goto out;
-
- ret = 0;
- if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED)
- goto out;
-
- files = defrag->total_files;
- size = defrag->total_data;
- lookup = defrag->num_files_lookedup;
- failures = defrag->total_failures;
-
- gettimeofday (&end, NULL);
-
- elapsed = end.tv_sec - defrag->start_time.tv_sec;
-
- if (!dict)
- goto log;
-
- ret = dict_set_uint64 (dict, "files", files);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set file count");
-
- ret = dict_set_uint64 (dict, "size", size);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set size of xfer");
-
- ret = dict_set_uint64 (dict, "lookups", lookup);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set lookedup file count");
-
- ret = dict_set_int32 (dict, "status", defrag->defrag_status);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set status");
- if (elapsed) {
- ret = dict_set_double (dict, "run-time", elapsed);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set run-time");
- }
-
- ret = dict_set_uint64 (dict, "failures", failures);
-log:
- switch (defrag->defrag_status) {
- case GF_DEFRAG_STATUS_NOT_STARTED:
- status = "not started";
- break;
- case GF_DEFRAG_STATUS_STARTED:
- status = "in progress";
- break;
- case GF_DEFRAG_STATUS_STOPPED:
- status = "stopped";
- break;
- case GF_DEFRAG_STATUS_COMPLETE:
- status = "completed";
- break;
- case GF_DEFRAG_STATUS_FAILED:
- status = "failed";
- break;
- }
-
- gf_log (THIS->name, GF_LOG_INFO, "Rebalance is %s. Time taken is %.2f "
- "secs", status, elapsed);
- gf_log (THIS->name, GF_LOG_INFO, "Files migrated: %"PRIu64", size: %"
- PRIu64", lookups: %"PRIu64", failures: %"PRIu64, files, size,
- lookup, failures);
-
-
-out:
- return 0;
-}
-
-int
-gf_defrag_stop (gf_defrag_info_t *defrag, dict_t *output)
-{
- /* TODO: set a variable 'stop_defrag' here, it should be checked
- in defrag loop */
- int ret = -1;
- GF_ASSERT (defrag);
-
- if (defrag->defrag_status == GF_DEFRAG_STATUS_NOT_STARTED) {
- goto out;
- }
-
- gf_log ("", GF_LOG_INFO, "Recieved stop command on rebalance");
- defrag->defrag_status = GF_DEFRAG_STATUS_STOPPED;
-
- if (output)
- gf_defrag_status_get (defrag, output);
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
index f1a4364df..f6ed8769d 100644
--- a/xlators/cluster/dht/src/dht-rename.c
+++ b/xlators/cluster/dht/src/dht-rename.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
/* TODO: link(oldpath, newpath) fails if newpath already exists. DHT should
@@ -26,8 +35,7 @@ int
dht_rename_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
dht_local_t *local = NULL;
int this_call_cnt = 0;
@@ -67,130 +75,65 @@ dht_rename_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
this_call_cnt = dht_frame_return (frame);
if (is_last_call (this_call_cnt)) {
+ local->stbuf.ia_ino = local->loc.inode->ino;
+
+ local->preoldparent.ia_ino = local->loc.parent->ino;
+ local->postoldparent.ia_ino = local->loc.parent->ino;
+
+ local->preparent.ia_ino = local->loc2.parent->ino;
+ local->postparent.ia_ino = local->loc2.parent->ino;
+
WIPE (&local->preoldparent);
WIPE (&local->postoldparent);
WIPE (&local->preparent);
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
&local->stbuf, &local->preoldparent,
&local->postoldparent,
- &local->preparent, &local->postparent, xdata);
+ &local->preparent, &local->postparent);
}
return 0;
}
+
int
-dht_rename_hashed_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
- struct iatt *preoldparent,
- struct iatt *postoldparent,
- struct iatt *prenewparent,
- struct iatt *postnewparent, dict_t *xdata)
+dht_rename_dir_do (call_frame_t *frame, xlator_t *this)
{
- dht_conf_t *conf = NULL;
dht_local_t *local = NULL;
- int call_cnt = 0;
- call_frame_t *prev = NULL;
+ dht_conf_t *conf = NULL;
int i = 0;
conf = this->private;
local = frame->local;
- prev = cookie;
-
- if (op_ret == -1) {
- /* TODO: undo the damage */
- gf_log (this->name, GF_LOG_INFO,
- "rename %s -> %s on %s failed (%s)",
- local->loc.path, local->loc2.path,
- prev->this->name, strerror (op_errno));
-
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- goto unwind;
- }
- /* TODO: construct proper stbuf for dir */
- /*
- * FIXME: is this the correct way to build stbuf and
- * parent bufs?
- */
- dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
- dht_iatt_merge (this, &local->preoldparent, preoldparent,
- prev->this);
- dht_iatt_merge (this, &local->postoldparent, postoldparent,
- prev->this);
- dht_iatt_merge (this, &local->preparent, prenewparent,
- prev->this);
- dht_iatt_merge (this, &local->postparent, postnewparent,
- prev->this);
-
- call_cnt = local->call_cnt = conf->subvolume_cnt - 1;
+ if (local->op_ret == -1)
+ goto err;
- if (!local->call_cnt)
- goto unwind;
+ local->call_cnt = conf->subvolume_cnt;
+ local->op_ret = 0;
for (i = 0; i < conf->subvolume_cnt; i++) {
- if (conf->subvolumes[i] == local->dst_hashed)
- continue;
STACK_WIND (frame, dht_rename_dir_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->rename,
- &local->loc, &local->loc2, NULL);
- if (!--call_cnt)
- break;
+ &local->loc, &local->loc2);
}
-
- return 0;
-unwind:
- WIPE (&local->preoldparent);
- WIPE (&local->postoldparent);
- WIPE (&local->preparent);
- WIPE (&local->postparent);
-
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
- DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
- &local->stbuf, &local->preoldparent,
- &local->postoldparent,
- &local->preparent, &local->postparent, NULL);
-
- return 0;
-}
-
-
-int
-dht_rename_dir_do (call_frame_t *frame, xlator_t *this)
-{
- dht_local_t *local = NULL;
-
- local = frame->local;
-
- if (local->op_ret == -1)
- goto err;
-
- local->op_ret = 0;
-
- STACK_WIND (frame, dht_rename_hashed_dir_cbk,
- local->dst_hashed,
- local->dst_hashed->fops->rename,
- &local->loc, &local->loc2, NULL);
return 0;
err:
DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
int
dht_rename_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int op_ret, int op_errno, gf_dirent_t *entries)
{
dht_local_t *local = NULL;
int this_call_cnt = -1;
@@ -219,7 +162,7 @@ dht_rename_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
dht_rename_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, fd_t *fd, dict_t *xdata)
+ int op_ret, int op_errno, fd_t *fd)
{
dht_local_t *local = NULL;
int this_call_cnt = -1;
@@ -239,7 +182,7 @@ dht_rename_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, dht_rename_readdir_cbk,
prev->this, prev->this->fops->readdir,
- local->fd, 4096, 0, NULL);
+ local->fd, 4096, 0);
return 0;
@@ -295,15 +238,14 @@ dht_rename_dir (call_frame_t *frame, xlator_t *this)
STACK_WIND (frame, dht_rename_opendir_cbk,
conf->subvolumes[i],
conf->subvolumes[i]->fops->opendir,
- &local->loc2, local->fd, NULL);
+ &local->loc2, local->fd);
}
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL, NULL);
+ DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -311,7 +253,7 @@ err:
int
dht_rename_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -340,11 +282,10 @@ dht_rename_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
WIPE (&local->postparent);
if (is_last_call (this_call_cnt)) {
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
&local->stbuf, &local->preoldparent,
&local->postoldparent, &local->preparent,
- &local->postparent, NULL);
+ &local->postparent);
}
out:
@@ -392,7 +333,7 @@ dht_rename_cleanup (call_frame_t *frame)
local->loc.path, dst_hashed->name, src_cached->name);
STACK_WIND (frame, dht_rename_unlink_cbk,
dst_hashed, dst_hashed->fops->unlink,
- &local->loc, 0, NULL);
+ &local->loc);
}
if (src_cached != dst_hashed) {
@@ -401,7 +342,7 @@ dht_rename_cleanup (call_frame_t *frame)
local->loc2.path, src_cached->name);
STACK_WIND (frame, dht_rename_unlink_cbk,
src_cached, src_cached->fops->unlink,
- &local->loc2, 0, NULL);
+ &local->loc2);
}
return 0;
@@ -412,36 +353,10 @@ nolinks:
WIPE (&local->preparent);
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
&local->stbuf, &local->preoldparent,
&local->postoldparent, &local->preparent,
- &local->postparent, NULL);
-
- return 0;
-}
-
-
-int
-dht_rename_links_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- call_frame_t *prev = NULL;
- dht_local_t *local = NULL;
-
- prev = cookie;
- local = frame->local;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "link/file %s on %s failed (%s)",
- local->loc.path, prev->this->name, strerror (op_errno));
- }
-
- DHT_STACK_DESTROY (frame);
+ &local->postparent);
return 0;
}
@@ -451,8 +366,7 @@ int
dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -461,8 +375,6 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
xlator_t *dst_hashed = NULL;
xlator_t *dst_cached = NULL;
xlator_t *rename_subvol = NULL;
- call_frame_t *link_frame = NULL;
- dht_local_t *link_local = NULL;
local = frame->local;
prev = cookie;
@@ -481,36 +393,20 @@ dht_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto cleanup;
}
- if ((src_cached == dst_cached) && (dst_hashed != dst_cached)) {
- link_frame = copy_frame (frame);
- if (!link_frame) {
- goto err;
- }
-
- /* fop value sent as maxvalue because it is not used
- anywhere in this case */
- link_local = dht_local_init (link_frame, &local->loc2, NULL,
- GF_FOP_MAXVALUE);
- if (!link_local) {
- goto err;
- }
-
- if (link_local->loc.inode)
- inode_unref (link_local->loc.inode);
- link_local->loc.inode = inode_ref (local->loc.inode);
- uuid_copy (link_local->gfid, local->loc.inode->gfid);
-
- dht_linkfile_create (link_frame, dht_rename_links_create_cbk,
- src_cached, dst_hashed, &link_local->loc);
- }
-
-err:
dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
dht_iatt_merge (this, &local->preoldparent, preoldparent, prev->this);
dht_iatt_merge (this, &local->postoldparent, postoldparent, prev->this);
dht_iatt_merge (this, &local->preparent, prenewparent, prev->this);
dht_iatt_merge (this, &local->postparent, postnewparent, prev->this);
+ local->stbuf.ia_ino = local->loc.inode->ino;
+
+ local->preoldparent.ia_ino = local->loc.parent->ino;
+ local->postoldparent.ia_ino = local->loc.parent->ino;
+
+ local->preparent.ia_ino = local->loc2.parent->ino;
+ local->postparent.ia_ino = local->loc2.parent->ino;
+
/* NOTE: rename_subvol is the same subvolume from which dht_rename_cbk
* is called. since rename has already happened on rename_subvol,
* unlink should not be sent for oldpath (either linkfile or cached-file)
@@ -541,7 +437,7 @@ err:
STACK_WIND (frame, dht_rename_unlink_cbk,
src_cached, src_cached->fops->unlink,
- &local->loc, 0, NULL);
+ &local->loc);
}
if (src_hashed != rename_subvol && src_hashed != src_cached) {
@@ -551,7 +447,7 @@ err:
STACK_WIND (frame, dht_rename_unlink_cbk,
src_hashed, src_hashed->fops->unlink,
- &local->loc, 0, NULL);
+ &local->loc);
}
if (dst_cached
@@ -563,7 +459,7 @@ err:
STACK_WIND (frame, dht_rename_unlink_cbk,
dst_cached, dst_cached->fops->unlink,
- &local->loc2, 0, NULL);
+ &local->loc2);
}
return 0;
@@ -573,11 +469,10 @@ unwind:
WIPE (&local->preparent);
WIPE (&local->postparent);
- DHT_STRIP_PHASE1_FLAGS (&local->stbuf);
DHT_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
&local->stbuf, &local->preoldparent,
&local->postoldparent, &local->preparent,
- &local->postparent, NULL);
+ &local->postparent);
return 0;
@@ -617,7 +512,7 @@ dht_do_rename (call_frame_t *frame)
STACK_WIND (frame, dht_rename_cbk,
rename_subvol, rename_subvol->fops->rename,
- &local->loc, &local->loc2, NULL);
+ &local->loc, &local->loc2);
return 0;
}
@@ -627,8 +522,7 @@ int
dht_rename_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -643,8 +537,7 @@ dht_rename_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"link/file on %s failed (%s)",
prev->this->name, strerror (op_errno));
local->op_ret = -1;
- if (op_errno != ENOENT)
- local->op_errno = op_errno;
+ local->op_errno = op_errno;
}
this_call_cnt = dht_frame_return (frame);
@@ -665,42 +558,6 @@ cleanup:
int
-dht_rename_unlink_links_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
-{
- dht_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
-
- local = frame->local;
- prev = cookie;
-
- if ((op_ret == -1) && (op_errno != ENOENT)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "unlink of %s on %s failed (%s)",
- local->loc2.path, prev->this->name,
- strerror (op_errno));
- local->op_ret = -1;
- local->op_errno = op_errno;
- }
-
- if (local->op_ret == -1)
- goto cleanup;
-
- dht_do_rename (frame);
-
- return 0;
-
-cleanup:
- dht_rename_cleanup (frame);
-
- return 0;
-}
-
-
-int
dht_rename_create_links (call_frame_t *frame)
{
dht_local_t *local = NULL;
@@ -720,20 +577,8 @@ dht_rename_create_links (call_frame_t *frame)
dst_hashed = local->dst_hashed;
dst_cached = local->dst_cached;
-
- if (src_cached == dst_cached) {
- if (dst_hashed == dst_cached)
- goto nolinks;
-
- gf_log (this->name, GF_LOG_TRACE,
- "unlinking dst linkfile %s @ %s",
- local->loc2.path, dst_hashed->name);
-
- STACK_WIND (frame, dht_rename_unlink_links_cbk,
- dst_hashed, dst_hashed->fops->unlink,
- &local->loc2, 0, NULL);
- return 0;
- }
+ if (src_cached == dst_cached)
+ goto nolinks;
if (dst_hashed != src_hashed && dst_hashed != src_cached)
call_cnt++;
@@ -748,18 +593,18 @@ dht_rename_create_links (call_frame_t *frame)
"linkfile %s @ %s => %s",
local->loc.path, dst_hashed->name, src_cached->name);
memcpy (local->gfid, local->loc.inode->gfid, 16);
- dht_linkfile_create (frame, dht_rename_links_cbk,
- src_cached, dst_hashed, &local->loc);
- }
-
- if (src_cached != dst_hashed) {
- gf_log (this->name, GF_LOG_TRACE,
- "link %s => %s (%s)", local->loc.path,
- local->loc2.path, src_cached->name);
- STACK_WIND (frame, dht_rename_links_cbk,
- src_cached, src_cached->fops->link,
- &local->loc, &local->loc2, NULL);
- }
+ dht_linkfile_create (frame, dht_rename_links_cbk,
+ src_cached, dst_hashed, &local->loc);
+ }
+
+ if (src_cached != dst_hashed) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "link %s => %s (%s)", local->loc.path,
+ local->loc2.path, src_cached->name);
+ STACK_WIND (frame, dht_rename_links_cbk,
+ src_cached, src_cached->fops->link,
+ &local->loc, &local->loc2);
+ }
nolinks:
if (!call_cnt) {
@@ -773,7 +618,7 @@ nolinks:
int
dht_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
xlator_t *src_cached = NULL;
xlator_t *src_hashed = NULL;
@@ -818,14 +663,17 @@ dht_rename (call_frame_t *frame, xlator_t *this,
if (newloc->inode)
dst_cached = dht_subvol_get_cached (this, newloc->inode);
- local = dht_local_init (frame, oldloc, NULL, GF_FOP_RENAME);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
- /* cached_subvol will be set from dht_local_init, reset it to NULL,
- as the logic of handling rename is different */
- local->cached_subvol = NULL;
+
+ ret = loc_copy (&local->loc, oldloc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
ret = loc_copy (&local->loc2, newloc);
if (ret == -1) {
@@ -855,8 +703,7 @@ dht_rename (call_frame_t *frame, xlator_t *this,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
- NULL, NULL);
+ DHT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
return 0;
}
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
index 8b7d15ce5..ddd043dc8 100644
--- a/xlators/cluster/dht/src/dht-selfheal.c
+++ b/xlators/cluster/dht/src/dht-selfheal.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -18,51 +27,6 @@
#include "xlator.h"
#include "dht-common.h"
-#define DHT_SET_LAYOUT_RANGE(layout,i,srt,chunk,cnt,path) do { \
- layout->list[i].start = srt; \
- layout->list[i].stop = srt + chunk - 1; \
- \
- gf_log (this->name, GF_LOG_TRACE, \
- "gave fix: %u - %u on %s for %s", \
- layout->list[i].start, layout->list[i].stop, \
- layout->list[i].xlator->name, path); \
- } while (0)
-
-static inline uint32_t
-dht_find_overlap (int idx, int cnk_idx, uint32_t start, uint32_t stop,
- uint32_t chunk_size)
-{
- uint32_t overlap = 0;
- uint32_t chunk_begin = 0;
-
- chunk_begin = cnk_idx * chunk_size;
-
- /* There is no chance of overlap */
- if ((chunk_begin > stop) ||
- ((chunk_begin + chunk_size) < start))
- goto out;
-
- if ((chunk_begin <= start) &&
- ((chunk_begin + chunk_size) <= stop)) {
- overlap = ((chunk_begin + chunk_size) - start);
- goto out;
- }
-
- if ((chunk_begin <= start) &&
- ((chunk_begin + chunk_size) >= stop)) {
- overlap = (stop - start);
- goto out;
- }
-
- if ((chunk_begin < stop) &&
- ((chunk_begin + chunk_size) >= stop)) {
- overlap = (stop - chunk_begin);
- goto out;
- }
-
-out:
- return overlap;
-}
int
dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
@@ -71,7 +35,7 @@ dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
local = frame->local;
local->selfheal.dir_cbk (frame, NULL, frame->this, ret,
- local->op_errno, NULL);
+ local->op_errno);
return 0;
}
@@ -79,7 +43,7 @@ dht_selfheal_dir_finish (call_frame_t *frame, xlator_t *this, int ret)
int
dht_selfheal_dir_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xdata)
+ int op_ret, int op_errno)
{
dht_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -125,18 +89,11 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
int ret = 0;
xlator_t *this = NULL;
int32_t *disk_layout = NULL;
- dht_local_t *local = NULL;
- local = frame->local;
subvol = layout->list[i].xlator;
this = frame->this;
- GF_VALIDATE_OR_GOTO ("", this, err);
- GF_VALIDATE_OR_GOTO (this->name, layout, err);
- GF_VALIDATE_OR_GOTO (this->name, local, err);
- GF_VALIDATE_OR_GOTO (this->name, subvol, err);
-
xattr = get_new_dict ();
if (!xattr) {
goto err;
@@ -167,12 +124,9 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
dict_ref (xattr);
- if (!uuid_is_null (local->gfid))
- uuid_copy (loc->gfid, local->gfid);
-
STACK_WIND (frame, dht_selfheal_dir_xattr_cbk,
subvol, subvol->fops->setxattr,
- loc, xattr, 0, NULL);
+ loc, xattr, 0);
dict_unref (xattr);
@@ -182,37 +136,14 @@ err:
if (xattr)
dict_destroy (xattr);
- GF_FREE (disk_layout);
+ if (disk_layout)
+ GF_FREE (disk_layout);
dht_selfheal_dir_xattr_cbk (frame, subvol, frame->this,
- -1, ENOMEM, NULL);
+ -1, ENOMEM);
return 0;
}
-int
-dht_fix_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
-{
- dht_local_t *local = NULL;
- int i = 0;
- int count = 0;
- xlator_t *this = NULL;
-
- local = frame->local;
- this = frame->this;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "writing the new range for all subvolumes");
-
- local->call_cnt = count = layout->cnt;
-
- for (i = 0; i < layout->cnt; i++) {
- dht_selfheal_dir_xattr_persubvol (frame, loc, layout, i);
-
- if (--count == 0)
- break;
- }
- return 0;
-}
int
dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
@@ -228,7 +159,7 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
for (i = 0; i < layout->cnt; i++) {
if (layout->list[i].err != -1 || !layout->list[i].stop) {
/* err != -1 would mean xattr present on the directory
- * or the directory is non existent.
+ * or the directory is itself non existant.
* !layout->list[i].stop would mean layout absent
*/
@@ -263,7 +194,7 @@ dht_selfheal_dir_xattr (call_frame_t *frame, loc_t *loc, dht_layout_t *layout)
int
dht_selfheal_dir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
dht_local_t *local = NULL;
dht_layout_t *layout = NULL;
@@ -304,9 +235,6 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
return 0;
}
- if (!uuid_is_null (local->gfid))
- uuid_copy (loc->gfid, local->gfid);
-
local->call_cnt = missing_attr;
for (i = 0; i < layout->cnt; i++) {
if (layout->list[i].err == -1) {
@@ -317,7 +245,7 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
STACK_WIND (frame, dht_selfheal_dir_setattr_cbk,
layout->list[i].xlator,
layout->list[i].xlator->fops->setattr,
- loc, stbuf, valid, NULL);
+ loc, stbuf, valid);
}
}
@@ -328,8 +256,7 @@ int
dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
dht_local_t *local = NULL;
dht_layout_t *layout = NULL;
@@ -362,6 +289,9 @@ dht_selfheal_dir_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
+ if (prev->this == local->hashed_subvol)
+ local->ia_ino = local->stbuf.ia_ino;
+
dht_iatt_merge (this, &local->preparent, preparent, prev->this);
dht_iatt_merge (this, &local->postparent, postparent, prev->this);
@@ -375,46 +305,6 @@ out:
return 0;
}
-void
-dht_selfheal_dir_mkdir_setacl (dict_t *xattr, dict_t *dict)
-{
- data_t *acl_default = NULL;
- data_t *acl_access = NULL;
- xlator_t *this = NULL;
- int ret = -1;
-
- GF_ASSERT (xattr);
- GF_ASSERT (dict);
-
- this = THIS;
- GF_ASSERT (this);
-
- acl_default = dict_get (xattr, POSIX_ACL_DEFAULT_XATTR);
-
- if (!acl_default) {
- gf_log (this->name, GF_LOG_DEBUG,
- "ACL_DEFAULT xattr not present");
- goto cont;
- }
- ret = dict_set (dict, POSIX_ACL_DEFAULT_XATTR, acl_default);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "Could not set ACL_DEFAULT xattr");
-cont:
- acl_access = dict_get (xattr, POSIX_ACL_ACCESS_XATTR);
- if (!acl_access) {
- gf_log (this->name, GF_LOG_DEBUG,
- "ACL_ACCESS xattr not present");
- goto out;
- }
- ret = dict_set (dict, POSIX_ACL_ACCESS_XATTR, acl_access);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "Could not set ACL_ACCESS xattr");
-
-out:
- return;
-}
int
dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
@@ -448,19 +338,16 @@ dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
ret = dict_set_static_bin (dict, "gfid-req", local->gfid, 16);
if (ret)
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"%s: failed to set gfid in dict", loc->path);
} else if (local->params) {
/* Send the dictionary from higher layers directly */
dict = dict_ref (local->params);
}
- /* Set acls */
- if (local->xattr && dict)
- dht_selfheal_dir_mkdir_setacl (local->xattr, dict);
if (!dict)
- gf_log (this->name, GF_LOG_WARNING,
- "dict is NULL, need to make sure gfids are same");
+ gf_log (this->name, GF_LOG_DEBUG,
+ "dict is NULL, need to make sure gfid's are same");
for (i = 0; i < layout->cnt; i++) {
if (layout->list[i].err == ENOENT || force) {
@@ -474,7 +361,7 @@ dht_selfheal_dir_mkdir (call_frame_t *frame, loc_t *loc,
loc,
st_mode_from_ia (local->stbuf.ia_prot,
local->stbuf.ia_type),
- 0, dict);
+ dict);
}
}
@@ -501,229 +388,40 @@ dht_selfheal_layout_alloc_start (xlator_t *this, loc_t *loc,
return start;
}
-static inline int
-dht_get_layout_count (xlator_t *this, dht_layout_t *layout, int new_layout)
+
+void
+dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
+ dht_layout_t *layout)
{
- int i = 0;
- int j = 0;
- int err = 0;
- int count = 0;
- dht_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ uint32_t chunk = 0;
+ int i = 0;
+ uint32_t start = 0;
+ int cnt = 0;
+ int err = 0;
+ int start_subvol = 0;
- /* Gets in use only for replace-brick, remove-brick */
- conf = this->private;
- for (i = 0; i < layout->cnt; i++) {
- for (j = 0; j < conf->subvolume_cnt; j++) {
- if (conf->decommissioned_bricks[j] &&
- conf->decommissioned_bricks[j] == layout->list[i].xlator) {
- layout->list[i].err = -EINVAL;
- break;
- }
- }
- }
+ this = frame->this;
for (i = 0; i < layout->cnt; i++) {
err = layout->list[i].err;
if (err == -1 || err == 0) {
layout->list[i].err = -1;
- count++;
+ cnt++;
}
}
/* no subvolume has enough space, but can't stop directory creation */
- if (!count || !new_layout) {
+ if (!cnt) {
for (i = 0; i < layout->cnt; i++) {
err = layout->list[i].err;
if (err == ENOSPC) {
layout->list[i].err = -1;
- count++;
- }
- }
- }
-
- count = ((layout->spread_cnt) ? layout->spread_cnt :
- ((count) ? count : 1));
-
- return count;
-}
-
-
-dht_layout_t *
-dht_fix_layout_of_directory (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout)
-{
- uint32_t chunk = 0;
- uint32_t start = 0;
- uint32_t stop = 0;
- uint32_t overlap = 0;
- uint32_t max_overlap = 0;
- uint32_t chunk_begin = 0;
- int count = 0;
- int cnt = 0;
- int i = 0;
- int j = 0;
- int k = 0;
- int loop_cnt = 0;
- int start_subvol = 0;
- int *fix_array = NULL;
- xlator_t *this = NULL;
- dht_layout_t *new_layout = NULL;
- dht_conf_t *priv = NULL;
- dht_local_t *local = NULL;
-
- this = frame->this;
- priv = this->private;
- local = frame->local;
-
- if (layout->type == DHT_HASH_TYPE_DM_USER) {
- gf_log (THIS->name, GF_LOG_DEBUG, "leaving %s alone",
- loc->path);
- goto done;
- }
-
- count = cnt = dht_get_layout_count (this, layout, 0);
-
- chunk = ((unsigned long) 0xffffffff) / ((cnt) ? cnt : 1);
-
- start_subvol = dht_selfheal_layout_alloc_start (this, loc, layout);
-
- fix_array = GF_CALLOC (sizeof (int), layout->cnt, gf_common_mt_char);
- if (!fix_array) {
- /* No fix, use the existing layout itself */
- goto done;
- }
-
- new_layout = dht_layout_new (this, priv->subvolume_cnt);
- if (!new_layout)
- goto done;
-
- for (i = 0; i < new_layout->cnt; i++) {
- /* TODO: fix this in layout_alloc() itself */
- new_layout->list[i].err = -ENOENT;
- if (i < layout->cnt)
- new_layout->list[i].xlator = layout->list[i].xlator;
- }
-
- /* Check if there are any overlap in layout, and give the proper fix */
- for (i = 0; i < layout->cnt; i++) {
- /* No need to fix if 'err' is not '-1' */
- if (layout->list[i].err != -1)
- continue;
-
- /* If already existing layout is having no range, skip it */
- start = layout->list[i].start;
- stop = layout->list[i].stop;
- if ((stop - start) == 0)
- continue;
-
- max_overlap = 0;
-
- /* 'j' is used as starting point of each chunk */
- for (j = 1; j <= count; j++) {
- /* if chunk is already used, don't use it again */
- for (k = 0; k < i; k++)
- if (j == fix_array[k])
- break;
- if (k < i)
- continue;
-
- overlap = dht_find_overlap (i, (j-1), start, stop, chunk);
- if (max_overlap < overlap) {
- max_overlap = overlap;
- fix_array[i] = j;
+ cnt++;
}
}
-
- /* If we have any overlap, then use that itself as new
- layout for the subvolume */
- if (fix_array[i]) {
- chunk_begin = chunk * (fix_array[i] - 1);
- new_layout->list[i].err = -1;
- DHT_SET_LAYOUT_RANGE (new_layout, i, chunk_begin,
- chunk, cnt, loc->path);
- /* make sure to give (max - 1) as 'stop' range,
- if it is last chunk */
- if (fix_array[i] == count)
- new_layout->list[i].stop = 0xffffffff;
- if (--cnt == 0)
- goto done;
-
- }
}
- /* Now, look for layouts which are not having any overlaps
- and give it a fix */
- for (loop_cnt = 0, i = start_subvol; loop_cnt < new_layout->cnt;
- i++, loop_cnt++) {
- if (i == new_layout->cnt)
- i = 0;
-
- /* If 'fix_array[i]' is set, the layout is already fixed. */
- if (fix_array[i])
- continue;
-
- if (layout->list[i].err != -1) {
- new_layout->list[i].err = layout->list[i].err;
- continue;
- }
-
- for (k = 1; k <= count; k++) {
- for (j = 0; j < new_layout->cnt; j++) {
- if (k == fix_array[j])
- break;
- }
- /* Didn't find any of the list begining with 'k' */
- if (j == new_layout->cnt)
- break;
- }
-
- fix_array[i] = k;
- chunk_begin = (k - 1) * chunk;
- new_layout->list[i].err = -1;
- DHT_SET_LAYOUT_RANGE (new_layout, i, chunk_begin, chunk, cnt,
- loc->path);
- /* make sure to give (max - 1) as 'stop' range,
- if it is last chunk */
- if (k == count)
- new_layout->list[i].stop = 0xffffffff;
- if (--cnt == 0)
- goto done;
- }
-
-done:
- if (new_layout) {
- /* Now that the new layout has all the proper layout, change the
- inode context */
- dht_layout_set (this, loc->inode, new_layout);
-
- /* Make sure the extra 'ref' for existing layout is removed */
- dht_layout_unref (this, local->layout);
-
- local->layout = new_layout;
- }
-
- GF_FREE (fix_array);
-
- return local->layout;
-}
-
-
-void
-dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
- dht_layout_t *layout)
-{
- xlator_t *this = NULL;
- uint32_t chunk = 0;
- int i = 0;
- uint32_t start = 0;
- int cnt = 0;
- int err = 0;
- int start_subvol = 0;
-
- this = frame->this;
-
- cnt = dht_get_layout_count (this, layout, 1);
-
chunk = ((unsigned long) 0xffffffff) / ((cnt) ? cnt : 1);
start_subvol = dht_selfheal_layout_alloc_start (this, loc, layout);
@@ -731,33 +429,43 @@ dht_selfheal_layout_new_directory (call_frame_t *frame, loc_t *loc,
for (i = start_subvol; i < layout->cnt; i++) {
err = layout->list[i].err;
if (err == -1) {
- DHT_SET_LAYOUT_RANGE(layout, i, start, chunk,
- cnt, loc->path);
+ layout->list[i].start = start;
+ layout->list[i].stop = start + chunk - 1;
+
+ start = start + chunk;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "gave fix: %u - %u on %s for %s",
+ layout->list[i].start, layout->list[i].stop,
+ layout->list[i].xlator->name, loc->path);
if (--cnt == 0) {
layout->list[i].stop = 0xffffffff;
- goto done;
+ break;
}
- start += chunk;
}
}
for (i = 0; i < start_subvol; i++) {
err = layout->list[i].err;
if (err == -1) {
- DHT_SET_LAYOUT_RANGE(layout, i, start, chunk,
- cnt, loc->path);
+ layout->list[i].start = start;
+ layout->list[i].stop = start + chunk - 1;
+
+ start = start + chunk;
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "gave fix: %u - %u on %s for %s",
+ layout->list[i].start, layout->list[i].stop,
+ layout->list[i].xlator->name, loc->path);
if (--cnt == 0) {
layout->list[i].stop = 0xffffffff;
- goto done;
+ break;
}
- start += chunk;
}
}
-
-done:
- return;
}
+
int
dht_selfheal_dir_getafix (call_frame_t *frame, loc_t *loc,
dht_layout_t *layout)
@@ -827,32 +535,13 @@ dht_selfheal_new_directory (call_frame_t *frame,
return 0;
}
-int
-dht_fix_directory_layout (call_frame_t *frame,
- dht_selfheal_dir_cbk_t dir_cbk,
- dht_layout_t *layout)
-{
- dht_local_t *local = NULL;
- dht_layout_t *tmp_layout = NULL;
-
- local = frame->local;
-
- local->selfheal.dir_cbk = dir_cbk;
- local->selfheal.layout = dht_layout_ref (frame->this, layout);
-
- /* No layout sorting required here */
- tmp_layout = dht_fix_layout_of_directory (frame, &local->loc, layout);
- dht_fix_dir_xattr (frame, &local->loc, tmp_layout);
-
- return 0;
-}
-
int
dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
loc_t *loc, dht_layout_t *layout)
{
dht_local_t *local = NULL;
+ uint32_t holes = 0;
uint32_t down = 0;
uint32_t misc = 0;
int ret = 0;
@@ -868,6 +557,7 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
&local->selfheal.down,
&local->selfheal.misc);
+ holes = local->selfheal.hole_cnt;
down = local->selfheal.down;
misc = local->selfheal.misc;
@@ -875,14 +565,14 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
local->selfheal.layout = dht_layout_ref (this, layout);
if (down) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"%d subvolumes down -- not fixing", down);
ret = 0;
goto sorry_no_fix;
}
if (misc) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"%d subvolumes have unrecoverable errors", misc);
ret = 0;
goto sorry_no_fix;
@@ -892,7 +582,7 @@ dht_selfheal_directory (call_frame_t *frame, dht_selfheal_dir_cbk_t dir_cbk,
ret = dht_selfheal_dir_getafix (frame, loc, layout);
if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_INFO,
"not able to form layout for the directory");
goto sorry_no_fix;
}
diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c
index 6b156c1d3..57c3072cd 100644
--- a/xlators/cluster/dht/src/dht.c
+++ b/xlators/cluster/dht/src/dht.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -17,7 +26,7 @@
/* TODO: add NS locking */
#include "statedump.h"
-#include "dht-common.h"
+#include "dht-common.c"
/* TODO:
- use volumename in xattr instead of "dht"
@@ -25,7 +34,7 @@
- handle all cases in self heal layout reconstruction
- complete linkfile selfheal
*/
-struct volume_options options[];
+
void
dht_layout_dump (dht_layout_t *layout, const char *prefix)
@@ -97,48 +106,59 @@ dht_priv_dump (xlator_t *this)
gf_proc_dump_add_section("xlator.cluster.dht.%s.priv", this->name);
gf_proc_dump_build_key(key_prefix,"xlator.cluster.dht","%s.priv",
this->name);
- gf_proc_dump_write("subvol_cnt","%d", conf->subvolume_cnt);
+ gf_proc_dump_build_key(key, key_prefix, "subvolume_cnt");
+ gf_proc_dump_write(key,"%d", conf->subvolume_cnt);
for (i = 0; i < conf->subvolume_cnt; i++) {
- sprintf (key, "subvolumes[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix, "subvolumes[%d]", i);
gf_proc_dump_write(key, "%s.%s", conf->subvolumes[i]->type,
conf->subvolumes[i]->name);
if (conf->file_layouts && conf->file_layouts[i]){
- sprintf (key, "file_layouts[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix,
+ "file_layouts[%d]",i);
dht_layout_dump(conf->file_layouts[i], key);
}
if (conf->dir_layouts && conf->dir_layouts[i]) {
- sprintf (key, "dir_layouts[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix,
+ "dir_layouts[%d]",i);
dht_layout_dump(conf->dir_layouts[i], key);
}
if (conf->subvolume_status) {
-
- sprintf (key, "subvolume_status[%d]", i);
+ gf_proc_dump_build_key(key, key_prefix,
+ "subvolume_status[%d]", i);
gf_proc_dump_write(key, "%d",
(int)conf->subvolume_status[i]);
}
}
- gf_proc_dump_write("search_unhashed", "%d", conf->search_unhashed);
- gf_proc_dump_write("gen", "%d", conf->gen);
- gf_proc_dump_write("min_free_disk", "%lu", conf->min_free_disk);
- gf_proc_dump_write("min_free_inodes", "%lu", conf->min_free_inodes);
- gf_proc_dump_write("disk_unit", "%c", conf->disk_unit);
- gf_proc_dump_write("refresh_interval", "%d", conf->refresh_interval);
- gf_proc_dump_write("unhashed_sticky_bit", "%d", conf->unhashed_sticky_bit);
+ gf_proc_dump_build_key(key, key_prefix,"default_dir_layout");
+ dht_layout_dump(conf->default_dir_layout, key);
+
+ gf_proc_dump_build_key(key, key_prefix, "search_unhashed");
+ gf_proc_dump_write(key, "%d", conf->search_unhashed);
+ gf_proc_dump_build_key(key, key_prefix, "gen");
+ gf_proc_dump_write(key, "%d", conf->gen);
+ gf_proc_dump_build_key(key, key_prefix, "min_free_disk");
+ gf_proc_dump_write(key, "%lu", conf->min_free_disk);
+ gf_proc_dump_build_key(key, key_prefix, "disk_unit");
+ gf_proc_dump_write(key, "%c", conf->disk_unit);
+ gf_proc_dump_build_key(key, key_prefix, "refresh_interval");
+ gf_proc_dump_write(key, "%d", conf->refresh_interval);
+ gf_proc_dump_build_key(key, key_prefix, "unhashed_sticky_bit");
+ gf_proc_dump_write(key, "%d", conf->unhashed_sticky_bit);
if (conf ->du_stats) {
- gf_proc_dump_write("du_stats.avail_percent", "%lf",
- conf->du_stats->avail_percent);
- gf_proc_dump_write("du_stats.avail_space", "%lu",
- conf->du_stats->avail_space);
- gf_proc_dump_write("du_stats.avail_inodes", "%lf",
- conf->du_stats->avail_inodes);
- gf_proc_dump_write("du_stats.log", "%lu", conf->du_stats->log);
+ gf_proc_dump_build_key(key, key_prefix,
+ "du_stats.avail_percent");
+ gf_proc_dump_write(key, "%lf", conf->du_stats->avail_percent);
+ gf_proc_dump_build_key(key, key_prefix,
+ "du_stats.avail_space");
+ gf_proc_dump_write(key, "%lu", conf->du_stats->avail_space);
+ gf_proc_dump_build_key(key, key_prefix,
+ "du_stats.log");
+ gf_proc_dump_write(key, "%lu", conf->du_stats->log);
}
-
- if (conf->last_stat_fetch.tv_sec)
- gf_proc_dump_write("last_stat_fetch", "%s",
- ctime(&conf->last_stat_fetch.tv_sec));
+ gf_proc_dump_build_key(key, key_prefix, "last_stat_fetch");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_stat_fetch.tv_sec));
UNLOCK(&conf->subvolume_lock);
@@ -150,6 +170,7 @@ int32_t
dht_inodectx_dump (xlator_t *this, inode_t *inode)
{
int ret = -1;
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
dht_layout_t *layout = NULL;
uint64_t tmp_layout = 0;
@@ -166,8 +187,9 @@ dht_inodectx_dump (xlator_t *this, inode_t *inode)
if (!layout)
return -1;
- gf_proc_dump_add_section("xlator.cluster.dht.%s.inode", this->name);
- dht_layout_dump(layout, "layout");
+ gf_proc_dump_build_key(key_prefix, "xlator.cluster.dht",
+ "%s.inode.%ld", this->name, inode->ino);
+ dht_layout_dump(layout, key_prefix);
out:
return ret;
@@ -176,20 +198,11 @@ out:
int
notify (xlator_t *this, int event, void *data, ...)
{
- int ret = -1;
- va_list ap;
- dict_t *output = NULL;
+ int ret = -1;
GF_VALIDATE_OR_GOTO ("dht", this, out);
-
- if (!data)
- goto out;
-
- va_start (ap, data);
- output = va_arg (ap, dict_t*);
-
- ret = dht_notify (this, event, data, output);
+ ret = dht_notify (this, event, data);
out:
return ret;
@@ -213,9 +226,14 @@ fini (xlator_t *this)
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
GF_FREE (conf);
}
@@ -241,44 +259,31 @@ out:
return ret;
}
-
int
-dht_parse_decommissioned_bricks (xlator_t *this, dht_conf_t *conf,
- const char *bricks)
+validate_options (xlator_t *this, char **op_errstr)
{
- int i = 0;
- int ret = -1;
- char *tmpstr = NULL;
- char *dup_brick = NULL;
- char *node = NULL;
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- if (!conf || !bricks)
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
goto out;
+ }
- dup_brick = gf_strdup (bricks);
- node = strtok_r (dup_brick, ",", &tmpstr);
- while (node) {
- for (i = 0; i < conf->subvolume_cnt; i++) {
- if (!strcmp (conf->subvolumes[i]->name, node)) {
- conf->decommissioned_bricks[i] =
- conf->subvolumes[i];
- gf_log (this->name, GF_LOG_INFO,
- "decommissioning subvolume %s",
- conf->subvolumes[i]->name);
- break;
- }
- }
- if (i == conf->subvolume_cnt) {
- /* Wrong node given. */
- goto out;
- }
- node = strtok_r (NULL, ",", &tmpstr);
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
}
- ret = 0;
- conf->decommission_in_progress = 1;
out:
- GF_FREE (dup_brick);
return ret;
}
@@ -289,6 +294,7 @@ reconfigure (xlator_t *this, dict_t *options)
dht_conf_t *conf = NULL;
char *temp_str = NULL;
gf_boolean_t search_unhashed;
+ uint32_t temp_free_disk = 0;
int ret = -1;
GF_VALIDATE_OR_GOTO ("dht", this, out);
@@ -303,12 +309,12 @@ reconfigure (xlator_t *this, dict_t *options)
if (strcasecmp (temp_str, "auto")) {
if (!gf_string2boolean (temp_str, &search_unhashed)) {
gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:"
- " lookup-unhashed reconfigured (%s)",
+ " lookup-unahashed reconfigured (%s)",
temp_str);
conf->search_unhashed = search_unhashed;
} else {
gf_log(this->name, GF_LOG_ERROR, "Reconfigure:"
- " lookup-unhashed should be boolean,"
+ " lookup-unahashed should be boolean,"
" not (%s), defaulting to (%d)",
temp_str, conf->search_unhashed);
//return -1;
@@ -317,46 +323,42 @@ reconfigure (xlator_t *this, dict_t *options)
}
} else {
gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:"
- " lookup-unhashed reconfigured auto ");
+ " lookup-unahashed reconfigured auto ");
conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
}
}
- GF_OPTION_RECONF ("min-free-disk", conf->min_free_disk, options,
- percent_or_size, out);
- GF_OPTION_RECONF ("min-free-inodes", conf->min_free_inodes, options,
- percent, out);
- GF_OPTION_RECONF ("directory-layout-spread", conf->dir_spread_cnt,
- options, uint32, out);
-
- if (conf->defrag) {
- GF_OPTION_RECONF ("rebalance-stats", conf->defrag->stats,
- options, bool, out);
- }
+ if (dict_get_str (options, "min-free-disk", &temp_str) == 0) {
+ if (gf_string2percent (temp_str, &temp_free_disk) == 0) {
+ if (temp_free_disk > 100) {
+ gf_string2bytesize (temp_str,
+ &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ } else {
+ conf->min_free_disk = (uint64_t)temp_free_disk;
+ }
+ } else {
+ gf_string2bytesize (temp_str, &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ }
- if (dict_get_str (options, "decommissioned-bricks", &temp_str) == 0) {
- ret = dht_parse_decommissioned_bricks (this, conf, temp_str);
- if (ret == -1)
- goto out;
+ gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:"
+ " min-free-disk reconfigured to %s",
+ temp_str);
}
-
ret = 0;
out:
return ret;
}
-
int
init (xlator_t *this)
{
- dht_conf_t *conf = NULL;
- char *temp_str = NULL;
- int ret = -1;
- int i = 0;
- gf_defrag_info_t *defrag = NULL;
- int cmd = 0;
- char *node_uuid = NULL;
-
+ dht_conf_t *conf = NULL;
+ char *temp_str = NULL;
+ int ret = -1;
+ int i = 0;
+ uint32_t temp_free_disk = 0;
GF_VALIDATE_OR_GOTO ("dht", this, err);
@@ -376,38 +378,6 @@ init (xlator_t *this)
goto err;
}
- ret = dict_get_int32 (this->options, "rebalance-cmd", &cmd);
-
- if (cmd) {
- defrag = GF_CALLOC (1, sizeof (gf_defrag_info_t),
- gf_defrag_info_mt);
-
- GF_VALIDATE_OR_GOTO (this->name, defrag, err);
-
- LOCK_INIT (&defrag->lock);
-
- defrag->is_exiting = 0;
-
- conf->defrag = defrag;
-
- ret = dict_get_str (this->options, "node-uuid", &node_uuid);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "node-uuid not "
- "specified");
- goto err;
- }
-
- if (uuid_parse (node_uuid, defrag->node_uuid)) {
- gf_log (this->name, GF_LOG_ERROR, "Cannot parse "
- "glusterd node uuid");
- goto err;
- }
-
- defrag->cmd = cmd;
-
- defrag->stats = _gf_false;
- }
-
conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON;
if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) {
/* If option is not "auto", other options _should_ be boolean */
@@ -417,26 +387,51 @@ init (xlator_t *this)
conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO;
}
- GF_OPTION_INIT ("unhashed-sticky-bit", conf->unhashed_sticky_bit, bool,
- err);
+ conf->unhashed_sticky_bit = 0;
- GF_OPTION_INIT ("use-readdirp", conf->use_readdirp, bool, err);
+ if (dict_get_str (this->options, "unhashed-sticky-bit",
+ &temp_str) == 0) {
+ gf_string2boolean (temp_str, &conf->unhashed_sticky_bit);
+ }
- GF_OPTION_INIT ("min-free-disk", conf->min_free_disk, percent_or_size,
- err);
+ conf->use_readdirp = 1;
- GF_OPTION_INIT ("min-free-inodes", conf->min_free_inodes, percent,
- err);
+ if (dict_get_str (this->options, "use-readdirp",
+ &temp_str) == 0) {
+ gf_string2boolean (temp_str, &conf->use_readdirp);
+ }
- conf->dir_spread_cnt = conf->subvolume_cnt;
- GF_OPTION_INIT ("directory-layout-spread", conf->dir_spread_cnt,
- uint32, err);
+ conf->disk_unit = 'p';
+ conf->min_free_disk = 10;
- GF_OPTION_INIT ("assert-no-child-down", conf->assert_no_child_down,
- bool, err);
+ if (dict_get_str (this->options, "min-free-disk", &temp_str) == 0) {
+ if (gf_string2percent (temp_str, &temp_free_disk) == 0) {
+ if (temp_free_disk > 100) {
+ gf_string2bytesize (temp_str,
+ &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ } else {
+ conf->min_free_disk = (uint64_t)temp_free_disk;
+ }
+ } else {
+ gf_string2bytesize (temp_str, &conf->min_free_disk);
+ conf->disk_unit = 'b';
+ }
+ }
- if (defrag) {
- GF_OPTION_INIT ("rebalance-stats", defrag->stats, bool, err);
+ conf->assert_no_child_down = 0;
+
+ ret = dict_get_str_boolean (this->options, "assert-no-child-down", 0);
+ if (ret != -1) {
+ if (conf->assert_no_child_down != ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Changing assert-no-child-down from %d to %d",
+ conf->assert_no_child_down, ret);
+ }
+ conf->assert_no_child_down = ret;
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'assert-no-child-down' takes only boolean arguments");
}
ret = dht_init_subvolumes (this, conf);
@@ -444,29 +439,22 @@ init (xlator_t *this)
goto err;
}
- if (dict_get_str (this->options, "decommissioned-bricks", &temp_str) == 0) {
- ret = dht_parse_decommissioned_bricks (this, conf, temp_str);
- if (ret == -1)
- goto err;
- }
-
ret = dht_layouts_init (this, conf);
if (ret == -1) {
goto err;
}
+ conf->du_stats = GF_CALLOC (conf->subvolume_cnt, sizeof (dht_du_t),
+ gf_dht_mt_dht_du_t);
+ if (!conf->du_stats) {
+ goto err;
+ }
+
LOCK_INIT (&conf->subvolume_lock);
LOCK_INIT (&conf->layout_lock);
conf->gen = 1;
- this->local_pool = mem_pool_new (dht_local_t, 512);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto err;
- }
-
this->private = conf;
return 0;
@@ -480,13 +468,17 @@ err:
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
- GF_FREE (conf->du_stats);
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
- GF_FREE (conf->defrag);
+ if (conf->du_stats)
+ GF_FREE (conf->du_stats);
GF_FREE (conf);
}
@@ -500,8 +492,23 @@ struct xlator_fops fops = {
.mknod = dht_mknod,
.create = dht_create,
+ .stat = dht_stat,
+ .fstat = dht_fstat,
+ .truncate = dht_truncate,
+ .ftruncate = dht_ftruncate,
+ .access = dht_access,
+ .readlink = dht_readlink,
+ .setxattr = dht_setxattr,
+ .fsetxattr = dht_fsetxattr,
+ .getxattr = dht_getxattr,
+ .removexattr = dht_removexattr,
.open = dht_open,
+ .readv = dht_readv,
+ .writev = dht_writev,
+ .flush = dht_flush,
+ .fsync = dht_fsync,
.statfs = dht_statfs,
+ .lk = dht_lk,
.opendir = dht_opendir,
.readdir = dht_readdir,
.readdirp = dht_readdirp,
@@ -512,31 +519,10 @@ struct xlator_fops fops = {
.mkdir = dht_mkdir,
.rmdir = dht_rmdir,
.rename = dht_rename,
- .entrylk = dht_entrylk,
- .fentrylk = dht_fentrylk,
-
- /* Inode read operations */
- .stat = dht_stat,
- .fstat = dht_fstat,
- .access = dht_access,
- .readlink = dht_readlink,
- .getxattr = dht_getxattr,
- .fgetxattr = dht_fgetxattr,
- .readv = dht_readv,
- .flush = dht_flush,
- .fsync = dht_fsync,
.inodelk = dht_inodelk,
.finodelk = dht_finodelk,
- .lk = dht_lk,
-
- /* Inode write operations */
- .fremovexattr = dht_fremovexattr,
- .removexattr = dht_removexattr,
- .setxattr = dht_setxattr,
- .fsetxattr = dht_fsetxattr,
- .truncate = dht_truncate,
- .ftruncate = dht_ftruncate,
- .writev = dht_writev,
+ .entrylk = dht_entrylk,
+ .fentrylk = dht_fentrylk,
.xattrop = dht_xattrop,
.fxattrop = dht_fxattrop,
.setattr = dht_setattr,
@@ -560,49 +546,19 @@ struct volume_options options[] = {
{ .key = {"lookup-unhashed"},
.value = {"auto", "yes", "no", "enable", "disable", "1", "0",
"on", "off"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_STR
},
{ .key = {"min-free-disk"},
.type = GF_OPTION_TYPE_PERCENT_OR_SIZET,
- .default_value = "10%",
- .description = "Percentage/Size of disk space that must be "
- "kept free."
- },
- { .key = {"min-free-inodes"},
- .type = GF_OPTION_TYPE_PERCENT,
- .default_value = "5%",
- .description = "Percentage inodes that must be "
- "kept free."
},
{ .key = {"unhashed-sticky-bit"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"use-readdirp"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"assert-no-child-down"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {"directory-layout-spread"},
- .type = GF_OPTION_TYPE_INT,
- },
- { .key = {"decommissioned-bricks"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {"rebalance-cmd"},
- .type = GF_OPTION_TYPE_INT,
- },
- { .key = {"node-uuid"},
- .type = GF_OPTION_TYPE_STR,
- },
- { .key = {"rebalance-stats"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
-
{ .key = {NULL} },
};
diff --git a/xlators/cluster/dht/src/nufa.c b/xlators/cluster/dht/src/nufa.c
index 53c66aa45..6f14362f4 100644
--- a/xlators/cluster/dht/src/nufa.c
+++ b/xlators/cluster/dht/src/nufa.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -14,7 +23,7 @@
#include "config.h"
#endif
-#include "dht-common.h"
+#include "dht-common.c"
/* TODO: all 'TODO's in dht.c holds good */
@@ -35,6 +44,7 @@ nufa_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int call_cnt = 0;
int ret = 0;
+
conf = this->private;
prev = cookie;
@@ -57,6 +67,10 @@ nufa_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!is_dir && !is_linkfile) {
/* non-directory and not a linkfile */
+
+ dht_itransform (this, prev->this, stbuf->ia_ino,
+ &stbuf->ia_ino);
+
ret = dht_layout_preset (this, prev->this, inode);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -131,7 +145,7 @@ out:
err:
DHT_STACK_UNWIND (lookup, frame, op_ret, op_errno,
- inode, stbuf, xattr, postparent);
+ inode, stbuf, xattr, NULL);
return 0;
}
@@ -140,6 +154,7 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
xlator_t *hashed_subvol = NULL;
+ xlator_t *cached_subvol = NULL;
xlator_t *subvol = NULL;
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
@@ -158,12 +173,21 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
conf = this->private;
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "copying location failed for path=%s",
+ loc->path);
+ goto err;
+ }
+
if (xattr_req) {
local->xattr_req = dict_ref (xattr_req);
} else {
@@ -171,11 +195,14 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
}
hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
+ cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
+ local->cached_subvol = cached_subvol;
local->hashed_subvol = hashed_subvol;
if (is_revalidate (loc)) {
- layout = local->layout;
+ local->layout = layout = dht_layout_get (this, loc->inode);
+
if (!layout) {
gf_log (this->name, GF_LOG_DEBUG,
"revalidate without cache. path=%s",
@@ -192,7 +219,8 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
goto do_fresh_lookup;
}
- local->inode = inode_ref (loc->inode);
+ local->inode = inode_ref (loc->inode);
+ local->ia_ino = loc->inode->ino;
local->call_cnt = layout->cnt;
call_cnt = local->call_cnt;
@@ -250,8 +278,7 @@ nufa_lookup (call_frame_t *frame, xlator_t *this,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -260,7 +287,7 @@ nufa_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf,
struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
@@ -271,27 +298,28 @@ nufa_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
STACK_WIND (frame, dht_create_cbk,
local->cached_subvol, local->cached_subvol->fops->create,
- &local->loc, local->flags, local->mode, local->umask,
- local->fd, local->params);
+ &local->loc, local->flags, local->mode, local->fd,
+ local->params);
return 0;
err:
DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
int
nufa_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *params)
+ fd_t *fd, dict_t *params)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
int op_errno = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -301,7 +329,7 @@ nufa_create (call_frame_t *frame, xlator_t *this,
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, fd, GF_FOP_CREATE);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -325,10 +353,17 @@ nufa_create (call_frame_t *frame, xlator_t *this,
if (subvol != avail_subvol) {
/* create a link file instead of actual file */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->fd = fd_ref (fd);
local->params = dict_ref (params);
local->mode = mode;
local->flags = flags;
- local->umask = umask;
+
local->cached_subvol = avail_subvol;
dht_linkfile_create (frame,
nufa_create_linkfile_create_cbk,
@@ -341,14 +376,14 @@ nufa_create (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
+ loc, flags, mode, fd, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -357,7 +392,7 @@ int
nufa_mknod_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
@@ -368,7 +403,7 @@ nufa_mknod_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cached_subvol,
local->cached_subvol->fops->mknod,
&local->loc, local->mode, local->rdev,
- local->umask, local->params);
+ local->params);
return 0;
}
@@ -377,20 +412,21 @@ nufa_mknod_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
WIPE (preparent);
DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
- inode, stbuf, preparent, postparent, xdata);
+ inode, stbuf, preparent, postparent);
return 0;
}
int
nufa_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *params)
+ loc_t *loc, mode_t mode, dev_t rdev, dict_t *params)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
int op_errno = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -400,7 +436,7 @@ nufa_mknod (call_frame_t *frame, xlator_t *this,
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -425,10 +461,14 @@ nufa_mknod (call_frame_t *frame, xlator_t *this,
if (avail_subvol != subvol) {
/* Create linkfile first */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
local->params = dict_ref (params);
local->mode = mode;
- local->umask = umask;
local->rdev = rdev;
local->cached_subvol = avail_subvol;
@@ -442,14 +482,14 @@ nufa_mknod (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_newfile_cbk,
subvol, subvol->fops->mknod,
- loc, mode, rdev, umask, params);
+ loc, mode, rdev, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -481,9 +521,14 @@ fini (xlator_t *this)
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
GF_FREE (conf);
}
@@ -607,13 +652,6 @@ init (xlator_t *this)
goto err;
}
- this->local_pool = mem_pool_new (dht_local_t, 128);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto err;
- }
-
this->private = conf;
return 0;
@@ -627,11 +665,17 @@ err:
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
- GF_FREE (conf->du_stats);
+ if (conf->du_stats)
+ GF_FREE (conf->du_stats);
GF_FREE (conf);
}
diff --git a/xlators/cluster/dht/src/switch.c b/xlators/cluster/dht/src/switch.c
index 0542d7f9a..ada6b2c46 100644
--- a/xlators/cluster/dht/src/switch.c
+++ b/xlators/cluster/dht/src/switch.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -14,7 +23,7 @@
#include "config.h"
#endif
-#include "dht-common.h"
+#include "dht-common.c"
#include "dht-mem-types.h"
#include <sys/time.h>
@@ -67,37 +76,29 @@ get_switch_matching_subvol (const char *path, dht_conf_t *conf,
struct switch_struct *cond = NULL;
struct switch_struct *trav = NULL;
char *pathname = NULL;
- int idx = 0;
- xlator_t *subvol = NULL;
+ int idx = 0;
cond = conf->private;
- subvol = hashed_subvol;
if (!cond)
- goto out;
-
- pathname = gf_strdup (path);
- if (!pathname)
- goto out;
+ return hashed_subvol;
trav = cond;
+ pathname = gf_strdup (path);
while (trav) {
if (fnmatch (trav->path_pattern,
pathname, FNM_NOESCAPE) == 0) {
for (idx = 0; idx < trav->num_child; idx++) {
if (trav->array[idx].xl == hashed_subvol)
- goto out;
+ return hashed_subvol;
}
idx = trav->node_index++;
trav->node_index %= trav->num_child;
- subvol = trav->array[idx].xl;
- goto out;
+ return trav->array[idx].xl;
}
trav = trav->next;
}
-out:
GF_FREE (pathname);
-
- return subvol;
+ return hashed_subvol;
}
@@ -141,6 +142,9 @@ switch_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!is_dir && !is_linkfile) {
/* non-directory and not a linkfile */
+ dht_itransform (this, prev->this, stbuf->ia_ino,
+ &stbuf->ia_ino);
+
ret = dht_layout_preset (this, prev->this, inode);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -245,12 +249,21 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
conf = this->private;
- local = dht_local_init (frame, loc, NULL, GF_FOP_LOOKUP);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
}
+ ret = loc_dup (loc, &local->loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "copying location failed for path=%s",
+ loc->path);
+ goto err;
+ }
+
if (xattr_req) {
local->xattr_req = dict_ref (xattr_req);
} else {
@@ -258,12 +271,14 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
}
hashed_subvol = dht_subvol_get_hashed (this, &local->loc);
- cached_subvol = local->cached_subvol;
+ cached_subvol = dht_subvol_get_cached (this, local->loc.inode);
+ local->cached_subvol = cached_subvol;
local->hashed_subvol = hashed_subvol;
if (is_revalidate (loc)) {
- layout = local->layout;
+ local->layout = layout = dht_layout_get (this, loc->inode);
+
if (!layout) {
gf_log (this->name, GF_LOG_DEBUG,
"revalidate without cache. path=%s",
@@ -281,6 +296,7 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
}
local->inode = inode_ref (loc->inode);
+ local->ia_ino = loc->inode->ino;
local->call_cnt = layout->cnt;
call_cnt = local->call_cnt;
@@ -365,8 +381,7 @@ switch_lookup (call_frame_t *frame, xlator_t *this,
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- DHT_STACK_UNWIND (lookup, frame, -1, op_errno,
- NULL, NULL, NULL, NULL);
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -375,7 +390,7 @@ switch_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf,
struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
@@ -386,27 +401,28 @@ switch_create_linkfile_create_cbk (call_frame_t *frame, void *cookie,
STACK_WIND (frame, dht_create_cbk,
local->cached_subvol, local->cached_subvol->fops->create,
- &local->loc, local->flags, local->mode, local->umask,
- local->fd, local->params);
+ &local->loc, local->flags, local->mode, local->fd,
+ local->params);
return 0;
err:
DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
int
switch_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *params)
+ fd_t *fd, dict_t *params)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
int op_errno = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -416,7 +432,7 @@ switch_create (call_frame_t *frame, xlator_t *this,
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, fd, GF_FOP_CREATE);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -439,9 +455,16 @@ switch_create (call_frame_t *frame, xlator_t *this,
if (subvol != avail_subvol) {
/* create a link file instead of actual file */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->fd = fd_ref (fd);
local->mode = mode;
local->flags = flags;
- local->umask = umask;
+
local->cached_subvol = avail_subvol;
dht_linkfile_create (frame,
switch_create_linkfile_create_cbk,
@@ -454,14 +477,14 @@ switch_create (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, dht_create_cbk,
subvol, subvol->fops->create,
- loc, flags, mode, umask, fd, params);
+ loc, flags, mode, fd, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (create, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -470,7 +493,7 @@ int
switch_mknod_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
dht_local_t *local = NULL;
@@ -481,26 +504,27 @@ switch_mknod_linkfile_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->cached_subvol,
local->cached_subvol->fops->mknod,
&local->loc, local->mode, local->rdev,
- local->umask, local->params);
+ local->params);
return 0;
}
DHT_STACK_UNWIND (link, frame, op_ret, op_errno,
- inode, stbuf, preparent, postparent, xdata);
+ inode, stbuf, preparent, postparent);
return 0;
}
int
-switch_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *params)
+switch_mknod (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dev_t rdev, dict_t *params)
{
dht_local_t *local = NULL;
dht_conf_t *conf = NULL;
xlator_t *subvol = NULL;
xlator_t *avail_subvol = NULL;
int op_errno = -1;
+ int ret = -1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -510,7 +534,7 @@ switch_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
dht_get_du_info (frame, this, loc);
- local = dht_local_init (frame, loc, NULL, GF_FOP_MKNOD);
+ local = dht_local_init (frame);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -534,10 +558,14 @@ switch_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
if (avail_subvol != subvol) {
/* Create linkfile first */
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto err;
+ }
local->params = dict_ref (params);
local->mode = mode;
- local->umask = umask;
local->rdev = rdev;
local->cached_subvol = avail_subvol;
@@ -551,14 +579,14 @@ switch_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
STACK_WIND (frame, dht_newfile_cbk,
subvol, subvol->fops->mknod,
- loc, mode, rdev, umask, params);
+ loc, mode, rdev, params);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
DHT_STACK_UNWIND (mknod, frame, -1, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -588,7 +616,8 @@ fini (xlator_t *this)
trav = (struct switch_struct *)conf->private;
conf->private = NULL;
while (trav) {
- GF_FREE (trav->array);
+ if (trav->array)
+ GF_FREE (trav->array);
prev = trav;
trav = trav->next;
GF_FREE (prev);
@@ -601,9 +630,14 @@ fini (xlator_t *this)
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
+
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
GF_FREE (conf);
}
@@ -668,10 +702,8 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
dup_str = gf_strdup (switch_str);
switch_opt = GF_CALLOC (1, sizeof (struct switch_struct),
gf_switch_mt_switch_struct);
- if (!switch_opt) {
- GF_FREE (dup_str);
+ if (!switch_opt)
goto err;
- }
pattern = strtok_r (dup_str, ":", &tmp_str1);
childs = strtok_r (NULL, ":", &tmp_str1);
@@ -681,7 +713,6 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
"for all the unconfigured child nodes,"
" hence neglecting current option");
switch_str = strtok_r (NULL, ";", &tmp_str);
- GF_FREE (switch_opt);
GF_FREE (dup_str);
continue;
}
@@ -754,7 +785,6 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
/* First entry */
switch_buf = switch_opt;
}
- switch_opt = NULL;
switch_str = strtok_r (NULL, ";", &tmp_str);
}
@@ -811,20 +841,19 @@ set_switch_pattern (xlator_t *this, dht_conf_t *conf,
/* First entry */
switch_buf = switch_opt;
}
- switch_opt = NULL;
}
/* */
conf->private = switch_buf;
return 0;
err:
- GF_FREE (switch_buf_array);
- GF_FREE (switch_opt);
-
if (switch_buf) {
+ if (switch_buf_array)
+ GF_FREE (switch_buf_array);
trav = switch_buf;
while (trav) {
- GF_FREE (trav->array);
+ if (trav->array)
+ GF_FREE (trav->array);
switch_opt = trav;
trav = trav->next;
GF_FREE (switch_opt);
@@ -927,13 +956,6 @@ init (xlator_t *this)
goto err;
}
- this->local_pool = mem_pool_new (dht_local_t, 128);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto err;
- }
-
this->private = conf;
return 0;
@@ -947,11 +969,17 @@ err:
GF_FREE (conf->file_layouts);
}
- GF_FREE (conf->subvolumes);
+ if (conf->default_dir_layout)
+ GF_FREE (conf->default_dir_layout);
+
+ if (conf->subvolumes)
+ GF_FREE (conf->subvolumes);
- GF_FREE (conf->subvolume_status);
+ if (conf->subvolume_status)
+ GF_FREE (conf->subvolume_status);
- GF_FREE (conf->du_stats);
+ if (conf->du_stats)
+ GF_FREE (conf->du_stats);
GF_FREE (conf);
}
diff --git a/xlators/cluster/ha/src/ha-helpers.c b/xlators/cluster/ha/src/ha-helpers.c
index 1e4af1b62..7c361547a 100644
--- a/xlators/cluster/ha/src/ha-helpers.c
+++ b/xlators/cluster/ha/src/ha-helpers.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/ha/src/ha-mem-types.h b/xlators/cluster/ha/src/ha-mem-types.h
index 9bfb3972b..b460588aa 100644
--- a/xlators/cluster/ha/src/ha-mem-types.h
+++ b/xlators/cluster/ha/src/ha-mem-types.h
@@ -1,19 +1,19 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/ha/src/ha.c b/xlators/cluster/ha/src/ha.c
index e7956b826..7bb1824a1 100644
--- a/xlators/cluster/ha/src/ha.c
+++ b/xlators/cluster/ha/src/ha.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -1876,9 +1876,13 @@ err:
}
if (hafdp) {
- GF_FREE (hafdp->fdstate);
+ if (hafdp->fdstate) {
+ GF_FREE (hafdp->fdstate);
+ }
- GF_FREE (hafdp->path);
+ if (hafdp->path) {
+ GF_FREE (hafdp->path);
+ }
GF_FREE (hafdp);
}
diff --git a/xlators/cluster/ha/src/ha.h b/xlators/cluster/ha/src/ha.h
index 39b6851e7..d6a519fa8 100644
--- a/xlators/cluster/ha/src/ha.h
+++ b/xlators/cluster/ha/src/ha.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/map/src/map-helper.c b/xlators/cluster/map/src/map-helper.c
index 81212fcfd..24ab6eb50 100644
--- a/xlators/cluster/map/src/map-helper.c
+++ b/xlators/cluster/map/src/map-helper.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2009-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/map/src/map-mem-types.h b/xlators/cluster/map/src/map-mem-types.h
index 669b93dc2..23c798dea 100644
--- a/xlators/cluster/map/src/map-mem-types.h
+++ b/xlators/cluster/map/src/map-mem-types.h
@@ -1,19 +1,19 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/map/src/map.c b/xlators/cluster/map/src/map.c
index 06d629a7e..73186e8cb 100644
--- a/xlators/cluster/map/src/map.c
+++ b/xlators/cluster/map/src/map.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -2375,7 +2375,8 @@ fini (xlator_t *this)
priv = this->private;
if (priv) {
- GF_FREE (priv->xlarray);
+ if (priv->xlarray)
+ GF_FREE (priv->xlarray);
trav_map = priv->map;
while (trav_map) {
diff --git a/xlators/cluster/map/src/map.h b/xlators/cluster/map/src/map.h
index bccac437c..44ba3ee12 100644
--- a/xlators/cluster/map/src/map.h
+++ b/xlators/cluster/map/src/map.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/cluster/stripe/src/Makefile.am b/xlators/cluster/stripe/src/Makefile.am
index 8c48d3410..0db3c9eeb 100644
--- a/xlators/cluster/stripe/src/Makefile.am
+++ b/xlators/cluster/stripe/src/Makefile.am
@@ -4,9 +4,7 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster
stripe_la_LDFLAGS = -module -avoidversion
-stripe_la_SOURCES = stripe.c stripe-helpers.c \
- $(top_builddir)/xlators/lib/src/libxlator.c
-
+stripe_la_SOURCES = stripe.c $(top_builddir)/xlators/lib/src/libxlator.c
stripe_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = stripe.h stripe-mem-types.h $(top_builddir)/xlators/lib/src/libxlator.h
diff --git a/xlators/cluster/stripe/src/stripe-helpers.c b/xlators/cluster/stripe/src/stripe-helpers.c
deleted file mode 100644
index 8053f871a..000000000
--- a/xlators/cluster/stripe/src/stripe-helpers.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#include <fnmatch.h>
-
-#include "stripe.h"
-#include "byte-order.h"
-
-void
-stripe_local_wipe (stripe_local_t *local)
-{
- if (!local)
- goto out;
-
- loc_wipe (&local->loc);
- loc_wipe (&local->loc2);
-
- if (local->fd)
- fd_unref (local->fd);
-
- if (local->inode)
- inode_unref (local->inode);
-
- if (local->xattr)
- dict_unref (local->xattr);
-
- if (local->xdata)
- dict_unref (local->xdata);
-
-out:
- return;
-}
-
-
-
-void
-stripe_aggregate (dict_t *this, char *key, data_t *value, void *data)
-{
- dict_t *dst = NULL;
- int64_t *ptr = 0, *size = NULL;
- int32_t ret = -1;
-
- dst = data;
-
- if (strcmp (key, GF_XATTR_QUOTA_SIZE_KEY) == 0) {
- ret = dict_get_bin (dst, key, (void **)&size);
- if (ret < 0) {
- size = GF_CALLOC (1, sizeof (int64_t),
- gf_common_mt_char);
- if (size == NULL) {
- gf_log ("stripe", GF_LOG_WARNING,
- "memory allocation failed");
- goto out;
- }
- ret = dict_set_bin (dst, key, size, sizeof (int64_t));
- if (ret < 0) {
- gf_log ("stripe", GF_LOG_WARNING,
- "stripe aggregate dict set failed");
- GF_FREE (size);
- goto out;
- }
- }
-
- ptr = data_to_bin (value);
- if (ptr == NULL) {
- gf_log ("stripe", GF_LOG_WARNING, "data to bin failed");
- goto out;
- }
-
- *size = hton64 (ntoh64 (*size) + ntoh64 (*ptr));
- } else if (strcmp (key, GF_CONTENT_KEY)) {
- /* No need to aggregate 'CONTENT' data */
- ret = dict_set (dst, key, value);
- if (ret)
- gf_log ("stripe", GF_LOG_WARNING, "xattr dict set failed");
- }
-
-out:
- return;
-}
-
-
-void
-stripe_aggregate_xattr (dict_t *dst, dict_t *src)
-{
- if ((dst == NULL) || (src == NULL)) {
- goto out;
- }
-
- dict_foreach (src, stripe_aggregate, dst);
-out:
- return;
-}
-
-
-int32_t
-stripe_xattr_aggregate (char *buffer, stripe_local_t *local, int32_t *total)
-{
- int32_t i = 0;
- int32_t ret = -1;
- int32_t len = 0;
- char *sbuf = NULL;
- stripe_xattr_sort_t *xattr = NULL;
-
- if (!buffer || !local || !local->xattr_list)
- goto out;
-
- sbuf = buffer;
-
- for (i = 0; i < local->nallocs; i++) {
- xattr = local->xattr_list + i;
- len = xattr->xattr_len;
-
- if (len && xattr && xattr->xattr_value) {
- memcpy (buffer, xattr->xattr_value, len);
- buffer += len;
- *buffer++ = ' ';
- }
- }
-
- *--buffer = '\0';
- if (total)
- *total = buffer - sbuf;
- ret = 0;
-
- out:
- return ret;
-}
-
-int32_t
-stripe_free_xattr_str (stripe_local_t *local)
-{
- int32_t i = 0;
- int32_t ret = -1;
- stripe_xattr_sort_t *xattr = NULL;
-
- if (!local || !local->xattr_list)
- goto out;
-
- for (i = 0; i < local->nallocs; i++) {
- xattr = local->xattr_list + i;
-
- if (xattr && xattr->xattr_value)
- GF_FREE (xattr->xattr_value);
- }
-
- ret = 0;
- out:
- return ret;
-}
-
-
-int32_t
-stripe_fill_pathinfo_xattr (xlator_t *this, stripe_local_t *local,
- char **xattr_serz)
-{
- int ret = -1;
- int32_t padding = 0;
- int32_t tlen = 0;
- char stripe_size_str[20] = {0,};
- char *pathinfo_serz = NULL;
-
- if (!local) {
- gf_log (this->name, GF_LOG_ERROR, "Possible NULL deref");
- goto out;
- }
-
- (void) snprintf (stripe_size_str, 20, "%ld",
- (local->fctx) ? local->fctx->stripe_size : 0);
-
- /* extra bytes for decorations (brackets and <>'s) */
- padding = strlen (this->name) + strlen (STRIPE_PATHINFO_HEADER)
- + strlen (stripe_size_str) + 7;
- local->xattr_total_len += (padding + 2);
-
- pathinfo_serz = GF_CALLOC (local->xattr_total_len, sizeof (char),
- gf_common_mt_char);
- if (!pathinfo_serz)
- goto out;
-
- /* xlator info */
- (void) sprintf (pathinfo_serz, "(<"STRIPE_PATHINFO_HEADER"%s:[%s]> ",
- this->name, stripe_size_str);
-
- ret = stripe_xattr_aggregate (pathinfo_serz + padding, local, &tlen);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Cannot aggregate pathinfo list");
- goto out;
- }
-
- *(pathinfo_serz + padding + tlen) = ')';
- *(pathinfo_serz + padding + tlen + 1) = '\0';
-
- *xattr_serz = pathinfo_serz;
-
- ret = 0;
- out:
- return ret;
-}
-
-/**
- * stripe_get_matching_bs - Get the matching block size for the given path.
- */
-int32_t
-stripe_get_matching_bs (const char *path, stripe_private_t *priv)
-{
- struct stripe_options *trav = NULL;
- uint64_t block_size = 0;
-
- GF_VALIDATE_OR_GOTO ("stripe", priv, out);
- GF_VALIDATE_OR_GOTO ("stripe", path, out);
-
- LOCK (&priv->lock);
- {
- block_size = priv->block_size;
- trav = priv->pattern;
- while (trav) {
- if (!fnmatch (trav->path_pattern, path, FNM_NOESCAPE)) {
- block_size = trav->block_size;
- break;
- }
- trav = trav->next;
- }
- }
- UNLOCK (&priv->lock);
-
-out:
- return block_size;
-}
-
-int32_t
-stripe_ctx_handle (xlator_t *this, call_frame_t *prev, stripe_local_t *local,
- dict_t *dict)
-{
- char key[256] = {0,};
- data_t *data = NULL;
- int32_t index = 0;
- stripe_private_t *priv = NULL;
-
- priv = this->private;
-
-
- if (!local->fctx) {
- local->fctx = GF_CALLOC (1, sizeof (stripe_fd_ctx_t),
- gf_stripe_mt_stripe_fd_ctx_t);
- if (!local->fctx) {
- local->op_errno = ENOMEM;
- local->op_ret = -1;
- goto out;
- }
-
- local->fctx->static_array = 0;
- }
- /* Stripe block size */
- sprintf (key, "trusted.%s.stripe-size", this->name);
- data = dict_get (dict, key);
- if (!data) {
- local->xattr_self_heal_needed = 1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get stripe-size");
- goto out;
- } else {
- if (!local->fctx->stripe_size) {
- local->fctx->stripe_size =
- data_to_int64 (data);
- }
-
- if (local->fctx->stripe_size != data_to_int64 (data)) {
- gf_log (this->name, GF_LOG_WARNING,
- "stripe-size mismatch in blocks");
- local->xattr_self_heal_needed = 1;
- }
- }
-
- /* Stripe count */
- sprintf (key, "trusted.%s.stripe-count", this->name);
- data = dict_get (dict, key);
-
- if (!data) {
- local->xattr_self_heal_needed = 1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get stripe-count");
- goto out;
- }
- if (!local->fctx->xl_array) {
- local->fctx->stripe_count = data_to_int32 (data);
- if (!local->fctx->stripe_count) {
- gf_log (this->name, GF_LOG_ERROR,
- "error with stripe-count xattr");
- local->op_ret = -1;
- local->op_errno = EIO;
- goto out;
- }
-
- local->fctx->xl_array = GF_CALLOC (local->fctx->stripe_count,
- sizeof (xlator_t *),
- gf_stripe_mt_xlator_t);
-
- if (!local->fctx->xl_array) {
- local->op_errno = ENOMEM;
- local->op_ret = -1;
- goto out;
- }
- }
- if (local->fctx->stripe_count != data_to_int32 (data)) {
- gf_log (this->name, GF_LOG_ERROR,
- "error with stripe-count xattr (%d != %d)",
- local->fctx->stripe_count, data_to_int32 (data));
- local->op_ret = -1;
- local->op_errno = EIO;
- goto out;
- }
-
- /* index */
- sprintf (key, "trusted.%s.stripe-index", this->name);
- data = dict_get (dict, key);
- if (!data) {
- local->xattr_self_heal_needed = 1;
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get stripe-index");
- goto out;
- }
- index = data_to_int32 (data);
- if (index > priv->child_count) {
- gf_log (this->name, GF_LOG_ERROR,
- "error with stripe-index xattr (%d)", index);
- local->op_ret = -1;
- local->op_errno = EIO;
- goto out;
- }
- if (local->fctx->xl_array) {
- if (!local->fctx->xl_array[index])
- local->fctx->xl_array[index] = prev->this;
- }
-
- sprintf(key, "trusted.%s.stripe-coalesce", this->name);
- data = dict_get(dict, key);
- if (!data) {
- /*
- * The file was probably created prior to coalesce support.
- * Assume non-coalesce mode for this file to maintain backwards
- * compatibility.
- */
- gf_log(this->name, GF_LOG_DEBUG, "missing stripe-coalesce "
- "attr, assume non-coalesce mode");
- local->fctx->stripe_coalesce = 0;
- } else {
- local->fctx->stripe_coalesce = data_to_int32(data);
- }
-
-
-out:
- return 0;
-}
-
-int32_t
-stripe_xattr_request_build (xlator_t *this, dict_t *dict, uint64_t stripe_size,
- uint32_t stripe_count, uint32_t stripe_index,
- uint32_t stripe_coalesce)
-{
- char key[256] = {0,};
- int32_t ret = -1;
-
- sprintf (key, "trusted.%s.stripe-size", this->name);
- ret = dict_set_int64 (dict, key, stripe_size);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set %s in xattr_req dict", key);
- goto out;
- }
-
- sprintf (key, "trusted.%s.stripe-count", this->name);
- ret = dict_set_int32 (dict, key, stripe_count);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set %s in xattr_req dict", key);
- goto out;
- }
-
- sprintf (key, "trusted.%s.stripe-index", this->name);
- ret = dict_set_int32 (dict, key, stripe_index);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set %s in xattr_req dict", key);
- goto out;
- }
-
- sprintf(key, "trusted.%s.stripe-coalesce", this->name);
- ret = dict_set_int32(dict, key, stripe_coalesce);
- if (ret) {
- gf_log(this->name, GF_LOG_WARNING,
- "failed to set %s in xattr_req_dict", key);
- goto out;
- }
-out:
- return ret;
-}
-
-
-static int
-set_default_block_size (stripe_private_t *priv, char *num)
-{
-
- int ret = -1;
- GF_VALIDATE_OR_GOTO ("stripe", THIS, out);
- GF_VALIDATE_OR_GOTO (THIS->name, priv, out);
- GF_VALIDATE_OR_GOTO (THIS->name, num, out);
-
-
- if (gf_string2bytesize (num, &priv->block_size) != 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "invalid number format \"%s\"", num);
- goto out;
- }
-
- ret = 0;
-
- out:
- return ret;
-
-}
-
-
-int
-set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data)
-{
- int ret = -1;
- char *tmp_str = NULL;
- char *tmp_str1 = NULL;
- char *dup_str = NULL;
- char *stripe_str = NULL;
- char *pattern = NULL;
- char *num = NULL;
- struct stripe_options *temp_stripeopt = NULL;
- struct stripe_options *stripe_opt = NULL;
-
- if (!this || !priv || !data)
- goto out;
-
- /* Get the pattern for striping.
- "option block-size *avi:10MB" etc */
- stripe_str = strtok_r (data, ",", &tmp_str);
- while (stripe_str) {
- dup_str = gf_strdup (stripe_str);
- stripe_opt = GF_CALLOC (1, sizeof (struct stripe_options),
- gf_stripe_mt_stripe_options);
- if (!stripe_opt) {
- goto out;
- }
-
- pattern = strtok_r (dup_str, ":", &tmp_str1);
- num = strtok_r (NULL, ":", &tmp_str1);
- if (!num) {
- num = pattern;
- pattern = "*";
- ret = set_default_block_size (priv, num);
- if (ret)
- goto out;
- }
- if (gf_string2bytesize (num, &stripe_opt->block_size) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid number format \"%s\"", num);
- goto out;
- }
-
- if (stripe_opt->block_size < STRIPE_MIN_BLOCK_SIZE) {
- gf_log (this->name, GF_LOG_ERROR, "Invalid Block-size: "
- "%s. Should be atleast %llu bytes", num,
- STRIPE_MIN_BLOCK_SIZE);
- goto out;
- }
- if (stripe_opt->block_size % 512) {
- gf_log (this->name, GF_LOG_ERROR, "Block-size: %s should"
- " be a multiple of 512 bytes", num);
- goto out;
- }
-
- memcpy (stripe_opt->path_pattern, pattern, strlen (pattern));
-
- gf_log (this->name, GF_LOG_DEBUG,
- "block-size : pattern %s : size %"PRId64,
- stripe_opt->path_pattern, stripe_opt->block_size);
-
- if (priv->pattern)
- temp_stripeopt = NULL;
- else
- temp_stripeopt = priv->pattern;
-
- stripe_opt->next = temp_stripeopt;
-
- priv->pattern = stripe_opt;
- stripe_opt = NULL;
-
- GF_FREE (dup_str);
- dup_str = NULL;
-
- stripe_str = strtok_r (NULL, ",", &tmp_str);
- }
-
- ret = 0;
-out:
-
- GF_FREE (dup_str);
-
- GF_FREE (stripe_opt);
-
- return ret;
-}
-
-int32_t
-stripe_iatt_merge (struct iatt *from, struct iatt *to)
-{
- if (to->ia_size < from->ia_size)
- to->ia_size = from->ia_size;
- if (to->ia_mtime < from->ia_mtime)
- to->ia_mtime = from->ia_mtime;
- if (to->ia_ctime < from->ia_ctime)
- to->ia_ctime = from->ia_ctime;
- if (to->ia_atime < from->ia_atime)
- to->ia_atime = from->ia_atime;
- return 0;
-}
-
-off_t
-coalesced_offset(off_t offset, uint64_t stripe_size, int stripe_count)
-{
- size_t line_size = 0;
- uint64_t stripe_num = 0;
- off_t coalesced_offset = 0;
-
- line_size = stripe_size * stripe_count;
- stripe_num = offset / line_size;
-
- coalesced_offset = (stripe_num * stripe_size) +
- (offset % stripe_size);
-
- return coalesced_offset;
-}
-
-off_t
-uncoalesced_size(off_t size, uint64_t stripe_size, int stripe_count,
- int stripe_index)
-{
- uint64_t nr_full_stripe_chunks = 0, mod = 0;
-
- if (!size)
- return size;
-
- /*
- * Estimate the number of fully written stripes from the
- * local file size. Each stripe_size chunk corresponds to
- * a stripe.
- */
- nr_full_stripe_chunks = (size / stripe_size) * stripe_count;
- mod = size % stripe_size;
-
- if (!mod) {
- /*
- * There is no remainder, thus we could have overestimated
- * the size of the file in terms of chunks. Trim the number
- * of chunks by the following stripe members and leave it
- * up to those nodes to respond with a larger size (if
- * necessary).
- */
- nr_full_stripe_chunks -= stripe_count -
- (stripe_index + 1);
- size = nr_full_stripe_chunks * stripe_size;
- } else {
- /*
- * There is a remainder and thus we own the last chunk of the
- * file. Add the preceding stripe members of the final stripe
- * along with the remainder to calculate the exact size.
- */
- nr_full_stripe_chunks += stripe_index;
- size = nr_full_stripe_chunks * stripe_size + mod;
- }
-
- return size;
-}
-
diff --git a/xlators/cluster/stripe/src/stripe-mem-types.h b/xlators/cluster/stripe/src/stripe-mem-types.h
index e05ba0c29..2d2757e86 100644
--- a/xlators/cluster/stripe/src/stripe-mem-types.h
+++ b/xlators/cluster/stripe/src/stripe-mem-types.h
@@ -1,11 +1,21 @@
+
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -15,15 +25,15 @@
#include "mem-types.h"
enum gf_stripe_mem_types_ {
- gf_stripe_mt_iovec = gf_common_mt_end + 1,
- gf_stripe_mt_stripe_replies,
+ gf_stripe_mt_stripe_local_t = gf_common_mt_end + 1,
+ gf_stripe_mt_iovec,
+ gf_stripe_mt_readv_replies,
gf_stripe_mt_stripe_fd_ctx_t,
gf_stripe_mt_char,
gf_stripe_mt_int8_t,
gf_stripe_mt_xlator_t,
gf_stripe_mt_stripe_private_t,
gf_stripe_mt_stripe_options,
- gf_stripe_mt_xattr_sort_t,
gf_stripe_mt_end
};
#endif
diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c
index 6588a4499..a06d275df 100644
--- a/xlators/cluster/stripe/src/stripe.c
+++ b/xlators/cluster/stripe/src/stripe.c
@@ -1,16 +1,25 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
/**
* xlators/cluster/stripe:
- * Stripe translator, stripes the data across its child nodes,
+ * Stripe translator, stripes the data accross its child nodes,
* as per the options given in the volfile. The striping works
* fairly simple. It writes files at different offset as per
* calculation. So, 'ls -l' output at the real posix level will
@@ -23,19 +32,69 @@
* very much necessary, or else, use it in combination with AFR, to have a
* backup copy.
*/
-#include <fnmatch.h>
#include "stripe.h"
#include "libxlator.h"
#include "byte-order.h"
-#include "statedump.h"
-struct volume_options options[];
+void
+stripe_local_wipe (stripe_local_t *local)
+{
+ if (!local)
+ goto out;
+
+ loc_wipe (&local->loc);
+ loc_wipe (&local->loc2);
+ if (local->xattr != NULL) {
+ dict_unref (local->xattr);
+ }
+
+out:
+ return;
+}
+
+/**
+ * stripe_get_matching_bs - Get the matching block size for the given path.
+ */
+int32_t
+stripe_get_matching_bs (const char *path, struct stripe_options *opts,
+ uint64_t default_bs)
+{
+ struct stripe_options *trav = NULL;
+ char *pathname = NULL;
+ uint64_t block_size = 0;
+
+ block_size = default_bs;
+
+ if (!path || !opts)
+ goto out;
+
+ /* FIXME: is a strdup really necessary? */
+ pathname = gf_strdup (path);
+ if (!pathname)
+ goto out;
+
+ trav = opts;
+ while (trav) {
+ if (!fnmatch (trav->path_pattern, pathname, FNM_NOESCAPE)) {
+ block_size = trav->block_size;
+ break;
+ }
+ trav = trav->next;
+ }
+
+ GF_FREE (pathname);
+
+out:
+ return block_size;
+}
+
+
int32_t
stripe_sh_chown_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
int callcnt = -1;
stripe_local_t *local = NULL;
@@ -64,7 +123,7 @@ int32_t
stripe_sh_make_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
stripe_local_t *local = NULL;
call_frame_t *prev = NULL;
@@ -79,7 +138,7 @@ stripe_sh_make_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, stripe_sh_chown_cbk, prev->this,
prev->this->fops->setattr, &local->loc,
- &local->stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID), NULL);
+ &local->stbuf, (GF_SET_ATTR_UID | GF_SET_ATTR_GID));
out:
return 0;
@@ -93,7 +152,7 @@ stripe_entry_self_heal (call_frame_t *frame, xlator_t *this,
call_frame_t *rframe = NULL;
stripe_local_t *rlocal = NULL;
stripe_private_t *priv = NULL;
- dict_t *xdata = NULL;
+ dict_t *dict = NULL;
int ret = 0;
if (!local || !this || !frame) {
@@ -111,7 +170,8 @@ stripe_entry_self_heal (call_frame_t *frame, xlator_t *this,
if (!rframe) {
goto out;
}
- rlocal = mem_get0 (this->local_pool);
+ rlocal = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!rlocal) {
goto out;
}
@@ -120,14 +180,14 @@ stripe_entry_self_heal (call_frame_t *frame, xlator_t *this,
loc_copy (&rlocal->loc, &local->loc);
memcpy (&rlocal->stbuf, &local->stbuf, sizeof (struct iatt));
- xdata = dict_new ();
- if (!xdata)
+ dict = dict_new ();
+ if (!dict)
goto out;
- ret = dict_set_static_bin (xdata, "gfid-req", local->stbuf.ia_gfid, 16);
+ ret = dict_set_static_bin (dict, "gfid-req", local->stbuf.ia_gfid, 16);
if (ret)
gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set gfid-req", local->loc.path);
+ "failed to set gfid-req");
while (trav) {
if (IA_ISREG (local->stbuf.ia_type)) {
@@ -135,43 +195,93 @@ stripe_entry_self_heal (call_frame_t *frame, xlator_t *this,
trav->xlator, trav->xlator->fops->mknod,
&local->loc,
st_mode_from_ia (local->stbuf.ia_prot,
- local->stbuf.ia_type),
- 0, 0, xdata);
+ local->stbuf.ia_type), 0,
+ dict);
}
if (IA_ISDIR (local->stbuf.ia_type)) {
STACK_WIND (rframe, stripe_sh_make_entry_cbk,
trav->xlator, trav->xlator->fops->mkdir,
- &local->loc,
- st_mode_from_ia (local->stbuf.ia_prot,
- local->stbuf.ia_type),
- 0, xdata);
+ &local->loc, st_mode_from_ia (local->stbuf.ia_prot,
+ local->stbuf.ia_type),
+ dict);
}
trav = trav->next;
}
- if (xdata)
- dict_unref (xdata);
- return 0;
-
out:
if (rframe)
STRIPE_STACK_DESTROY (rframe);
- if (xdata)
- dict_unref (xdata);
+ if (dict)
+ dict_unref (dict);
return 0;
}
+void
+stripe_aggregate (dict_t *this, char *key, data_t *value, void *data)
+{
+ dict_t *dst = NULL;
+ int64_t *ptr = 0, *size = NULL;
+ int32_t ret = -1;
+
+ dst = data;
+
+ if (strcmp (key, GF_XATTR_QUOTA_SIZE_KEY) == 0) {
+ ret = dict_get_bin (dst, key, (void **)&size);
+ if (ret < 0) {
+ size = GF_CALLOC (1, sizeof (int64_t),
+ gf_common_mt_char);
+ if (size == NULL) {
+ gf_log ("stripe", GF_LOG_WARNING,
+ "memory allocation failed");
+ return;
+ }
+ ret = dict_set_bin (dst, key, size, sizeof (int64_t));
+ if (ret < 0) {
+ gf_log ("stripe", GF_LOG_WARNING,
+ "stripe aggregate dict set failed");
+ GF_FREE (size);
+ return;
+ }
+ }
+
+ ptr = data_to_bin (value);
+ if (ptr == NULL) {
+ gf_log ("stripe", GF_LOG_WARNING, "data to bin failed");
+ return;
+ }
+
+ *size = hton64 (ntoh64 (*size) + ntoh64 (*ptr));
+ }
+
+ return;
+}
+
+
+void
+stripe_aggregate_xattr (dict_t *dst, dict_t *src)
+{
+ if ((dst == NULL) || (src == NULL)) {
+ goto out;
+ }
+
+ dict_foreach (src, stripe_aggregate, dst);
+out:
+ return;
+}
+
+
int32_t
stripe_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+ struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
- int32_t callcnt = 0;
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
- int ret = 0;
+ int32_t callcnt = 0;
+ dict_t *tmp_dict = NULL;
+ inode_t *tmp_inode = NULL;
+ stripe_local_t *local = NULL;
+ call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -202,81 +312,63 @@ stripe_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
local->op_ret = 0;
- if (IA_ISREG (buf->ia_type)) {
- ret = stripe_ctx_handle (this, prev, local,
- xdata);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Error getting fctx info from"
- " dict");
- }
if (FIRST_CHILD(this) == prev->this) {
local->stbuf = *buf;
local->postparent = *postparent;
local->inode = inode_ref (inode);
- if (xdata)
- local->xdata = dict_ref (xdata);
- if (local->xattr) {
- stripe_aggregate_xattr (local->xdata,
- local->xattr);
- dict_unref (local->xattr);
- local->xattr = NULL;
- }
}
- if (!local->xdata && !local->xattr) {
- local->xattr = dict_ref (xdata);
- } else if (local->xdata) {
- stripe_aggregate_xattr (local->xdata, xdata);
- } else if (local->xattr) {
- stripe_aggregate_xattr (local->xattr, xdata);
+ if (local->dict == NULL) {
+ local->dict = dict_ref (dict);
+ } else {
+ stripe_aggregate_xattr (local->dict, dict);
}
local->stbuf_blocks += buf->ia_blocks;
local->postparent_blocks += postparent->ia_blocks;
- correct_file_size(buf, local->fctx, prev);
-
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
if (local->postparent_size < postparent->ia_size)
local->postparent_size = postparent->ia_size;
- if (uuid_is_null (local->ia_gfid))
- uuid_copy (local->ia_gfid, buf->ia_gfid);
-
/* Make sure the gfid on all the nodes are same */
- if (uuid_compare (local->ia_gfid, buf->ia_gfid)) {
+ if (uuid_compare (local->stbuf.ia_gfid, buf->ia_gfid)) {
gf_log (this->name, GF_LOG_WARNING,
- "%s: gfid different on subvolume %s",
- local->loc.path, prev->this->name);
+ "%s: gfid different on subvolume",
+ local->loc.path);
}
}
}
UNLOCK (&frame->lock);
if (!callcnt) {
- if (local->op_ret == 0 && local->entry_self_heal_needed &&
- !uuid_is_null (local->loc.inode->gfid))
+ if (local->op_ret == 0 && local->entry_self_heal_needed)
stripe_entry_self_heal (frame, this, local);
if (local->failed)
local->op_ret = -1;
+ tmp_dict = local->dict;
+ tmp_inode = local->inode;
+
if (local->op_ret != -1) {
local->stbuf.ia_blocks = local->stbuf_blocks;
local->stbuf.ia_size = local->stbuf_size;
local->postparent.ia_blocks = local->postparent_blocks;
local->postparent.ia_size = local->postparent_size;
- inode_ctx_put (local->inode, this,
- (uint64_t) (long)local->fctx);
}
STRIPE_STACK_UNWIND (lookup, frame, local->op_ret,
local->op_errno, local->inode,
- &local->stbuf, local->xdata,
+ &local->stbuf, local->dict,
&local->postparent);
+
+ if (tmp_inode)
+ inode_unref (tmp_inode);
+ if (tmp_dict)
+ dict_unref (tmp_dict);
}
out:
return 0;
@@ -284,15 +376,12 @@ out:
int32_t
stripe_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+ dict_t *xattr_req)
{
- stripe_local_t *local = NULL;
- xlator_list_t *trav = NULL;
- stripe_private_t *priv = NULL;
+ stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ stripe_private_t *priv = NULL;
int32_t op_errno = EINVAL;
- int64_t filesize = 0;
- int ret = 0;
- uint64_t tmpctx = 0;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -304,7 +393,8 @@ stripe_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -313,50 +403,16 @@ stripe_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
frame->local = local;
loc_copy (&local->loc, loc);
- inode_ctx_get (local->inode, this, &tmpctx);
- if (tmpctx)
- local->fctx = (stripe_fd_ctx_t*) (long)tmpctx;
-
- /* quick-read friendly changes */
- if (xdata && dict_get (xdata, GF_CONTENT_KEY)) {
- ret = dict_get_int64 (xdata, GF_CONTENT_KEY, &filesize);
- if (!ret && (filesize > priv->block_size))
- dict_del (xdata, GF_CONTENT_KEY);
- }
-
- /* get stripe-size xattr on lookup. This would be required for
- * open/read/write/pathinfo calls. Hence we send down the request
- * even when type == IA_INVAL */
-
- /*
- * We aren't guaranteed to have xdata here. We need the format info for
- * the file, so allocate xdata if necessary.
- */
- if (!xdata)
- xdata = dict_new();
- else
- xdata = dict_ref(xdata);
-
- if (xdata && (IA_ISREG (loc->inode->ia_type) ||
- (loc->inode->ia_type == IA_INVAL))) {
- ret = stripe_xattr_request_build (this, xdata, 8, 4, 4, 0);
- if (ret)
- gf_log (this->name , GF_LOG_ERROR, "Failed to build"
- " xattr request for %s", loc->path);
-
- }
-
/* Everytime in stripe lookup, all child nodes
should be looked up */
local->call_count = priv->child_count;
while (trav) {
STACK_WIND (frame, stripe_lookup_cbk, trav->xlator,
- trav->xlator->fops->lookup, loc, xdata);
+ trav->xlator->fops->lookup,
+ loc, xattr_req);
trav = trav->next;
}
- dict_unref(xdata);
-
return 0;
err:
STRIPE_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
@@ -366,7 +422,7 @@ err:
int32_t
stripe_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -401,9 +457,6 @@ stripe_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
local->stbuf_blocks += buf->ia_blocks;
-
- correct_file_size(buf, local->fctx, prev);
-
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
}
@@ -420,19 +473,18 @@ stripe_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STRIPE_STACK_UNWIND (stat, frame, local->op_ret,
- local->op_errno, &local->stbuf, NULL);
+ local->op_errno, &local->stbuf);
}
out:
return 0;
}
int32_t
-stripe_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+stripe_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = EINVAL;
VALIDATE_OR_GOTO (frame, err);
@@ -450,7 +502,8 @@ stripe_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -459,30 +512,23 @@ stripe_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
frame->local = local;
local->call_count = priv->child_count;
- if (IA_ISREG(loc->inode->ia_type)) {
- inode_ctx_get(loc->inode, this, (uint64_t *) &fctx);
- if (!fctx)
- goto err;
- local->fctx = fctx;
- }
-
while (trav) {
STACK_WIND (frame, stripe_stat_cbk, trav->xlator,
- trav->xlator->fops->stat, loc, NULL);
+ trav->xlator->fops->stat, loc);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
return 0;
}
int32_t
stripe_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *stbuf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *stbuf)
{
stripe_local_t *local = NULL;
int32_t callcnt = 0;
@@ -520,14 +566,14 @@ stripe_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!callcnt) {
STRIPE_STACK_UNWIND (statfs, frame, local->op_ret,
- local->op_errno, &local->statvfs_buf, NULL);
+ local->op_errno, &local->statvfs_buf);
}
out:
return 0;
}
int32_t
-stripe_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+stripe_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
@@ -542,7 +588,8 @@ stripe_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
priv = this->private;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -554,13 +601,13 @@ stripe_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
local->call_count = priv->child_count;
while (trav) {
STACK_WIND (frame, stripe_statfs_cbk, trav->xlator,
- trav->xlator->fops->statfs, loc, NULL);
+ trav->xlator->fops->statfs, loc);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (statfs, frame, -1, op_errno, NULL);
return 0;
}
@@ -569,7 +616,7 @@ err:
int32_t
stripe_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -607,9 +654,6 @@ stripe_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->prebuf_blocks += prebuf->ia_blocks;
local->postbuf_blocks += postbuf->ia_blocks;
- correct_file_size(prebuf, local->fctx, prev);
- correct_file_size(postbuf, local->fctx, prev);
-
if (local->prebuf_size < prebuf->ia_size)
local->prebuf_size = prebuf->ia_size;
@@ -632,21 +676,19 @@ stripe_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (truncate, frame, local->op_ret,
local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
+ &local->post_buf);
}
out:
return 0;
}
int32_t
-stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata)
+stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
+ xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = EINVAL;
- int i, eof_idx;
- off_t dest_offset, tmp_offset;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -655,6 +697,7 @@ stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
VALIDATE_OR_GOTO (loc->inode, err);
priv = this->private;
+ trav = this->children;
if (priv->first_child_down) {
op_errno = ENOTCONN;
@@ -662,7 +705,8 @@ stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -671,55 +715,15 @@ stripe_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
frame->local = local;
local->call_count = priv->child_count;
- inode_ctx_get(loc->inode, this, (uint64_t *) &fctx);
- if (!fctx) {
- gf_log(this->name, GF_LOG_ERROR, "no stripe context");
- op_errno = EINVAL;
- goto err;
- }
-
- local->fctx = fctx;
- eof_idx = (offset / fctx->stripe_size) % fctx->stripe_count;
-
- for (i = 0; i < fctx->stripe_count; i++) {
- if (!fctx->xl_array[i]) {
- gf_log(this->name, GF_LOG_ERROR,
- "no xlator at index %d", i);
- op_errno = EINVAL;
- goto err;
- }
-
- if (fctx->stripe_coalesce) {
- /*
- * The node that owns EOF is truncated to the exact
- * coalesced offset. Nodes prior to this index should
- * be rounded up to the size of the complete stripe,
- * while nodes after this index should be rounded down
- * to the size of the previous stripe.
- */
- if (i < eof_idx)
- tmp_offset = roof(offset, fctx->stripe_size *
- fctx->stripe_count);
- else if (i > eof_idx)
- tmp_offset = floor(offset, fctx->stripe_size *
- fctx->stripe_count);
- else
- tmp_offset = offset;
-
- dest_offset = coalesced_offset(tmp_offset,
- fctx->stripe_size, fctx->stripe_count);
- } else {
- dest_offset = offset;
- }
-
- STACK_WIND(frame, stripe_truncate_cbk, fctx->xl_array[i],
- fctx->xl_array[i]->fops->truncate, loc, dest_offset,
- NULL);
- }
+ while (trav) {
+ STACK_WIND (frame, stripe_truncate_cbk, trav->xlator,
+ trav->xlator->fops->truncate, loc, offset);
+ trav = trav->next;
+ }
return 0;
err:
- STRIPE_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -727,7 +731,7 @@ err:
int32_t
stripe_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -766,9 +770,6 @@ stripe_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->prebuf_blocks += preop->ia_blocks;
local->postbuf_blocks += postop->ia_blocks;
- correct_file_size(preop, local->fctx, prev);
- correct_file_size(postop, local->fctx, prev);
-
if (local->prebuf_size < preop->ia_size)
local->prebuf_size = preop->ia_size;
if (local->postbuf_size < postop->ia_size)
@@ -790,7 +791,7 @@ stripe_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (setattr, frame, local->op_ret,
local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
+ &local->post_buf);
}
out:
return 0;
@@ -799,12 +800,11 @@ out:
int32_t
stripe_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = EINVAL;
VALIDATE_OR_GOTO (frame, err);
@@ -822,47 +822,33 @@ stripe_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
local->op_ret = -1;
frame->local = local;
- if (!IA_ISDIR (loc->inode->ia_type) &&
- !IA_ISREG (loc->inode->ia_type)) {
- local->call_count = 1;
- STACK_WIND (frame, stripe_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, NULL);
- return 0;
- }
-
- if (IA_ISREG(loc->inode->ia_type)) {
- inode_ctx_get(loc->inode, this, (uint64_t *) &fctx);
- if (!fctx)
- goto err;
- local->fctx = fctx;
- }
-
local->call_count = priv->child_count;
+
while (trav) {
STACK_WIND (frame, stripe_setattr_cbk,
trav->xlator, trav->xlator->fops->setattr,
- loc, stbuf, valid, NULL);
+ loc, stbuf, valid);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
stripe_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
@@ -878,7 +864,8 @@ stripe_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -889,13 +876,13 @@ stripe_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
while (trav) {
STACK_WIND (frame, stripe_setattr_cbk, trav->xlator,
- trav->xlator->fops->fsetattr, fd, stbuf, valid, NULL);
+ trav->xlator->fops->fsetattr, fd, stbuf, valid);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -903,8 +890,7 @@ int32_t
stripe_stack_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -941,8 +927,6 @@ stripe_stack_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->pre_buf.ia_blocks += prenewparent->ia_blocks;
local->post_buf.ia_blocks += postnewparent->ia_blocks;
- correct_file_size(buf, local->fctx, prev);
-
if (local->stbuf.ia_size < buf->ia_size)
local->stbuf.ia_size = buf->ia_size;
@@ -968,7 +952,7 @@ stripe_stack_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (rename, frame, local->op_ret, local->op_errno,
&local->stbuf, &local->preparent,
&local->postparent, &local->pre_buf,
- &local->post_buf, NULL);
+ &local->post_buf);
}
out:
return 0;
@@ -978,8 +962,7 @@ int32_t
stripe_first_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
@@ -1010,25 +993,24 @@ stripe_first_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
while (trav) {
STACK_WIND (frame, stripe_stack_rename_cbk,
trav->xlator, trav->xlator->fops->rename,
- &local->loc, &local->loc2, NULL);
+ &local->loc, &local->loc2);
trav = trav->next;
}
return 0;
unwind:
STRIPE_STACK_UNWIND (rename, frame, -1, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, NULL);
+ postoldparent, prenewparent, postnewparent);
return 0;
}
int32_t
stripe_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
stripe_private_t *priv = NULL;
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = EINVAL;
VALIDATE_OR_GOTO (frame, err);
@@ -1048,7 +1030,8 @@ stripe_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -1059,67 +1042,24 @@ stripe_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
local->call_count = priv->child_count;
- if (IA_ISREG(oldloc->inode->ia_type)) {
- inode_ctx_get(oldloc->inode, this, (uint64_t *) &fctx);
- if (!fctx)
- goto err;
- local->fctx = fctx;
- }
-
frame->local = local;
STACK_WIND (frame, stripe_first_rename_cbk, trav->xlator,
- trav->xlator->fops->rename, oldloc, newloc, NULL);
+ trav->xlator->fops->rename, oldloc, newloc);
return 0;
err:
STRIPE_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-int32_t
-stripe_first_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- local = frame->local;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s returned %s",
- prev->this->name, strerror (op_errno));
- goto out;
- }
- local->op_ret = 0;
- local->preparent = *preparent;
- local->postparent = *postparent;
- local->preparent_blocks += preparent->ia_blocks;
- local->postparent_blocks += postparent->ia_blocks;
-
- STRIPE_STACK_UNWIND(unlink, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, xdata);
- return 0;
-out:
- STRIPE_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
-
+ NULL, NULL);
return 0;
}
-
int32_t
stripe_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -1141,33 +1081,49 @@ stripe_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_DEBUG, "%s returned %s",
prev->this->name, strerror (op_errno));
local->op_errno = op_errno;
- if (op_errno != ENOENT) {
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
local->failed = 1;
- local->op_ret = op_ret;
+ }
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ if (FIRST_CHILD(this) == prev->this) {
+ local->preparent = *preparent;
+ local->postparent = *postparent;
}
+ local->preparent_blocks += preparent->ia_blocks;
+ local->postparent_blocks += postparent->ia_blocks;
+
+ if (local->preparent_size < preparent->ia_size)
+ local->preparent_size = preparent->ia_size;
+
+ if (local->postparent_size < postparent->ia_size)
+ local->postparent_size = postparent->ia_size;
}
}
UNLOCK (&frame->lock);
- if (callcnt == 1) {
- if (local->failed) {
- op_errno = local->op_errno;
- goto out;
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->op_ret != -1) {
+ local->preparent.ia_blocks = local->preparent_blocks;
+ local->preparent.ia_size = local->preparent_size;
+ local->postparent.ia_blocks = local->postparent_blocks;
+ local->postparent.ia_size = local->postparent_size;
}
- STACK_WIND(frame, stripe_first_unlink_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->unlink, &local->loc,
- local->xflag, local->xdata);
+
+ STRIPE_STACK_UNWIND (unlink, frame, local->op_ret,
+ local->op_errno, &local->preparent,
+ &local->postparent);
}
- return 0;
out:
- STRIPE_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
-
return 0;
}
int32_t
-stripe_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int xflag, dict_t *xdata)
+stripe_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
@@ -1195,32 +1151,26 @@ stripe_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
local->op_ret = -1;
- loc_copy (&local->loc, loc);
- local->xflag = xflag;
-
- if (xdata)
- local->xdata = dict_ref (xdata);
-
frame->local = local;
local->call_count = priv->child_count;
- trav = trav->next; /* Skip the first child */
while (trav) {
STACK_WIND (frame, stripe_unlink_cbk,
trav->xlator, trav->xlator->fops->unlink,
- loc, xflag, xdata);
+ loc);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -1228,8 +1178,10 @@ err:
int32_t
stripe_first_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
+
{
+ xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
if (!this || !frame || !frame->local) {
@@ -1242,10 +1194,11 @@ stripe_first_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto err;
}
+ trav = this->children;
local = frame->local;
- local->op_ret = 0;
local->call_count--; /* First child successful */
+ trav = trav->next; /* Skip first child */
local->preparent = *preparent;
local->postparent = *postparent;
@@ -1254,60 +1207,22 @@ stripe_first_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->preparent_blocks += preparent->ia_blocks;
local->postparent_blocks += postparent->ia_blocks;
- STRIPE_STACK_UNWIND (rmdir, frame, local->op_ret, local->op_errno,
- &local->preparent, &local->postparent, xdata);
- return 0;
-err:
- STRIPE_STACK_UNWIND (rmdir, frame, op_ret, op_errno, NULL, NULL, NULL);
- return 0;
-
-}
-
-int32_t
-stripe_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- int32_t callcnt = 0;
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s returned %s",
- prev->this->name, strerror (op_errno));
- if (op_errno != ENOENT)
- local->failed = 1;
- }
+ while (trav) {
+ STACK_WIND (frame, stripe_unlink_cbk, trav->xlator,
+ trav->xlator->fops->rmdir, &local->loc,
+ local->flags);
+ trav = trav->next;
}
- UNLOCK (&frame->lock);
- if (callcnt == 1) {
- if (local->failed)
- goto out;
- STACK_WIND (frame, stripe_first_rmdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rmdir, &local->loc,
- local->flags, NULL);
- }
return 0;
-out:
- STRIPE_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
+err:
+ STRIPE_STACK_UNWIND (rmdir, frame, op_ret, op_errno, NULL, NULL);
return 0;
+
}
int32_t
-stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
+stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
@@ -1330,7 +1245,8 @@ stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -1340,17 +1256,13 @@ stripe_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t
loc_copy (&local->loc, loc);
local->flags = flags;
local->call_count = priv->child_count;
- trav = trav->next; /* skip the first child */
- while (trav) {
- STACK_WIND (frame, stripe_rmdir_cbk, trav->xlator,
- trav->xlator->fops->rmdir, loc, flags, NULL);
- trav = trav->next;
- }
+ STACK_WIND (frame, stripe_first_rmdir_cbk, trav->xlator,
+ trav->xlator->fops->rmdir, loc, flags);
return 0;
err:
- STRIPE_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -1359,7 +1271,7 @@ int32_t
stripe_mknod_ifreg_fail_unlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -1380,7 +1292,7 @@ stripe_mknod_ifreg_fail_unlink_cbk (call_frame_t *frame, void *cookie,
if (!callcnt) {
STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
}
out:
return 0;
@@ -1392,7 +1304,7 @@ out:
int32_t
stripe_mknod_ifreg_setxattr_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -1431,7 +1343,7 @@ stripe_mknod_ifreg_setxattr_cbk (call_frame_t *frame, void *cookie,
stripe_mknod_ifreg_fail_unlink_cbk,
trav->xlator,
trav->xlator->fops->unlink,
- &local->loc, 0, NULL);
+ &local->loc);
trav = trav->next;
}
return 0;
@@ -1439,7 +1351,7 @@ stripe_mknod_ifreg_setxattr_cbk (call_frame_t *frame, void *cookie,
STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
}
out:
return 0;
@@ -1449,13 +1361,13 @@ int32_t
stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
+ int ret = 0;
int32_t callcnt = 0;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
call_frame_t *prev = NULL;
- xlator_list_t *trav = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -1463,7 +1375,7 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
prev = cookie;
- priv = this->private;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -1479,24 +1391,20 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->failed = 1;
local->op_errno = op_errno;
}
+
if (op_ret >= 0) {
local->op_ret = op_ret;
- /* Can be used as a mechanism to understand if mknod
- was successful in at least one place */
- if (uuid_is_null (local->ia_gfid))
- uuid_copy (local->ia_gfid, buf->ia_gfid);
-
- if (stripe_ctx_handle(this, prev, local, xdata))
- gf_log(this->name, GF_LOG_ERROR,
- "Error getting fctx info from dict");
+ if (FIRST_CHILD(this) == prev->this) {
+ local->stbuf = *buf;
+ local->preparent = *preparent;
+ local->postparent = *postparent;
+ }
local->stbuf_blocks += buf->ia_blocks;
local->preparent_blocks += preparent->ia_blocks;
local->postparent_blocks += postparent->ia_blocks;
- correct_file_size(buf, local->fctx, prev);
-
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
if (local->preparent_size < preparent->ia_size)
@@ -1511,23 +1419,6 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
- if ((local->op_ret == -1) && !uuid_is_null (local->ia_gfid)) {
- /* ia_gfid set means, at least on one node 'mknod'
- is successful */
- local->call_count = priv->child_count;
- trav = this->children;
- while (trav) {
- STACK_WIND (frame,
- stripe_mknod_ifreg_fail_unlink_cbk,
- trav->xlator,
- trav->xlator->fops->unlink,
- &local->loc, 0, NULL);
- trav = trav->next;
- }
- return 0;
- }
-
-
if (local->op_ret != -1) {
local->preparent.ia_blocks = local->preparent_blocks;
local->preparent.ia_size = local->preparent_size;
@@ -1535,109 +1426,72 @@ stripe_mknod_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->postparent.ia_size = local->postparent_size;
local->stbuf.ia_size = local->stbuf_size;
local->stbuf.ia_blocks = local->stbuf_blocks;
- inode_ctx_put (local->inode, this,
- (uint64_t)(long) local->fctx);
-
}
- STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
- local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
- }
-out:
- return 0;
-}
+ if ((local->op_ret != -1) && priv->xattr_supported) {
+ /* Send a setxattr request to nodes where the
+ files are created */
+ int32_t i = 0;
+ char size_key[256] = {0,};
+ char index_key[256] = {0,};
+ char count_key[256] = {0,};
+ dict_t *dict = NULL;
+
+ sprintf (size_key,
+ "trusted.%s.stripe-size", this->name);
+ sprintf (count_key,
+ "trusted.%s.stripe-count", this->name);
+ sprintf (index_key,
+ "trusted.%s.stripe-index", this->name);
-int32_t
-stripe_mknod_first_ifreg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- stripe_private_t *priv = NULL;
- call_frame_t *prev = NULL;
- xlator_list_t *trav = NULL;
- int i = 1;
- dict_t *dict = NULL;
- int ret = 0;
- int need_unref = 0;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- priv = this->private;
- local = frame->local;
- trav = this->children;
-
- local->call_count--;
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s returned error %s",
- prev->this->name, strerror (op_errno));
- local->failed = 1;
- local->op_errno = op_errno;
- goto out;
- }
-
- local->op_ret = op_ret;
+ local->call_count = priv->child_count;
+ memcpy (local->loc.inode->gfid, local->stbuf.ia_gfid, 16);
+ for (i = 0; i < priv->child_count; i++) {
+ dict = get_new_dict ();
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to allocate dict");
+ }
- local->stbuf = *buf;
- local->preparent = *preparent;
- local->postparent = *postparent;
+ dict_ref (dict);
+ /* TODO: check return value */
+ ret = dict_set_int64 (dict, size_key,
+ local->stripe_size);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set stripe-size failed",
+ local->loc.path);
+ ret = dict_set_int32 (dict, count_key,
+ priv->child_count);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set child_count failed",
+ local->loc.path);
+ ret = dict_set_int32 (dict, index_key, i);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set stripe-index failed",
+ local->loc.path);
- if (uuid_is_null (local->ia_gfid))
- uuid_copy (local->ia_gfid, buf->ia_gfid);
- local->preparent.ia_blocks = local->preparent_blocks;
- local->preparent.ia_size = local->preparent_size;
- local->postparent.ia_blocks = local->postparent_blocks;
- local->postparent.ia_size = local->postparent_size;
- local->stbuf.ia_size = local->stbuf_size;
- local->stbuf.ia_blocks = local->stbuf_blocks;
+ STACK_WIND (frame,
+ stripe_mknod_ifreg_setxattr_cbk,
+ priv->xl_array[i],
+ priv->xl_array[i]->fops->setxattr,
+ &local->loc, dict, 0);
- trav = trav->next;
- while (trav) {
- if (priv->xattr_supported) {
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to allocate dict %s", local->loc.path);
+ dict_unref (dict);
}
- need_unref = 1;
-
- dict_copy (local->xattr, dict);
-
- ret = stripe_xattr_request_build (this, dict,
- local->stripe_size,
- priv->child_count, i,
- priv->coalesce);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to build xattr request");
-
- } else {
- dict = local->xattr;
+ return 0;
}
- STACK_WIND (frame, stripe_mknod_ifreg_cbk,
- trav->xlator, trav->xlator->fops->mknod,
- &local->loc, local->mode, local->rdev, 0, dict);
- trav = trav->next;
- i++;
-
- if (dict && need_unref)
- dict_unref (dict);
+ /* Create itself has failed.. so return
+ without setxattring */
+ STRIPE_STACK_UNWIND (mknod, frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf,
+ &local->preparent, &local->postparent);
}
-
- return 0;
-
out:
-
- STRIPE_STACK_UNWIND (mknod, frame, op_ret, op_errno, NULL, NULL, NULL, NULL, NULL);
- return 0;
+ return 0;
}
@@ -1645,25 +1499,22 @@ int32_t
stripe_single_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STRIPE_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *params)
{
- stripe_private_t *priv = NULL;
- stripe_local_t *local = NULL;
- int32_t op_errno = EINVAL;
- int32_t i = 0;
- dict_t *dict = NULL;
- int ret = 0;
- int need_unref = 0;
+ stripe_private_t *priv = NULL;
+ stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ int32_t op_errno = EINVAL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -1672,6 +1523,7 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
VALIDATE_OR_GOTO (loc->inode, err);
priv = this->private;
+ trav = this->children;
if (priv->first_child_down) {
op_errno = ENOTCONN;
@@ -1690,63 +1542,43 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->stripe_size = stripe_get_matching_bs (loc->path, priv);
+ local->stripe_size = stripe_get_matching_bs (loc->path,
+ priv->pattern,
+ priv->block_size);
frame->local = local;
- local->inode = inode_ref (loc->inode);
+ local->inode = loc->inode;
loc_copy (&local->loc, loc);
- local->xattr = dict_copy_with_ref (xdata, NULL);
- local->mode = mode;
- local->umask = umask;
- local->rdev = rdev;
/* Everytime in stripe lookup, all child nodes should
be looked up */
local->call_count = priv->child_count;
- if (priv->xattr_supported) {
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to allocate dict %s", loc->path);
- }
- need_unref = 1;
-
- dict_copy (xdata, dict);
-
- ret = stripe_xattr_request_build (this, dict,
- local->stripe_size,
- priv->child_count,
- i, priv->coalesce);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to build xattr request");
- } else {
- dict = xdata;
+ while (trav) {
+ STACK_WIND (frame, stripe_mknod_ifreg_cbk,
+ trav->xlator, trav->xlator->fops->mknod,
+ loc, mode, rdev, params);
+ trav = trav->next;
}
- STACK_WIND (frame, stripe_mknod_first_ifreg_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->mknod,
- loc, mode, rdev, umask, dict);
-
- if (dict && need_unref)
- dict_unref (dict);
+ /* This case is handled, no need to continue further. */
return 0;
}
STACK_WIND (frame, stripe_single_mknod_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
+ loc, mode, rdev, params);
return 0;
err:
- STRIPE_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -1755,10 +1587,11 @@ int32_t
stripe_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
+ inode_t *local_inode = NULL;
call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
@@ -1786,6 +1619,12 @@ stripe_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
local->op_ret = 0;
+ if (FIRST_CHILD(this) == prev->this) {
+ local->inode = inode_ref (inode);
+ local->stbuf = *buf;
+ local->postparent = *postparent;
+ local->preparent = *preparent;
+ }
local->stbuf_blocks += buf->ia_blocks;
local->preparent_blocks += preparent->ia_blocks;
local->postparent_blocks += postparent->ia_blocks;
@@ -1801,7 +1640,12 @@ stripe_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&frame->lock);
if (!callcnt) {
- if (local->failed != -1) {
+ if (local->failed)
+ local->op_ret = -1;
+
+ local_inode = local->inode;
+
+ if (local->op_ret != -1) {
local->preparent.ia_blocks = local->preparent_blocks;
local->preparent.ia_size = local->preparent_size;
local->postparent.ia_blocks = local->postparent_blocks;
@@ -1812,76 +1656,19 @@ stripe_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (mkdir, frame, local->op_ret,
local->op_errno, local->inode,
&local->stbuf, &local->preparent,
- &local->postparent, NULL);
- }
-out:
- return 0;
-}
-
-
-int32_t
-stripe_first_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- call_frame_t *prev = NULL;
- xlator_list_t *trav = NULL;
-
- if (!this || !frame || !frame->local || !cookie) {
- gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
- goto out;
- }
-
- prev = cookie;
- local = frame->local;
- trav = this->children;
-
- local->call_count--; /* first child is successful */
- trav = trav->next; /* skip first child */
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s returned error %s",
- prev->this->name, strerror (op_errno));
- local->op_errno = op_errno;
- goto out;
- }
-
- local->op_ret = 0;
-
- local->inode = inode_ref (inode);
- local->stbuf = *buf;
- local->postparent = *postparent;
- local->preparent = *preparent;
-
- local->stbuf_blocks += buf->ia_blocks;
- local->preparent_blocks += preparent->ia_blocks;
- local->postparent_blocks += postparent->ia_blocks;
-
- local->stbuf_size = buf->ia_size;
- local->preparent_size = preparent->ia_size;
- local->postparent_size = postparent->ia_size;
+ &local->postparent);
- while (trav) {
- STACK_WIND (frame, stripe_mkdir_cbk, trav->xlator,
- trav->xlator->fops->mkdir, &local->loc, local->mode,
- local->umask, local->xdata);
- trav = trav->next;
+ if (local_inode)
+ inode_unref (local_inode);
}
- return 0;
out:
- STRIPE_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
return 0;
-
}
int
stripe_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
stripe_private_t *priv = NULL;
stripe_local_t *local = NULL;
@@ -1903,27 +1690,27 @@ stripe_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
local->op_ret = -1;
local->call_count = priv->child_count;
- if (xdata)
- local->xdata = dict_ref (xdata);
- local->mode = mode;
- local->umask = umask;
- loc_copy (&local->loc, loc);
frame->local = local;
/* Everytime in stripe lookup, all child nodes should be looked up */
- STACK_WIND (frame, stripe_first_mkdir_cbk, trav->xlator,
- trav->xlator->fops->mkdir, loc, mode, umask, xdata);
+ while (trav) {
+ STACK_WIND (frame, stripe_mkdir_cbk,
+ trav->xlator, trav->xlator->fops->mkdir,
+ loc, mode, params);
+ trav = trav->next;
+ }
return 0;
err:
- STRIPE_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -1932,12 +1719,12 @@ int32_t
stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
+ inode_t *local_inode = NULL;
call_frame_t *prev = NULL;
- stripe_fd_ctx_t *fctx = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -1964,16 +1751,6 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
local->op_ret = 0;
- if (IA_ISREG(inode->ia_type)) {
- inode_ctx_get(inode, this, (uint64_t *) &fctx);
- if (!fctx) {
- gf_log(this->name, GF_LOG_ERROR,
- "failed to get stripe context");
- op_ret = -1;
- op_errno = EINVAL;
- }
- }
-
if (FIRST_CHILD(this) == prev->this) {
local->inode = inode_ref (inode);
local->stbuf = *buf;
@@ -1984,8 +1761,6 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->preparent_blocks += preparent->ia_blocks;
local->postparent_blocks += postparent->ia_blocks;
- correct_file_size(buf, fctx, prev);
-
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
if (local->preparent_size < preparent->ia_size)
@@ -2000,6 +1775,8 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
+ local_inode = local->inode;
+
if (local->op_ret != -1) {
local->preparent.ia_blocks = local->preparent_blocks;
local->preparent.ia_size = local->preparent_size;
@@ -2011,14 +1788,17 @@ stripe_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (link, frame, local->op_ret,
local->op_errno, local->inode,
&local->stbuf, &local->preparent,
- &local->postparent, NULL);
+ &local->postparent);
+
+ if (local_inode)
+ inode_unref (local_inode);
}
out:
return 0;
}
int32_t
-stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
@@ -2041,7 +1821,8 @@ stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2055,13 +1836,13 @@ stripe_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
while (trav) {
STACK_WIND (frame, stripe_link_cbk,
trav->xlator, trav->xlator->fops->link,
- oldloc, newloc, NULL);
+ oldloc, newloc);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -2069,10 +1850,12 @@ int32_t
stripe_create_fail_unlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t callcnt = 0;
+ fd_t *lfd = NULL;
stripe_local_t *local = NULL;
+ inode_t *local_inode = NULL;
if (!this || !frame || !frame->local) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -2088,9 +1871,17 @@ stripe_create_fail_unlink_cbk (call_frame_t *frame, void *cookie,
UNLOCK (&frame->lock);
if (!callcnt) {
+ local_inode = local->inode;
+ lfd = local->fd;
+
STRIPE_STACK_UNWIND (create, frame, local->op_ret, local->op_errno,
local->fd, local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ &local->preparent, &local->postparent);
+
+ if (local_inode)
+ inode_unref (local_inode);
+ if (lfd)
+ fd_unref (lfd);
}
out:
return 0;
@@ -2098,16 +1889,16 @@ out:
int32_t
-stripe_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd,
- inode_t *inode, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+stripe_create_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- int32_t callcnt = 0;
+ inode_t *local_inode = NULL;
+ fd_t *lfd = NULL;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- call_frame_t *prev = NULL;
xlator_list_t *trav = NULL;
+ int32_t callcnt = 0;
+ call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -2115,7 +1906,7 @@ stripe_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
prev = cookie;
- priv = this->private;
+ priv = this->private;
local = frame->local;
LOCK (&frame->lock);
@@ -2126,40 +1917,13 @@ stripe_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_DEBUG,
"%s returned error %s",
prev->this->name, strerror (op_errno));
- local->failed = 1;
+ local->op_ret = -1;
local->op_errno = op_errno;
}
-
- if (op_ret >= 0) {
- if (IA_ISREG(buf->ia_type)) {
- if (stripe_ctx_handle(this, prev, local, xdata))
- gf_log(this->name, GF_LOG_ERROR,
- "Error getting fctx info from "
- "dict");
- }
-
- local->op_ret = op_ret;
-
- local->stbuf_blocks += buf->ia_blocks;
- local->preparent_blocks += preparent->ia_blocks;
- local->postparent_blocks += postparent->ia_blocks;
-
- correct_file_size(buf, local->fctx, prev);
-
- if (local->stbuf_size < buf->ia_size)
- local->stbuf_size = buf->ia_size;
- if (local->preparent_size < preparent->ia_size)
- local->preparent_size = preparent->ia_size;
- if (local->postparent_size < postparent->ia_size)
- local->postparent_size = postparent->ia_size;
- }
}
UNLOCK (&frame->lock);
if (!callcnt) {
- if (local->failed)
- local->op_ret = -1;
-
if (local->op_ret == -1) {
local->call_count = priv->child_count;
trav = this->children;
@@ -2168,57 +1932,43 @@ stripe_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stripe_create_fail_unlink_cbk,
trav->xlator,
trav->xlator->fops->unlink,
- &local->loc, 0, NULL);
+ &local->loc);
trav = trav->next;
}
return 0;
}
- if (local->op_ret >= 0) {
- local->preparent.ia_blocks = local->preparent_blocks;
- local->preparent.ia_size = local->preparent_size;
- local->postparent.ia_blocks = local->postparent_blocks;
- local->postparent.ia_size = local->postparent_size;
- local->stbuf.ia_size = local->stbuf_size;
- local->stbuf.ia_blocks = local->stbuf_blocks;
+ lfd = local->fd;
+ local_inode = local->inode;
- stripe_copy_xl_array(local->fctx->xl_array,
- priv->xl_array,
- local->fctx->stripe_count);
- inode_ctx_put(local->inode, this,
- (uint64_t) local->fctx);
- }
+ STRIPE_STACK_UNWIND (create, frame, local->op_ret, local->op_errno,
+ local->fd, local->inode, &local->stbuf,
+ &local->preparent, &local->postparent);
- /* Create itself has failed.. so return
- without setxattring */
- STRIPE_STACK_UNWIND (create, frame, local->op_ret,
- local->op_errno, local->fd,
- local->inode, &local->stbuf,
- &local->preparent, &local->postparent, NULL);
+ if (local_inode)
+ inode_unref (local_inode);
+ if (lfd)
+ fd_unref (lfd);
}
-
out:
return 0;
}
-
-
int32_t
-stripe_first_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+stripe_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd,
inode_t *inode, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
+ int32_t callcnt = 0;
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
+ fd_t *lfd = NULL;
+ stripe_fd_ctx_t *fctx = NULL;
+ inode_t *local_inode = NULL;
call_frame_t *prev = NULL;
- xlator_list_t *trav = NULL;
- int i = 1;
- dict_t *dict = NULL;
- loc_t *loc = NULL;
- int32_t need_unref = 0;
- int32_t ret = -1;
+ int ret = 0;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -2228,89 +1978,149 @@ stripe_first_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
priv = this->private;
local = frame->local;
- trav = this->children;
- loc = &local->loc;
- --local->call_count;
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "%s returned error %s",
- prev->this->name, strerror (op_errno));
- local->failed = 1;
- local->op_errno = op_errno;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s returned error %s",
+ prev->this->name, strerror (op_errno));
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ local->op_errno = op_errno;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ /* Get the mapping in inode private */
+ /* Get the stat buf right */
+ if (FIRST_CHILD(this) == prev->this) {
+ local->stbuf = *buf;
+ local->preparent = *preparent;
+ local->postparent = *postparent;
+ }
+
+ local->stbuf_blocks += buf->ia_blocks;
+ local->preparent_blocks += preparent->ia_blocks;
+ local->postparent_blocks += postparent->ia_blocks;
+
+ if (local->stbuf_size < buf->ia_size)
+ local->stbuf_size = buf->ia_size;
+ if (local->preparent_size < preparent->ia_size)
+ local->preparent_size = preparent->ia_size;
+ if (local->postparent_size < postparent->ia_size)
+ local->postparent_size = postparent->ia_size;
+ }
}
+ UNLOCK (&frame->lock);
- local->op_ret = 0;
- /* Get the mapping in inode private */
- /* Get the stat buf right */
- local->stbuf = *buf;
- local->preparent = *preparent;
- local->postparent = *postparent;
+ if (!callcnt) {
+ if (local->failed)
+ local->op_ret = -1;
- local->stbuf_blocks += buf->ia_blocks;
- local->preparent_blocks += preparent->ia_blocks;
- local->postparent_blocks += postparent->ia_blocks;
+ if (local->op_ret != -1) {
+ local->preparent.ia_blocks = local->preparent_blocks;
+ local->preparent.ia_size = local->preparent_size;
+ local->postparent.ia_blocks = local->postparent_blocks;
+ local->postparent.ia_size = local->postparent_size;
+ local->stbuf.ia_size = local->stbuf_size;
+ local->stbuf.ia_blocks = local->stbuf_blocks;
+ }
- if (local->stbuf_size < buf->ia_size)
- local->stbuf_size = buf->ia_size;
- if (local->preparent_size < preparent->ia_size)
- local->preparent_size = preparent->ia_size;
- if (local->postparent_size < postparent->ia_size)
- local->postparent_size = postparent->ia_size;
+ /* */
+ if (local->op_ret >= 0) {
+ fctx = GF_CALLOC (1, sizeof (stripe_fd_ctx_t),
+ gf_stripe_mt_stripe_fd_ctx_t);
+ if (!fctx) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto unwind;
+ }
- if (local->failed)
- local->op_ret = -1;
+ fctx->stripe_size = local->stripe_size;
+ fctx->stripe_count = priv->child_count;
+ fctx->static_array = 1;
+ fctx->xl_array = priv->xl_array;
+ fd_ctx_set (local->fd, this,
+ (uint64_t)(long)fctx);
+ }
- if (local->op_ret == -1) {
- local->call_count = 1;
- STACK_WIND (frame, stripe_create_fail_unlink_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->unlink,
- &local->loc, 0, NULL);
- return 0;
- }
+ if ((local->op_ret != -1) &&
+ local->stripe_size && priv->xattr_supported) {
+ /* Send a setxattr request to nodes where
+ the files are created */
+ int32_t i = 0;
+ char size_key[256] = {0,};
+ char index_key[256] = {0,};
+ char count_key[256] = {0,};
+ dict_t *dict = NULL;
+
+ sprintf (size_key,
+ "trusted.%s.stripe-size", this->name);
+ sprintf (count_key,
+ "trusted.%s.stripe-count", this->name);
+ sprintf (index_key,
+ "trusted.%s.stripe-index", this->name);
- if (local->op_ret >= 0) {
- local->preparent.ia_blocks = local->preparent_blocks;
- local->preparent.ia_size = local->preparent_size;
- local->postparent.ia_blocks = local->postparent_blocks;
- local->postparent.ia_size = local->postparent_size;
- local->stbuf.ia_size = local->stbuf_size;
- local->stbuf.ia_blocks = local->stbuf_blocks;
- }
+ local->call_count = priv->child_count;
+ memcpy (local->loc.inode->gfid, local->stbuf.ia_gfid, 16);
+ for (i = 0; i < priv->child_count; i++) {
+ dict = get_new_dict ();
+ if (!dict) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error allocating dict");
+ }
+ dict_ref (dict);
- /* Send a setxattr request to nodes where the
- files are created */
- trav = trav->next;
- while (trav) {
- if (priv->xattr_supported) {
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to allocate dict %s", loc->path);
- }
- need_unref = 1;
+ /* TODO: check return values */
+ ret = dict_set_int64 (dict, size_key,
+ local->stripe_size);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set stripe-size failed",
+ local->loc.path);
- dict_copy (local->xattr, dict);
+ ret = dict_set_int32 (dict, count_key,
+ priv->child_count);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set stripe-size failed",
+ local->loc.path);
- ret = stripe_xattr_request_build (this, dict,
- local->stripe_size,
- priv->child_count,
- i, priv->coalesce);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to build xattr request");
- } else {
- dict = local->xattr;
+ ret = dict_set_int32 (dict, index_key, i);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: set stripe-size failed",
+ local->loc.path);
+
+ STACK_WIND (frame, stripe_create_setxattr_cbk,
+ priv->xl_array[i],
+ priv->xl_array[i]->fops->setxattr,
+ &local->loc, dict, 0);
+
+ dict_unref (dict);
+ }
+ return 0;
}
- STACK_WIND (frame, stripe_create_cbk, trav->xlator,
- trav->xlator->fops->create, &local->loc,
- local->flags, local->mode, local->umask, local->fd,
- dict);
- trav = trav->next;
- if (need_unref && dict)
- dict_unref (dict);
- i++;
+unwind:
+ /* Create itself has failed.. so return
+ without setxattring */
+ lfd = local->fd;
+ local_inode = local->inode;
+
+ STRIPE_STACK_UNWIND (create, frame, local->op_ret,
+ local->op_errno, local->fd,
+ local->inode, &local->stbuf,
+ &local->preparent, &local->postparent);
+
+ if (local_inode)
+ inode_unref (local_inode);
+ if (lfd)
+ fd_unref (lfd);
}
out:
@@ -2318,7 +2128,6 @@ out:
}
-
/**
* stripe_create - If a block-size is specified for the 'name', create the
* file in all the child nodes. If not, create it in only first child.
@@ -2327,15 +2136,12 @@ out:
*/
int32_t
stripe_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
stripe_private_t *priv = NULL;
stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
int32_t op_errno = EINVAL;
- int ret = 0;
- int need_unref = 0;
- int i = 0;
- dict_t *dict = NULL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -2356,71 +2162,46 @@ stripe_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
local->op_ret = -1;
local->op_errno = ENOTCONN;
- local->stripe_size = stripe_get_matching_bs (loc->path, priv);
+ local->stripe_size = stripe_get_matching_bs (loc->path,
+ priv->pattern,
+ priv->block_size);
frame->local = local;
local->inode = inode_ref (loc->inode);
loc_copy (&local->loc, loc);
local->fd = fd_ref (fd);
- local->flags = flags;
- local->mode = mode;
- local->umask = umask;
- if (xdata)
- local->xattr = dict_ref (xdata);
local->call_count = priv->child_count;
- /* Send a setxattr request to nodes where the
- files are created */
-
- if (priv->xattr_supported) {
- dict = dict_new ();
- if (!dict) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to allocate dict %s", loc->path);
- }
- need_unref = 1;
-
- dict_copy (xdata, dict);
- ret = stripe_xattr_request_build (this, dict,
- local->stripe_size,
- priv->child_count,
- i, priv->coalesce);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "failed to build xattr request");
- } else {
- dict = xdata;
+ trav = this->children;
+ while (trav) {
+ STACK_WIND (frame, stripe_create_cbk, trav->xlator,
+ trav->xlator->fops->create, loc, flags,
+ mode, fd, params);
+ trav = trav->next;
}
-
- STACK_WIND (frame, stripe_first_create_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->create, loc, flags, mode,
- umask, fd, dict);
-
- if (need_unref && dict)
- dict_unref (dict);
-
-
return 0;
err:
STRIPE_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, xdata);
+ NULL, NULL);
return 0;
}
int32_t
stripe_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
+ fd_t *lfd = NULL;
call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
@@ -2455,20 +2236,226 @@ stripe_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
+ if (local->op_ret == -1) {
+ if (local->fctx) {
+ if (!local->fctx->static_array)
+ GF_FREE (local->fctx->xl_array);
+ GF_FREE (local->fctx);
+ }
+ } else {
+ fd_ctx_set (local->fd, this,
+ (uint64_t)(long)local->fctx);
+ }
+
+ lfd = local->fd;
+
STRIPE_STACK_UNWIND (open, frame, local->op_ret,
- local->op_errno, local->fd, xdata);
+ local->op_errno, local->fd);
+ if (lfd)
+ fd_unref (lfd);
+
}
out:
return 0;
}
+int32_t
+stripe_open_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ int32_t index = 0;
+ int32_t callcnt = 0;
+ char key[256] = {0,};
+ stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ stripe_private_t *priv = NULL;
+ data_t *data = NULL;
+ call_frame_t *prev = NULL;
+ fd_t *lfd = NULL;
+
+ if (!this || !frame || !frame->local || !cookie) {
+ gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
+ goto out;
+ }
+
+ prev = (call_frame_t *)cookie;
+ priv = this->private;
+ local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s returned error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_ret = -1;
+ if (local->op_errno != EIO)
+ local->op_errno = op_errno;
+ if ((op_errno != ENOENT) ||
+ (prev->this == FIRST_CHILD (this)))
+ local->failed = 1;
+ goto unlock;
+ }
+
+ if (!dict)
+ goto unlock;
+
+ if (!local->fctx) {
+ local->fctx = GF_CALLOC (1, sizeof (stripe_fd_ctx_t),
+ gf_stripe_mt_stripe_fd_ctx_t);
+ if (!local->fctx) {
+ local->op_errno = ENOMEM;
+ local->op_ret = -1;
+ goto unlock;
+ }
+
+ local->fctx->static_array = 0;
+ }
+ /* Stripe block size */
+ sprintf (key, "trusted.%s.stripe-size", this->name);
+ data = dict_get (dict, key);
+ if (!data) {
+ local->xattr_self_heal_needed = 1;
+ } else {
+ if (!local->fctx->stripe_size) {
+ local->fctx->stripe_size =
+ data_to_int64 (data);
+ }
+
+ if (local->fctx->stripe_size != data_to_int64 (data)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stripe-size mismatch in blocks");
+ local->xattr_self_heal_needed = 1;
+ }
+ }
+ /* Stripe count */
+ sprintf (key, "trusted.%s.stripe-count", this->name);
+ data = dict_get (dict, key);
+ if (!data) {
+ local->xattr_self_heal_needed = 1;
+ goto unlock;
+ }
+ if (!local->fctx->xl_array) {
+ local->fctx->stripe_count = data_to_int32 (data);
+ if (!local->fctx->stripe_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error with stripe-count xattr");
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto unlock;
+ }
+
+ local->fctx->xl_array =
+ GF_CALLOC (local->fctx->stripe_count,
+ sizeof (xlator_t *),
+ gf_stripe_mt_xlator_t);
+ if (!local->fctx->xl_array) {
+ local->op_errno = ENOMEM;
+ local->op_ret = -1;
+ goto unlock;
+ }
+ }
+ if (local->fctx->stripe_count != data_to_int32 (data)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error with stripe-count xattr (%d != %d)",
+ local->fctx->stripe_count, data_to_int32 (data));
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto unlock;
+ }
+
+ /* index */
+ sprintf (key, "trusted.%s.stripe-index", this->name);
+ data = dict_get (dict, key);
+ if (!data) {
+ local->xattr_self_heal_needed = 1;
+ goto unlock;
+ }
+ index = data_to_int32 (data);
+ if (index > priv->child_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error with stripe-index xattr (%d)", index);
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto unlock;
+ }
+ if (local->fctx->xl_array) {
+ if (local->fctx->xl_array[index]) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "duplicate entry @ index (%d)", index);
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto unlock;
+ }
+ local->fctx->xl_array[index] = prev->this;
+ }
+ local->entry_count++;
+ local->op_ret = 0;
+ }
+unlock:
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ /* TODO: if self-heal flag is set, do it */
+ if (local->xattr_self_heal_needed) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: stripe info need to be healed",
+ local->loc.path);
+ }
+
+ if (local->failed)
+ local->op_ret = -1;
+
+ if (local->op_ret)
+ goto err;
+
+ if (local->entry_count != local->fctx->stripe_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "entry-count (%d) != stripe-count (%d)",
+ local->entry_count, local->fctx->stripe_count);
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto err;
+ }
+ if (!local->fctx->stripe_size) {
+ gf_log (this->name, GF_LOG_ERROR, "stripe size not set");
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ goto err;
+ }
+
+ local->call_count = local->fctx->stripe_count;
+
+ trav = this->children;
+ while (trav) {
+ STACK_WIND (frame, stripe_open_cbk, trav->xlator,
+ trav->xlator->fops->open, &local->loc,
+ local->flags, local->fd, 0);
+ trav = trav->next;
+ }
+ }
+
+ return 0;
+err:
+ lfd = local->fd;
+
+ STRIPE_STACK_UNWIND (open, frame, local->op_ret, local->op_errno,
+ local->fd);
+ if (lfd)
+ fd_unref (lfd);
+out:
+ return 0;
+}
+
/**
* stripe_open -
*/
int32_t
stripe_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+ int32_t flags, fd_t *fd, int32_t wbflags)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
@@ -2490,7 +2477,8 @@ stripe_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2506,28 +2494,52 @@ stripe_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
/* Striped files */
local->flags = flags;
local->call_count = priv->child_count;
- local->stripe_size = stripe_get_matching_bs (loc->path, priv);
+ local->stripe_size = stripe_get_matching_bs (loc->path,
+ priv->pattern,
+ priv->block_size);
+
+ if (priv->xattr_supported) {
+ while (trav) {
+ STACK_WIND (frame, stripe_open_getxattr_cbk,
+ trav->xlator, trav->xlator->fops->getxattr,
+ loc, NULL);
+ trav = trav->next;
+ }
+ return 0;
+ }
+ local->fctx = GF_CALLOC (1, sizeof (stripe_fd_ctx_t),
+ gf_stripe_mt_stripe_fd_ctx_t);
+ if (!local->fctx) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ local->fctx->static_array = 1;
+ local->fctx->stripe_size = local->stripe_size;
+ local->fctx->stripe_count = priv->child_count;
+ local->fctx->xl_array = priv->xl_array;
while (trav) {
STACK_WIND (frame, stripe_open_cbk, trav->xlator,
trav->xlator->fops->open,
&local->loc, local->flags, local->fd,
- xdata);
+ wbflags);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (open, frame, -1, op_errno, NULL);
return 0;
}
int32_t
stripe_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
+ fd_t *local_fd = NULL;
call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
@@ -2556,8 +2568,11 @@ stripe_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&frame->lock);
if (!callcnt) {
+ local_fd = local->fd;
STRIPE_STACK_UNWIND (opendir, frame, local->op_ret,
- local->op_errno, local->fd, NULL);
+ local->op_errno, local->fd);
+ if (local_fd)
+ fd_unref (local_fd);
}
out:
return 0;
@@ -2565,7 +2580,7 @@ out:
int32_t
-stripe_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata)
+stripe_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
xlator_list_t *trav = NULL;
stripe_local_t *local = NULL;
@@ -2587,7 +2602,8 @@ stripe_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2598,19 +2614,19 @@ stripe_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_
while (trav) {
STACK_WIND (frame, stripe_opendir_cbk, trav->xlator,
- trav->xlator->fops->opendir, loc, fd, NULL);
+ trav->xlator->fops->opendir, loc, fd);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
return 0;
}
int32_t
stripe_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -2650,7 +2666,7 @@ stripe_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->failed)
local->op_ret = -1;
STRIPE_STACK_UNWIND (lk, frame, local->op_ret,
- local->op_errno, &local->lock, NULL);
+ local->op_errno, &local->lock);
}
out:
return 0;
@@ -2658,7 +2674,7 @@ out:
int32_t
stripe_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
stripe_local_t *local = NULL;
xlator_list_t *trav = NULL;
@@ -2674,7 +2690,8 @@ stripe_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
priv = this->private;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2685,20 +2702,20 @@ stripe_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
while (trav) {
STACK_WIND (frame, stripe_lk_cbk, trav->xlator,
- trav->xlator->fops->lk, fd, cmd, lock, NULL);
+ trav->xlator->fops->lk, fd, cmd, lock);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (lk, frame, -1, op_errno, NULL);
return 0;
}
int32_t
stripe_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -2735,14 +2752,14 @@ stripe_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = -1;
STRIPE_STACK_UNWIND (flush, frame, local->op_ret,
- local->op_errno, NULL);
+ local->op_errno);
}
out:
return 0;
}
int32_t
-stripe_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+stripe_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
@@ -2762,7 +2779,8 @@ stripe_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto err;
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2773,13 +2791,13 @@ stripe_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
while (trav) {
STACK_WIND (frame, stripe_flush_cbk, trav->xlator,
- trav->xlator->fops->flush, fd, NULL);
+ trav->xlator->fops->flush, fd);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ STRIPE_STACK_UNWIND (flush, frame, -1, op_errno);
return 0;
}
@@ -2788,7 +2806,7 @@ err:
int32_t
stripe_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -2824,9 +2842,6 @@ stripe_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->prebuf_blocks += prebuf->ia_blocks;
local->postbuf_blocks += postbuf->ia_blocks;
- correct_file_size(prebuf, local->fctx, prev);
- correct_file_size(postbuf, local->fctx, prev);
-
if (local->prebuf_size < prebuf->ia_size)
local->prebuf_size = prebuf->ia_size;
@@ -2849,19 +2864,18 @@ stripe_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STRIPE_STACK_UNWIND (fsync, frame, local->op_ret,
local->op_errno, &local->pre_buf,
- &local->post_buf, NULL);
+ &local->post_buf);
}
out:
return 0;
}
int32_t
-stripe_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+stripe_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
xlator_list_t *trav = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
@@ -2873,38 +2887,31 @@ stripe_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
-
- inode_ctx_get(fd->inode, this, (uint64_t *) &fctx);
- if (!fctx) {
- op_errno = EINVAL;
- goto err;
- }
- local->fctx = fctx;
-
local->op_ret = -1;
frame->local = local;
local->call_count = priv->child_count;
while (trav) {
STACK_WIND (frame, stripe_fsync_cbk, trav->xlator,
- trav->xlator->fops->fsync, fd, flags, NULL);
+ trav->xlator->fops->fsync, fd, flags);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
stripe_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -2939,9 +2946,6 @@ stripe_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->stbuf = *buf;
local->stbuf_blocks += buf->ia_blocks;
-
- correct_file_size(buf, local->fctx, prev);
-
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
}
@@ -2958,7 +2962,7 @@ stripe_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STRIPE_STACK_UNWIND (fstat, frame, local->op_ret,
- local->op_errno, &local->stbuf, NULL);
+ local->op_errno, &local->stbuf);
}
out:
@@ -2968,12 +2972,11 @@ out:
int32_t
stripe_fstat (call_frame_t *frame,
xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
xlator_list_t *trav = NULL;
- stripe_fd_ctx_t *fctx = NULL;
int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
@@ -2985,7 +2988,8 @@ stripe_fstat (call_frame_t *frame,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -2994,35 +2998,26 @@ stripe_fstat (call_frame_t *frame,
frame->local = local;
local->call_count = priv->child_count;
- if (IA_ISREG(fd->inode->ia_type)) {
- inode_ctx_get(fd->inode, this, (uint64_t *) &fctx);
- if (!fctx)
- goto err;
- local->fctx = fctx;
- }
-
while (trav) {
STACK_WIND (frame, stripe_fstat_cbk, trav->xlator,
- trav->xlator->fops->fstat, fd, NULL);
+ trav->xlator->fops->fstat, fd);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (fstat, frame, -1, op_errno, NULL);
return 0;
}
int32_t
-stripe_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
+stripe_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
- stripe_fd_ctx_t *fctx = NULL;
- int i, eof_idx;
- off_t dest_offset, tmp_offset;
- int32_t op_errno = 1;
+ xlator_list_t *trav = NULL;
+ int32_t op_errno = 1;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -3030,9 +3025,11 @@ stripe_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, d
VALIDATE_OR_GOTO (fd->inode, err);
priv = this->private;
+ trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3041,60 +3038,22 @@ stripe_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, d
frame->local = local;
local->call_count = priv->child_count;
- inode_ctx_get(fd->inode, this, (uint64_t *) &fctx);
- if (!fctx) {
- gf_log(this->name, GF_LOG_ERROR, "no stripe context");
- op_errno = EINVAL;
- goto err;
- }
- if (!fctx->stripe_count) {
- gf_log(this->name, GF_LOG_ERROR, "no stripe count");
- op_errno = EINVAL;
- goto err;
- }
-
- local->fctx = fctx;
- eof_idx = (offset / fctx->stripe_size) % fctx->stripe_count;
-
- for (i = 0; i < fctx->stripe_count; i++) {
- if (!fctx->xl_array[i]) {
- gf_log(this->name, GF_LOG_ERROR, "no xlator at index "
- "%d", i);
- op_errno = EINVAL;
- goto err;
- }
-
- if (fctx->stripe_coalesce) {
- if (i < eof_idx)
- tmp_offset = roof(offset, fctx->stripe_size *
- fctx->stripe_count);
- else if (i > eof_idx)
- tmp_offset = floor(offset, fctx->stripe_size *
- fctx->stripe_count);
- else
- tmp_offset = offset;
-
- dest_offset = coalesced_offset(tmp_offset,
- fctx->stripe_size, fctx->stripe_count);
- } else {
- dest_offset = offset;
- }
-
- STACK_WIND(frame, stripe_truncate_cbk, fctx->xl_array[i],
- fctx->xl_array[i]->fops->ftruncate, fd, dest_offset,
- NULL);
- }
+ while (trav) {
+ STACK_WIND (frame, stripe_truncate_cbk, trav->xlator,
+ trav->xlator->fops->ftruncate, fd, offset);
+ trav = trav->next;
+ }
return 0;
err:
- STRIPE_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
stripe_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
@@ -3131,14 +3090,14 @@ stripe_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = -1;
STRIPE_STACK_UNWIND (fsyncdir, frame, local->op_ret,
- local->op_errno, NULL);
+ local->op_errno);
}
out:
return 0;
}
int32_t
-stripe_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+stripe_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
@@ -3154,7 +3113,8 @@ stripe_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3165,20 +3125,20 @@ stripe_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
while (trav) {
STACK_WIND (frame, stripe_fsyncdir_cbk, trav->xlator,
- trav->xlator->fops->fsyncdir, fd, flags, NULL);
+ trav->xlator->fops->fsyncdir, fd, flags);
trav = trav->next;
}
return 0;
err:
- STRIPE_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
+ STRIPE_STACK_UNWIND (fsyncdir, frame, -1, op_errno);
return 0;
}
int32_t
stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
int32_t i = 0;
int32_t callcnt = 0;
@@ -3188,7 +3148,6 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct iatt tmp_stbuf = {0,};
struct iobref *tmp_iobref = NULL;
struct iobuf *iobuf = NULL;
- call_frame_t *prev = NULL;
if (!this || !frame || !frame->local) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -3196,16 +3155,13 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
local = frame->local;
- prev = cookie;
LOCK (&frame->lock);
{
callcnt = --local->call_count;
- if (op_ret != -1) {
- correct_file_size(buf, local->fctx, prev);
+ if (op_ret != -1)
if (local->stbuf_size < buf->ia_size)
local->stbuf_size = buf->ia_size;
- }
}
UNLOCK (&frame->lock);
@@ -3234,8 +3190,7 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
vec[count].iov_len =
(local->replies[i].requested_size -
local->replies[i].op_ret);
- iobuf = iobuf_get2 (this->ctx->iobuf_pool,
- vec[count].iov_len);
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
if (!iobuf) {
gf_log (this->name, GF_LOG_ERROR,
"Out of memory.");
@@ -3244,10 +3199,8 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto done;
}
memset (iobuf->ptr, 0, vec[count].iov_len);
- vec[count].iov_base = iobuf->ptr;
-
iobref_add (local->iobref, iobuf);
- iobuf_unref(iobuf);
+ vec[count].iov_base = iobuf->ptr;
op_ret += vec[count].iov_len;
count++;
@@ -3265,11 +3218,13 @@ stripe_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
done:
GF_FREE (local->replies);
tmp_iobref = local->iobref;
+ fd_unref (local->fd);
STRIPE_STACK_UNWIND (readv, frame, op_ret, op_errno, vec,
- count, &tmp_stbuf, tmp_iobref, NULL);
+ count, &tmp_stbuf, tmp_iobref);
iobref_unref (tmp_iobref);
- GF_FREE (vec);
+ if (vec)
+ GF_FREE (vec);
}
out:
return 0;
@@ -3282,7 +3237,7 @@ out:
int32_t
stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
int32_t index = 0;
int32_t callcnt = 0;
@@ -3293,10 +3248,8 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stripe_local_t *local = NULL;
struct iovec *final_vec = NULL;
struct iatt tmp_stbuf = {0,};
- struct iatt *tmp_stbuf_p = NULL; //need it for a warning
struct iobref *tmp_iobref = NULL;
stripe_fd_ctx_t *fctx = NULL;
- call_frame_t *prev = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -3305,7 +3258,6 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
index = local->node_index;
- prev = cookie;
mframe = local->orig_frame;
if (!mframe)
goto out;
@@ -3326,12 +3278,6 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
mlocal->replies[index].count = count;
mlocal->replies[index].vector = iov_dup (vector, count);
- correct_file_size(stbuf, fctx, prev);
-
- if (local->stbuf_size < stbuf->ia_size)
- local->stbuf_size = stbuf->ia_size;
- local->stbuf_blocks += stbuf->ia_blocks;
-
if (!mlocal->iobref)
mlocal->iobref = iobref_new ();
iobref_merge (mlocal->iobref, iobref);
@@ -3388,21 +3334,18 @@ stripe_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
* cause any bugs at higher levels */
memcpy (&tmp_stbuf, &mlocal->replies[0].stbuf,
sizeof (struct iatt));
- tmp_stbuf.ia_size = local->stbuf_size;
- tmp_stbuf.ia_blocks = local->stbuf_blocks;
done:
/* */
GF_FREE (mlocal->replies);
tmp_iobref = mlocal->iobref;
- /* work around for nfs truncated read. Bug 3774 */
- tmp_stbuf_p = &tmp_stbuf;
- WIPE (tmp_stbuf_p);
+ fd_unref (mlocal->fd);
STRIPE_STACK_UNWIND (readv, mframe, op_ret, op_errno, final_vec,
- final_count, &tmp_stbuf, tmp_iobref, NULL);
+ final_count, &tmp_stbuf, tmp_iobref);
iobref_unref (tmp_iobref);
- GF_FREE (final_vec);
+ if (final_vec)
+ GF_FREE (final_vec);
}
goto out;
@@ -3414,7 +3357,7 @@ check_size:
STACK_WIND (mframe, stripe_readv_fstat_cbk,
(fctx->xl_array[index]),
(fctx->xl_array[index])->fops->fstat,
- mlocal->fd, NULL);
+ mlocal->fd);
}
out:
@@ -3426,7 +3369,7 @@ end:
int32_t
stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ size_t size, off_t offset)
{
int32_t op_errno = EINVAL;
int32_t idx = 0;
@@ -3439,7 +3382,6 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
uint64_t stripe_size = 0;
off_t rounded_start = 0;
off_t frame_offset = offset;
- off_t dest_offset = 0;
stripe_local_t *local = NULL;
call_frame_t *rframe = NULL;
stripe_local_t *rlocal = NULL;
@@ -3450,7 +3392,7 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
VALIDATE_OR_GOTO (fd, err);
VALIDATE_OR_GOTO (fd->inode, err);
- inode_ctx_get (fd->inode, this, &tmp_fctx);
+ fd_ctx_get (fd, this, &tmp_fctx);
if (!tmp_fctx) {
op_errno = EBADFD;
goto err;
@@ -3458,8 +3400,6 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
stripe_size = fctx->stripe_size;
- STRIPE_VALIDATE_FCTX (fctx, err);
-
if (!stripe_size) {
gf_log (this->name, GF_LOG_DEBUG,
"Wrong stripe size for the file");
@@ -3474,7 +3414,8 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
rounded_end = roof (offset+size, stripe_size);
num_stripe = (rounded_end- rounded_start)/stripe_size;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -3482,8 +3423,8 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
frame->local = local;
/* This is where all the vectors should be copied. */
- local->replies = GF_CALLOC (num_stripe, sizeof (struct stripe_replies),
- gf_stripe_mt_stripe_replies);
+ local->replies = GF_CALLOC (num_stripe, sizeof (struct readv_replies),
+ gf_stripe_mt_readv_replies);
if (!local->replies) {
op_errno = ENOMEM;
goto err;
@@ -3498,7 +3439,8 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
for (index = off_index; index < (num_stripe + off_index); index++) {
rframe = copy_frame (frame);
- rlocal = mem_get0 (this->local_pool);
+ rlocal = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!rlocal) {
op_errno = ENOMEM;
goto err;
@@ -3512,26 +3454,21 @@ stripe_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
rlocal->readv_size = frame_size;
rframe->local = rlocal;
idx = (index % fctx->stripe_count);
-
- if (fctx->stripe_coalesce)
- dest_offset = coalesced_offset(frame_offset,
- stripe_size, fctx->stripe_count);
- else
- dest_offset = frame_offset;
-
STACK_WIND (rframe, stripe_readv_cbk, fctx->xl_array[idx],
fctx->xl_array[idx]->fops->readv,
- fd, frame_size, dest_offset, flags, xdata);
+ fd, frame_size, frame_offset);
frame_offset += frame_size;
}
return 0;
err:
+ if (local && local->fd)
+ fd_unref (local->fd);
if (rframe)
STRIPE_STACK_DESTROY (rframe);
- STRIPE_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
}
@@ -3539,15 +3476,11 @@ err:
int32_t
stripe_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
int32_t callcnt = 0;
stripe_local_t *local = NULL;
- stripe_local_t *mlocal = NULL;
call_frame_t *prev = NULL;
- call_frame_t *mframe = NULL;
- struct stripe_replies *reply = NULL;
- int32_t i = 0;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -3556,82 +3489,39 @@ stripe_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
local = frame->local;
- mframe = local->orig_frame;
- mlocal = mframe->local;
LOCK(&frame->lock);
{
- callcnt = ++mlocal->call_count;
-
- mlocal->replies[local->node_index].op_ret = op_ret;
- mlocal->replies[local->node_index].op_errno = op_errno;
+ callcnt = ++local->call_count;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s returned error %s",
+ prev->this->name, strerror (op_errno));
+ local->op_errno = op_errno;
+ local->op_ret = -1;
+ }
if (op_ret >= 0) {
- mlocal->post_buf = *postbuf;
- mlocal->pre_buf = *prebuf;
-
- mlocal->prebuf_blocks += prebuf->ia_blocks;
- mlocal->postbuf_blocks += postbuf->ia_blocks;
-
- correct_file_size(prebuf, mlocal->fctx, prev);
- correct_file_size(postbuf, mlocal->fctx, prev);
-
- if (mlocal->prebuf_size < prebuf->ia_size)
- mlocal->prebuf_size = prebuf->ia_size;
- if (mlocal->postbuf_size < postbuf->ia_size)
- mlocal->postbuf_size = postbuf->ia_size;
+ local->op_ret += op_ret;
+ local->post_buf = *postbuf;
+ local->pre_buf = *prebuf;
}
}
UNLOCK (&frame->lock);
- if ((callcnt == mlocal->wind_count) && mlocal->unwind) {
- mlocal->pre_buf.ia_size = mlocal->prebuf_size;
- mlocal->pre_buf.ia_blocks = mlocal->prebuf_blocks;
- mlocal->post_buf.ia_size = mlocal->postbuf_size;
- mlocal->post_buf.ia_blocks = mlocal->postbuf_blocks;
-
- /*
- * Only return the number of consecutively written bytes up until
- * the first error. Only return an error if it occurs first.
- *
- * When a short write occurs, the application should retry at the
- * appropriate offset, at which point we'll potentially pass back
- * the error.
- */
- for (i = 0, reply = mlocal->replies; i < mlocal->wind_count;
- i++, reply++) {
- if (reply->op_ret == -1) {
- gf_log(this->name, GF_LOG_DEBUG, "reply %d "
- "returned error %s", i,
- strerror(reply->op_errno));
- if (!mlocal->op_ret) {
- mlocal->op_ret = -1;
- mlocal->op_errno = reply->op_errno;
- }
- break;
- }
-
- mlocal->op_ret += reply->op_ret;
-
- if (reply->op_ret < reply->requested_size)
- break;
- }
-
- GF_FREE(mlocal->replies);
-
- STRIPE_STACK_UNWIND (writev, mframe, mlocal->op_ret,
- mlocal->op_errno, &mlocal->pre_buf,
- &mlocal->post_buf, NULL);
+ if ((callcnt == local->wind_count) && local->unwind) {
+ STRIPE_STACK_UNWIND (writev, frame, local->op_ret,
+ local->op_errno, &local->pre_buf,
+ &local->post_buf);
}
out:
- STRIPE_STACK_DESTROY(frame);
return 0;
}
int32_t
stripe_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
struct iovec *tmp_vec = NULL;
stripe_local_t *local = NULL;
@@ -3645,19 +3535,13 @@ stripe_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
off_t fill_size = 0;
uint64_t stripe_size = 0;
uint64_t tmp_fctx = 0;
- off_t dest_offset = 0;
- off_t rounded_start = 0;
- off_t rounded_end = 0;
- int32_t total_chunks = 0;
- call_frame_t *wframe = NULL;
- stripe_local_t *wlocal = NULL;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
VALIDATE_OR_GOTO (fd->inode, err);
- inode_ctx_get (fd->inode, this, &tmp_fctx);
+ fd_ctx_get (fd, this, &tmp_fctx);
if (!tmp_fctx) {
op_errno = EINVAL;
goto err;
@@ -3665,51 +3549,22 @@ stripe_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
fctx = (stripe_fd_ctx_t *)(long)tmp_fctx;
stripe_size = fctx->stripe_size;
- STRIPE_VALIDATE_FCTX (fctx, err);
-
/* File has to be stripped across the child nodes */
for (idx = 0; idx< count; idx ++) {
total_size += vector[idx].iov_len;
}
remaining_size = total_size;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
}
frame->local = local;
local->stripe_size = stripe_size;
- local->fctx = fctx;
- if (!stripe_size) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Wrong stripe size for the file");
- op_errno = EINVAL;
- goto err;
- }
-
- rounded_start = floor(offset, stripe_size);
- rounded_end = roof(offset + total_size, stripe_size);
- total_chunks = (rounded_end - rounded_start) / stripe_size;
- local->replies = GF_CALLOC(total_chunks, sizeof(struct stripe_replies),
- gf_stripe_mt_stripe_replies);
- if (!local->replies) {
- op_errno = ENOMEM;
- goto err;
- }
-
- total_chunks = 0;
while (1) {
- wframe = copy_frame(frame);
- wlocal = mem_get0(this->local_pool);
- if (!wlocal) {
- op_errno = ENOMEM;
- goto err;
- }
- wlocal->orig_frame = frame;
- wframe->local = wlocal;
-
/* Send striped chunk of the vector to child
nodes appropriately. */
idx = (((offset + offset_offset) /
@@ -3737,38 +3592,18 @@ stripe_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (remaining_size == 0)
local->unwind = 1;
- /*
- * Store off the request index (with respect to the chunk of the
- * initial offset) and the size of the request. This is required
- * in the callback to calculate an appropriate return value in
- * the event of a write failure in one or more requests.
- */
- wlocal->node_index = total_chunks;
- local->replies[total_chunks].requested_size = fill_size;
-
- dest_offset = offset + offset_offset;
- if (fctx->stripe_coalesce)
- dest_offset = coalesced_offset(dest_offset,
- local->stripe_size, fctx->stripe_count);
-
- STACK_WIND (wframe, stripe_writev_cbk, fctx->xl_array[idx],
+ STACK_WIND (frame, stripe_writev_cbk, fctx->xl_array[idx],
fctx->xl_array[idx]->fops->writev, fd, tmp_vec,
- tmp_count, dest_offset, flags, iobref,
- xdata);
-
+ tmp_count, offset + offset_offset, iobref);
GF_FREE (tmp_vec);
offset_offset += fill_size;
- total_chunks++;
if (remaining_size == 0)
break;
}
return 0;
err:
- if (wframe)
- STRIPE_STACK_DESTROY(wframe);
-
- STRIPE_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ STRIPE_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -3776,19 +3611,13 @@ err:
int32_t
stripe_release (xlator_t *this, fd_t *fd)
{
- return 0;
-}
-
-int
-stripe_forget (xlator_t *this, inode_t *inode)
-{
uint64_t tmp_fctx = 0;
stripe_fd_ctx_t *fctx = NULL;
VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (inode, err);
+ VALIDATE_OR_GOTO (fd, err);
- (void) inode_ctx_del (inode, this, &tmp_fctx);
+ fd_ctx_del (fd, this, &tmp_fctx);
if (!tmp_fctx) {
goto err;
}
@@ -3799,10 +3628,12 @@ stripe_forget (xlator_t *this, inode_t *inode)
GF_FREE (fctx->xl_array);
GF_FREE (fctx);
+
err:
- return 0;
+ return 0;
}
+
int32_t
notify (xlator_t *this, int32_t event, void *data, ...)
{
@@ -3882,299 +3713,139 @@ notify (xlator_t *this, int32_t event, void *data, ...)
}
int
-stripe_setxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno, dict_t *xdata)
+set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data)
{
- int ret = -1;
- int call_cnt = 0;
- stripe_local_t *local = NULL;
-
- if (!frame || !frame->local || !this) {
- gf_log ("", GF_LOG_ERROR, "Possible NULL deref");
- return ret;
- }
-
- local = frame->local;
-
- LOCK (&frame->lock);
- {
- call_cnt = --local->wind_count;
+ int ret = -1;
+ char *tmp_str = NULL;
+ char *tmp_str1 = NULL;
+ char *dup_str = NULL;
+ char *stripe_str = NULL;
+ char *pattern = NULL;
+ char *num = NULL;
+ struct stripe_options *temp_stripeopt = NULL;
+ struct stripe_options *stripe_opt = NULL;
+
+ if (!this || !priv || !data)
+ goto out;
- /**
- * We overwrite ->op_* values here for subsequent faliure
- * conditions, hence we propogate the last errno down the
- * stack.
- */
- if (op_ret < 0) {
- local->op_ret = op_ret;
- local->op_errno = op_errno;
- goto unlock;
+ /* Get the pattern for striping.
+ "option block-size *avi:10MB" etc */
+ stripe_str = strtok_r (data, ",", &tmp_str);
+ while (stripe_str) {
+ dup_str = gf_strdup (stripe_str);
+ stripe_opt = CALLOC (1, sizeof (struct stripe_options));
+ if (!stripe_opt) {
+ GF_FREE (dup_str);
+ goto out;
}
- }
-
- unlock:
- UNLOCK (&frame->lock);
- if (!call_cnt) {
- STRIPE_STACK_UNWIND (setxattr, frame, local->op_ret,
- local->op_errno, xdata);
- }
-
- return 0;
-}
-
-int
-stripe_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
-{
- data_pair_t *pair = NULL;
- int32_t op_errno = EINVAL;
- xlator_list_t *trav = NULL;
- stripe_private_t *priv = NULL;
- stripe_local_t *local = NULL;
- int i = 0;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
- VALIDATE_OR_GOTO (loc->inode, err);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.*stripe*", dict,
- pair, op_errno, err);
-
- priv = this->private;
- trav = this->children;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto err;
- }
+ pattern = strtok_r (dup_str, ":", &tmp_str1);
+ num = strtok_r (NULL, ":", &tmp_str1);
+ if (!num) {
+ num = pattern;
+ pattern = "*";
+ }
+ if (gf_string2bytesize (num, &stripe_opt->block_size) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\"", num);
+ goto out;
+ }
+ memcpy (stripe_opt->path_pattern, pattern, strlen (pattern));
- frame->local = local;
- local->wind_count = priv->child_count;
- local->op_ret = local->op_errno = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "block-size : pattern %s : size %"PRId64,
+ stripe_opt->path_pattern, stripe_opt->block_size);
- /**
- * Set xattrs for directories on all subvolumes. Additionally
- * this power is only given to a special client.
- */
- if ((frame->root->pid == -1) && IA_ISDIR (loc->inode->ia_type)) {
- for (i = 0; i < priv->child_count; i++, trav = trav->next) {
- STACK_WIND (frame, stripe_setxattr_cbk,
- trav->xlator, trav->xlator->fops->setxattr,
- loc, dict, flags, xdata);
+ if (!priv->pattern) {
+ priv->pattern = stripe_opt;
+ } else {
+ temp_stripeopt = priv->pattern;
+ while (temp_stripeopt->next)
+ temp_stripeopt = temp_stripeopt->next;
+ temp_stripeopt->next = stripe_opt;
}
- } else {
- local->wind_count = 1;
- STACK_WIND (frame, stripe_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
+ stripe_str = strtok_r (NULL, ",", &tmp_str);
+ GF_FREE (dup_str);
}
- return 0;
-err:
- STRIPE_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int
-stripe_fsetxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno, dict_t *xdata)
-{
- STRIPE_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-stripe_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int flags, dict_t *xdata)
-{
- data_pair_t *trav = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.*stripe*", dict,
- trav, op_errno, err);
-
- STACK_WIND (frame, stripe_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
- err:
- STRIPE_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-int
-stripe_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STRIPE_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-stripe_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (this, err);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.*stripe*",
- name, op_errno, err);
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (loc, err);
-
- STACK_WIND (frame, stripe_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-err:
- STRIPE_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int
-stripe_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STRIPE_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata);
- return 0;
+ ret = 0;
+out:
+ return ret;
}
-int
-stripe_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
+int32_t
+stripe_iatt_merge (struct iatt *from, struct iatt *to)
{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.*stripe*",
- name, op_errno, err);
-
- STACK_WIND (frame, stripe_fremovexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
- return 0;
- err:
- STRIPE_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata);
+ if (to->ia_size < from->ia_size)
+ to->ia_size = from->ia_size;
+ if (to->ia_mtime < from->ia_mtime)
+ to->ia_mtime = from->ia_mtime;
+ if (to->ia_ctime < from->ia_ctime)
+ to->ia_ctime = from->ia_ctime;
+ if (to->ia_atime < from->ia_atime)
+ to->ia_atime = from->ia_atime;
return 0;
}
int32_t
-stripe_readdirp_lookup_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno,
- inode_t *inode, struct iatt *stbuf,
- dict_t *xattr, struct iatt *parent)
+stripe_readdirp_entry_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- stripe_local_t *local = NULL;
- call_frame_t *main_frame = NULL;
- stripe_local_t *main_local = NULL;
- gf_dirent_t *entry = NULL;
- call_frame_t *prev = NULL;
- int done = 0;
+ gf_dirent_t *entry = NULL;
+ stripe_local_t *local = NULL;
+ int32_t done = 0;
+ int32_t ret = -1;
+ if (!this || !frame || !frame->local || !cookie) {
+ gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
+ goto out;
+ }
+ entry = cookie;
local = frame->local;
- prev = cookie;
-
- entry = local->dirent;
-
- main_frame = local->orig_frame;
- main_local = main_frame->local;
LOCK (&frame->lock);
{
- local->call_count--;
- if (!local->call_count)
+ local->count++;
+ if (local->count == local->wind_count)
done = 1;
if (op_ret == -1) {
local->op_errno = op_errno;
local->op_ret = op_ret;
goto unlock;
}
-
- if (stripe_ctx_handle(this, prev, local, xattr))
- gf_log(this->name, GF_LOG_ERROR,
- "Error getting fctx info from dict.");
-
- correct_file_size(stbuf, local->fctx, prev);
-
- stripe_iatt_merge (stbuf, &entry->d_stat);
- local->stbuf_blocks += stbuf->ia_blocks;
+ stripe_iatt_merge (buf, &entry->d_stat);
}
unlock:
UNLOCK(&frame->lock);
-
if (done) {
- inode_ctx_put (entry->inode, this,
- (uint64_t) (long)local->fctx);
-
- done = 0;
- LOCK (&main_frame->lock);
- {
- main_local->wind_count--;
- if (!main_local->wind_count)
- done = 1;
- if (local->op_ret == -1) {
- main_local->op_errno = local->op_errno;
- main_local->op_ret = local->op_ret;
- }
- entry->d_stat.ia_blocks = local->stbuf_blocks;
- }
- UNLOCK (&main_frame->lock);
- if (done) {
- main_frame->local = NULL;
- STRIPE_STACK_UNWIND (readdir, main_frame,
- main_local->op_ret,
- main_local->op_errno,
- &main_local->entries, NULL);
- gf_dirent_free (&main_local->entries);
- stripe_local_wipe (main_local);
- mem_put (main_local);
- }
+ fd_unref (local->fd);
frame->local = NULL;
+ ret = local->op_ret;
+ STRIPE_STACK_UNWIND (readdir, frame, local->op_ret,
+ local->op_errno, &local->entries);
+ if (ret > 0)
+ gf_dirent_free (&local->entries);
stripe_local_wipe (local);
- mem_put (local);
- STRIPE_STACK_DESTROY (frame);
}
+out:
+ return 0;
- return 0;
}
int32_t
stripe_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- gf_dirent_t *orig_entries, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *orig_entries)
{
stripe_local_t *local = NULL;
call_frame_t *prev = NULL;
gf_dirent_t *local_entry = NULL;
+ int32_t ret = -1;
gf_dirent_t *tmp_entry = NULL;
xlator_list_t *trav = NULL;
loc_t loc = {0, };
+ inode_t *inode = NULL;
+ char *path;
int32_t count = 0;
- stripe_private_t *priv = NULL;
- int32_t subvols = 0;
- dict_t *xattrs = NULL;
- call_frame_t *local_frame = NULL;
- stripe_local_t *local_ent = NULL;
if (!this || !frame || !frame->local || !cookie) {
gf_log ("stripe", GF_LOG_DEBUG, "possible NULL deref");
@@ -4183,12 +3854,10 @@ stripe_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
local = frame->local;
trav = this->children;
- priv = this->private;
-
- subvols = priv->child_count;
LOCK (&frame->lock);
{
+
if (op_ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
"%s returned error %s",
@@ -4200,95 +3869,83 @@ stripe_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
list_splice_init (&orig_entries->list,
&local->entries.list);
- local->wind_count = op_ret;
}
-
}
unlock:
- UNLOCK (&frame->lock);
-
+ UNLOCK (&frame->lock);
if (op_ret == -1)
goto out;
-
- xattrs = dict_new ();
- if (xattrs)
- (void) stripe_xattr_request_build (this, xattrs, 0, 0, 0, 0);
- count = op_ret;
- list_for_each_entry_safe (local_entry, tmp_entry,
- (&local->entries.list), list) {
+ ret = 0;
+ list_for_each_entry_safe (local_entry, tmp_entry
+ , (&local->entries.list), list) {
if (!local_entry)
break;
- if (!IA_ISREG (local_entry->d_stat.ia_type)) {
- LOCK (&frame->lock);
- {
- local->wind_count--;
- count = local->wind_count;
- }
- UNLOCK (&frame->lock);
+ if (!IA_ISREG(local_entry->d_stat.ia_type))
continue;
- }
-
- local_frame = copy_frame (frame);
- if (!local_frame) {
- op_errno = ENOMEM;
- op_ret = -1;
+ inode = inode_new(local->fd->inode->table);
+ if (inode) {
+ loc.ino= inode->ino = local_entry->d_ino;
+ loc.inode = inode;
+ } else {
goto out;
}
- local_ent = mem_get0 (this->local_pool);
- if (!local_ent) {
- op_errno = ENOMEM;
- op_ret = -1;
- goto out;
+ loc.parent = local->fd->inode;
+ ret = inode_path (local->fd->inode, local_entry->d_name, &path);
+ if (ret != -1) {
+ loc.path = path;
+ } else if (inode) {
+ ret = inode_path (inode, NULL, &path);
+ if (ret != -1) {
+ loc.path = path;
+ } else {
+ goto out;
+ }
}
- loc.inode = inode_ref (local_entry->inode);
-
- uuid_copy (loc.gfid, local_entry->d_stat.ia_gfid);
-
- local_ent->orig_frame = frame;
-
- local_ent->call_count = subvols;
-
- local_ent->dirent = local_entry;
-
- local_frame->local = local_ent;
-
+ loc.name = strrchr (loc.path, '/');
+ loc.name++;
trav = this->children;
while (trav) {
- STACK_WIND (local_frame, stripe_readdirp_lookup_cbk,
- trav->xlator, trav->xlator->fops->lookup,
- &loc, xattrs);
+ LOCK (&frame->lock);
+ {
+ local->wind_count++;
+ }
+ UNLOCK (&frame->lock);
+ STACK_WIND_COOKIE (frame, stripe_readdirp_entry_stat_cbk,
+ local_entry, trav->xlator,
+ trav->xlator->fops->stat, &loc);
+ count++;
trav = trav->next;
}
- loc_wipe (&loc);
- }
+ inode_unref (loc.inode);
+ }
out:
- if (!count) {
- /* all entries are directories */
+ if (!count){ //all entries are directories
+ fd_unref (local->fd);
frame->local = NULL;
- STRIPE_STACK_UNWIND (readdir, frame, local->op_ret,
- local->op_errno, &local->entries, NULL);
- gf_dirent_free (&local->entries);
+ STRIPE_STACK_UNWIND (readdir, frame, local->op_ret,
+ local->op_errno, &local->entries);
+ if (op_ret > 0)
+ gf_dirent_free (&local->entries);
stripe_local_wipe (local);
- mem_put (local);
}
- if (xattrs)
- dict_unref (xattrs);
+
return 0;
}
int32_t
stripe_readdirp (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t off, dict_t *xdata)
+ fd_t *fd, size_t size, off_t off)
{
stripe_local_t *local = NULL;
stripe_private_t *priv = NULL;
xlator_list_t *trav = NULL;
int op_errno = -1;
+
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
VALIDATE_OR_GOTO (fd, err);
@@ -4302,7 +3959,8 @@ stripe_readdirp (call_frame_t *frame, xlator_t *this,
}
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -4313,25 +3971,23 @@ stripe_readdirp (call_frame_t *frame, xlator_t *this,
local->fd = fd_ref (fd);
local->wind_count = 0;
-
+
local->count = 0;
local->op_ret = -1;
INIT_LIST_HEAD(&local->entries);
if (!trav)
goto err;
-
STACK_WIND (frame, stripe_readdirp_cbk, trav->xlator,
- trav->xlator->fops->readdirp, fd, size, off, xdata);
+ trav->xlator->fops->readdirp, fd, size, off);
return 0;
err:
op_errno = (op_errno == -1) ? errno : op_errno;
- STRIPE_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
+ STRIPE_STACK_UNWIND (readdir, frame, -1, op_errno, NULL);
return 0;
}
-
int32_t
mem_acct_init (xlator_t *this)
{
@@ -4351,87 +4007,65 @@ mem_acct_init (xlator_t *this)
out:
return ret;
}
-
-static int
-clear_pattern_list (stripe_private_t *priv)
+int
+validate_options (xlator_t *this, char **op_errstr)
{
- struct stripe_options *prev = NULL;
- struct stripe_options *trav = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("stripe", priv, out);
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- trav = priv->pattern;
- priv->pattern = NULL;
- while (trav) {
- prev = trav;
- trav = trav->next;
- GF_FREE (prev);
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
}
- ret = 0;
- out:
- return ret;
+ if (list_empty (&this->volume_options))
+ goto out;
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
-}
+out:
+ return ret;
+}
int
reconfigure (xlator_t *this, dict_t *options)
{
- stripe_private_t *priv = NULL;
- data_t *data = NULL;
- int ret = -1;
- volume_option_t *opt = NULL;
-
- GF_ASSERT (this);
- GF_ASSERT (this->private);
-
- priv = this->private;
-
+ stripe_private_t *priv = NULL;
+ data_t *data = NULL;
+ int ret = 0;
- ret = 0;
- LOCK (&priv->lock);
- {
- ret = clear_pattern_list (priv);
- if (ret)
- goto unlock;
-
- data = dict_get (options, "block-size");
- if (data) {
- ret = set_stripe_block_size (this, priv, data->data);
- if (ret)
- goto unlock;
- } else {
- opt = xlator_volume_option_get (this, "block-size");
- if (!opt) {
- gf_log (this->name, GF_LOG_WARNING,
- "option 'block-size' not found");
- ret = -1;
- goto unlock;
- }
+ priv = this->private;
- if (gf_string2bytesize (opt->default_value, &priv->block_size)){
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to set default block-size ");
- ret = -1;
- goto unlock;
- }
- }
-
- GF_OPTION_RECONF("coalesce", priv->coalesce, options, bool,
- unlock);
+ data = dict_get (options, "block-size");
+ if (data) {
+ gf_log (this->name, GF_LOG_TRACE,"Reconfiguring Stripe"
+ " Block-size");
+ ret = set_stripe_block_size (this, priv, data->data);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Reconfigue: Block-Size reconfiguration failed");
+ ret = -1;
+ goto out;
+ }
+ gf_log (this->name, GF_LOG_TRACE,
+ "Reconfigue: Block-Size reconfigured Successfully");
+ }
+ else {
+ priv->block_size = (128 * GF_UNIT_KB);
}
- unlock:
- UNLOCK (&priv->lock);
- if (ret)
- goto out;
- ret = 0;
- out:
- return ret;
+out:
+ return ret;
}
@@ -4444,7 +4078,6 @@ int32_t
init (xlator_t *this)
{
stripe_private_t *priv = NULL;
- volume_option_t *opt = NULL;
xlator_list_t *trav = NULL;
data_t *data = NULL;
int32_t count = 0;
@@ -4510,56 +4143,42 @@ init (xlator_t *this)
goto out;
}
- ret = 0;
- LOCK (&priv->lock);
- {
- opt = xlator_volume_option_get (this, "block-size");
- if (!opt) {
- gf_log (this->name, GF_LOG_WARNING,
- "option 'block-size' not found");
- ret = -1;
- goto unlock;
- }
- if (gf_string2bytesize (opt->default_value, &priv->block_size)){
+ priv->block_size = (128 * GF_UNIT_KB);
+ /* option stripe-pattern *avi:1GB,*pdf:4096 */
+ data = dict_get (this->options, "block-size");
+ if (!data) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "No \"option block-size <x>\" given, defaulting "
+ "to 128KB");
+ } else {
+ ret = set_stripe_block_size (this, priv, data->data);
+ if (ret)
+ goto out;
+ }
+
+ priv->xattr_supported = 1;
+ data = dict_get (this->options, "use-xattr");
+ if (data) {
+ if (gf_string2boolean (data->data,
+ &priv->xattr_supported) == -1) {
gf_log (this->name, GF_LOG_ERROR,
- "Unable to set default block-size ");
- ret = -1;
- goto unlock;
- }
- /* option stripe-pattern *avi:1GB,*pdf:16K */
- data = dict_get (this->options, "block-size");
- if (data) {
- ret = set_stripe_block_size (this, priv, data->data);
- if (ret)
- goto unlock;
+ "error setting hard check for extended "
+ "attribute");
+ //return -1;
}
}
- unlock:
- UNLOCK (&priv->lock);
- if (ret)
- goto out;
- GF_OPTION_INIT ("use-xattr", priv->xattr_supported, bool, out);
/* notify related */
priv->nodes_down = priv->child_count;
-
- GF_OPTION_INIT("coalesce", priv->coalesce, bool, out);
-
- this->local_pool = mem_pool_new (stripe_local_t, 128);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
this->private = priv;
+
ret = 0;
out:
if (ret) {
if (priv) {
- GF_FREE (priv->xl_array);
+ if (priv->xl_array)
+ GF_FREE (priv->xl_array);
GF_FREE (priv);
}
}
@@ -4583,13 +4202,14 @@ fini (xlator_t *this)
priv = this->private;
if (priv) {
this->private = NULL;
- GF_FREE (priv->xl_array);
+ if (priv->xl_array)
+ GF_FREE (priv->xl_array);
trav = priv->pattern;
while (trav) {
prev = trav;
trav = trav->next;
- GF_FREE (prev);
+ FREE (prev);
}
LOCK_DESTROY (&priv->lock);
GF_FREE (priv);
@@ -4601,50 +4221,17 @@ out:
int32_t
stripe_getxattr_unwind (call_frame_t *frame,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *dict)
{
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
-int
-stripe_internal_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr,
- dict_t *xdata)
-{
-
- char size_key[256] = {0,};
- char index_key[256] = {0,};
- char count_key[256] = {0,};
- char coalesce_key[256] = {0,};
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (frame->local, out);
-
- if (!xattr || (op_ret == -1))
- goto out;
-
- sprintf (size_key, "trusted.%s.stripe-size", this->name);
- sprintf (count_key, "trusted.%s.stripe-count", this->name);
- sprintf (index_key, "trusted.%s.stripe-index", this->name);
- sprintf (coalesce_key, "trusted.%s.stripe-coalesce", this->name);
-
- dict_del (xattr, size_key);
- dict_del (xattr, count_key);
- dict_del (xattr, index_key);
- dict_del (xattr, coalesce_key);
-
-out:
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
-
- return 0;
-
-}
int
stripe_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *xattr, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *xattr)
{
int call_cnt = 0;
stripe_local_t *local = NULL;
@@ -4674,122 +4261,23 @@ stripe_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
if (!call_cnt) {
STRIPE_STACK_UNWIND (getxattr, frame, local->op_ret, op_errno,
- local->xattr, xdata);
+ local->xattr);
}
return 0;
}
-int32_t
-stripe_vgetxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- dict_t *dict, dict_t *xdata)
-{
- stripe_local_t *local = NULL;
- int32_t callcnt = 0;
- int32_t ret = -1;
- long cky = 0;
- char *xattr_val = NULL;
- char *xattr_serz = NULL;
- stripe_xattr_sort_t *xattr = NULL;
- dict_t *stripe_xattr = NULL;
-
- if (!frame || !frame->local || !this) {
- gf_log ("", GF_LOG_ERROR, "Possible NULL deref");
- return ret;
- }
-
- local = frame->local;
- cky = (long) cookie;
-
- if (local->xsel[0] == '\0') {
- gf_log (this->name, GF_LOG_ERROR, "Empty xattr in cbk");
- return ret;
- }
-
- LOCK (&frame->lock);
- {
- callcnt = --local->wind_count;
-
- if (!dict || (op_ret < 0))
- goto out;
-
- if (!local->xattr_list)
- local->xattr_list = (stripe_xattr_sort_t *)
- GF_CALLOC (local->nallocs,
- sizeof (stripe_xattr_sort_t),
- gf_stripe_mt_xattr_sort_t);
-
- if (local->xattr_list) {
- ret = dict_get_str (dict, local->xsel, &xattr_val);
- if (ret)
- goto out;
-
- xattr = local->xattr_list + (int32_t) cky;
-
- xattr_val = gf_strdup (xattr_val);
- xattr->pos = cky;
- xattr->xattr_value = xattr_val;
- xattr->xattr_len = strlen (xattr_val);
-
- local->xattr_total_len += xattr->xattr_len + 1;
- }
- }
- out:
- UNLOCK (&frame->lock);
-
- if (!callcnt) {
- if (!local->xattr_total_len)
- goto unwind;
-
- stripe_xattr = dict_new ();
- if (!stripe_xattr)
- goto unwind;
-
- /* select filler based on ->xsel */
- if (XATTR_IS_PATHINFO (local->xsel))
- ret = stripe_fill_pathinfo_xattr (this, local,
- &xattr_serz);
- else {
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown xattr in xattr request");
- goto unwind;
- }
-
- if (!ret) {
- ret = dict_set_dynstr (stripe_xattr, local->xsel,
- xattr_serz);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Can't set %s key in dict", local->xsel);
- }
-
- unwind:
- STRIPE_STACK_UNWIND (getxattr, frame, op_ret, op_errno,
- stripe_xattr, NULL);
-
- ret = stripe_free_xattr_str (local);
-
- GF_FREE (local->xattr_list);
-
- if (stripe_xattr)
- dict_unref (stripe_xattr);
- }
-
- return ret;
-}
int32_t
stripe_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
- stripe_local_t *local = NULL;
- xlator_list_t *trav = NULL;
- stripe_private_t *priv = NULL;
- int32_t op_errno = EINVAL;
- int i = 0;
- xlator_t **sub_volumes;
- int ret = 0;
+ stripe_local_t *local = NULL;
+ xlator_list_t *trav = NULL;
+ stripe_private_t *priv = NULL;
+ int32_t op_errno = EINVAL;
+ int i = 0;
+ xlator_t **sub_volumes;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -4801,7 +4289,8 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
trav = this->children;
/* Initialization */
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (stripe_local_t),
+ gf_stripe_mt_stripe_local_t);
if (!local) {
op_errno = ENOMEM;
goto err;
@@ -4812,13 +4301,13 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
if (name && (strcmp (GF_XATTR_MARKER_KEY, name) == 0)
- && (-1 == frame->root->pid)) {
+ && (-1 == frame->root->pid)) {
local->marker.call_count = priv->child_count;
sub_volumes = alloca ( priv->child_count *
sizeof (xlator_t *));
for (i = 0, trav = this->children; trav ;
- trav = trav->next, i++) {
+ trav = trav->next, i++) {
*(sub_volumes + i) = trav->xlator;
@@ -4836,204 +4325,99 @@ stripe_getxattr (call_frame_t *frame, xlator_t *this,
}
if (name && strncmp (name, GF_XATTR_QUOTA_SIZE_KEY,
- strlen (GF_XATTR_QUOTA_SIZE_KEY)) == 0) {
+ strlen (GF_XATTR_QUOTA_SIZE_KEY) == 0)) {
local->wind_count = priv->child_count;
for (i = 0, trav=this->children; i < priv->child_count; i++,
trav = trav->next) {
STACK_WIND (frame, stripe_getxattr_cbk,
trav->xlator, trav->xlator->fops->getxattr,
- loc, name, xdata);
+ loc, name);
}
return 0;
}
- if (name &&
- ((strncmp (name, GF_XATTR_PATHINFO_KEY,
- strlen (GF_XATTR_PATHINFO_KEY)) == 0))) {
- if (IA_ISREG (loc->inode->ia_type)) {
- ret = inode_ctx_get (loc->inode, this,
- (uint64_t *) &local->fctx);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "stripe size unavailable from fctx"
- " relying on pathinfo could lead to"
- " wrong results");
- }
-
- local->nallocs = local->wind_count = priv->child_count;
- (void) strncpy (local->xsel, name, strlen (name));
-
- /**
- * for xattrs that need info from all childs, fill ->xsel
- * as above and call the filler function in cbk based on
- * it
- */
- for (i = 0, trav = this->children; i < priv->child_count; i++,
- trav = trav->next) {
- STACK_WIND_COOKIE (frame, stripe_vgetxattr_cbk,
- (void *) (long) i, trav->xlator,
- trav->xlator->fops->getxattr,
- loc, name, xdata);
- }
-
- return 0;
- }
-
- if (name &&(*priv->vol_uuid)) {
+ if (*priv->vol_uuid) {
if ((match_uuid_local (name, priv->vol_uuid) == 0)
&& (-1 == frame->root->pid)) {
+ local->marker.call_count = priv->child_count;
- if (!IA_FILE_OR_DIR (loc->inode->ia_type))
- local->marker.call_count = 1;
- else
- local->marker.call_count = priv->child_count;
-
- sub_volumes = alloca (local->marker.call_count *
- sizeof (xlator_t *));
+ sub_volumes = alloca ( priv->child_count *
+ sizeof (xlator_t *));
+ for (i = 0, trav = this->children; trav ;
+ trav = trav->next, i++) {
- for (i = 0, trav = this->children;
- i < local->marker.call_count;
- i++, trav = trav->next) {
*(sub_volumes + i) = trav->xlator;
}
if (cluster_getmarkerattr (frame, this, loc, name,
- local,
- stripe_getxattr_unwind,
+ local, stripe_getxattr_unwind,
sub_volumes,
- local->marker.call_count,
+ priv->child_count,
MARKER_XTIME_TYPE,
priv->vol_uuid)) {
op_errno = EINVAL;
goto err;
}
-
return 0;
}
}
- STACK_WIND (frame, stripe_internal_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
+ STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr, loc, name);
return 0;
err:
- STRIPE_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL);
return 0;
}
-int32_t
-stripe_priv_dump (xlator_t *this)
-{
- char key[GF_DUMP_MAX_BUF_LEN];
- int i = 0;
- stripe_private_t *priv = NULL;
- int ret = -1;
- struct stripe_options *options = NULL;
-
- GF_VALIDATE_OR_GOTO ("stripe", this, out);
-
- priv = this->private;
- if (!priv)
- goto out;
-
- ret = TRY_LOCK (&priv->lock);
- if (ret != 0)
- goto out;
-
- gf_proc_dump_add_section("xlator.cluster.stripe.%s.priv", this->name);
- gf_proc_dump_write("child_count","%d", priv->child_count);
-
- for (i = 0; i < priv->child_count; i++) {
- sprintf (key, "subvolumes[%d]", i);
- gf_proc_dump_write (key, "%s.%s", priv->xl_array[i]->type,
- priv->xl_array[i]->name);
- }
-
- options = priv->pattern;
- while (options != NULL) {
- gf_proc_dump_write ("path_pattern", "%s", priv->pattern->path_pattern);
- gf_proc_dump_write ("options_block_size", "%ul", options->block_size);
-
- options = options->next;
- }
-
- gf_proc_dump_write ("block_size", "%ul", priv->block_size);
- gf_proc_dump_write ("nodes-down", "%d", priv->nodes_down);
- gf_proc_dump_write ("first-child_down", "%d", priv->first_child_down);
- gf_proc_dump_write ("xattr_supported", "%d", priv->xattr_supported);
-
- UNLOCK (&priv->lock);
-
-out:
- return ret;
-}
-
struct xlator_fops fops = {
- .stat = stripe_stat,
- .unlink = stripe_unlink,
- .rename = stripe_rename,
- .link = stripe_link,
- .truncate = stripe_truncate,
- .create = stripe_create,
- .open = stripe_open,
- .readv = stripe_readv,
- .writev = stripe_writev,
- .statfs = stripe_statfs,
- .flush = stripe_flush,
- .fsync = stripe_fsync,
- .ftruncate = stripe_ftruncate,
- .fstat = stripe_fstat,
- .mkdir = stripe_mkdir,
- .rmdir = stripe_rmdir,
- .lk = stripe_lk,
- .opendir = stripe_opendir,
- .fsyncdir = stripe_fsyncdir,
- .setattr = stripe_setattr,
- .fsetattr = stripe_fsetattr,
- .lookup = stripe_lookup,
- .mknod = stripe_mknod,
- .setxattr = stripe_setxattr,
- .fsetxattr = stripe_fsetxattr,
- .getxattr = stripe_getxattr,
- .removexattr = stripe_removexattr,
- .fremovexattr = stripe_fremovexattr,
- .readdirp = stripe_readdirp,
+ .stat = stripe_stat,
+ .unlink = stripe_unlink,
+ .rename = stripe_rename,
+ .link = stripe_link,
+ .truncate = stripe_truncate,
+ .create = stripe_create,
+ .open = stripe_open,
+ .readv = stripe_readv,
+ .writev = stripe_writev,
+ .statfs = stripe_statfs,
+ .flush = stripe_flush,
+ .fsync = stripe_fsync,
+ .ftruncate = stripe_ftruncate,
+ .fstat = stripe_fstat,
+ .mkdir = stripe_mkdir,
+ .rmdir = stripe_rmdir,
+ .lk = stripe_lk,
+ .opendir = stripe_opendir,
+ .fsyncdir = stripe_fsyncdir,
+ .setattr = stripe_setattr,
+ .fsetattr = stripe_fsetattr,
+ .lookup = stripe_lookup,
+ .mknod = stripe_mknod,
+
+ .getxattr = stripe_getxattr,
+ .readdirp = stripe_readdirp,
};
struct xlator_cbks cbks = {
.release = stripe_release,
- .forget = stripe_forget,
};
-struct xlator_dumpops dumpops = {
- .priv = stripe_priv_dump,
-};
struct volume_options options[] = {
{ .key = {"block-size"},
- .type = GF_OPTION_TYPE_SIZE_LIST,
- .default_value = "128KB",
- .min = STRIPE_MIN_BLOCK_SIZE,
- .description = "Size of the stripe unit that would be read "
- "from or written to the striped servers."
+ .type = GF_OPTION_TYPE_ANY
},
{ .key = {"use-xattr"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "true"
+ .type = GF_OPTION_TYPE_BOOL
},
- { .key = {"coalesce"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false",
- .description = "Enable coalesce mode to flatten striped files as "
- "stored on the server (i.e., eliminate holes caused "
- "by the traditional format)."
- },
{ .key = {NULL} },
};
diff --git a/xlators/cluster/stripe/src/stripe.h b/xlators/cluster/stripe/src/stripe.h
index a440f87ba..2d7b92dd5 100644
--- a/xlators/cluster/stripe/src/stripe.h
+++ b/xlators/cluster/stripe/src/stripe.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -28,55 +37,30 @@
#include <fnmatch.h>
#include <signal.h>
-#define STRIPE_PATHINFO_HEADER "STRIPE:"
-#define STRIPE_MIN_BLOCK_SIZE (16*GF_UNIT_KB)
#define STRIPE_STACK_UNWIND(fop, frame, params ...) do { \
stripe_local_t *__local = NULL; \
- if (frame) { \
- __local = frame->local; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- if (__local) { \
- stripe_local_wipe(__local); \
- mem_put (__local); \
- } \
- } while (0)
-
-#define STRIPE_STACK_DESTROY(frame) do { \
- stripe_local_t *__local = NULL; \
- __local = frame->local; \
- frame->local = NULL; \
- STACK_DESTROY (frame->root); \
+ if (frame) { \
+ __local = frame->local; \
+ frame->local = NULL; \
+ } \
+ STACK_UNWIND_STRICT (fop, frame, params); \
if (__local) { \
- stripe_local_wipe (__local); \
- mem_put (__local); \
+ stripe_local_wipe(__local); \
+ GF_FREE (__local); \
} \
} while (0)
-#define STRIPE_VALIDATE_FCTX(fctx, label) do { \
- int idx = 0; \
- if (!fctx) { \
- op_errno = EINVAL; \
- goto label; \
- } \
- for (idx = 0; idx < fctx->stripe_count; idx++) { \
- if (!fctx->xl_array[idx]) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "fctx->xl_array[%d] is NULL", \
- idx); \
- op_errno = ESTALE; \
- goto label; \
- } \
- } \
- } while (0)
-
-typedef struct stripe_xattr_sort {
- int32_t pos;
- int32_t xattr_len;
- char *xattr_value;
-} stripe_xattr_sort_t;
+#define STRIPE_STACK_DESTROY(frame) do { \
+ stripe_local_t *__local = NULL; \
+ __local = frame->local; \
+ frame->local = NULL; \
+ STACK_DESTROY (frame->root); \
+ if (__local) { \
+ stripe_local_wipe (__local); \
+ GF_FREE (__local); \
+ } \
+ } while (0)
/**
* struct stripe_options : This keeps the pattern and the block-size
@@ -101,14 +85,13 @@ struct stripe_private {
int8_t child_count;
int8_t *state; /* Current state of child node */
gf_boolean_t xattr_supported; /* default yes */
- gf_boolean_t coalesce;
char vol_uuid[UUID_SIZE + 1];
};
/**
- * Used to keep info about the replies received from readv/writev calls
+ * Used to keep info about the replies received from fops->readv calls
*/
-struct stripe_replies {
+struct readv_replies {
struct iovec *vector;
int32_t count; //count of vector
int32_t op_ret; //op_ret of readv
@@ -120,7 +103,6 @@ struct stripe_replies {
typedef struct _stripe_fd_ctx {
off_t stripe_size;
int stripe_count;
- int stripe_coalesce;
int static_array;
xlator_t **xl_array;
} stripe_fd_ctx_t;
@@ -156,7 +138,7 @@ struct stripe_local {
blkcnt_t preparent_blocks;
blkcnt_t postparent_blocks;
- struct stripe_replies *replies;
+ struct readv_replies *replies;
struct statvfs statvfs_buf;
dir_entry_t *entry;
@@ -180,15 +162,8 @@ struct stripe_local {
loc_t loc;
loc_t loc2;
- mode_t mode;
- dev_t rdev;
/* For File I/O fops */
- dict_t *xdata;
-
- stripe_xattr_sort_t *xattr_list;
- int32_t xattr_total_len;
- int32_t nallocs;
- char xsel[256];
+ dict_t *dict;
struct marker_str marker;
@@ -205,81 +180,11 @@ struct stripe_local {
void *value;
struct iobref *iobref;
gf_dirent_t entries;
- gf_dirent_t *dirent;
dict_t *xattr;
- uuid_t ia_gfid;
-
- int xflag;
- mode_t umask;
};
typedef struct stripe_local stripe_local_t;
typedef struct stripe_private stripe_private_t;
-/*
- * Determine the stripe index of a particular frame based on the translator.
- */
-static inline int32_t stripe_get_frame_index(stripe_fd_ctx_t *fctx,
- call_frame_t *prev)
-{
- int32_t i, idx = -1;
-
- for (i = 0; i < fctx->stripe_count; i++) {
- if (fctx->xl_array[i] == prev->this) {
- idx = i;
- break;
- }
- }
-
- return idx;
-}
-
-static inline void stripe_copy_xl_array(xlator_t **dst, xlator_t **src,
- int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- dst[i] = src[i];
-}
-
-void stripe_local_wipe (stripe_local_t *local);
-int32_t stripe_ctx_handle (xlator_t *this, call_frame_t *prev,
- stripe_local_t *local, dict_t *dict);
-void stripe_aggregate_xattr (dict_t *dst, dict_t *src);
-int32_t stripe_xattr_request_build (xlator_t *this, dict_t *dict,
- uint64_t stripe_size, uint32_t stripe_count,
- uint32_t stripe_index,
- uint32_t stripe_coalesce);
-int32_t stripe_get_matching_bs (const char *path, stripe_private_t *priv);
-int set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data);
-int32_t stripe_iatt_merge (struct iatt *from, struct iatt *to);
-int32_t stripe_fill_pathinfo_xattr (xlator_t *this, stripe_local_t *local,
- char **xattr_serz);
-int32_t stripe_free_xattr_str (stripe_local_t *local);
-int32_t stripe_xattr_aggregate (char *buffer, stripe_local_t *local,
- int32_t *total);
-off_t coalesced_offset(off_t offset, uint64_t stripe_size, int stripe_count);
-off_t uncoalesced_size(off_t size, uint64_t stripe_size, int stripe_count,
- int stripe_index);
-
-/*
- * Adjust the size attribute for files if coalesce is enabled.
- */
-static inline void correct_file_size(struct iatt *buf, stripe_fd_ctx_t *fctx,
- call_frame_t *prev)
-{
- int index;
-
- if (!IA_ISREG(buf->ia_type))
- return;
-
- if (!fctx || !fctx->stripe_coalesce)
- return;
-
- index = stripe_get_frame_index(fctx, prev);
- buf->ia_size = uncoalesced_size(buf->ia_size, fctx->stripe_size,
- fctx->stripe_count, index);
-}
#endif /* _STRIPE_H_ */
diff --git a/xlators/cluster/unify/Makefile.am b/xlators/cluster/unify/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/cluster/unify/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/cluster/unify/src/Makefile.am b/xlators/cluster/unify/src/Makefile.am
new file mode 100644
index 000000000..2a1fe8372
--- /dev/null
+++ b/xlators/cluster/unify/src/Makefile.am
@@ -0,0 +1,16 @@
+
+xlator_LTLIBRARIES = unify.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/cluster
+
+unify_la_LDFLAGS = -module -avoidversion
+
+unify_la_SOURCES = unify.c unify-self-heal.c
+unify_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = unify.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+
+CLEANFILES =
+
diff --git a/xlators/cluster/unify/src/unify-mem-types.h b/xlators/cluster/unify/src/unify-mem-types.h
new file mode 100644
index 000000000..dcf964779
--- /dev/null
+++ b/xlators/cluster/unify/src/unify-mem-types.h
@@ -0,0 +1,41 @@
+
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __UNIFY_MEM_TYPES_H__
+#define __UNIFY_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_unify_mem_types_ {
+ gf_unify_mt_char = gf_common_mt_end + 1,
+ gf_unify_mt_int16_t,
+ gf_unify_mt_xlator_t,
+ gf_unify_mt_unify_private_t,
+ gf_unify_mt_xlator_list_t,
+ gf_unify_mt_dir_entry_t,
+ gf_unify_mt_off_t,
+ gf_unify_mt_int,
+ gf_unify_mt_unify_self_heal_struct,
+ gf_unify_mt_unify_local_t,
+ gf_unify_mt_end
+};
+#endif
+
diff --git a/xlators/cluster/unify/src/unify-self-heal.c b/xlators/cluster/unify/src/unify-self-heal.c
new file mode 100644
index 000000000..725523a2e
--- /dev/null
+++ b/xlators/cluster/unify/src/unify-self-heal.c
@@ -0,0 +1,1239 @@
+/*
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * unify-self-heal.c :
+ * This file implements few functions which enables 'unify' translator
+ * to be consistent in its behaviour when
+ * > a node fails,
+ * > a node gets added,
+ * > a failed node comes back
+ * > a new namespace server is added (ie, an fresh namespace server).
+ *
+ * This functionality of 'unify' will enable glusterfs to support storage
+ * system failure, and maintain consistancy. This works both ways, ie, when
+ * an entry (either file or directory) is found on namespace server, and not
+ * on storage nodes, its created in storage nodes and vica-versa.
+ *
+ * The two fops, where it can be implemented are 'getdents ()' and 'lookup ()'
+ *
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "unify.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "common-utils.h"
+
+int32_t
+unify_sh_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count);
+
+int32_t
+unify_sh_ns_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count);
+
+int32_t
+unify_bgsh_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count);
+
+int32_t
+unify_bgsh_ns_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count);
+
+/**
+ * unify_local_wipe - free all the extra allocation of local->* here.
+ */
+static void
+unify_local_wipe (unify_local_t *local)
+{
+ /* Free the strdup'd variables in the local structure */
+ if (local->name) {
+ GF_FREE (local->name);
+ }
+
+ if (local->sh_struct) {
+ if (local->sh_struct->offset_list)
+ GF_FREE (local->sh_struct->offset_list);
+
+ if (local->sh_struct->entry_list)
+ GF_FREE (local->sh_struct->entry_list);
+
+ if (local->sh_struct->count_list)
+ GF_FREE (local->sh_struct->count_list);
+
+ GF_FREE (local->sh_struct);
+ }
+
+ loc_wipe (&local->loc1);
+ loc_wipe (&local->loc2);
+}
+
+int32_t
+unify_sh_setdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ inode_t *inode = NULL;
+ dict_t *tmp_dict = NULL;
+ dir_entry_t *prev, *entry, *trav;
+
+ LOCK (&frame->lock);
+ {
+ /* if local->call_count == 0, that means, setdents on
+ * storagenodes is still pending.
+ */
+ if (local->call_count)
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (callcnt == 0) {
+ if (local->sh_struct->entry_list[0]) {
+ prev = entry = local->sh_struct->entry_list[0];
+ if (!entry)
+ return 0;
+ trav = entry->next;
+ while (trav) {
+ prev->next = trav->next;
+ GF_FREE (trav->name);
+ if (IA_ISLNK (trav->buf.ia_type))
+ GF_FREE (trav->link);
+ GF_FREE (trav);
+ trav = prev->next;
+ }
+ GF_FREE (entry);
+ }
+
+ if (!local->flags) {
+ if (local->sh_struct->count_list[0] >=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ /* count == size, that means, there are more entries
+ to read from */
+ //local->call_count = 0;
+ local->sh_struct->offset_list[0] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+ STACK_WIND (frame,
+ unify_sh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[0],
+ GF_GET_DIR_ONLY);
+ }
+ } else {
+ inode = local->loc1.inode;
+ fd_unref (local->fd);
+ tmp_dict = local->dict;
+
+ unify_local_wipe (local);
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ inode, &local->stbuf, local->dict,
+ &local->oldpostparent);
+ if (tmp_dict)
+ dict_unref (tmp_dict);
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_sh_ns_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count)
+{
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = 0;
+ unsigned long final = 0;
+ dir_entry_t *tmp = GF_CALLOC (1, sizeof (dir_entry_t),
+ gf_unify_mt_dir_entry_t);
+
+ local->sh_struct->entry_list[0] = tmp;
+ local->sh_struct->count_list[0] = count;
+ if (entry) {
+ tmp->next = entry->next;
+ entry->next = NULL;
+ }
+
+ if ((count < UNIFY_SELF_HEAL_GETDENTS_COUNT) || !entry) {
+ final = 1;
+ }
+
+ LOCK (&frame->lock);
+ {
+ /* local->call_count will be '0' till now. make it 1 so, it
+ can be UNWIND'ed for the last call. */
+ local->call_count = priv->child_count;
+ if (final)
+ local->flags = 1;
+ }
+ UNLOCK (&frame->lock);
+
+ for (index = 0; index < priv->child_count; index++)
+ {
+ STACK_WIND_COOKIE (frame,
+ unify_sh_setdents_cbk,
+ (void *)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->setdents,
+ local->fd, GF_SET_DIR_ONLY,
+ local->sh_struct->entry_list[0], count);
+ }
+
+ return 0;
+}
+
+int32_t
+unify_sh_ns_setdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = (long)cookie;
+ dir_entry_t *prev, *entry, *trav;
+
+ LOCK (&frame->lock);
+ {
+ if (local->sh_struct->entry_list[index]) {
+ prev = entry = local->sh_struct->entry_list[index];
+ trav = entry->next;
+ while (trav) {
+ prev->next = trav->next;
+ GF_FREE (trav->name);
+ if (IA_ISLNK (trav->buf.ia_type))
+ GF_FREE (trav->link);
+ GF_FREE (trav);
+ trav = prev->next;
+ }
+ GF_FREE (entry);
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (local->sh_struct->count_list[index] <
+ UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+ } else {
+ /* count == size, that means, there are more entries
+ to read from */
+ local->sh_struct->offset_list[index] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+ STACK_WIND_COOKIE (frame,
+ unify_sh_getdents_cbk,
+ cookie,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[index],
+ GF_GET_ALL);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir on (%s) with offset %"PRId64"",
+ priv->xl_array[index]->name,
+ local->sh_struct->offset_list[index]);
+ }
+
+ if (!callcnt) {
+ /* All storage nodes have done unified setdents on NS node.
+ * Now, do getdents from NS and do setdents on storage nodes.
+ */
+
+ /* sh_struct->offset_list is no longer required for
+ storage nodes now */
+ local->sh_struct->offset_list[0] = 0; /* reset */
+
+ STACK_WIND (frame,
+ unify_sh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_DIR_ONLY);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_sh_getdents_cbk -
+ */
+int32_t
+unify_sh_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = (long)cookie;
+ dir_entry_t *tmp = NULL;
+
+ if (op_ret >= 0 && count > 0) {
+ /* There is some dentry found, just send the dentry to NS */
+ tmp = GF_CALLOC (1, sizeof (dir_entry_t),
+ gf_unify_mt_dir_entry_t);
+ local->sh_struct->entry_list[index] = tmp;
+ local->sh_struct->count_list[index] = count;
+ if (entry) {
+ tmp->next = entry->next;
+ entry->next = NULL;
+ }
+ STACK_WIND_COOKIE (frame,
+ unify_sh_ns_setdents_cbk,
+ cookie,
+ NS(this),
+ NS(this)->fops->setdents,
+ local->fd,
+ GF_SET_IF_NOT_PRESENT,
+ local->sh_struct->entry_list[index],
+ count);
+ return 0;
+ }
+
+ if (count < UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+ } else {
+ /* count == size, that means, there are more entries
+ to read from */
+ local->sh_struct->offset_list[index] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+ STACK_WIND_COOKIE (frame,
+ unify_sh_getdents_cbk,
+ cookie,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[index],
+ GF_GET_ALL);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir on (%s) with offset %"PRId64"",
+ priv->xl_array[index]->name,
+ local->sh_struct->offset_list[index]);
+ }
+
+ if (!callcnt) {
+ /* All storage nodes have done unified setdents on NS node.
+ * Now, do getdents from NS and do setdents on storage nodes.
+ */
+
+ /* sh_struct->offset_list is no longer required for
+ storage nodes now */
+ local->sh_struct->offset_list[0] = 0; /* reset */
+
+ STACK_WIND (frame,
+ unify_sh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_DIR_ONLY);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_sh_opendir_cbk -
+ *
+ * @cookie:
+ */
+int32_t
+unify_sh_opendir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t index = 0;
+ inode_t *inode = NULL;
+ dict_t *tmp_dict = NULL;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ } else {
+ gf_log (this->name, GF_LOG_WARNING, "failed");
+ local->failed = 1;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local->call_count = priv->child_count + 1;
+
+ if (!local->failed) {
+ /* send getdents() namespace after finishing
+ storage nodes */
+ local->call_count--;
+
+ fd_bind (fd);
+
+ if (local->call_count) {
+ /* Used as the offset index. This list keeps
+ * track of offset sent to each node during
+ * STACK_WIND.
+ */
+ local->sh_struct->offset_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (off_t),
+ gf_unify_mt_off_t);
+ ERR_ABORT (local->sh_struct->offset_list);
+
+ local->sh_struct->entry_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (dir_entry_t *),
+ gf_unify_mt_dir_entry_t);
+ ERR_ABORT (local->sh_struct->entry_list);
+
+ local->sh_struct->count_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (int),
+ gf_unify_mt_int);
+ ERR_ABORT (local->sh_struct->count_list);
+
+ /* Send getdents on all the fds */
+ for (index = 0;
+ index < priv->child_count; index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_sh_getdents_cbk,
+ (void *)(long)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_ALL);
+ }
+
+ /* did stack wind, so no need to unwind here */
+ return 0;
+ } /* (local->call_count) */
+ } /* (!local->failed) */
+
+ /* Opendir failed on one node. */
+ inode = local->loc1.inode;
+ fd_unref (local->fd);
+ tmp_dict = local->dict;
+
+ unify_local_wipe (local);
+ /* Only 'self-heal' failed, lookup() was successful. */
+ local->op_ret = 0;
+
+ /* This is lookup_cbk ()'s UNWIND. */
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, inode,
+ &local->stbuf, local->dict, &local->oldpostparent);
+ if (tmp_dict)
+ dict_unref (tmp_dict);
+ }
+
+ return 0;
+}
+
+/**
+ * gf_sh_checksum_cbk -
+ *
+ * @frame: frame used in lookup. get a copy of it, and use that copy.
+ * @this: pointer to unify xlator.
+ * @inode: pointer to inode, for which the consistency check is required.
+ *
+ */
+int32_t
+unify_sh_checksum_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ uint8_t *file_checksum,
+ uint8_t *dir_checksum)
+{
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t index = 0;
+ int32_t callcnt = 0;
+ inode_t *inode = NULL;
+ dict_t *tmp_dict = NULL;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret >= 0) {
+ if (NS(this) == (xlator_t *)cookie) {
+ memcpy (local->sh_struct->ns_file_checksum,
+ file_checksum, NAME_MAX);
+ memcpy (local->sh_struct->ns_dir_checksum,
+ dir_checksum, NAME_MAX);
+ } else {
+ if (local->entry_count == 0) {
+ /* Initialize the dir_checksum to be
+ * used for comparision with other
+ * storage nodes. Should be done for
+ * the first successful call *only*.
+ */
+ /* Using 'entry_count' as a flag */
+ local->entry_count = 1;
+ memcpy (local->sh_struct->dir_checksum,
+ dir_checksum, NAME_MAX);
+ }
+
+ /* Reply from the storage nodes */
+ for (index = 0;
+ index < NAME_MAX; index++) {
+ /* Files should be present in
+ only one node */
+ local->sh_struct->file_checksum[index] ^= file_checksum[index];
+
+ /* directory structure should be
+ same accross */
+ if (local->sh_struct->dir_checksum[index] != dir_checksum[index])
+ local->failed = 1;
+ }
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ for (index = 0; index < NAME_MAX ; index++) {
+ if (local->sh_struct->file_checksum[index] !=
+ local->sh_struct->ns_file_checksum[index]) {
+ local->failed = 1;
+ break;
+ }
+ if (local->sh_struct->dir_checksum[index] !=
+ local->sh_struct->ns_dir_checksum[index]) {
+ local->failed = 1;
+ break;
+ }
+ }
+
+ if (local->failed) {
+ /* Log it, it should be a rare event */
+ gf_log (this->name, GF_LOG_WARNING,
+ "Self-heal triggered on directory %s",
+ local->loc1.path);
+
+ /* Any self heal will be done at directory level */
+ local->call_count = 0;
+ local->op_ret = -1;
+ local->failed = 0;
+
+ local->fd = fd_create (local->loc1.inode,
+ frame->root->pid);
+
+ local->call_count = priv->child_count + 1;
+
+ for (index = 0;
+ index < (priv->child_count + 1); index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_sh_opendir_cbk,
+ priv->xl_array[index]->name,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->opendir,
+ &local->loc1,
+ local->fd);
+ }
+ /* opendir can be done on the directory */
+ return 0;
+ }
+
+ /* no mismatch */
+ inode = local->loc1.inode;
+ tmp_dict = local->dict;
+
+ unify_local_wipe (local);
+
+ /* This is lookup_cbk ()'s UNWIND. */
+ STACK_UNWIND (frame,
+ local->op_ret,
+ local->op_errno,
+ inode,
+ &local->stbuf,
+ local->dict, &local->oldpostparent);
+ if (tmp_dict)
+ dict_unref (tmp_dict);
+ }
+
+ return 0;
+}
+
+/* Foreground self-heal part over */
+
+/* Background self-heal part */
+
+int32_t
+unify_bgsh_setdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ dir_entry_t *prev, *entry, *trav;
+
+ LOCK (&frame->lock);
+ {
+ /* if local->call_count == 0, that means, setdents
+ on storagenodes is still pending. */
+ if (local->call_count)
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+
+ if (callcnt == 0) {
+ if (local->sh_struct->entry_list[0]) {
+ prev = entry = local->sh_struct->entry_list[0];
+ trav = entry->next;
+ while (trav) {
+ prev->next = trav->next;
+ GF_FREE (trav->name);
+ if (IA_ISLNK (trav->buf.ia_type))
+ GF_FREE (trav->link);
+ GF_FREE (trav);
+ trav = prev->next;
+ }
+ GF_FREE (entry);
+ }
+
+ if (!local->flags) {
+ if (local->sh_struct->count_list[0] >=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ /* count == size, that means, there are more
+ entries to read from */
+ //local->call_count = 0;
+ local->sh_struct->offset_list[0] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+ STACK_WIND (frame,
+ unify_bgsh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[0],
+ GF_GET_DIR_ONLY);
+ }
+ } else {
+ fd_unref (local->fd);
+ unify_local_wipe (local);
+ STACK_DESTROY (frame->root);
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_bgsh_ns_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count)
+{
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = 0;
+ unsigned long final = 0;
+ dir_entry_t *tmp = GF_CALLOC (1, sizeof (dir_entry_t),
+ gf_unify_mt_dir_entry_t);
+
+ local->sh_struct->entry_list[0] = tmp;
+ local->sh_struct->count_list[0] = count;
+ if (entry) {
+ tmp->next = entry->next;
+ entry->next = NULL;
+ }
+
+ if ((count < UNIFY_SELF_HEAL_GETDENTS_COUNT) || !entry) {
+ final = 1;
+ }
+
+ LOCK (&frame->lock);
+ {
+ /* local->call_count will be '0' till now. make it 1 so,
+ it can be UNWIND'ed for the last call. */
+ local->call_count = priv->child_count;
+ if (final)
+ local->flags = 1;
+ }
+ UNLOCK (&frame->lock);
+
+ for (index = 0; index < priv->child_count; index++)
+ {
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_setdents_cbk,
+ (void *)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->setdents,
+ local->fd, GF_SET_DIR_ONLY,
+ local->sh_struct->entry_list[0], count);
+ }
+
+ return 0;
+}
+
+int32_t
+unify_bgsh_ns_setdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = (long)cookie;
+ dir_entry_t *prev, *entry, *trav;
+
+ if (local->sh_struct->entry_list[index]) {
+ prev = entry = local->sh_struct->entry_list[index];
+ if (!entry)
+ return 0;
+ trav = entry->next;
+ while (trav) {
+ prev->next = trav->next;
+ GF_FREE (trav->name);
+ if (IA_ISLNK (trav->buf.ia_type))
+ GF_FREE (trav->link);
+ GF_FREE (trav);
+ trav = prev->next;
+ }
+ GF_FREE (entry);
+ }
+
+ if (local->sh_struct->count_list[index] <
+ UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+ } else {
+ /* count == size, that means, there are more entries
+ to read from */
+ local->sh_struct->offset_list[index] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_getdents_cbk,
+ cookie,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[index],
+ GF_GET_ALL);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir on (%s) with offset %"PRId64"",
+ priv->xl_array[index]->name,
+ local->sh_struct->offset_list[index]);
+ }
+
+ if (!callcnt) {
+ /* All storage nodes have done unified setdents on NS node.
+ * Now, do getdents from NS and do setdents on storage nodes.
+ */
+
+ /* sh_struct->offset_list is no longer required for
+ storage nodes now */
+ local->sh_struct->offset_list[0] = 0; /* reset */
+
+ STACK_WIND (frame,
+ unify_bgsh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_DIR_ONLY);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_bgsh_getdents_cbk -
+ */
+int32_t
+unify_bgsh_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count)
+{
+ int32_t callcnt = -1;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ long index = (long)cookie;
+ dir_entry_t *tmp = NULL;
+
+ if (op_ret >= 0 && count > 0) {
+ /* There is some dentry found, just send the dentry to NS */
+ tmp = GF_CALLOC (1, sizeof (dir_entry_t),
+ gf_unify_mt_dir_entry_t);
+ local->sh_struct->entry_list[index] = tmp;
+ local->sh_struct->count_list[index] = count;
+ if (entry) {
+ tmp->next = entry->next;
+ entry->next = NULL;
+ }
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_ns_setdents_cbk,
+ cookie,
+ NS(this),
+ NS(this)->fops->setdents,
+ local->fd,
+ GF_SET_IF_NOT_PRESENT,
+ local->sh_struct->entry_list[index],
+ count);
+ return 0;
+ }
+
+ if (count < UNIFY_SELF_HEAL_GETDENTS_COUNT) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+ } else {
+ /* count == size, that means, there are more entries to read from */
+ local->sh_struct->offset_list[index] +=
+ UNIFY_SELF_HEAL_GETDENTS_COUNT;
+
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_getdents_cbk,
+ cookie,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ local->sh_struct->offset_list[index],
+ GF_GET_ALL);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "readdir on (%s) with offset %"PRId64"",
+ priv->xl_array[index]->name,
+ local->sh_struct->offset_list[index]);
+ }
+
+ if (!callcnt) {
+ /* All storage nodes have done unified setdents on NS node.
+ * Now, do getdents from NS and do setdents on storage nodes.
+ */
+
+ /* sh_struct->offset_list is no longer required for
+ storage nodes now */
+ local->sh_struct->offset_list[0] = 0; /* reset */
+
+ STACK_WIND (frame,
+ unify_bgsh_ns_getdents_cbk,
+ NS(this),
+ NS(this)->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_DIR_ONLY);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_bgsh_opendir_cbk -
+ *
+ * @cookie:
+ */
+int32_t
+unify_bgsh_opendir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int32_t callcnt = 0;
+ int16_t index = 0;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ } else {
+ local->failed = 1;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local->call_count = priv->child_count + 1;
+
+ if (!local->failed) {
+ /* send getdents() namespace after finishing
+ storage nodes */
+ local->call_count--;
+ callcnt = local->call_count;
+
+ fd_bind (fd);
+
+ if (local->call_count) {
+ /* Used as the offset index. This list keeps
+ track of offset sent to each node during
+ STACK_WIND. */
+ local->sh_struct->offset_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (off_t),
+ gf_unify_mt_off_t);
+ ERR_ABORT (local->sh_struct->offset_list);
+
+ local->sh_struct->entry_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (dir_entry_t *),
+ gf_unify_mt_dir_entry_t);
+ ERR_ABORT (local->sh_struct->entry_list);
+
+ local->sh_struct->count_list =
+ GF_CALLOC (priv->child_count,
+ sizeof (int),
+ gf_unify_mt_int);
+ ERR_ABORT (local->sh_struct->count_list);
+
+ /* Send getdents on all the fds */
+ for (index = 0;
+ index < priv->child_count; index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_getdents_cbk,
+ (void *)(long)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getdents,
+ local->fd,
+ UNIFY_SELF_HEAL_GETDENTS_COUNT,
+ 0, /* In this call, do send '0' as offset */
+ GF_GET_ALL);
+ }
+ /* did a stack wind, so no need to unwind here */
+ return 0;
+ } /* (local->call_count) */
+ } /* (!local->failed) */
+
+ /* Opendir failed on one node. */
+ fd_unref (local->fd);
+
+ unify_local_wipe (local);
+ STACK_DESTROY (frame->root);
+ }
+
+ return 0;
+}
+
+/**
+ * gf_bgsh_checksum_cbk -
+ *
+ * @frame: frame used in lookup. get a copy of it, and use that copy.
+ * @this: pointer to unify xlator.
+ * @inode: pointer to inode, for which the consistency check is required.
+ *
+ */
+int32_t
+unify_bgsh_checksum_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ uint8_t *file_checksum,
+ uint8_t *dir_checksum)
+{
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t index = 0;
+ int32_t callcnt = 0;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret >= 0) {
+ if (NS(this) == (xlator_t *)cookie) {
+ memcpy (local->sh_struct->ns_file_checksum,
+ file_checksum, NAME_MAX);
+ memcpy (local->sh_struct->ns_dir_checksum,
+ dir_checksum, NAME_MAX);
+ } else {
+ if (local->entry_count == 0) {
+ /* Initialize the dir_checksum to be
+ * used for comparision with other
+ * storage nodes. Should be done for
+ * the first successful call *only*.
+ */
+ /* Using 'entry_count' as a flag */
+ local->entry_count = 1;
+ memcpy (local->sh_struct->dir_checksum,
+ dir_checksum, NAME_MAX);
+ }
+
+ /* Reply from the storage nodes */
+ for (index = 0;
+ index < NAME_MAX; index++) {
+ /* Files should be present in only
+ one node */
+ local->sh_struct->file_checksum[index] ^= file_checksum[index];
+
+ /* directory structure should be same
+ accross */
+ if (local->sh_struct->dir_checksum[index] != dir_checksum[index])
+ local->failed = 1;
+ }
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ for (index = 0; index < NAME_MAX ; index++) {
+ if (local->sh_struct->file_checksum[index] !=
+ local->sh_struct->ns_file_checksum[index]) {
+ local->failed = 1;
+ break;
+ }
+ if (local->sh_struct->dir_checksum[index] !=
+ local->sh_struct->ns_dir_checksum[index]) {
+ local->failed = 1;
+ break;
+ }
+ }
+
+ if (local->failed) {
+ /* Log it, it should be a rare event */
+ gf_log (this->name, GF_LOG_WARNING,
+ "Self-heal triggered on directory %s",
+ local->loc1.path);
+
+ /* Any self heal will be done at the directory level */
+ local->op_ret = -1;
+ local->failed = 0;
+
+ local->fd = fd_create (local->loc1.inode,
+ frame->root->pid);
+ local->call_count = priv->child_count + 1;
+
+ for (index = 0;
+ index < (priv->child_count + 1); index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_bgsh_opendir_cbk,
+ priv->xl_array[index]->name,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->opendir,
+ &local->loc1,
+ local->fd);
+ }
+
+ /* opendir can be done on the directory */
+ return 0;
+ }
+
+ /* no mismatch */
+ unify_local_wipe (local);
+ STACK_DESTROY (frame->root);
+ }
+
+ return 0;
+}
+
+/* Background self-heal part over */
+
+
+
+
+/**
+ * zr_unify_self_heal -
+ *
+ * @frame: frame used in lookup. get a copy of it, and use that copy.
+ * @this: pointer to unify xlator.
+ * @inode: pointer to inode, for which the consistency check is required.
+ *
+ */
+int32_t
+zr_unify_self_heal (call_frame_t *frame,
+ xlator_t *this,
+ unify_local_t *local)
+{
+ unify_private_t *priv = this->private;
+ call_frame_t *bg_frame = NULL;
+ unify_local_t *bg_local = NULL;
+ inode_t *tmp_inode = NULL;
+ dict_t *tmp_dict = NULL;
+ int16_t index = 0;
+
+ if (local->inode_generation < priv->inode_generation) {
+ /* Any self heal will be done at the directory level */
+ /* Update the inode's generation to the current generation
+ value. */
+ local->inode_generation = priv->inode_generation;
+ inode_ctx_put (local->loc1.inode, this,
+ (uint64_t)(long)local->inode_generation);
+
+ if (priv->self_heal == ZR_UNIFY_FG_SELF_HEAL) {
+ local->op_ret = 0;
+ local->failed = 0;
+ local->call_count = priv->child_count + 1;
+ local->sh_struct =
+ GF_CALLOC (1, sizeof (struct unify_self_heal_struct),
+ gf_unify_mt_unify_self_heal_struct);
+
+ /* +1 is for NS */
+ for (index = 0;
+ index < (priv->child_count + 1); index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_sh_checksum_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->checksum,
+ &local->loc1,
+ 0);
+ }
+
+ /* Self-heal in foreground, hence no need
+ to UNWIND here */
+ return 0;
+ }
+
+ /* Self Heal done in background */
+ bg_frame = copy_frame (frame);
+ INIT_LOCAL (bg_frame, bg_local);
+ loc_copy (&bg_local->loc1, &local->loc1);
+ bg_local->op_ret = 0;
+ bg_local->failed = 0;
+ bg_local->call_count = priv->child_count + 1;
+ bg_local->sh_struct =
+ GF_CALLOC (1, sizeof (struct unify_self_heal_struct),
+ gf_unify_mt_unify_self_heal_struct);
+
+ /* +1 is for NS */
+ for (index = 0; index < (priv->child_count + 1); index++) {
+ STACK_WIND_COOKIE (bg_frame,
+ unify_bgsh_checksum_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->checksum,
+ &bg_local->loc1,
+ 0);
+ }
+ }
+
+ /* generation number matches, self heal already done or
+ * self heal done in background: just do STACK_UNWIND
+ */
+ tmp_inode = local->loc1.inode;
+ tmp_dict = local->dict;
+
+ unify_local_wipe (local);
+
+ /* This is lookup_cbk ()'s UNWIND. */
+ STACK_UNWIND (frame,
+ local->op_ret,
+ local->op_errno,
+ tmp_inode,
+ &local->stbuf,
+ local->dict,
+ &local->oldpostparent);
+
+ if (tmp_dict)
+ dict_unref (tmp_dict);
+
+ return 0;
+}
+
diff --git a/xlators/cluster/unify/src/unify.c b/xlators/cluster/unify/src/unify.c
new file mode 100644
index 000000000..422c8d6d8
--- /dev/null
+++ b/xlators/cluster/unify/src/unify.c
@@ -0,0 +1,4589 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * xlators/cluster/unify:
+ * - This xlator is one of the main translator in GlusterFS, which
+ * actually does the clustering work of the file system. One need to
+ * understand that, unify assumes file to be existing in only one of
+ * the child node, and directories to be present on all the nodes.
+ *
+ * NOTE:
+ * Now, unify has support for global namespace, which is used to keep a
+ * global view of fs's namespace tree. The stat for directories are taken
+ * just from the namespace, where as for files, just 'ia_ino' is taken from
+ * Namespace node, and other stat info is taken from the actual storage node.
+ * Also Namespace node helps to keep consistant inode for files across
+ * glusterfs (re-)mounts.
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "unify.h"
+#include "dict.h"
+#include "xlator.h"
+#include "hashfn.h"
+#include "logging.h"
+#include "stack.h"
+#include "defaults.h"
+#include "common-utils.h"
+#include <signal.h>
+#include <libgen.h>
+#include "compat-errno.h"
+#include "compat.h"
+
+#define UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR(_loc) do { \
+ if (!(_loc && _loc->inode)) { \
+ STACK_UNWIND (frame, -1, EINVAL, NULL, NULL, NULL); \
+ return 0; \
+ } \
+} while(0)
+
+
+#define UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR(_fd) do { \
+ if (!(_fd && !fd_ctx_get (_fd, this, NULL))) { \
+ STACK_UNWIND (frame, -1, EBADFD, NULL, NULL); \
+ return 0; \
+ } \
+} while(0)
+
+#define UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(_fd) do { \
+ if (!_fd) { \
+ STACK_UNWIND (frame, -1, EBADFD, NULL, NULL); \
+ return 0; \
+ } \
+} while(0)
+
+/**
+ * unify_local_wipe - free all the extra allocation of local->* here.
+ */
+static void
+unify_local_wipe (unify_local_t *local)
+{
+ /* Free the strdup'd variables in the local structure */
+ if (local->name) {
+ GF_FREE (local->name);
+ }
+ loc_wipe (&local->loc1);
+ loc_wipe (&local->loc2);
+}
+
+
+
+/*
+ * unify_normalize_stats -
+ */
+void
+unify_normalize_stats (struct statvfs *buf,
+ unsigned long bsize,
+ unsigned long frsize)
+{
+ double factor;
+
+ if (buf->f_bsize != bsize) {
+ factor = ((double) buf->f_bsize) / bsize;
+ buf->f_bsize = bsize;
+ buf->f_bfree = (fsblkcnt_t) (factor * buf->f_bfree);
+ buf->f_bavail = (fsblkcnt_t) (factor * buf->f_bavail);
+ }
+
+ if (buf->f_frsize != frsize) {
+ factor = ((double) buf->f_frsize) / frsize;
+ buf->f_frsize = frsize;
+ buf->f_blocks = (fsblkcnt_t) (factor * buf->f_blocks);
+ }
+}
+
+
+xlator_t *
+unify_loc_subvol (loc_t *loc, xlator_t *this)
+{
+ unify_private_t *priv = NULL;
+ xlator_t *subvol = NULL;
+ int16_t *list = NULL;
+ long index = 0;
+ xlator_t *subvol_i = NULL;
+ int ret = 0;
+ uint64_t tmp_list = 0;
+
+ priv = this->private;
+ subvol = NS (this);
+
+ if (!IA_ISDIR (loc->inode->ia_type)) {
+ ret = inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+ if (!list)
+ goto out;
+
+ for (index = 0; list[index] != -1; index++) {
+ subvol_i = priv->xl_array[list[index]];
+ if (subvol_i != NS (this)) {
+ subvol = subvol_i;
+ break;
+ }
+ }
+ }
+out:
+ return subvol;
+}
+
+
+
+/**
+ * unify_statfs_cbk -
+ */
+int32_t
+unify_statfs_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct statvfs *stbuf)
+{
+ int32_t callcnt = 0;
+ struct statvfs *dict_buf = NULL;
+ unsigned long bsize;
+ unsigned long frsize;
+ unify_local_t *local = (unify_local_t *)frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret >= 0) {
+ /* when a call is successfull, add it to local->dict */
+ dict_buf = &local->statvfs_buf;
+
+ if (dict_buf->f_bsize != 0) {
+ bsize = max (dict_buf->f_bsize,
+ stbuf->f_bsize);
+
+ frsize = max (dict_buf->f_frsize,
+ stbuf->f_frsize);
+ unify_normalize_stats(dict_buf, bsize, frsize);
+ unify_normalize_stats(stbuf, bsize, frsize);
+ } else {
+ dict_buf->f_bsize = stbuf->f_bsize;
+ dict_buf->f_frsize = stbuf->f_frsize;
+ }
+
+ dict_buf->f_blocks += stbuf->f_blocks;
+ dict_buf->f_bfree += stbuf->f_bfree;
+ dict_buf->f_bavail += stbuf->f_bavail;
+ dict_buf->f_files += stbuf->f_files;
+ dict_buf->f_ffree += stbuf->f_ffree;
+ dict_buf->f_favail += stbuf->f_favail;
+ dict_buf->f_fsid = stbuf->f_fsid;
+ dict_buf->f_flag = stbuf->f_flag;
+ dict_buf->f_namemax = stbuf->f_namemax;
+ local->op_ret = op_ret;
+ } else {
+ /* fop on storage node has failed due to some error */
+ if (op_errno != ENOTCONN) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): %s",
+ prev_frame->this->name,
+ strerror (op_errno));
+ }
+ local->op_errno = op_errno;
+ }
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->statvfs_buf);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_statfs -
+ */
+int32_t
+unify_statfs (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ unify_local_t *local = NULL;
+ xlator_list_t *trav = this->children;
+
+ INIT_LOCAL (frame, local);
+ local->call_count = ((unify_private_t *)this->private)->child_count;
+
+ while(trav) {
+ STACK_WIND (frame,
+ unify_statfs_cbk,
+ trav->xlator,
+ trav->xlator->fops->statfs,
+ loc);
+ trav = trav->next;
+ }
+
+ return 0;
+}
+
+/**
+ * unify_buf_cbk -
+ */
+int32_t
+unify_buf_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s(): child(%s): path(%s): %s",
+ gf_fop_list[frame->root->op],
+ prev_frame->this->name,
+ (local->loc1.path)?local->loc1.path:"",
+ strerror (op_errno));
+
+ local->op_errno = op_errno;
+ if ((op_errno == ENOENT) && priv->optimist)
+ local->op_ret = 0;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = 0;
+
+ if (NS (this) == prev_frame->this) {
+ local->ia_ino = buf->ia_ino;
+ /* If the entry is directory, get the stat
+ from NS node */
+ if (IA_ISDIR (buf->ia_type) ||
+ !local->stbuf.ia_blksize) {
+ local->stbuf = *buf;
+ }
+ }
+
+ if ((!IA_ISDIR (buf->ia_type)) &&
+ (NS (this) != prev_frame->this)) {
+ /* If file, take the stat info from Storage
+ node. */
+ local->stbuf = *buf;
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ /* If the inode number is not filled, operation should
+ fail */
+ if (!local->ia_ino)
+ local->op_ret = -1;
+
+ local->stbuf.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf);
+ }
+
+ return 0;
+}
+
+#define check_if_dht_linkfile(s) \
+ ((st_mode_from_ia (s->ia_prot, s->ia_type) & ~S_IFMT) == S_ISVTX)
+
+/**
+ * unify_lookup_cbk -
+ */
+int32_t
+unify_lookup_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ dict_t *dict,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ inode_t *tmp_inode = NULL;
+ dict_t *local_dict = NULL;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ if (local->revalidate &&
+ (op_errno == ESTALE)) {
+ /* ESTALE takes priority */
+ local->op_errno = op_errno;
+ local->failed = 1;
+ }
+
+ if ((op_errno != ENOTCONN)
+ && (op_errno != ENOENT)
+ && (local->op_errno != ESTALE)) {
+ /* if local->op_errno is already ESTALE, then
+ * ESTALE has to propogated to the parent first.
+ * do not enter here.
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ priv->xl_array[(long)cookie]->name,
+ local->loc1.path, strerror (op_errno));
+ local->op_errno = op_errno;
+ local->failed = 1;
+
+ } else if (local->revalidate &&
+ (local->op_errno != ESTALE) &&
+ !(priv->optimist && (op_errno == ENOENT))) {
+
+ gf_log (this->name,
+ (op_errno == ENOTCONN) ?
+ GF_LOG_DEBUG:GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ priv->xl_array[(long)cookie]->name,
+ local->loc1.path, strerror (op_errno));
+ local->op_errno = op_errno;
+ local->failed = 1;
+ }
+ }
+
+ if (op_ret == 0) {
+ local->op_ret = 0;
+
+ if (check_if_dht_linkfile(buf)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "file %s may be DHT link file on %s, "
+ "make sure the backend is not shared "
+ "between unify and DHT",
+ local->loc1.path,
+ priv->xl_array[(long)cookie]->name);
+ }
+
+ if (local->stbuf.ia_type && local->stbuf.ia_blksize) {
+ /* make sure we already have a stbuf
+ stored in local->stbuf */
+ if (IA_ISDIR (local->stbuf.ia_type) &&
+ !IA_ISDIR (buf->ia_type)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "[CRITICAL] '%s' is directory "
+ "on namespace, non-directory "
+ "on node '%s', returning EIO",
+ local->loc1.path,
+ priv->xl_array[(long)cookie]->name);
+ local->return_eio = 1;
+ }
+ if (!IA_ISDIR (local->stbuf.ia_type) &&
+ IA_ISDIR (buf->ia_type)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "[CRITICAL] '%s' is directory "
+ "on node '%s', non-directory "
+ "on namespace, returning EIO",
+ local->loc1.path,
+ priv->xl_array[(long)cookie]->name);
+ local->return_eio = 1;
+ }
+ }
+
+ if (!local->revalidate && !IA_ISDIR (buf->ia_type)) {
+ /* This is the first time lookup on file*/
+ if (!local->list) {
+ /* list is not allocated, allocate
+ the max possible range */
+ local->list = GF_CALLOC (1, 2 * (priv->child_count + 2),
+ gf_unify_mt_int16_t);
+ if (!local->list) {
+ gf_log (this->name,
+ GF_LOG_CRITICAL,
+ "Not enough memory");
+ STACK_UNWIND (frame, -1,
+ ENOMEM, inode,
+ NULL, NULL, NULL);
+ return 0;
+ }
+ }
+ /* update the index of the list */
+ local->list [local->index++] =
+ (int16_t)(long)cookie;
+ }
+
+ if (!local->revalidate && IA_ISDIR (buf->ia_type)) {
+ /* fresh lookup of a directory */
+ inode_ctx_put (local->loc1.inode, this,
+ priv->inode_generation);
+ }
+
+ if ((!local->dict) && dict &&
+ (priv->xl_array[(long)cookie] != NS(this))) {
+ local->dict = dict_ref (dict);
+ }
+
+ /* index of NS node is == total child count */
+ if (priv->child_count == (int16_t)(long)cookie) {
+ /* Take the inode number from namespace */
+ local->ia_ino = buf->ia_ino;
+ if (IA_ISDIR (buf->ia_type) ||
+ !(local->stbuf.ia_blksize)) {
+ local->stbuf = *buf;
+ local->oldpostparent = *postparent;
+ }
+ } else if (!IA_ISDIR (buf->ia_type)) {
+ /* If file, then get the stat from
+ storage node */
+ local->stbuf = *buf;
+ }
+
+ if (local->ia_nlink < buf->ia_nlink) {
+ local->ia_nlink = buf->ia_nlink;
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local_dict = local->dict;
+ if (local->return_eio) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "[CRITICAL] Unable to fix the path (%s) with "
+ "self-heal, try manual verification. "
+ "returning EIO.", local->loc1.path);
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, -1, EIO, inode, NULL, NULL);
+ if (local_dict) {
+ dict_unref (local_dict);
+ }
+ return 0;
+ }
+
+ if (!local->stbuf.ia_blksize) {
+ /* Inode not present */
+ local->op_ret = -1;
+ } else {
+ if (!local->revalidate &&
+ !IA_ISDIR (local->stbuf.ia_type)) {
+ /* If its a file, big array is useless,
+ allocate the smaller one */
+ int16_t *list = NULL;
+ list = GF_CALLOC (1, 2 * (local->index + 1),
+ gf_unify_mt_int16_t);
+ ERR_ABORT (list);
+ memcpy (list, local->list, 2 * local->index);
+ /* Make the end of the list as -1 */
+ GF_FREE (local->list);
+ local->list = list;
+ local->list [local->index] = -1;
+ /* Update the inode's ctx with proper array */
+ /* TODO: log on failure */
+ inode_ctx_put (local->loc1.inode, this,
+ (uint64_t)(long)local->list);
+ }
+
+ if (IA_ISDIR(local->loc1.inode->ia_type)) {
+ /* lookup is done for directory */
+ if (local->failed && priv->self_heal) {
+ /* Triggering self-heal */
+ /* means, self-heal required for this
+ inode */
+ local->inode_generation = 0;
+ priv->inode_generation++;
+ }
+ } else {
+ local->stbuf.ia_ino = local->ia_ino;
+ }
+
+ local->stbuf.ia_nlink = local->ia_nlink;
+ }
+ if (local->op_ret == -1) {
+ if (!local->revalidate && local->list)
+ GF_FREE (local->list);
+ }
+
+ if ((local->op_ret >= 0) && local->failed &&
+ local->revalidate) {
+ /* Done revalidate, but it failed */
+ if ((op_errno != ENOTCONN)
+ && (local->op_errno != ESTALE)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Revalidate failed for path(%s): %s",
+ local->loc1.path, strerror (op_errno));
+ }
+ local->op_ret = -1;
+ }
+
+ if ((priv->self_heal && !priv->optimist) &&
+ (!local->revalidate && (local->op_ret == 0) &&
+ IA_ISDIR(local->stbuf.ia_type))) {
+ /* Let the self heal be done here */
+ zr_unify_self_heal (frame, this, local);
+ local_dict = NULL;
+ } else {
+ if (local->failed) {
+ /* NOTE: directory lookup is sent to all
+ * subvolumes and success from a subvolume
+ * might set local->op_ret to 0 (zero) */
+ local->op_ret = -1;
+ }
+
+ /* either no self heal, or op_ret == -1 (failure) */
+ tmp_inode = local->loc1.inode;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ tmp_inode, &local->stbuf, local->dict,
+ &local->oldpostparent);
+ }
+ if (local_dict) {
+ dict_unref (local_dict);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * unify_lookup -
+ */
+int32_t
+unify_lookup (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xattr_req)
+{
+ unify_local_t *local = NULL;
+ unify_private_t *priv = this->private;
+ int16_t *list = NULL;
+ long index = 0;
+
+ if (!(loc && loc->inode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: Argument not right", loc?loc->path:"(null)");
+ STACK_UNWIND (frame, -1, EINVAL, NULL, NULL, NULL, NULL);
+ return 0;
+ }
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL, NULL, NULL);
+ return 0;
+ }
+
+ if (inode_ctx_get (loc->inode, this, NULL)
+ && IA_ISDIR (loc->inode->ia_type)) {
+ local->revalidate = 1;
+ }
+
+ if (!inode_ctx_get (loc->inode, this, NULL) &&
+ loc->inode->ia_type &&
+ !IA_ISDIR (loc->inode->ia_type)) {
+ uint64_t tmp_list = 0;
+ /* check if revalidate or fresh lookup */
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ local->list = (int16_t *)(long)tmp_list;
+ }
+
+ if (local->list) {
+ list = local->list;
+ for (index = 0; list[index] != -1; index++);
+ if (index != 2) {
+ if (index < 2) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "returning ESTALE for %s: file "
+ "count is %ld", loc->path, index);
+ /* Print where all the file is present */
+ for (index = 0;
+ local->list[index] != -1; index++) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: found on %s", loc->path,
+ priv->xl_array[list[index]]->name);
+ }
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, -1, ESTALE,
+ NULL, NULL, NULL, NULL);
+ return 0;
+ } else {
+ /* There are more than 2 presences */
+ /* Just log and continue */
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: file count is %ld",
+ loc->path, index);
+ /* Print where all the file is present */
+ for (index = 0;
+ local->list[index] != -1; index++) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: found on %s", loc->path,
+ priv->xl_array[list[index]]->name);
+ }
+ }
+ }
+
+ /* is revalidate */
+ local->revalidate = 1;
+
+ for (index = 0; list[index] != -1; index++)
+ local->call_count++;
+
+ for (index = 0; list[index] != -1; index++) {
+ char need_break = (list[index+1] == -1);
+ STACK_WIND_COOKIE (frame,
+ unify_lookup_cbk,
+ (void *)(long)list[index], //cookie
+ priv->xl_array [list[index]],
+ priv->xl_array [list[index]]->fops->lookup,
+ loc,
+ xattr_req);
+ if (need_break)
+ break;
+ }
+ } else {
+ if (loc->inode->ia_type) {
+ if (inode_ctx_get (loc->inode, this, NULL)) {
+ inode_ctx_get (loc->inode, this,
+ &local->inode_generation);
+ }
+ }
+ /* This is first call, there is no list */
+ /* call count should be all child + 1 namespace */
+ local->call_count = priv->child_count + 1;
+
+ for (index = 0; index <= priv->child_count; index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_lookup_cbk,
+ (void *)index, //cookie
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->lookup,
+ loc,
+ xattr_req);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * unify_stat - if directory, get the stat directly from NameSpace child.
+ * if file, check for a hint and send it only there (also to NS).
+ * if its a fresh stat, then do it on all the nodes.
+ *
+ * NOTE: for all the call, sending cookie as xlator pointer, which will be
+ * used in cbk.
+ */
+int32_t
+unify_stat (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ unify_local_t *local = NULL;
+ unify_private_t *priv = this->private;
+ int16_t index = 0;
+ int16_t *list = NULL;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, NULL);
+ return 0;
+ }
+ local->ia_ino = loc->inode->ino;
+ if (IA_ISDIR (loc->inode->ia_type)) {
+ /* Directory */
+ local->call_count = 1;
+ STACK_WIND (frame, unify_buf_cbk, NS(this),
+ NS(this)->fops->stat, loc);
+ } else {
+ /* File */
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++)
+ local->call_count++;
+
+ for (index = 0; list[index] != -1; index++) {
+ char need_break = (list[index+1] == -1);
+ STACK_WIND (frame,
+ unify_buf_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->stat,
+ loc);
+ if (need_break)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * unify_access_cbk -
+ */
+int32_t
+unify_access_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+/**
+ * unify_access - Send request to only namespace, which has all the
+ * attributes set for the file.
+ */
+int32_t
+unify_access (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t mask)
+{
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ STACK_WIND (frame,
+ unify_access_cbk,
+ NS(this),
+ NS(this)->fops->access,
+ loc,
+ mask);
+
+ return 0;
+}
+
+int32_t
+unify_mkdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ inode_t *tmp_inode = NULL;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if ((op_ret == -1) && !(priv->optimist &&
+ (op_errno == ENOENT ||
+ op_errno == EEXIST))) {
+ /* TODO: Decrement the inode_generation of
+ * this->inode's parent inode, hence the missing
+ * directory is created properly by self-heal.
+ * Currently, there is no way to get the parent
+ * inode directly.
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ priv->xl_array[(long)cookie]->name,
+ local->loc1.path, strerror (op_errno));
+ if (op_errno != EEXIST)
+ local->failed = 1;
+ local->op_errno = op_errno;
+ }
+
+ if (op_ret >= 0)
+ local->op_ret = 0;
+
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (!local->failed) {
+ inode_ctx_put (local->loc1.inode, this,
+ priv->inode_generation);
+ }
+
+ tmp_inode = local->loc1.inode;
+ unify_local_wipe (local);
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ tmp_inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_ns_mkdir_cbk -
+ */
+int32_t
+unify_ns_mkdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ long index = 0;
+
+ if (op_ret == -1) {
+ /* No need to send mkdir request to other servers,
+ * as namespace action failed
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s): %s",
+ local->name, strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+
+ /* Create one inode for this entry */
+ local->op_ret = 0;
+ local->stbuf = *buf;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ local->call_count = priv->child_count;
+
+ /* Send mkdir request to all the nodes now */
+ for (index = 0; index < priv->child_count; index++) {
+ STACK_WIND_COOKIE (frame,
+ unify_mkdir_cbk,
+ (void *)index, //cookie
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->mkdir,
+ &local->loc1,
+ local->mode);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_mkdir -
+ */
+int32_t
+unify_mkdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode)
+{
+ unify_local_t *local = NULL;
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ local->mode = mode;
+
+ loc_copy (&local->loc1, loc);
+
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_ns_mkdir_cbk,
+ NS(this),
+ NS(this)->fops->mkdir,
+ loc,
+ mode);
+ return 0;
+}
+
+/**
+ * unify_rmdir_cbk -
+ */
+int32_t
+unify_rmdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret == 0 || (priv->optimist && (op_errno == ENOENT)))
+ local->op_ret = 0;
+ if (op_ret == -1)
+ local->op_errno = op_errno;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->oldpreparent, &local->oldpostparent);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_ns_rmdir_cbk -
+ */
+int32_t
+unify_ns_rmdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int16_t index = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ /* No need to send rmdir request to other servers,
+ * as namespace action failed
+ */
+ gf_log (this->name,
+ ((op_errno != ENOTEMPTY) ?
+ GF_LOG_ERROR : GF_LOG_DEBUG),
+ "namespace: path(%s): %s",
+ local->loc1.path, strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, NULL, NULL);
+ return 0;
+ }
+
+ local->call_count = priv->child_count;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ for (index = 0; index < priv->child_count; index++) {
+ STACK_WIND (frame,
+ unify_rmdir_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->rmdir,
+ &local->loc1);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_rmdir -
+ */
+int32_t
+unify_rmdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ unify_local_t *local = NULL;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+
+ loc_copy (&local->loc1, loc);
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, NULL, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_ns_rmdir_cbk,
+ NS(this),
+ NS(this)->fops->rmdir,
+ loc);
+
+ return 0;
+}
+
+/**
+ * unify_open_cbk -
+ */
+int32_t
+unify_open_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ if (NS(this) != (xlator_t *)cookie) {
+ /* Store child node's ptr, used in
+ all the f*** / FileIO calls */
+ fd_ctx_set (fd, this, (uint64_t)(long)cookie);
+ }
+ }
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ local->failed = 1;
+ }
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if ((local->failed == 1) && (local->op_ret >= 0)) {
+ local->call_count = 1;
+ /* return -1 to user */
+ local->op_ret = -1;
+ //local->op_errno = EIO;
+
+ if (!fd_ctx_get (local->fd, this, NULL)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Open success on child node, "
+ "failed on namespace");
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Open success on namespace, "
+ "failed on child node");
+ }
+ }
+
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret,
+ local->op_errno, local->fd);
+ }
+
+ return 0;
+}
+
+#ifdef GF_DARWIN_HOST_OS
+/**
+ * unify_create_lookup_cbk -
+ */
+int32_t
+unify_open_lookup_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ dict_t *dict,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ int16_t index = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if ((op_ret == -1) && (op_errno != ENOENT)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ priv->xl_array[(long)cookie]->name,
+ local->loc1.path, strerror (op_errno));
+ local->op_errno = op_errno;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ local->index++;
+ if (NS(this) == priv->xl_array[(long)cookie]) {
+ local->list[0] = (int16_t)(long)cookie;
+ } else {
+ local->list[1] = (int16_t)(long)cookie;
+ }
+ if (IA_ISDIR (buf->ia_type))
+ local->failed = 1;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ int16_t file_list[3] = {0,};
+ local->op_ret = -1;
+
+ file_list[0] = local->list[0];
+ file_list[1] = local->list[1];
+ file_list[2] = -1;
+
+ if (local->index != 2) {
+ /* Lookup failed, can't do open */
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: present on %d nodes",
+ local->name, local->index);
+
+ if (local->index < 2) {
+ unify_local_wipe (local);
+ gf_log (this->name, GF_LOG_ERROR,
+ "returning as file found on less "
+ "than 2 nodes");
+ STACK_UNWIND (frame, local->op_ret,
+ local->op_errno, local->fd);
+ return 0;
+ }
+ }
+
+ if (local->failed) {
+ /* Open on directory, return EISDIR */
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, -1, EISDIR, local->fd);
+ return 0;
+ }
+
+ /* Everything is perfect :) */
+ local->call_count = 2;
+
+ for (index = 0; file_list[index] != -1; index++) {
+ char need_break = (file_list[index+1] == -1);
+ STACK_WIND_COOKIE (frame,
+ unify_open_cbk,
+ priv->xl_array[file_list[index]],
+ priv->xl_array[file_list[index]],
+ priv->xl_array[file_list[index]]->fops->open,
+ &local->loc1,
+ local->flags,
+ local->fd, local->wbflags);
+ if (need_break)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_open_readlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ const char *path,
+ struct iatt *sbuf)
+{
+ int16_t index = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ STACK_UNWIND (frame, -1, ENOENT);
+ return 0;
+ }
+
+ if (path[0] == '/') {
+ local->name = gf_strdup (path);
+ ERR_ABORT (local->name);
+ } else {
+ char *tmp_str = gf_strdup (local->loc1.path);
+ char *tmp_base = dirname (tmp_str);
+ local->name = GF_CALLOC (1, ZR_PATH_MAX, gf_unify_mt_char);
+ strcpy (local->name, tmp_base);
+ strncat (local->name, "/", 1);
+ strcat (local->name, path);
+ GF_FREE (tmp_str);
+ }
+
+ local->list = GF_CALLOC (1, sizeof (int16_t) * 3,
+ gf_unify_mt_int16_t);
+ ERR_ABORT (local->list);
+ local->call_count = priv->child_count + 1;
+ local->op_ret = -1;
+ for (index = 0; index <= priv->child_count; index++) {
+ /* Send the lookup to all the nodes including namespace */
+ STACK_WIND_COOKIE (frame,
+ unify_open_lookup_cbk,
+ (void *)(long)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->lookup,
+ &local->loc1,
+ NULL);
+ }
+
+ return 0;
+}
+#endif /* GF_DARWIN_HOST_OS */
+
+/**
+ * unify_open -
+ */
+int32_t
+unify_open (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ fd_t *fd,
+ int32_t wbflags)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = NULL;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ int16_t file_list[3] = {0,};
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Init */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+ local->fd = fd;
+ local->flags = flags;
+ local->wbflags = wbflags;
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ local->list = list;
+ file_list[0] = priv->child_count; /* Thats namespace */
+ file_list[2] = -1;
+ for (index = 0; list[index] != -1; index++) {
+ local->call_count++;
+ if (list[index] != priv->child_count)
+ file_list[1] = list[index];
+ }
+
+ if (local->call_count != 2) {
+ /* If the lookup was done for file */
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: entry_count is %d",
+ loc->path, local->call_count);
+ for (index = 0; local->list[index] != -1; index++)
+ gf_log (this->name, GF_LOG_ERROR, "%s: found on %s",
+ loc->path, priv->xl_array[list[index]]->name);
+
+ if (local->call_count < 2) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "returning EIO as file found on onlyone node");
+ STACK_UNWIND (frame, -1, EIO, fd);
+ return 0;
+ }
+ }
+
+#ifdef GF_DARWIN_HOST_OS
+ /* Handle symlink here */
+ if (IA_ISLNK (loc->inode->ia_type)) {
+ /* Callcount doesn't matter here */
+ STACK_WIND (frame,
+ unify_open_readlink_cbk,
+ NS(this),
+ NS(this)->fops->readlink,
+ loc, ZR_PATH_MAX);
+ return 0;
+ }
+#endif /* GF_DARWIN_HOST_OS */
+
+ local->call_count = 2;
+ for (index = 0; file_list[index] != -1; index++) {
+ char need_break = (file_list[index+1] == -1);
+ STACK_WIND_COOKIE (frame,
+ unify_open_cbk,
+ priv->xl_array[file_list[index]], //cookie
+ priv->xl_array[file_list[index]],
+ priv->xl_array[file_list[index]]->fops->open,
+ loc,
+ flags,
+ fd, wbflags);
+ if (need_break)
+ break;
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_create_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+ inode_t *inode = local->loc1.inode;
+
+ unify_local_wipe (local);
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, local->fd,
+ inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+
+ return 0;
+}
+
+/**
+ * unify_create_open_cbk -
+ */
+int32_t
+unify_create_open_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ int ret = 0;
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+ inode_t *inode = NULL;
+ xlator_t *child = NULL;
+ uint64_t tmp_value = 0;
+
+ LOCK (&frame->lock);
+ {
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ if (NS(this) != (xlator_t *)cookie) {
+ /* Store child node's ptr, used in all
+ the f*** / FileIO calls */
+ /* TODO: log on failure */
+ ret = fd_ctx_get (fd, this, &tmp_value);
+ cookie = (void *)(long)tmp_value;
+ } else {
+ /* NOTE: open successful on namespace.
+ * fd's ctx can be used to identify open
+ * failure on storage subvolume. cool
+ * ide ;) */
+ local->failed = 0;
+ }
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ ((xlator_t *)cookie)->name,
+ local->loc1.path, strerror (op_errno));
+ local->op_errno = op_errno;
+ local->failed = 1;
+ }
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed == 1 && (local->op_ret >= 0)) {
+ local->call_count = 1;
+ /* return -1 to user */
+ local->op_ret = -1;
+ local->op_errno = EIO;
+ local->fd = fd;
+ local->call_count = 1;
+
+ if (!fd_ctx_get (local->fd, this, &tmp_value)) {
+ child = (xlator_t *)(long)tmp_value;
+
+ gf_log (this->name, GF_LOG_ERROR,
+ "Create success on child node, "
+ "failed on namespace");
+
+ STACK_WIND (frame,
+ unify_create_unlink_cbk,
+ child,
+ child->fops->unlink,
+ &local->loc1);
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Create success on namespace, "
+ "failed on child node");
+
+ STACK_WIND (frame,
+ unify_create_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+ }
+ return 0;
+ }
+ inode = local->loc1.inode;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, fd,
+ inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+ }
+ return 0;
+}
+
+/**
+ * unify_create_lookup_cbk -
+ */
+int32_t
+unify_create_lookup_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ dict_t *dict,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ int16_t index = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ priv->xl_array[(long)cookie]->name,
+ local->loc1.path, strerror (op_errno));
+ local->op_errno = op_errno;
+ local->failed = 1;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ local->list[local->index++] = (int16_t)(long)cookie;
+ if (NS(this) == priv->xl_array[(long)cookie]) {
+ local->ia_ino = buf->ia_ino;
+ } else {
+ local->stbuf = *buf;
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ int16_t *list = local->list;
+ int16_t file_list[3] = {0,};
+ local->op_ret = -1;
+
+ local->list [local->index] = -1;
+ file_list[0] = list[0];
+ file_list[1] = list[1];
+ file_list[2] = -1;
+
+ local->stbuf.ia_ino = local->ia_ino;
+ /* TODO: log on failure */
+ inode_ctx_put (local->loc1.inode, this,
+ (uint64_t)(long)local->list);
+
+ if (local->index != 2) {
+ /* Lookup failed, can't do open */
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: present on %d nodes",
+ local->loc1.path, local->index);
+ file_list[0] = priv->child_count;
+ for (index = 0; list[index] != -1; index++) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: found on %s", local->loc1.path,
+ priv->xl_array[list[index]]->name);
+ if (list[index] != priv->child_count)
+ file_list[1] = list[index];
+ }
+
+ if (local->index < 2) {
+ unify_local_wipe (local);
+ gf_log (this->name, GF_LOG_ERROR,
+ "returning EIO as file found on "
+ "only one node");
+ STACK_UNWIND (frame, -1, EIO,
+ local->fd, inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+ }
+ /* Everything is perfect :) */
+ local->call_count = 2;
+
+ for (index = 0; file_list[index] != -1; index++) {
+ char need_break = (file_list[index+1] == -1);
+ STACK_WIND_COOKIE (frame,
+ unify_create_open_cbk,
+ priv->xl_array[file_list[index]],
+ priv->xl_array[file_list[index]],
+ priv->xl_array[file_list[index]]->fops->open,
+ &local->loc1,
+ local->flags,
+ local->fd, 0);
+ if (need_break)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_create_cbk -
+ */
+int32_t
+unify_create_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int ret = 0;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+ inode_t *tmp_inode = NULL;
+
+ if (op_ret == -1) {
+ /* send unlink () on Namespace */
+ local->op_errno = op_errno;
+ local->op_ret = -1;
+ local->call_count = 1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "create failed on %s (file %s, error %s), "
+ "sending unlink to namespace",
+ prev_frame->this->name,
+ local->loc1.path, strerror (op_errno));
+
+ STACK_WIND (frame,
+ unify_create_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+
+ return 0;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = op_ret;
+ local->stbuf = *buf;
+ /* Just inode number should be from NS node */
+ local->stbuf.ia_ino = local->ia_ino;
+
+ /* TODO: log on failure */
+ ret = fd_ctx_set (fd, this, (uint64_t)(long)prev_frame->this);
+ }
+
+ tmp_inode = local->loc1.inode;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, local->fd,
+ tmp_inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+
+ return 0;
+}
+
+/**
+ * unify_ns_create_cbk -
+ *
+ */
+int32_t
+unify_ns_create_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ struct sched_ops *sched_ops = NULL;
+ xlator_t *sched_xl = NULL;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t *list = NULL;
+ int16_t index = 0;
+
+ if (op_ret == -1) {
+ /* No need to send create request to other servers, as
+ namespace action failed. Handle exclusive create here. */
+ if ((op_errno != EEXIST) ||
+ ((op_errno == EEXIST) &&
+ ((local->flags & O_EXCL) == O_EXCL))) {
+ /* If its just a create call without O_EXCL,
+ don't do this */
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s): %s",
+ local->loc1.path, strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent);
+ return 0;
+ }
+ }
+
+ if (op_ret >= 0) {
+ /* Get the inode number from the NS node */
+ local->ia_ino = buf->ia_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ local->op_ret = -1;
+
+ /* Start the mapping list */
+ list = GF_CALLOC (1, sizeof (int16_t) * 3,
+ gf_unify_mt_int16_t);
+ ERR_ABORT (list);
+ inode_ctx_put (inode, this, (uint64_t)(long)list);
+ list[0] = priv->child_count;
+ list[2] = -1;
+
+ /* This means, file doesn't exist anywhere in the Filesystem */
+ sched_ops = priv->sched_ops;
+
+ /* Send create request to the scheduled node now */
+ sched_xl = sched_ops->schedule (this, local->loc1.path);
+ if (sched_xl == NULL)
+ {
+ /* send unlink () on Namespace */
+ local->op_errno = ENOTCONN;
+ local->op_ret = -1;
+ local->call_count = 1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "no node online to schedule create:(file %s) "
+ "sending unlink to namespace",
+ (local->loc1.path)?local->loc1.path:"");
+
+ STACK_WIND (frame,
+ unify_create_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+
+ return 0;
+ }
+
+ for (index = 0; index < priv->child_count; index++)
+ if (sched_xl == priv->xl_array[index])
+ break;
+ list[1] = index;
+
+ STACK_WIND (frame, unify_create_cbk,
+ sched_xl, sched_xl->fops->create,
+ &local->loc1, local->flags, local->mode, fd);
+ } else {
+ /* File already exists, and there is no O_EXCL flag */
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "File(%s) already exists on namespace, sending "
+ "open instead", local->loc1.path);
+
+ local->list = GF_CALLOC (1, sizeof (int16_t) * 3,
+ gf_unify_mt_int16_t);
+ ERR_ABORT (local->list);
+ local->call_count = priv->child_count + 1;
+ local->op_ret = -1;
+ for (index = 0; index <= priv->child_count; index++) {
+ /* Send lookup() to all nodes including namespace */
+ STACK_WIND_COOKIE (frame,
+ unify_create_lookup_cbk,
+ (void *)(long)index,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->lookup,
+ &local->loc1,
+ NULL);
+ }
+ }
+ return 0;
+}
+
+/**
+ * unify_create - create a file in global namespace first, so other
+ * clients can see them. Create the file in storage nodes in background.
+ */
+int32_t
+unify_create (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ mode_t mode,
+ fd_t *fd)
+{
+ unify_local_t *local = NULL;
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ local->mode = mode;
+ local->flags = flags;
+ local->fd = fd;
+
+ loc_copy (&local->loc1, loc);
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, fd, loc->inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_ns_create_cbk,
+ NS(this),
+ NS(this)->fops->create,
+ loc,
+ flags | O_EXCL,
+ mode,
+ fd);
+
+ return 0;
+}
+
+
+/**
+ * unify_opendir_cbk -
+ */
+int32_t
+unify_opendir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+
+ return 0;
+}
+
+/**
+ * unify_opendir -
+ */
+int32_t
+unify_opendir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ fd_t *fd)
+{
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ STACK_WIND (frame, unify_opendir_cbk,
+ NS(this), NS(this)->fops->opendir, loc, fd);
+
+ return 0;
+}
+
+
+int32_t
+unify_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s(): child(%s): path(%s): %s",
+ gf_fop_list[frame->root->op],
+ prev_frame->this->name,
+ (local->loc1.path)?local->loc1.path:"",
+ strerror (op_errno));
+
+ local->op_errno = op_errno;
+ if ((op_errno == ENOENT) && priv->optimist)
+ local->op_ret = 0;
+ }
+
+ if (op_ret >= 0) {
+ local->op_ret = 0;
+
+ if (NS (this) == prev_frame->this) {
+ local->ia_ino = statpost->ia_ino;
+ /* If the entry is directory, get the stat
+ from NS node */
+ if (IA_ISDIR (statpost->ia_type) ||
+ !local->stpost.ia_blksize) {
+ local->stpre = *statpre;
+ local->stpost = *statpost;
+ }
+ }
+
+ if ((!IA_ISDIR (statpost->ia_type)) &&
+ (NS (this) != prev_frame->this)) {
+ /* If file, take the stat info from Storage
+ node. */
+ local->stpre = *statpre;
+ local->stpost = *statpost;
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ /* If the inode number is not filled, operation should
+ fail */
+ if (!local->ia_ino)
+ local->op_ret = -1;
+
+ local->stpre.ia_ino = local->ia_ino;
+ local->stpost.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stpre, &local->stpost);
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid)
+{
+ unify_local_t *local = NULL;
+ unify_private_t *priv = this->private;
+ int32_t index = 0;
+ int32_t callcnt = 0;
+ uint64_t tmp_list = 0;
+
+ if (!(loc && loc->inode)) {
+ STACK_UNWIND (frame, -1, EINVAL, NULL, NULL);
+ return 0;
+ }
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+
+ if (IA_ISDIR (loc->inode->ia_type)) {
+ local->call_count = 1;
+
+ STACK_WIND (frame,
+ unify_setattr_cbk,
+ NS (this),
+ NS (this)->fops->setattr,
+ loc, stbuf, valid);
+ } else {
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ local->list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; local->list[index] != -1; index++) {
+ local->call_count++;
+ callcnt++;
+ }
+
+ for (index = 0; local->list[index] != -1; index++) {
+ STACK_WIND (frame,
+ unify_setattr_cbk,
+ priv->xl_array[local->list[index]],
+ priv->xl_array[local->list[index]]->fops->setattr,
+ loc, stbuf, valid);
+
+ if (!--callcnt)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+unify_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid)
+{
+ unify_local_t *local = NULL;
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+
+ if (!fd_ctx_get (fd, this, &tmp_child)) {
+ /* If its set, then its file */
+ child = (xlator_t *)(long)tmp_child;
+
+ local->call_count = 2;
+
+ STACK_WIND (frame, unify_setattr_cbk, child,
+ child->fops->fsetattr, fd, stbuf, valid);
+
+ STACK_WIND (frame, unify_setattr_cbk, NS(this),
+ NS(this)->fops->fsetattr, fd, stbuf, valid);
+ } else {
+ local->call_count = 1;
+
+ STACK_WIND (frame, unify_setattr_cbk,
+ NS(this), NS(this)->fops->fsetattr,
+ fd, stbuf, valid);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_truncate_cbk -
+ */
+int32_t
+unify_truncate_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ prev_frame->this->name,
+ (local->loc1.path)?local->loc1.path:"",
+ strerror (op_errno));
+ local->op_errno = op_errno;
+ if (!((op_errno == ENOENT) && priv->optimist))
+ local->op_ret = -1;
+ }
+
+ if (op_ret >= 0) {
+ if (NS (this) == prev_frame->this) {
+ local->ia_ino = postbuf->ia_ino;
+ /* If the entry is directory, get the
+ stat from NS node */
+ if (IA_ISDIR (postbuf->ia_type) ||
+ !local->stbuf.ia_blksize) {
+ local->stbuf = *prebuf;
+ local->poststbuf = *postbuf;
+ }
+ }
+
+ if ((!IA_ISDIR (postbuf->ia_type)) &&
+ (NS (this) != prev_frame->this)) {
+ /* If file, take the stat info from
+ Storage node. */
+ local->stbuf = *prebuf;
+ local->poststbuf = *postbuf;
+ }
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->ia_ino) {
+ local->stbuf.ia_ino = local->ia_ino;
+ local->poststbuf.ia_ino = local->ia_ino;
+ } else {
+ local->op_ret = -1;
+ }
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->poststbuf);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_truncate -
+ */
+int32_t
+unify_truncate (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ off_t offset)
+{
+ unify_local_t *local = NULL;
+ unify_private_t *priv = this->private;
+ int32_t index = 0;
+ int32_t callcnt = 0;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+ local->ia_ino = loc->inode->ino;
+
+ if (IA_ISDIR (loc->inode->ia_type)) {
+ local->call_count = 1;
+
+ STACK_WIND (frame,
+ unify_truncate_cbk,
+ NS(this),
+ NS(this)->fops->truncate,
+ loc,
+ 0);
+ } else {
+ local->op_ret = 0;
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ local->list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; local->list[index] != -1; index++) {
+ local->call_count++;
+ callcnt++;
+ }
+
+ /* Don't send offset to NS truncate */
+ STACK_WIND (frame, unify_truncate_cbk, NS(this),
+ NS(this)->fops->truncate, loc, 0);
+ callcnt--;
+
+ for (index = 0; local->list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[local->list[index]]) {
+ STACK_WIND (frame,
+ unify_truncate_cbk,
+ priv->xl_array[local->list[index]],
+ priv->xl_array[local->list[index]]->fops->truncate,
+ loc,
+ offset);
+ if (!--callcnt)
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * unify_readlink_cbk -
+ */
+int32_t
+unify_readlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ const char *path,
+ struct iatt *sbuf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, path, sbuf);
+ return 0;
+}
+
+/**
+ * unify_readlink - Read the link only from the storage node.
+ */
+int32_t
+unify_readlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ size_t size)
+{
+ unify_private_t *priv = this->private;
+ int32_t entry_count = 0;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++)
+ entry_count++;
+
+ if (entry_count >= 2) {
+ for (index = 0; list[index] != -1; index++) {
+ if (priv->xl_array[list[index]] != NS(this)) {
+ STACK_WIND (frame,
+ unify_readlink_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->readlink,
+ loc,
+ size);
+ break;
+ }
+ }
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "returning ENOENT, no softlink files found "
+ "on storage node");
+ STACK_UNWIND (frame, -1, ENOENT, NULL);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_unlink_cbk -
+ */
+int32_t
+unify_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret == 0 || ((op_errno == ENOENT) && priv->optimist))
+ local->op_ret = 0;
+ if (op_ret == -1)
+ local->op_errno = op_errno;
+
+ if (((call_frame_t *)cookie)->this == NS(this)) {
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->oldpreparent, &local->oldpostparent);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_unlink -
+ */
+int32_t
+unify_unlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = NULL;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++)
+ local->call_count++;
+
+ if (local->call_count) {
+ for (index = 0; list[index] != -1; index++) {
+ char need_break = (list[index+1] == -1);
+ STACK_WIND (frame,
+ unify_unlink_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->unlink,
+ loc);
+ if (need_break)
+ break;
+ }
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: returning ENOENT", loc->path);
+ STACK_UNWIND (frame, -1, ENOENT, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_readv_cbk -
+ */
+int32_t
+unify_readv_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iovec *vector,
+ int32_t count,
+ struct iatt *stbuf,
+ struct iobref *iobref)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf, iobref);
+ return 0;
+}
+
+/**
+ * unify_readv -
+ */
+int32_t
+unify_readv (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame,
+ unify_readv_cbk,
+ child,
+ child->fops->readv,
+ fd,
+ size,
+ offset);
+
+
+ return 0;
+}
+
+/**
+ * unify_writev_cbk -
+ */
+int32_t
+unify_writev_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ unify_local_t *local = NULL;
+
+ local = frame->local;
+
+ local->stbuf = *prebuf;
+ local->stbuf.ia_ino = local->ia_ino;
+
+ local->poststbuf = *postbuf;
+ local->poststbuf.ia_ino = local->ia_ino;
+
+ STACK_UNWIND (frame, op_ret, op_errno,
+ &local->stbuf, &local->poststbuf);
+ return 0;
+}
+
+/**
+ * unify_writev -
+ */
+int32_t
+unify_writev (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t off,
+ struct iobref *iobref)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+ unify_local_t *local = NULL;
+
+ INIT_LOCAL (frame, local);
+ local->ia_ino = fd->inode->ino;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame,
+ unify_writev_cbk,
+ child,
+ child->fops->writev,
+ fd,
+ vector,
+ count,
+ off,
+ iobref);
+
+ return 0;
+}
+
+/**
+ * unify_ftruncate -
+ */
+int32_t
+unify_ftruncate (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset)
+{
+ xlator_t *child = NULL;
+ unify_local_t *local = NULL;
+ uint64_t tmp_child = 0;
+
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR(fd);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ local->op_ret = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ local->call_count = 2;
+
+ STACK_WIND (frame, unify_truncate_cbk,
+ child, child->fops->ftruncate,
+ fd, offset);
+
+ STACK_WIND (frame, unify_truncate_cbk,
+ NS(this), NS(this)->fops->ftruncate,
+ fd, 0);
+
+ return 0;
+}
+
+
+/**
+ * unify_flush_cbk -
+ */
+int32_t
+unify_flush_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+/**
+ * unify_flush -
+ */
+int32_t
+unify_flush (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_flush_cbk, child,
+ child->fops->flush, fd);
+
+ return 0;
+}
+
+
+/**
+ * unify_fsync_cbk -
+ */
+int32_t
+unify_fsync_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
+}
+
+/**
+ * unify_fsync -
+ */
+int32_t
+unify_fsync (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t flags)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_fsync_cbk, child,
+ child->fops->fsync, fd, flags);
+
+ return 0;
+}
+
+/**
+ * unify_fstat - Send fstat FOP to Namespace only if its directory, and to
+ * both namespace and the storage node if its a file.
+ */
+int32_t
+unify_fstat (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ unify_local_t *local = NULL;
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR(fd);
+
+ INIT_LOCAL (frame, local);
+ local->ia_ino = fd->inode->ino;
+
+ if (!fd_ctx_get (fd, this, &tmp_child)) {
+ /* If its set, then its file */
+ child = (xlator_t *)(long)tmp_child;
+ local->call_count = 2;
+
+ STACK_WIND (frame, unify_buf_cbk, child,
+ child->fops->fstat, fd);
+
+ STACK_WIND (frame, unify_buf_cbk, NS(this),
+ NS(this)->fops->fstat, fd);
+
+ } else {
+ /* this is an directory */
+ local->call_count = 1;
+ STACK_WIND (frame, unify_buf_cbk, NS(this),
+ NS(this)->fops->fstat, fd);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_getdents_cbk -
+ */
+int32_t
+unify_getdents_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dir_entry_t *entry,
+ int32_t count)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, entry, count);
+ return 0;
+}
+
+/**
+ * unify_getdents - send the FOP request to all the nodes.
+ */
+int32_t
+unify_getdents (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset,
+ int32_t flag)
+{
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd);
+
+ STACK_WIND (frame, unify_getdents_cbk, NS(this),
+ NS(this)->fops->getdents, fd, size, offset, flag);
+
+ return 0;
+}
+
+
+/**
+ * unify_readdir_cbk -
+ */
+int32_t
+unify_readdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+
+ return 0;
+}
+
+/**
+ * unify_readdir - send the FOP request to all the nodes.
+ */
+int32_t
+unify_readdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset)
+{
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd);
+
+ STACK_WIND (frame, unify_readdir_cbk, NS(this),
+ NS(this)->fops->readdir, fd, size, offset);
+
+ return 0;
+}
+
+
+int32_t
+unify_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+
+ return 0;
+}
+
+
+int32_t
+unify_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd);
+
+ STACK_WIND (frame, unify_readdirp_cbk, NS(this),
+ NS(this)->fops->readdirp, fd, size, offset);
+
+ return 0;
+}
+
+
+/**
+ * unify_fsyncdir_cbk -
+ */
+int32_t
+unify_fsyncdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/**
+ * unify_fsyncdir -
+ */
+int32_t
+unify_fsyncdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t flags)
+{
+ UNIFY_CHECK_FD_AND_UNWIND_ON_ERR (fd);
+
+ STACK_WIND (frame, unify_fsyncdir_cbk,
+ NS(this), NS(this)->fops->fsyncdir, fd, flags);
+
+ return 0;
+}
+
+/**
+ * unify_lk_cbk - UNWIND frame with the proper return arguments.
+ */
+int32_t
+unify_lk_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct gf_flock *lock)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, lock);
+ return 0;
+}
+
+/**
+ * unify_lk - Send it to all the storage nodes, (should be 1) which has file.
+ */
+int32_t
+unify_lk (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t cmd,
+ struct gf_flock *lock)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_lk_cbk, child,
+ child->fops->lk, fd, cmd, lock);
+
+ return 0;
+}
+
+
+int32_t
+unify_setxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno);
+
+static int32_t
+unify_setxattr_file_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ unify_private_t *private = this->private;
+ unify_local_t *local = frame->local;
+ xlator_t *sched_xl = NULL;
+ struct sched_ops *sched_ops = NULL;
+
+ if (op_ret == -1) {
+ if (!ENOTSUP)
+ gf_log (this->name, GF_LOG_ERROR,
+ "setxattr with XATTR_CREATE on ns: "
+ "path(%s) key(%s): %s",
+ local->loc1.path, local->name,
+ strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+ }
+
+ LOCK (&frame->lock);
+ {
+ local->failed = 0;
+ local->op_ret = 0;
+ local->op_errno = 0;
+ local->call_count = 1;
+ }
+ UNLOCK (&frame->lock);
+
+ /* schedule XATTR_CREATE on one of the child node */
+ sched_ops = private->sched_ops;
+
+ /* Send create request to the scheduled node now */
+ sched_xl = sched_ops->schedule (this, local->name);
+ if (!sched_xl) {
+ STACK_UNWIND (frame, -1, ENOTCONN);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_setxattr_cbk,
+ sched_xl,
+ sched_xl->fops->setxattr,
+ &local->loc1,
+ local->dict,
+ local->flags);
+ return 0;
+}
+
+/**
+ * unify_setxattr_cbk - When all the child nodes return, UNWIND frame.
+ */
+int32_t
+unify_setxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+ dict_t *dict = NULL;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ gf_log (this->name, (((op_errno == ENOENT) ||
+ (op_errno == ENOTSUP))?
+ GF_LOG_DEBUG : GF_LOG_ERROR),
+ "child(%s): path(%s): %s",
+ prev_frame->this->name,
+ (local->loc1.path)?local->loc1.path:"",
+ strerror (op_errno));
+ if (local->failed == -1) {
+ local->failed = 1;
+ }
+ local->op_errno = op_errno;
+ } else {
+ local->failed = 0;
+ local->op_ret = op_ret;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ if (local->failed && local->name &&
+ ZR_FILE_CONTENT_REQUEST(local->name)) {
+ dict = get_new_dict ();
+ dict_set (dict, local->dict->members_list->key,
+ data_from_dynptr(NULL, 0));
+ dict_ref (dict);
+
+ local->call_count = 1;
+
+ STACK_WIND (frame,
+ unify_setxattr_file_cbk,
+ NS(this),
+ NS(this)->fops->setxattr,
+ &local->loc1,
+ dict,
+ XATTR_CREATE);
+
+ dict_unref (dict);
+ return 0;
+ }
+
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_sexattr - This function should be sent to all the storage nodes,
+ * which contains the file, (excluding namespace).
+ */
+int32_t
+unify_setxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ int32_t flags)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = NULL;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ int32_t call_count = 0;
+ uint64_t tmp_list = 0;
+ data_pair_t *trav = dict->members_list;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ local->failed = -1;
+ loc_copy (&local->loc1, loc);
+
+ if (IA_ISDIR (loc->inode->ia_type)) {
+
+ if (trav && trav->key && ZR_FILE_CONTENT_REQUEST(trav->key)) {
+ /* direct the storage xlators to change file
+ content only if file exists */
+ local->flags = flags;
+ local->dict = dict;
+ local->name = gf_strdup (trav->key);
+ flags |= XATTR_REPLACE;
+ }
+
+ local->call_count = priv->child_count;
+ for (index = 0; index < priv->child_count; index++) {
+ STACK_WIND (frame,
+ unify_setxattr_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->setxattr,
+ loc, dict, flags);
+ }
+ return 0;
+ }
+
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[list[index]]) {
+ local->call_count++;
+ call_count++;
+ }
+ }
+
+ if (local->call_count) {
+ for (index = 0; list[index] != -1; index++) {
+ if (priv->xl_array[list[index]] != NS(this)) {
+ STACK_WIND (frame,
+ unify_setxattr_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->setxattr,
+ loc,
+ dict,
+ flags);
+ if (!--call_count)
+ break;
+ }
+ }
+ return 0;
+ }
+
+ /* No entry in storage nodes */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "returning ENOENT, file not found on storage node.");
+ STACK_UNWIND (frame, -1, ENOENT);
+
+ return 0;
+}
+
+
+/**
+ * unify_getxattr_cbk - This function is called from only one child, so, no
+ * need of any lock or anything else, just send it to above layer
+ */
+int32_t
+unify_getxattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *value)
+{
+ int32_t callcnt = 0;
+ dict_t *local_value = NULL;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ gf_log (this->name,
+ (((op_errno == ENOENT) ||
+ (op_errno == ENODATA) ||
+ (op_errno == ENOTSUP)) ?
+ GF_LOG_DEBUG : GF_LOG_ERROR),
+ "child(%s): path(%s): %s",
+ prev_frame->this->name,
+ (local->loc1.path)?local->loc1.path:"",
+ strerror (op_errno));
+ } else {
+ if (!local->dict)
+ local->dict = dict_ref (value);
+ local->op_ret = op_ret;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local_value = local->dict;
+ local->dict = NULL;
+
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ local_value);
+
+ if (local_value)
+ dict_unref (local_value);
+ }
+
+ return 0;
+}
+
+
+/**
+ * unify_getxattr - This FOP is sent to only the storage node.
+ */
+int32_t
+unify_getxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ unify_private_t *priv = this->private;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ int16_t count = 0;
+ unify_local_t *local = NULL;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+ INIT_LOCAL (frame, local);
+
+ if (IA_ISDIR (loc->inode->ia_type)) {
+ local->call_count = priv->child_count;
+ for (index = 0; index < priv->child_count; index++)
+ STACK_WIND (frame,
+ unify_getxattr_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->getxattr,
+ loc,
+ name);
+ return 0;
+ }
+
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[list[index]]) {
+ local->call_count++;
+ count++;
+ }
+ }
+
+ if (count) {
+ for (index = 0; list[index] != -1; index++) {
+ if (priv->xl_array[list[index]] != NS(this)) {
+ STACK_WIND (frame,
+ unify_getxattr_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->getxattr,
+ loc,
+ name);
+ if (!--count)
+ break;
+ }
+ }
+ } else {
+ dict_t *tmp_dict = get_new_dict ();
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: returning ENODATA, no file found on storage node",
+ loc->path);
+ STACK_UNWIND (frame, -1, ENODATA, tmp_dict);
+ dict_destroy (tmp_dict);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_removexattr_cbk - Wait till all the child node returns the call
+ * and then UNWIND to above layer.
+ */
+int32_t
+unify_removexattr_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno)
+{
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ if (op_errno != ENOTSUP)
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ prev_frame->this->name,
+ local->loc1.path, strerror (op_errno));
+ } else {
+ local->op_ret = op_ret;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ STACK_UNWIND (frame, local->op_ret, local->op_errno);
+ }
+
+ return 0;
+}
+
+/**
+ * unify_removexattr - Send it to all the child nodes which has the files.
+ */
+int32_t
+unify_removexattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = NULL;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ int32_t call_count = 0;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (loc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+
+ if (IA_ISDIR (loc->inode->ia_type)) {
+ local->call_count = priv->child_count;
+ for (index = 0; index < priv->child_count; index++)
+ STACK_WIND (frame,
+ unify_removexattr_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->removexattr,
+ loc,
+ name);
+
+ return 0;
+ }
+
+ inode_ctx_get (loc->inode, this, &tmp_list);
+ list = (int16_t *)(long)tmp_list;
+
+ for (index = 0; list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[list[index]]) {
+ local->call_count++;
+ call_count++;
+ }
+ }
+
+ if (local->call_count) {
+ for (index = 0; list[index] != -1; index++) {
+ if (priv->xl_array[list[index]] != NS(this)) {
+ STACK_WIND (frame,
+ unify_removexattr_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->removexattr,
+ loc,
+ name);
+ if (!--call_count)
+ break;
+ }
+ }
+ return 0;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s: returning ENOENT, not found on storage node.", loc->path);
+ STACK_UNWIND (frame, -1, ENOENT);
+
+ return 0;
+}
+
+
+int32_t
+unify_mknod_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: %s", local->loc1.path, strerror (op_errno));
+
+ unify_local_wipe (local);
+ /* No log required here as this -1 is for mknod call */
+ STACK_UNWIND (frame, -1, local->op_errno, NULL, NULL);
+ return 0;
+}
+
+/**
+ * unify_mknod_cbk -
+ */
+int32_t
+unify_mknod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "mknod failed on storage node, sending unlink to "
+ "namespace");
+ local->op_errno = op_errno;
+ STACK_WIND (frame,
+ unify_mknod_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+ return 0;
+ }
+
+ local->stbuf = *buf;
+ local->stbuf.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+ return 0;
+}
+
+/**
+ * unify_ns_mknod_cbk -
+ */
+int32_t
+unify_ns_mknod_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ struct sched_ops *sched_ops = NULL;
+ xlator_t *sched_xl = NULL;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t *list = NULL;
+ int16_t index = 0;
+ call_frame_t *prev_frame = cookie;
+
+ if (op_ret == -1) {
+ /* No need to send mknod request to other servers,
+ * as namespace action failed
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s): %s",
+ prev_frame->this->name, local->loc1.path,
+ strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
+ }
+
+ /* Create one inode for this entry */
+ local->op_ret = 0;
+ local->stbuf = *buf;
+ local->ia_ino = buf->ia_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ list = GF_CALLOC (1, sizeof (int16_t) * 3, gf_unify_mt_int16_t);
+ ERR_ABORT (list);
+ list[0] = priv->child_count;
+ list[2] = -1;
+ inode_ctx_put (inode, this, (uint64_t)(long)list);
+
+ sched_ops = priv->sched_ops;
+
+ /* Send mknod request to scheduled node now */
+ sched_xl = sched_ops->schedule (this, local->loc1.path);
+ if (!sched_xl) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "mknod failed on storage node, no node online "
+ "at the moment, sending unlink to NS");
+ local->op_errno = ENOTCONN;
+ STACK_WIND (frame,
+ unify_mknod_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+
+ return 0;
+ }
+
+ for (index = 0; index < priv->child_count; index++)
+ if (sched_xl == priv->xl_array[index])
+ break;
+ list[1] = index;
+
+ STACK_WIND (frame, unify_mknod_cbk,
+ sched_xl, sched_xl->fops->mknod,
+ &local->loc1, local->mode, local->dev);
+
+ return 0;
+}
+
+/**
+ * unify_mknod - Create a device on namespace first, and later create on
+ * the storage node.
+ */
+int32_t
+unify_mknod (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode,
+ dev_t rdev)
+{
+ unify_local_t *local = NULL;
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ local->mode = mode;
+ local->dev = rdev;
+ loc_copy (&local->loc1, loc);
+ if (local->loc1.path == NULL) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_ns_mknod_cbk,
+ NS(this),
+ NS(this)->fops->mknod,
+ loc,
+ mode,
+ rdev);
+
+ return 0;
+}
+
+int32_t
+unify_symlink_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: %s", local->loc1.path, strerror (op_errno));
+
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, -1, local->op_errno, NULL, NULL);
+ return 0;
+}
+
+/**
+ * unify_symlink_cbk -
+ */
+int32_t
+unify_symlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ /* Symlink on storage node failed, hence send unlink
+ to the NS node */
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "symlink on storage node failed, sending unlink "
+ "to namespace");
+
+ STACK_WIND (frame,
+ unify_symlink_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+
+ return 0;
+ }
+
+ local->stbuf = *buf;
+ local->stbuf.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+
+ return 0;
+}
+
+/**
+ * unify_ns_symlink_cbk -
+ */
+int32_t
+unify_ns_symlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+
+ struct sched_ops *sched_ops = NULL;
+ xlator_t *sched_xl = NULL;
+ int16_t *list = NULL;
+ unify_local_t *local = frame->local;
+ unify_private_t *priv = this->private;
+ int16_t index = 0;
+
+ if (op_ret == -1) {
+ /* No need to send symlink request to other servers,
+ * as namespace action failed
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s): %s",
+ local->loc1.path, strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, NULL, buf,
+ preparent, postparent);
+ return 0;
+ }
+
+ /* Create one inode for this entry */
+ local->op_ret = 0;
+ local->ia_ino = buf->ia_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ /* Start the mapping list */
+
+ list = GF_CALLOC (1, sizeof (int16_t) * 3, gf_unify_mt_int16_t);
+ ERR_ABORT (list);
+ list[0] = priv->child_count; //namespace's index
+ list[2] = -1;
+ inode_ctx_put (inode, this, (uint64_t)(long)list);
+
+ sched_ops = priv->sched_ops;
+
+ /* Send symlink request to all the nodes now */
+ sched_xl = sched_ops->schedule (this, local->loc1.path);
+ if (!sched_xl) {
+ /* Symlink on storage node failed, hence send unlink
+ to the NS node */
+ local->op_errno = ENOTCONN;
+ gf_log (this->name, GF_LOG_ERROR,
+ "symlink on storage node failed, no node online, "
+ "sending unlink to namespace");
+
+ STACK_WIND (frame,
+ unify_symlink_unlink_cbk,
+ NS(this),
+ NS(this)->fops->unlink,
+ &local->loc1);
+
+ return 0;
+ }
+
+ for (index = 0; index < priv->child_count; index++)
+ if (sched_xl == priv->xl_array[index])
+ break;
+ list[1] = index;
+
+ STACK_WIND (frame,
+ unify_symlink_cbk,
+ sched_xl,
+ sched_xl->fops->symlink,
+ local->name,
+ &local->loc1);
+
+ return 0;
+}
+
+/**
+ * unify_symlink -
+ */
+int32_t
+unify_symlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *linkpath,
+ loc_t *loc)
+{
+ unify_local_t *local = NULL;
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, loc);
+ local->name = gf_strdup (linkpath);
+
+ if ((local->name == NULL) ||
+ (local->loc1.path == NULL)) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, loc->inode, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame,
+ unify_ns_symlink_cbk,
+ NS(this),
+ NS(this)->fops->symlink,
+ linkpath,
+ loc);
+
+ return 0;
+}
+
+
+int32_t
+unify_rename_unlink_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ int32_t callcnt = 0;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s -> %s): %s",
+ prev_frame->this->name,
+ local->loc1.path, local->loc2.path,
+ strerror (op_errno));
+
+ }
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local->stbuf.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf);
+ }
+ return 0;
+}
+
+int32_t
+unify_ns_rename_undo_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf,
+ struct iatt *preoldparent,
+ struct iatt *postoldparent,
+ struct iatt *prenewparent,
+ struct iatt *postnewparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s -> %s): %s",
+ local->loc1.path, local->loc2.path,
+ strerror (op_errno));
+ }
+
+ local->stbuf.ia_ino = local->ia_ino;
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, &local->stbuf);
+ return 0;
+}
+
+int32_t
+unify_rename_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf,
+ struct iatt *preoldparent,
+ struct iatt *postoldparent,
+ struct iatt *prenewparent,
+ struct iatt *postnewparent)
+{
+ int32_t index = 0;
+ int32_t callcnt = 0;
+ int16_t *list = NULL;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ call_frame_t *prev_frame = cookie;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (op_ret >= 0) {
+ if (!IA_ISDIR (buf->ia_type))
+ local->stbuf = *buf;
+ local->op_ret = op_ret;
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "child(%s): path(%s -> %s): %s",
+ prev_frame->this->name,
+ local->loc1.path, local->loc2.path,
+ strerror (op_errno));
+ local->op_errno = op_errno;
+ }
+ }
+ UNLOCK (&frame->lock);
+
+ if (!callcnt) {
+ local->stbuf.ia_ino = local->ia_ino;
+ if (IA_ISDIR (local->loc1.inode->ia_type)) {
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno,
+ &local->stbuf, &local->oldpreparent,
+ &local->oldpostparent, &local->newpreparent,
+ &local->newpostparent);
+ return 0;
+ }
+
+ if (local->op_ret == -1) {
+ /* TODO: check this logic */
+
+ /* Rename failed in storage node, successful on NS,
+ * hence, rename back the entries in NS */
+ /* NOTE: this will be done only if the destination
+ * doesn't exists, if the destination exists, the
+ * job of correcting NS is left to self-heal
+ */
+ if (!local->index) {
+ loc_t tmp_oldloc = {
+ /* its actual 'newloc->path' */
+ .path = local->loc2.path,
+ .inode = local->loc1.inode,
+ .parent = local->loc2.parent
+ };
+
+ loc_t tmp_newloc = {
+ /* Actual 'oldloc->path' */
+ .path = local->loc1.path,
+ .parent = local->loc1.parent
+ };
+
+ gf_log (this->name, GF_LOG_ERROR,
+ "rename succussful on namespace, on "
+ "stroage node failed, reverting back");
+
+ STACK_WIND (frame,
+ unify_ns_rename_undo_cbk,
+ NS(this),
+ NS(this)->fops->rename,
+ &tmp_oldloc,
+ &tmp_newloc);
+ return 0;
+ }
+ } else {
+ /* Rename successful on storage nodes */
+
+ int32_t idx = 0;
+ int16_t *tmp_list = NULL;
+ uint64_t tmp_list_int64 = 0;
+ if (local->loc2.inode) {
+ inode_ctx_get (local->loc2.inode,
+ this, &tmp_list_int64);
+ list = (int16_t *)(long)tmp_list_int64;
+
+ }
+
+ if (list) {
+ for (index = 0; list[index] != -1; index++);
+ tmp_list = GF_CALLOC (1, index * 2,
+ gf_unify_mt_int16_t);
+ memcpy (tmp_list, list, index * 2);
+
+ for (index = 0; list[index] != -1; index++) {
+ /* TODO: Check this logic. */
+ /* If the destination file exists in
+ * the same storage node where we sent
+ * 'rename' call, no need to send
+ * unlink
+ */
+ for (idx = 0;
+ local->list[idx] != -1; idx++) {
+ if (tmp_list[index] == local->list[idx]) {
+ tmp_list[index] = priv->child_count;
+ continue;
+ }
+ }
+
+ if (NS(this) != priv->xl_array[tmp_list[index]]) {
+ local->call_count++;
+ callcnt++;
+ }
+ }
+
+ if (local->call_count) {
+ if (callcnt > 1)
+ gf_log (this->name,
+ GF_LOG_ERROR,
+ "%s->%s: more (%d) "
+ "subvolumes have the "
+ "newloc entry",
+ local->loc1.path,
+ local->loc2.path,
+ callcnt);
+
+ for (index=0;
+ tmp_list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[tmp_list[index]]) {
+ STACK_WIND (frame,
+ unify_rename_unlink_cbk,
+ priv->xl_array[tmp_list[index]],
+ priv->xl_array[tmp_list[index]]->fops->unlink,
+ &local->loc2);
+ if (!--callcnt)
+ break;
+ }
+ }
+
+ GF_FREE (tmp_list);
+ return 0;
+ }
+ if (tmp_list)
+ GF_FREE (tmp_list);
+ }
+ }
+
+ /* Need not send 'unlink' to storage node */
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, local->op_ret,
+ local->op_errno, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent,
+ &local->newpreparent, &local->newpostparent);
+ }
+
+ return 0;
+}
+
+int32_t
+unify_ns_rename_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *buf,
+ struct iatt *preoldparent,
+ struct iatt *postoldparent,
+ struct iatt *prenewparent,
+ struct iatt *postnewparent)
+{
+ int32_t index = 0;
+ int32_t callcnt = 0;
+ int16_t *list = NULL;
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+
+ if (op_ret == -1) {
+ /* Free local->new_inode */
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s -> %s): %s",
+ local->loc1.path, local->loc2.path,
+ strerror (op_errno));
+
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, buf,
+ preoldparent, postoldparent,
+ prenewparent, postnewparent);
+ return 0;
+ }
+
+ local->stbuf = *buf;
+ local->ia_ino = buf->ia_ino;
+
+ local->oldpreparent = *preoldparent;
+ local->oldpostparent = *postoldparent;
+ local->newpreparent = *prenewparent;
+ local->newpostparent = *postnewparent;
+
+ /* Everything is fine. */
+ if (IA_ISDIR (buf->ia_type)) {
+ local->call_count = priv->child_count;
+ for (index=0; index < priv->child_count; index++) {
+ STACK_WIND (frame,
+ unify_rename_cbk,
+ priv->xl_array[index],
+ priv->xl_array[index]->fops->rename,
+ &local->loc1,
+ &local->loc2);
+ }
+
+ return 0;
+ }
+
+ local->call_count = 0;
+ /* send rename */
+ list = local->list;
+ for (index=0; list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[list[index]]) {
+ local->call_count++;
+ callcnt++;
+ }
+ }
+
+ if (local->call_count) {
+ for (index=0; list[index] != -1; index++) {
+ if (NS(this) != priv->xl_array[list[index]]) {
+ STACK_WIND (frame,
+ unify_rename_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->rename,
+ &local->loc1,
+ &local->loc2);
+ if (!--callcnt)
+ break;
+ }
+ }
+ } else {
+ /* file doesn't seem to be present in storage nodes */
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "CRITICAL: source file not in storage node, "
+ "rename successful on namespace :O");
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, -1, EIO, NULL,
+ NULL, NULL, /* preoldparent, postoldparent */
+ NULL, NULL); /* prenewparent, postnewparent */
+ }
+ return 0;
+}
+
+
+/**
+ * unify_rename - One of the tricky function. The deadliest of all :O
+ */
+int32_t
+unify_rename (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ unify_local_t *local = NULL;
+ uint64_t tmp_list = 0;
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+ loc_copy (&local->loc1, oldloc);
+ loc_copy (&local->loc2, newloc);
+
+ if ((local->loc1.path == NULL) ||
+ (local->loc2.path == NULL)) {
+ gf_log (this->name, GF_LOG_CRITICAL, "Not enough memory :O");
+ STACK_UNWIND (frame, -1, ENOMEM, NULL,
+ NULL, NULL, /* preoldparent, postoldparent */
+ NULL, NULL); /* prenewparent, postnewparent */
+ return 0;
+ }
+
+ inode_ctx_get (oldloc->inode, this, &tmp_list);
+ local->list = (int16_t *)(long)tmp_list;
+
+ STACK_WIND (frame,
+ unify_ns_rename_cbk,
+ NS(this),
+ NS(this)->fops->rename,
+ oldloc,
+ newloc);
+ return 0;
+}
+
+/**
+ * unify_link_cbk -
+ */
+int32_t
+unify_link_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_local_t *local = frame->local;
+
+ if (op_ret >= 0)
+ local->stbuf = *buf;
+ local->stbuf.ia_ino = local->ia_ino;
+
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &local->stbuf,
+ &local->oldpreparent, &local->oldpostparent);
+
+ return 0;
+}
+
+/**
+ * unify_ns_link_cbk -
+ */
+int32_t
+unify_ns_link_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ struct iatt *preparent,
+ struct iatt *postparent)
+{
+ unify_private_t *priv = this->private;
+ unify_local_t *local = frame->local;
+ int16_t *list = local->list;
+ int16_t index = 0;
+
+ if (op_ret == -1) {
+ /* No need to send link request to other servers,
+ * as namespace action failed
+ */
+ gf_log (this->name, GF_LOG_ERROR,
+ "namespace: path(%s -> %s): %s",
+ local->loc1.path, local->loc2.path,
+ strerror (op_errno));
+ unify_local_wipe (local);
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
+ }
+
+ /* Update inode for this entry */
+ local->op_ret = 0;
+ local->ia_ino = buf->ia_ino;
+
+ local->oldpreparent = *preparent;
+ local->oldpostparent = *postparent;
+
+ /* Send link request to the node now */
+ for (index = 0; list[index] != -1; index++) {
+ char need_break = (list[index+1] == -1);
+ if (priv->xl_array[list[index]] != NS (this)) {
+ STACK_WIND (frame,
+ unify_link_cbk,
+ priv->xl_array[list[index]],
+ priv->xl_array[list[index]]->fops->link,
+ &local->loc1,
+ &local->loc2);
+ break;
+ }
+ if (need_break)
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * unify_link -
+ */
+int32_t
+unify_link (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ unify_local_t *local = NULL;
+ uint64_t tmp_list = 0;
+
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (oldloc);
+ UNIFY_CHECK_INODE_CTX_AND_UNWIND_ON_ERR (newloc);
+
+ /* Initialization */
+ INIT_LOCAL (frame, local);
+
+ loc_copy (&local->loc1, oldloc);
+ loc_copy (&local->loc2, newloc);
+
+ inode_ctx_get (oldloc->inode, this, &tmp_list);
+ local->list = (int16_t *)(long)tmp_list;
+
+ STACK_WIND (frame,
+ unify_ns_link_cbk,
+ NS(this),
+ NS(this)->fops->link,
+ oldloc,
+ newloc);
+
+ return 0;
+}
+
+
+/**
+ * unify_checksum_cbk -
+ */
+int32_t
+unify_checksum_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ uint8_t *fchecksum,
+ uint8_t *dchecksum)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, fchecksum, dchecksum);
+
+ return 0;
+}
+
+/**
+ * unify_checksum -
+ */
+int32_t
+unify_checksum (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flag)
+{
+ STACK_WIND (frame,
+ unify_checksum_cbk,
+ NS(this),
+ NS(this)->fops->checksum,
+ loc,
+ flag);
+
+ return 0;
+}
+
+
+/**
+ * unify_finodelk_cbk -
+ */
+int
+unify_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+/**
+ * unify_finodelk
+ */
+int
+unify_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int cmd, struct gf_flock *flock)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_finodelk_cbk,
+ child, child->fops->finodelk,
+ volume, fd, cmd, flock);
+
+ return 0;
+}
+
+
+
+/**
+ * unify_fentrylk_cbk -
+ */
+int
+unify_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+/**
+ * unify_fentrylk
+ */
+int
+unify_fentrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_fentrylk_cbk,
+ child, child->fops->fentrylk,
+ volume, fd, basename, cmd, type);
+
+ return 0;
+}
+
+
+
+/**
+ * unify_fxattrop_cbk -
+ */
+int
+unify_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, xattr);
+ return 0;
+}
+
+/**
+ * unify_fxattrop
+ */
+int
+unify_fxattrop (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, gf_xattrop_flags_t optype, dict_t *xattr)
+{
+ UNIFY_CHECK_FD_CTX_AND_UNWIND_ON_ERR (fd);
+ xlator_t *child = NULL;
+ uint64_t tmp_child = 0;
+
+ fd_ctx_get (fd, this, &tmp_child);
+ child = (xlator_t *)(long)tmp_child;
+
+ STACK_WIND (frame, unify_fxattrop_cbk,
+ child, child->fops->fxattrop,
+ fd, optype, xattr);
+
+ return 0;
+}
+
+
+/**
+ * unify_inodelk_cbk -
+ */
+int
+unify_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+/**
+ * unify_inodelk
+ */
+int
+unify_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int cmd, struct gf_flock *flock)
+{
+ xlator_t *child = NULL;
+
+ child = unify_loc_subvol (loc, this);
+
+ STACK_WIND (frame, unify_inodelk_cbk,
+ child, child->fops->inodelk,
+ volume, loc, cmd, flock);
+
+ return 0;
+}
+
+
+
+/**
+ * unify_entrylk_cbk -
+ */
+int
+unify_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+/**
+ * unify_entrylk
+ */
+int
+unify_entrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+
+{
+ xlator_t *child = NULL;
+
+ child = unify_loc_subvol (loc, this);
+
+ STACK_WIND (frame, unify_entrylk_cbk,
+ child, child->fops->entrylk,
+ volume, loc, basename, cmd, type);
+
+ return 0;
+}
+
+
+
+/**
+ * unify_xattrop_cbk -
+ */
+int
+unify_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, xattr);
+ return 0;
+}
+
+/**
+ * unify_xattrop
+ */
+int
+unify_xattrop (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, gf_xattrop_flags_t optype, dict_t *xattr)
+{
+ xlator_t *child = NULL;
+
+ child = unify_loc_subvol (loc, this);
+
+ STACK_WIND (frame, unify_xattrop_cbk,
+ child, child->fops->xattrop,
+ loc, optype, xattr);
+
+ return 0;
+}
+
+int
+unify_forget (xlator_t *this,
+ inode_t *inode)
+{
+ int16_t *list = NULL;
+ uint64_t tmp_list = 0;
+
+ if (inode->ia_type && (!IA_ISDIR(inode->ia_type))) {
+ inode_ctx_get (inode, this, &tmp_list);
+ if (tmp_list) {
+ list = (int16_t *)(long)tmp_list;
+ GF_FREE (list);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * notify
+ */
+int32_t
+notify (xlator_t *this,
+ int32_t event,
+ void *data,
+ ...)
+{
+ unify_private_t *priv = this->private;
+ struct sched_ops *sched = NULL;
+
+ if (!priv) {
+ return 0;
+ }
+
+ sched = priv->sched_ops;
+ if (!sched) {
+ gf_log (this->name, GF_LOG_CRITICAL, "No scheduler :O");
+ raise (SIGTERM);
+ return 0;
+ }
+ if (priv->namespace == data) {
+ if (event == GF_EVENT_CHILD_UP) {
+ sched->notify (this, event, data);
+ }
+ return 0;
+ }
+
+ switch (event)
+ {
+ case GF_EVENT_CHILD_UP:
+ {
+ /* Call scheduler's update () to enable it for scheduling */
+ sched->notify (this, event, data);
+
+ LOCK (&priv->lock);
+ {
+ /* Increment the inode's generation, which is
+ used for self_heal */
+ ++priv->inode_generation;
+ ++priv->num_child_up;
+ }
+ UNLOCK (&priv->lock);
+
+ if (!priv->is_up) {
+ default_notify (this, event, data);
+ priv->is_up = 1;
+ }
+ }
+ break;
+ case GF_EVENT_CHILD_DOWN:
+ {
+ /* Call scheduler's update () to disable the child node
+ * for scheduling
+ */
+ sched->notify (this, event, data);
+ LOCK (&priv->lock);
+ {
+ --priv->num_child_up;
+ }
+ UNLOCK (&priv->lock);
+
+ if (priv->num_child_up == 0) {
+ /* Send CHILD_DOWN to upper layer */
+ default_notify (this, event, data);
+ priv->is_up = 0;
+ }
+ }
+ break;
+
+ default:
+ {
+ default_notify (this, event, data);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_unify_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * init - This function is called first in the xlator, while initializing.
+ * All the config file options are checked and appropriate flags are set.
+ *
+ * @this -
+ */
+int32_t
+init (xlator_t *this)
+{
+ int32_t ret = 0;
+ int32_t count = 0;
+ data_t *scheduler = NULL;
+ data_t *data = NULL;
+ xlator_t *ns_xl = NULL;
+ xlator_list_t *trav = NULL;
+ xlator_list_t *xlparent = NULL;
+ xlator_list_t *parent = NULL;
+ unify_private_t *_private = NULL;
+
+
+ /* Check for number of child nodes, if there is no child nodes, exit */
+ if (!this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "No child nodes specified. check \"subvolumes \" "
+ "option in volfile");
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ /* Check for 'scheduler' in volume */
+ scheduler = dict_get (this->options, "scheduler");
+ if (!scheduler) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "\"option scheduler <x>\" is missing in volfile");
+ return -1;
+ }
+
+ /* Setting "option namespace <node>" */
+ data = dict_get (this->options, "namespace");
+ if(!data) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "namespace option not specified, Exiting");
+ return -1;
+ }
+ /* Search namespace in the child node, if found, exit */
+ trav = this->children;
+ while (trav) {
+ if (strcmp (trav->xlator->name, data->data) == 0)
+ break;
+ trav = trav->next;
+ }
+ if (trav) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "namespace node used as a subvolume, Exiting");
+ return -1;
+ }
+
+ /* Search for the namespace node, if found, continue */
+ ns_xl = this->next;
+ while (ns_xl) {
+ if (strcmp (ns_xl->name, data->data) == 0)
+ break;
+ ns_xl = ns_xl->next;
+ }
+ if (!ns_xl) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "namespace node not found in volfile, Exiting");
+ return -1;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "namespace node specified as %s", data->data);
+
+ _private = GF_CALLOC (1, sizeof (*_private),
+ gf_unify_mt_unify_private_t);
+ ERR_ABORT (_private);
+ _private->sched_ops = get_scheduler (this, scheduler->data);
+ if (!_private->sched_ops) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Error while loading scheduler. Exiting");
+ GF_FREE (_private);
+ return -1;
+ }
+
+ if (ns_xl->parents) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Namespace node should not be a child of any other node. Exiting");
+ GF_FREE (_private);
+ return -1;
+ }
+
+ _private->namespace = ns_xl;
+
+ /* update _private structure */
+ {
+ count = 0;
+ trav = this->children;
+ /* Get the number of child count */
+ while (trav) {
+ count++;
+ trav = trav->next;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Child node count is %d", count);
+
+ _private->child_count = count;
+ if (count == 1) {
+ /* TODO: Should I error out here? */
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "WARNING: You have defined only one "
+ "\"subvolumes\" for unify volume. It may not "
+ "be the desired config, review your volume "
+ "volfile. If this is how you are testing it,"
+ " you may hit some performance penalty");
+ }
+
+ _private->xl_array = GF_CALLOC (1,
+ sizeof (xlator_t) * (count + 1),
+ gf_unify_mt_xlator_t);
+ ERR_ABORT (_private->xl_array);
+
+ count = 0;
+ trav = this->children;
+ while (trav) {
+ _private->xl_array[count++] = trav->xlator;
+ trav = trav->next;
+ }
+ _private->xl_array[count] = _private->namespace;
+
+ /* self-heal part, start with generation '1' */
+ _private->inode_generation = 1;
+ /* Because, Foreground part is tested well */
+ _private->self_heal = ZR_UNIFY_FG_SELF_HEAL;
+ data = dict_get (this->options, "self-heal");
+ if (data) {
+ if (strcasecmp (data->data, "off") == 0)
+ _private->self_heal = ZR_UNIFY_SELF_HEAL_OFF;
+
+ if (strcasecmp (data->data, "foreground") == 0)
+ _private->self_heal = ZR_UNIFY_FG_SELF_HEAL;
+
+ if (strcasecmp (data->data, "background") == 0)
+ _private->self_heal = ZR_UNIFY_BG_SELF_HEAL;
+ }
+
+ /* optimist - ask bulde for more about it */
+ data = dict_get (this->options, "optimist");
+ if (data) {
+ if (gf_string2boolean (data->data,
+ &_private->optimist) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "optimist excepts only boolean "
+ "options");
+ }
+ }
+
+ LOCK_INIT (&_private->lock);
+ }
+
+ /* Now that everything is fine. */
+ this->private = (void *)_private;
+ {
+ ret = _private->sched_ops->mem_acct_init (this);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ /* Initialize scheduler, if everything else is successful */
+ ret = _private->sched_ops->init (this);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "Initializing scheduler failed, Exiting");
+ GF_FREE (_private);
+ return -1;
+ }
+
+
+ ret = 0;
+
+ /* This section is required because some fops may look
+ * for 'xl->parent' variable
+ */
+ xlparent = GF_CALLOC (1, sizeof (*xlparent),
+ gf_unify_mt_xlator_list_t);
+ xlparent->xlator = this;
+ if (!ns_xl->parents) {
+ ns_xl->parents = xlparent;
+ } else {
+ parent = ns_xl->parents;
+ while (parent->next)
+ parent = parent->next;
+ parent->next = xlparent;
+ }
+ }
+
+ /* Tell namespace node that init is done */
+ xlator_notify (ns_xl, GF_EVENT_PARENT_UP, this);
+
+ return 0;
+}
+
+/**
+ * fini - Free all the allocated memory
+ */
+void
+fini (xlator_t *this)
+{
+ unify_private_t *priv = this->private;
+ priv->sched_ops->fini (this);
+ this->private = NULL;
+ LOCK_DESTROY (&priv->lock);
+ GF_FREE (priv->xl_array);
+ GF_FREE (priv);
+ return;
+}
+
+
+struct xlator_fops fops = {
+ .stat = unify_stat,
+ .readlink = unify_readlink,
+ .mknod = unify_mknod,
+ .mkdir = unify_mkdir,
+ .unlink = unify_unlink,
+ .rmdir = unify_rmdir,
+ .symlink = unify_symlink,
+ .rename = unify_rename,
+ .link = unify_link,
+ .truncate = unify_truncate,
+ .create = unify_create,
+ .open = unify_open,
+ .readv = unify_readv,
+ .writev = unify_writev,
+ .statfs = unify_statfs,
+ .flush = unify_flush,
+ .fsync = unify_fsync,
+ .setxattr = unify_setxattr,
+ .getxattr = unify_getxattr,
+ .removexattr = unify_removexattr,
+ .opendir = unify_opendir,
+ .readdir = unify_readdir,
+ .readdirp = unify_readdirp,
+ .fsyncdir = unify_fsyncdir,
+ .access = unify_access,
+ .ftruncate = unify_ftruncate,
+ .fstat = unify_fstat,
+ .lk = unify_lk,
+ .lookup = unify_lookup,
+ .getdents = unify_getdents,
+ .checksum = unify_checksum,
+ .inodelk = unify_inodelk,
+ .finodelk = unify_finodelk,
+ .entrylk = unify_entrylk,
+ .fentrylk = unify_fentrylk,
+ .xattrop = unify_xattrop,
+ .fxattrop = unify_fxattrop,
+ .setattr = unify_setattr,
+ .fsetattr = unify_fsetattr,
+};
+
+
+struct xlator_cbks cbks = {
+ .forget = unify_forget,
+};
+
+struct volume_options options[] = {
+ { .key = { "namespace" },
+ .type = GF_OPTION_TYPE_XLATOR
+ },
+ { .key = { "scheduler" },
+ .value = { "alu", "rr", "random", "nufa", "switch" },
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"self-heal"},
+ .value = { "foreground", "background", "off" },
+ .type = GF_OPTION_TYPE_STR
+ },
+ /* TODO: remove it some time later */
+ { .key = {"optimist"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+
+ { .key = {NULL} },
+};
diff --git a/xlators/cluster/unify/src/unify.h b/xlators/cluster/unify/src/unify.h
new file mode 100644
index 000000000..3cfe725f4
--- /dev/null
+++ b/xlators/cluster/unify/src/unify.h
@@ -0,0 +1,146 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _UNIFY_H
+#define _UNIFY_H
+
+#include "scheduler.h"
+#include "list.h"
+#include "unify-mem-types.h"
+
+#define MAX_DIR_ENTRY_STRING (32 * 1024)
+
+#define ZR_UNIFY_SELF_HEAL_OFF 0
+#define ZR_UNIFY_FG_SELF_HEAL 1
+#define ZR_UNIFY_BG_SELF_HEAL 2
+
+/* Sometimes one should use completely random numbers.. its good :p */
+#define UNIFY_SELF_HEAL_GETDENTS_COUNT 512
+
+#define NS(xl) (((unify_private_t *)xl->private)->namespace)
+
+/* This is used to allocate memory for local structure */
+#define INIT_LOCAL(fr, loc) \
+do { \
+ loc = GF_CALLOC (1, sizeof (unify_local_t), gf_unify_mt_unify_local_t); \
+ ERR_ABORT (loc); \
+ if (!loc) { \
+ STACK_UNWIND (fr, -1, ENOMEM); \
+ return 0; \
+ } \
+ fr->local = loc; \
+ loc->op_ret = -1; \
+ loc->op_errno = ENOENT; \
+} while (0)
+
+
+
+struct unify_private {
+ /* Update this structure depending on requirement */
+ void *scheduler; /* THIS SHOULD BE THE FIRST VARIABLE,
+ if xlator is using scheduler */
+ struct sched_ops *sched_ops; /* Scheduler options */
+ xlator_t *namespace; /* ptr to namespace xlator */
+ xlator_t **xl_array;
+ gf_boolean_t optimist;
+ int16_t child_count;
+ int16_t num_child_up;
+ uint8_t self_heal;
+ uint8_t is_up;
+ uint64_t inode_generation;
+ gf_lock_t lock;
+};
+typedef struct unify_private unify_private_t;
+
+struct unify_self_heal_struct {
+ uint8_t dir_checksum[NAME_MAX];
+ uint8_t ns_dir_checksum[NAME_MAX];
+ uint8_t file_checksum[NAME_MAX];
+ uint8_t ns_file_checksum[NAME_MAX];
+ off_t *offset_list;
+ int *count_list;
+ dir_entry_t **entry_list;
+};
+
+
+struct _unify_local_t {
+ int32_t call_count;
+ int32_t op_ret;
+ int32_t op_errno;
+ mode_t mode;
+ off_t offset;
+ dev_t dev;
+ uid_t uid;
+ gid_t gid;
+ int32_t flags;
+ int32_t entry_count;
+ int32_t count; // dir_entry_t count;
+ fd_t *fd;
+ struct iatt stbuf;
+ struct iatt stpre;
+ struct iatt stpost;
+ struct statvfs statvfs_buf;
+ struct timespec tv[2];
+ char *name;
+ int32_t revalidate;
+
+ ino_t ia_ino;
+ nlink_t ia_nlink;
+
+ dict_t *dict;
+
+ int16_t *list;
+ int16_t *new_list; /* Used only in case of rename */
+ int16_t index;
+
+ int32_t failed;
+ int32_t return_eio; /* Used in case of different st-mode
+ present for a given path */
+
+ uint64_t inode_generation; /* used to store the per directory
+ * inode_generation. Got from inode's ctx
+ * of directory inodes
+ */
+
+ struct unify_self_heal_struct *sh_struct;
+ loc_t loc1, loc2;
+
+ struct iatt poststbuf;
+ /* When not used for rename, old*
+ * are used as the attrs for the current
+ * parent directory.
+ */
+ struct iatt oldpreparent;
+ struct iatt oldpostparent;
+ struct iatt newpreparent;
+ struct iatt newpostparent;
+ int32_t wbflags;
+};
+typedef struct _unify_local_t unify_local_t;
+
+int32_t zr_unify_self_heal (call_frame_t *frame,
+ xlator_t *this,
+ unify_local_t *local);
+
+#endif /* _UNIFY_H */
diff --git a/xlators/debug/error-gen/src/Makefile.am b/xlators/debug/error-gen/src/Makefile.am
index df9080358..f353b61e6 100644
--- a/xlators/debug/error-gen/src/Makefile.am
+++ b/xlators/debug/error-gen/src/Makefile.am
@@ -7,7 +7,7 @@ error_gen_la_LDFLAGS = -module -avoidversion
error_gen_la_SOURCES = error-gen.c
error_gen_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = error-gen.h error-gen-mem-types.h
+noinst_HEADERS = error-gen.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
diff --git a/xlators/debug/error-gen/src/error-gen-mem-types.h b/xlators/debug/error-gen/src/error-gen-mem-types.h
deleted file mode 100644
index b643dc5f7..000000000
--- a/xlators/debug/error-gen/src/error-gen-mem-types.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef __ERROR_GEN_MEM_TYPES_H__
-#define __ERROR_GEN_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_error_gen_mem_types_ {
- gf_error_gen_mt_eg_t = gf_common_mt_end + 1,
- gf_error_gen_mt_end
-};
-#endif
diff --git a/xlators/debug/error-gen/src/error-gen.c b/xlators/debug/error-gen/src/error-gen.c
index 6ecca2ee5..84a420727 100644
--- a/xlators/debug/error-gen/src/error-gen.c
+++ b/xlators/debug/error-gen/src/error-gen.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -113,15 +113,6 @@ sys_error_t error_no_list[] = {
[GF_FOP_REMOVEXATTR] = { .error_no_count = 4,
.error_no = {EACCES,EBADF,ENAMETOOLONG,
EINTR}},
- [GF_FOP_FSETXATTR] = { .error_no_count = 4,
- .error_no = {EACCES,EBADF,EINTR,
- ENAMETOOLONG}},
- [GF_FOP_FGETXATTR] = { .error_no_count = 4,
- .error_no = {EACCES,EBADF,ENAMETOOLONG,
- EINTR}},
- [GF_FOP_FREMOVEXATTR] = { .error_no_count = 4,
- .error_no = {EACCES,EBADF,ENAMETOOLONG,
- EINTR}},
[GF_FOP_OPENDIR] = { .error_no_count = 8,
.error_no = {EACCES,EEXIST,EFAULT,
EISDIR,EMFILE,
@@ -295,12 +286,6 @@ get_fop_int (char **op_no_str)
return GF_FOP_GETXATTR;
else if (!strcmp ((*op_no_str), "removexattr"))
return GF_FOP_REMOVEXATTR;
- else if (!strcmp ((*op_no_str), "fsetxattr"))
- return GF_FOP_FSETXATTR;
- else if (!strcmp ((*op_no_str), "fgetxattr"))
- return GF_FOP_FGETXATTR;
- else if (!strcmp ((*op_no_str), "fremovexattr"))
- return GF_FOP_FREMOVEXATTR;
else if (!strcmp ((*op_no_str), "opendir"))
return GF_FOP_OPENDIR;
else if (!strcmp ((*op_no_str), "readdir"))
@@ -377,8 +362,7 @@ error_gen (xlator_t *this, int op_no)
rand_no = 0;
ret = error_no_list[op_no].error_no[rand_no];
}
- if (egp->random_failure == _gf_true)
- egp->failure_iter_no = 3 + (rand () % GF_UNIVERSAL_ANSWER);
+ egp->failure_iter_no = 3 + (rand () % GF_UNIVERSAL_ANSWER);
}
return ret;
}
@@ -387,17 +371,17 @@ error_gen (xlator_t *this, int op_no)
int
error_gen_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+ struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode,
- buf, xdata, postparent);
- return 0;
+ buf, dict, postparent);
+ return 0;
}
int
error_gen_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+ dict_t *xattr_req)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -412,28 +396,36 @@ error_gen_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
- return 0;
+ NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xdata);
- return 0;
+ loc, xattr_req);
+ return 0;
+}
+
+
+int
+error_gen_forget (xlator_t *this, inode_t *inode)
+{
+ return 0;
}
int
error_gen_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
+
+ return 0;
}
int
-error_gen_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+error_gen_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -447,31 +439,32 @@ error_gen_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_stat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->stat,
- loc, xdata);
- return 0;
+ loc);
+ return 0;
}
int
error_gen_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop);
+
+ return 0;
}
int
error_gen_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -485,21 +478,21 @@ error_gen_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
+ loc, stbuf, valid);
+ return 0;
}
int
error_gen_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -513,32 +506,32 @@ error_gen_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
+ fd, stbuf, valid);
+ return 0;
}
int
error_gen_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
- return 0;
+ prebuf, postbuf);
+ return 0;
}
int
error_gen_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -553,32 +546,32 @@ error_gen_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (truncate, frame, -1, op_errno,
- NULL, NULL, xdata);
- return 0;
+ NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_truncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
- return 0;
+ loc, offset);
+ return 0;
}
int
error_gen_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
- return 0;
+ prebuf, postbuf);
+ return 0;
}
int
error_gen_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
int op_errno = 0;
eg_t *egp =NULL;
@@ -593,30 +586,31 @@ error_gen_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno,
- NULL, NULL, xdata);
- return 0;
+ NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_ftruncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
- fd, offset, xdata);
- return 0;
+ fd, offset);
+ return 0;
}
int
error_gen_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
+
+ return 0;
}
int
error_gen_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask, dict_t *xdata)
+ int32_t mask)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -630,31 +624,31 @@ error_gen_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (access, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (access, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_access_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->access,
- loc, mask, xdata);
- return 0;
+ loc, mask);
+ return 0;
}
int
error_gen_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- const char *path, struct iatt *sbuf, dict_t *xdata)
+ const char *path, struct iatt *sbuf)
{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, sbuf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, sbuf);
+ return 0;
}
int
error_gen_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, dict_t *xdata)
+ size_t size)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -668,15 +662,15 @@ error_gen_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_readlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
- loc, size, xdata);
- return 0;
+ loc, size);
+ return 0;
}
@@ -684,18 +678,18 @@ int
error_gen_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno,
inode, buf,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
error_gen_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
+ mode_t mode, dev_t rdev, dict_t *params)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -710,15 +704,15 @@ error_gen_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, xdata);
- return 0;
+ NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
+ loc, mode, rdev, params);
+ return 0;
}
@@ -726,17 +720,17 @@ int
error_gen_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno,
inode, buf,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
error_gen_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dict_t *params)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -751,32 +745,31 @@ error_gen_mkdir (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, xdata);
- return 0;
+ NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
+ loc, mode, params);
+ return 0;
}
int
error_gen_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
-error_gen_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+error_gen_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -790,34 +783,31 @@ error_gen_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL,
- xdata);
- return 0;
+ STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
+ loc);
+ return 0;
}
int
error_gen_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
-error_gen_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+error_gen_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -831,15 +821,15 @@ error_gen_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
- return 0;
+ loc, flags);
+ return 0;
}
@@ -847,17 +837,17 @@ int
error_gen_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
error_gen_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -872,15 +862,15 @@ error_gen_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL); /* pre & post parent attr */
+ NULL, NULL); /* pre & post parent attr */
return 0;
}
STACK_WIND (frame, error_gen_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
+ linkpath, loc, params);
+ return 0;
}
@@ -888,19 +878,18 @@ int
error_gen_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf,
preoldparent, postoldparent,
- prenewparent, postnewparent, xdata);
- return 0;
+ prenewparent, postnewparent);
+ return 0;
}
int
error_gen_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -915,15 +904,15 @@ error_gen_rename (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL); /* pre & post parent attr */
return 0;
}
STACK_WIND (frame, error_gen_rename_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
+ oldloc, newloc);
+ return 0;
}
@@ -931,17 +920,17 @@ int
error_gen_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
error_gen_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -956,15 +945,15 @@ error_gen_link (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL); /* pre & post parent attr */
return 0;
}
STACK_WIND (frame, error_gen_link_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
+ oldloc, newloc);
+ return 0;
}
@@ -972,18 +961,17 @@ int
error_gen_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
fd_t *fd, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ preparent, postparent);
+ return 0;
}
int
error_gen_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
- dict_t *xdata)
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -998,30 +986,30 @@ error_gen_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL); /* pre & post attr */
return 0;
}
STACK_WIND (frame, error_gen_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
- return 0;
+ loc, flags, mode, fd, params);
+ return 0;
}
int
error_gen_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ return 0;
}
int
error_gen_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+ int32_t flags, fd_t *fd, int32_t wbflags)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1035,15 +1023,15 @@ error_gen_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_open_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
- return 0;
+ loc, flags, fd, wbflags);
+ return 0;
}
@@ -1051,17 +1039,17 @@ int
error_gen_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *stbuf, struct iobref *iobref)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata);
- return 0;
+ vector, count, stbuf, iobref);
+ return 0;
}
int
error_gen_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ fd_t *fd, size_t size, off_t offset)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1076,33 +1064,33 @@ error_gen_readv (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0,
- NULL, NULL, xdata);
- return 0;
+ NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_readv_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
- return 0;
+ fd, size, offset);
+ return 0;
}
int
error_gen_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
}
int
error_gen_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count,
- off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ off_t off, struct iobref *iobref)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1116,29 +1104,29 @@ error_gen_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- fd, vector, count, off, flags, iobref, xdata);
- return 0;
+ fd, vector, count, off, iobref);
+ return 0;
}
int
error_gen_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
+ return 0;
}
int
-error_gen_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+error_gen_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1152,15 +1140,15 @@ error_gen_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (flush, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
- return 0;
+ fd);
+ return 0;
}
@@ -1168,15 +1156,15 @@ int
error_gen_fsync_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
}
int
-error_gen_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+error_gen_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1190,29 +1178,29 @@ error_gen_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_fsync_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
- fd, flags, xdata);
- return 0;
+ fd, flags);
+ return 0;
}
int
error_gen_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
+ return 0;
}
int
-error_gen_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+error_gen_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1226,29 +1214,29 @@ error_gen_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
- return 0;
+ fd);
+ return 0;
}
int
error_gen_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
- return 0;
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
+ return 0;
}
int
-error_gen_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata)
+error_gen_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1262,29 +1250,29 @@ error_gen_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, di
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- return 0;
+ loc, fd);
+ return 0;
}
int
error_gen_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
+ return 0;
}
int
error_gen_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1298,29 +1286,30 @@ error_gen_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_fsyncdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsyncdir,
- fd, flags, xdata);
- return 0;
+ fd, flags);
+ return 0;
}
int
error_gen_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
+
+ return 0;
}
int
-error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1334,30 +1323,31 @@ error_gen_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_statfs_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
- return 0;
+ loc);
+ return 0;
}
int
error_gen_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
+
+ return 0;
}
int
error_gen_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1371,30 +1361,30 @@ error_gen_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_setxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
+ loc, dict, flags);
+ return 0;
}
int
error_gen_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+ return 0;
}
int
error_gen_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1408,103 +1398,31 @@ error_gen_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_getxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
- return 0;
-}
-
-int
-error_gen_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-error_gen_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
-{
- int op_errno = 0;
- eg_t *egp = NULL;
- int enable = 1;
-
- egp = this->private;
- enable = egp->enable[GF_FOP_FSETXATTR];
-
- if (enable)
- op_errno = error_gen (this, GF_FOP_FSETXATTR);
-
- if (op_errno) {
- GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno, xdata);
- return 0;
- }
-
- STACK_WIND (frame, error_gen_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
-}
-
-
-int
-error_gen_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int
-error_gen_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int op_errno = 0;
- eg_t *egp = NULL;
- int enable = 1;
-
- egp = this->private;
- enable = egp->enable[GF_FOP_FGETXATTR];
-
- if (enable)
- op_errno = error_gen (this, GF_FOP_FGETXATTR);
-
- if (op_errno) {
- GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL, xdata);
- return 0;
- }
-
- STACK_WIND (frame, error_gen_fgetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
- return 0;
+ loc, name);
+ return 0;
}
int
error_gen_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
+
+ return 0;
}
int
error_gen_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1518,30 +1436,31 @@ error_gen_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_xattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
- loc, flags, dict, xdata);
- return 0;
+ loc, flags, dict);
+ return 0;
}
int
error_gen_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
+
+ return 0;
}
int
error_gen_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1555,30 +1474,31 @@ error_gen_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_fxattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fxattrop,
- fd, flags, dict, xdata);
- return 0;
+ fd, flags, dict);
+ return 0;
}
int
error_gen_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
+
+ return 0;
}
int
error_gen_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1592,66 +1512,30 @@ error_gen_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_removexattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
-int
-error_gen_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-error_gen_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int op_errno = 0;
- eg_t *egp = NULL;
- int enable = 1;
-
- egp = this->private;
- enable = egp->enable[GF_FOP_FREMOVEXATTR];
-
- if (enable)
- op_errno = error_gen (this, GF_FOP_FREMOVEXATTR);
-
- if (op_errno) {
- GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, op_errno, xdata);
- return 0;
- }
-
- STACK_WIND (frame, error_gen_fremovexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
- return 0;
+ loc, name);
+ return 0;
}
int
error_gen_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
- return 0;
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
+ return 0;
}
int
error_gen_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1665,31 +1549,32 @@ error_gen_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL, xdata);
- return 0;
+ STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL);
+ return 0;
}
STACK_WIND (frame, error_gen_lk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lk,
- fd, cmd, lock, xdata);
- return 0;
+ fd, cmd, lock);
+ return 0;
}
int
-error_gen_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+error_gen_inodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
+ return 0;
}
int
error_gen_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1703,31 +1588,32 @@ error_gen_inodelk (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_inodelk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock, xdata);
- return 0;
+ volume, loc, cmd, lock);
+ return 0;
}
int
-error_gen_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+error_gen_finodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
+ return 0;
}
int
error_gen_finodelk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1741,31 +1627,32 @@ error_gen_finodelk (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_finodelk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock, xdata);
- return 0;
+ volume, fd, cmd, lock);
+ return 0;
}
int
-error_gen_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+error_gen_entrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
+ return 0;
}
int
error_gen_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1779,31 +1666,32 @@ error_gen_entrylk (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_entrylk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
- return 0;
+ volume, loc, basename, cmd, type);
+ return 0;
}
int
-error_gen_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+error_gen_fentrylk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
+
{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
+ return 0;
}
int
error_gen_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1817,15 +1705,15 @@ error_gen_fentrylk (call_frame_t *frame, xlator_t *this,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno, xdata);
- return 0;
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno);
+ return 0;
}
STACK_WIND (frame, error_gen_fentrylk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
- return 0;
+ volume, fd, basename, cmd, type);
+ return 0;
}
@@ -1837,7 +1725,8 @@ error_gen_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, char *spec_data)
{
STACK_UNWIND_STRICT (getspec, frame, op_ret, op_errno, spec_data);
- return 0;
+
+ return 0;
}
@@ -1871,17 +1760,16 @@ error_gen_getspec (call_frame_t *frame, xlator_t *this, const char *key,
int
error_gen_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
return 0;
}
int
error_gen_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
+ size_t size, off_t off)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1895,31 +1783,30 @@ error_gen_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL);
return 0;
}
STACK_WIND (frame, error_gen_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
+ fd, size, off);
return 0;
}
int
error_gen_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
return 0;
}
int
error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t off, dict_t *dict)
+ off_t off)
{
int op_errno = 0;
eg_t *egp = NULL;
@@ -1933,36 +1820,32 @@ error_gen_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if (op_errno) {
GF_ERROR(this, "unwind(-1, %s)", strerror (op_errno));
- STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL);
return 0;
}
STACK_WIND (frame, error_gen_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, off, dict);
+ fd, size, off);
return 0;
}
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
- if (!this)
- return ret;
+int
+error_gen_closedir (xlator_t *this, fd_t *fd)
+{
+ return 0;
+}
- ret = xlator_mem_acct_init (this, gf_error_gen_mt_end + 1);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- " failed");
- return ret;
- }
-
- return ret;
+int
+error_gen_close (xlator_t *this, fd_t *fd)
+{
+ return 0;
}
+
int
init (xlator_t *this)
{
@@ -1970,7 +1853,6 @@ init (xlator_t *this)
data_t *error_no = NULL;
data_t *failure_percent = NULL;
data_t *enable = NULL;
- gf_boolean_t random_failure = _gf_false;
int32_t ret = 0;
char *error_enable_fops = NULL;
char *op_no_str = NULL;
@@ -1994,7 +1876,7 @@ init (xlator_t *this)
failure_percent = dict_get (this->options, "failure");
enable = dict_get (this->options, "enable");
- pvt = GF_CALLOC (1, sizeof (eg_t), gf_error_gen_mt_eg_t);
+ pvt = CALLOC (1, sizeof (eg_t));
if (!pvt) {
gf_log (this->name, GF_LOG_ERROR,
@@ -2053,11 +1935,6 @@ init (xlator_t *this)
}
}
}
-
- random_failure = dict_get_str_boolean (this->options, "random-failure",
- _gf_false);
- pvt->random_failure = random_failure;
-
this->private = pvt;
/* Give some seed value here */
@@ -2078,15 +1955,12 @@ fini (xlator_t *this)
if (pvt) {
LOCK_DESTROY (&pvt->lock);
- GF_FREE (pvt);
+ FREE (pvt);
gf_log (this->name, GF_LOG_DEBUG, "fini called");
}
return;
}
-struct xlator_fops cbks = {
-};
-
struct xlator_fops fops = {
.lookup = error_gen_lookup,
.stat = error_gen_stat,
@@ -2109,9 +1983,6 @@ struct xlator_fops fops = {
.setxattr = error_gen_setxattr,
.getxattr = error_gen_getxattr,
.removexattr = error_gen_removexattr,
- .fsetxattr = error_gen_fsetxattr,
- .fgetxattr = error_gen_fgetxattr,
- .fremovexattr = error_gen_fremovexattr,
.opendir = error_gen_opendir,
.readdir = error_gen_readdir,
.readdirp = error_gen_readdirp,
@@ -2132,6 +2003,11 @@ struct xlator_fops fops = {
.getspec = error_gen_getspec,
};
+struct xlator_cbks cbks = {
+ .release = error_gen_close,
+ .releasedir = error_gen_closedir,
+};
+
struct volume_options options[] = {
{ .key = {"failure"},
.type = GF_OPTION_TYPE_INT },
@@ -2142,8 +2018,6 @@ struct volume_options options[] = {
"ENODEV","EXDEV","EMFILE","ENFILE","ENOSYS","EINTR",
"EFBIG","EAGAIN"},
.type = GF_OPTION_TYPE_STR },
- { .key = {"random-failure"},
- .type = GF_OPTION_TYPE_BOOL},
{ .key = {"enable"},
.type = GF_OPTION_TYPE_STR },
{ .key = {NULL} }
diff --git a/xlators/debug/error-gen/src/error-gen.h b/xlators/debug/error-gen/src/error-gen.h
index bb3adb2ab..1c902cf4f 100644
--- a/xlators/debug/error-gen/src/error-gen.h
+++ b/xlators/debug/error-gen/src/error-gen.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -25,8 +25,6 @@
#include "config.h"
#endif
-#include "error-gen-mem-types.h"
-
#define GF_FAILURE_DEFAULT 10
typedef struct {
@@ -34,7 +32,6 @@ typedef struct {
int op_count;
int failure_iter_no;
char *error_no;
- gf_boolean_t random_failure;
gf_lock_t lock;
} eg_t;
diff --git a/xlators/debug/io-stats/src/io-stats-mem-types.h b/xlators/debug/io-stats/src/io-stats-mem-types.h
index 2063f6d6a..59f88ea32 100644
--- a/xlators/debug/io-stats/src/io-stats-mem-types.h
+++ b/xlators/debug/io-stats/src/io-stats-mem-types.h
@@ -1,19 +1,19 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index 1057ace85..326645cf3 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -45,7 +45,6 @@
#include "io-stats-mem-types.h"
#include <stdarg.h>
#include "defaults.h"
-#include "logging.h"
#define MAX_LIST_MEMBERS 100
@@ -58,7 +57,7 @@ typedef enum {
IOS_STATS_TYPE_READDIRP,
IOS_STATS_TYPE_READ_THROUGHPUT,
IOS_STATS_TYPE_WRITE_THROUGHPUT,
- IOS_STATS_TYPE_MAX
+ IOS_STATS_TYPE_MAX,
}ios_stats_type_t;
typedef enum {
@@ -110,7 +109,6 @@ struct ios_global_stats {
struct ios_lat latency[GF_FOP_MAXVALUE];
uint64_t nr_opens;
uint64_t max_nr_opens;
- struct timeval max_openfd_time;
};
@@ -121,7 +119,7 @@ struct ios_conf {
struct ios_global_stats incremental;
gf_boolean_t dump_fd_stats;
gf_boolean_t count_fop_hits;
- gf_boolean_t measure_latency;
+ int measure_latency;
struct ios_stat_head list[IOS_STATS_TYPE_MAX];
struct ios_stat_head thru_list[IOS_STATS_THRU_MAX];
};
@@ -159,8 +157,6 @@ struct ios_local {
struct timeval unwind_at;
};
-struct volume_options options[];
-
inline static int
is_fop_latency_started (call_frame_t *frame)
{
@@ -293,43 +289,43 @@ is_fop_latency_started (call_frame_t *frame)
} \
UNLOCK (&iosstat->lock); \
ios_stat_add_to_list (&conf->list[type], \
- value, iosstat); \
+ value, iosstat); \
\
} while (0)
#define BUMP_THROUGHPUT(iosstat, type) \
do { \
- struct ios_conf *conf = NULL; \
- double elapsed; \
- struct timeval *begin, *end; \
- double throughput; \
+ struct ios_conf *conf = NULL; \
+ double elapsed; \
+ struct timeval *begin, *end; \
+ double throughput; \
int flag = 0; \
- \
- begin = &frame->begin; \
- end = &frame->end; \
- \
- elapsed = (end->tv_sec - begin->tv_sec) * 1e6 \
- + (end->tv_usec - begin->tv_usec); \
- throughput = op_ret / elapsed; \
- \
- conf = this->private; \
- LOCK(&iosstat->lock); \
- { \
- if (iosstat->thru_counters[type].throughput \
+ \
+ begin = &frame->begin; \
+ end = &frame->end; \
+ \
+ elapsed = (end->tv_sec - begin->tv_sec) * 1e6 \
+ + (end->tv_usec - begin->tv_usec); \
+ throughput = op_ret / elapsed; \
+ \
+ conf = this->private; \
+ LOCK(&iosstat->lock); \
+ { \
+ if (iosstat->thru_counters[type].throughput \
<= throughput) { \
- iosstat->thru_counters[type].throughput = \
+ iosstat->thru_counters[type].throughput = \
throughput; \
- gettimeofday (&iosstat-> \
+ gettimeofday (&iosstat-> \
thru_counters[type].time, NULL); \
flag = 1; \
} \
} \
- UNLOCK (&iosstat->lock); \
+ UNLOCK (&iosstat->lock); \
if (flag) \
ios_stat_add_to_list (&conf->thru_list[type], \
throughput, iosstat); \
- } while (0)
+ } while (0)
int
ios_fd_ctx_get (fd_t *fd, xlator_t *this, struct ios_fd **iosfd)
@@ -484,12 +480,12 @@ ios_stat_add_to_list (struct ios_stat_head *list_head, uint64_t value,
new = GF_CALLOC (1, sizeof (*new),
gf_io_stats_mt_ios_stat_list);
new->iosstat = iosstat;
- new->value = value;
+ new->value = value;
ios_stat_ref (iosstat);
- list_add_tail (&new->list, &tmp->list);
+ list_add_tail (&new->list, &tmp->list);
stat = last->iosstat;
last->iosstat = NULL;
- ios_stat_unref (stat);
+ ios_stat_unref (stat);
list_del (&last->list);
GF_FREE (last);
if (reposition == MAX_LIST_MEMBERS)
@@ -511,7 +507,7 @@ ios_stat_add_to_list (struct ios_stat_head *list_head, uint64_t value,
list_head->members++;
if (list_head->min_cnt > value)
list_head->min_cnt = value;
- }
+ }
}
out:
UNLOCK (&list_head->lock);
@@ -555,7 +551,7 @@ ios_dump_file_stats (struct ios_stat_head *list_head, xlator_t *this, FILE* logf
LOCK (&list_head->lock);
{
list_for_each_entry (entry, &list_head->iosstats->list, list) {
- ios_log (this, logfp, "%-12.0f %s",
+ ios_log (this, logfp, "%.0f\t\t%s",
entry->value, entry->iosstat->filename);
}
}
@@ -568,20 +564,24 @@ ios_dump_throughput_stats (struct ios_stat_head *list_head, xlator_t *this,
FILE* logfp, ios_stats_type_t type)
{
struct ios_stat_list *entry = NULL;
- struct timeval time = {0, };
+ struct timeval time = {0, };
+ struct tm *tm = NULL;
char timestr[256] = {0, };
LOCK (&list_head->lock);
{
list_for_each_entry (entry, &list_head->iosstats->list, list) {
- gf_time_fmt (timestr, sizeof timestr,
- entry->iosstat->thru_counters[type].time.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
+ time = entry->iosstat->thru_counters[type].time;
+ tm = localtime (&time.tv_sec);
+ if (!tm)
+ continue;
+ strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", tm);
+ snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
".%"GF_PRI_SUSECONDS, time.tv_usec);
- ios_log (this, logfp, "%s \t %-10.2f \t %s",
- timestr, entry->value, entry->iosstat->filename);
+ ios_log (this, logfp, "%.2f\t\t%s \t\t- %s",
+ entry->value,
+ entry->iosstat->filename, timestr);
}
}
UNLOCK (&list_head->lock);
@@ -592,153 +592,91 @@ int
io_stats_dump_global_to_logfp (xlator_t *this, struct ios_global_stats *stats,
struct timeval *now, int interval, FILE* logfp)
{
- int i = 0;
- int per_line = 0;
- int index = 0;
+ int i = 0;
struct ios_stat_head *list_head = NULL;
struct ios_conf *conf = NULL;
- char timestr[256] = {0, };
- char str_header[128] = {0};
- char str_read[128] = {0};
- char str_write[128] = {0};
conf = this->private;
if (interval == -1)
- ios_log (this, logfp, "\n=== Cumulative stats ===");
+ ios_log (this, logfp, "=== Cumulative stats ===");
else
- ios_log (this, logfp, "\n=== Interval %d stats ===",
+ ios_log (this, logfp, "=== Interval %d stats ===",
interval);
- ios_log (this, logfp, " Duration : %"PRId64" secs",
+ ios_log (this, logfp, " Duration : %"PRId64"secs",
(uint64_t) (now->tv_sec - stats->started_at.tv_sec));
ios_log (this, logfp, " BytesRead : %"PRId64,
stats->data_read);
- ios_log (this, logfp, " BytesWritten : %"PRId64"\n",
+ ios_log (this, logfp, " BytesWritten : %"PRId64,
stats->data_written);
- snprintf (str_header, sizeof (str_header), "%-12s %c", "Block Size", ':');
- snprintf (str_read, sizeof (str_read), "%-12s %c", "Read Count", ':');
- snprintf (str_write, sizeof (str_write), "%-12s %c", "Write Count", ':');
- index = 14;
for (i = 0; i < 32; i++) {
- if ((stats->block_count_read[i] == 0) &&
- (stats->block_count_write[i] == 0))
- continue;
- per_line++;
-
- snprintf (str_header+index, sizeof (str_header)-index,
- "%16dB+", (1<<i));
if (stats->block_count_read[i])
- snprintf (str_read+index, sizeof (str_read)-index,
- "%18"PRId64, stats->block_count_read[i]);
- else snprintf (str_read+index, sizeof (str_read)-index,
- "%18s", "0");
- if (stats->block_count_write[i])
- snprintf (str_write+index, sizeof (str_write)-index,
- "%18"PRId64, stats->block_count_write[i]);
- else snprintf (str_write+index, sizeof (str_write)-index,
- "%18s", "0");
-
- index += 18;
- if (per_line == 3) {
- ios_log (this, logfp, "%s", str_header);
- ios_log (this, logfp, "%s", str_read);
- ios_log (this, logfp, "%s\n", str_write);
-
- memset (str_header, 0, sizeof (str_header));
- memset (str_read, 0, sizeof (str_read));
- memset (str_write, 0, sizeof (str_write));
-
- snprintf (str_header, sizeof (str_header), "%-12s %c",
- "Block Size", ':');
- snprintf (str_read, sizeof (str_read), "%-12s %c",
- "Read Count", ':');
- snprintf (str_write, sizeof (str_write), "%-12s %c",
- "Write Count", ':');
-
- index = 14;
- per_line = 0;
- }
+ ios_log (this, logfp, " Read %06db+ : %"PRId64,
+ (1 << i), stats->block_count_read[i]);
}
- if (per_line != 0) {
- ios_log (this, logfp, "%s", str_header);
- ios_log (this, logfp, "%s", str_read);
- ios_log (this, logfp, "%s\n", str_write);
+ for (i = 0; i < 32; i++) {
+ if (stats->block_count_write[i])
+ ios_log (this, logfp, "Write %06db+ : %"PRId64,
+ (1 << i), stats->block_count_write[i]);
}
- ios_log (this, logfp, "%-13s %10s %14s %14s %14s", "Fop",
- "Call Count", "Avg-Latency", "Min-Latency",
- "Max-Latency");
- ios_log (this, logfp, "%-13s %10s %14s %14s %14s", "---", "----------",
- "-----------", "-----------", "-----------");
-
for (i = 0; i < GF_FOP_MAXVALUE; i++) {
if (stats->fop_hits[i] && !stats->latency[i].avg)
- ios_log (this, logfp, "%-13s %10"PRId64" %11s "
- "us %11s us %11s us", gf_fop_list[i],
- stats->fop_hits[i], "0", "0", "0");
+ ios_log (this, logfp, "%14s : %"PRId64,
+ gf_fop_list[i], stats->fop_hits[i]);
else if (stats->fop_hits[i] && stats->latency[i].avg)
- ios_log (this, logfp, "%-13s %10"PRId64" %11.2lf us "
- "%11.2lf us %11.2lf us", gf_fop_list[i],
- stats->fop_hits[i], stats->latency[i].avg,
- stats->latency[i].min, stats->latency[i].max);
+ ios_log (this, logfp, "%14s : %"PRId64 ", latency"
+ "(avg: %f, min: %f, max: %f)",
+ gf_fop_list[i], stats->fop_hits[i],
+ stats->latency[i].avg, stats->latency[i].min,
+ stats->latency[i].max);
}
- ios_log (this, logfp, "------ ----- ----- ----- ----- ----- ----- ----- "
- " ----- ----- ----- -----\n");
if (interval == -1) {
LOCK (&conf->lock);
{
- gf_time_fmt (timestr, sizeof timestr,
- conf->cumulative.max_openfd_time.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS,
- conf->cumulative.max_openfd_time.tv_usec);
- ios_log (this, logfp, "Current open fd's: %"PRId64
- " Max open fd's: %"PRId64" time %s",
- conf->cumulative.nr_opens,
- conf->cumulative.max_nr_opens, timestr);
+ ios_log (this, logfp, "Current open fd's: %"PRId64
+ " Max open fd's: %"PRId64,conf->cumulative.nr_opens,
+ conf->cumulative.max_nr_opens);
}
UNLOCK (&conf->lock);
- ios_log (this, logfp, "\n==========Open File Stats========");
- ios_log (this, logfp, "\nCOUNT: \t FILE NAME");
+ ios_log (this, logfp, "==========Open file stats========");
+ ios_log (this, logfp, "open call count:\t\t\tfile name");
list_head = &conf->list[IOS_STATS_TYPE_OPEN];
ios_dump_file_stats (list_head, this, logfp);
- ios_log (this, logfp, "\n==========Read File Stats========");
- ios_log (this, logfp, "\nCOUNT: \t FILE NAME");
+ ios_log (this, logfp, "==========Read file stats========");
+ ios_log (this, logfp, "read call count:\t\t\tfilename");
list_head = &conf->list[IOS_STATS_TYPE_READ];
ios_dump_file_stats (list_head, this, logfp);
- ios_log (this, logfp, "\n==========Write File Stats========");
- ios_log (this, logfp, "\nCOUNT: \t FILE NAME");
+ ios_log (this, logfp, "==========Write file stats========");
+ ios_log (this, logfp, "write call count:\t\t\tfilename");
list_head = &conf->list[IOS_STATS_TYPE_WRITE];
ios_dump_file_stats (list_head, this, logfp);
- ios_log (this, logfp, "\n==========Directory open stats========");
- ios_log (this, logfp, "\nCOUNT: \t DIRECTORY NAME");
+ ios_log (this, logfp, "==========Directory open stats========");
+ ios_log (this, logfp, "Opendir count:\t\t\tdirectory name");
list_head = &conf->list[IOS_STATS_TYPE_OPENDIR];
ios_dump_file_stats (list_head, this, logfp);
- ios_log (this, logfp, "\n========Directory readdirp Stats=======");
- ios_log (this, logfp, "\nCOUNT: \t DIRECTORY NAME");
+ ios_log (this, logfp, "==========Directory readdirp stats========");
+ ios_log (this, logfp, "readdirp count:\t\t\tdirectory name");
list_head = &conf->list[IOS_STATS_TYPE_READDIRP];
ios_dump_file_stats (list_head, this, logfp);
- ios_log (this, logfp, "\n========Read Throughput File Stats=====");
- ios_log (this, logfp, "\nTIMESTAMP \t\t\t THROUGHPUT(KBPS)"
- "\tFILE NAME");
+ ios_log (this, logfp, "==========Read throughput file stats========");
+ ios_log (this, logfp, "read throughput(MBps):\t\t\tfilename");
list_head = &conf->thru_list[IOS_STATS_THRU_READ];
- ios_dump_throughput_stats(list_head, this, logfp, IOS_STATS_THRU_READ);
+ ios_dump_throughput_stats(list_head, this, logfp, IOS_STATS_THRU_READ);
- ios_log (this, logfp, "\n======Write Throughput File Stats======");
- ios_log (this, logfp, "\nTIMESTAMP \t\t\t THROUGHPUT(KBPS)"
- "\tFILE NAME");
+ ios_log (this, logfp, "==========Write throughput file stats========");
+ ios_log (this, logfp, "write througput (MBps):\t\t\tfilename");
list_head = &conf->thru_list[IOS_STATS_THRU_WRITE];
- ios_dump_throughput_stats (list_head, this, logfp, IOS_STATS_THRU_WRITE);
+ ios_dump_throughput_stats (list_head, this, logfp, IOS_STATS_THRU_WRITE);
}
return 0;
}
@@ -1077,44 +1015,25 @@ io_stats_dump_stats_to_dict (xlator_t *this, dict_t *resp,
struct ios_stat_list *entry = NULL;
int ret = -1;
ios_stats_thru_t index = IOS_STATS_THRU_MAX;
- char timestr[256] = {0, };
- char *dict_timestr = NULL;
conf = this->private;
switch (flags) {
- case IOS_STATS_TYPE_OPEN:
+ case IOS_STATS_TYPE_OPEN:
list_head = &conf->list[IOS_STATS_TYPE_OPEN];
LOCK (&conf->lock);
{
ret = dict_set_uint64 (resp, "current-open",
conf->cumulative.nr_opens);
if (ret)
- goto unlock;
+ goto out;
ret = dict_set_uint64 (resp, "max-open",
- conf->cumulative.max_nr_opens);
-
- gf_time_fmt (timestr, sizeof timestr,
- conf->cumulative.max_openfd_time.tv_sec,
- gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS,
- conf->cumulative.max_openfd_time.tv_usec);
-
- dict_timestr = gf_strdup (timestr);
- if (!dict_timestr)
- goto unlock;
- ret = dict_set_dynstr (resp, "max-openfd-time",
- dict_timestr);
+ conf->cumulative.max_nr_opens);
if (ret)
- goto unlock;
+ goto out;
}
- unlock:
UNLOCK (&conf->lock);
- /* Do not proceed if we came here because of some error
- * during the dict operation */
- if (ret)
- goto out;
+
break;
case IOS_STATS_TYPE_READ:
list_head = &conf->list[IOS_STATS_TYPE_READ];
@@ -1130,7 +1049,7 @@ io_stats_dump_stats_to_dict (xlator_t *this, dict_t *resp,
break;
case IOS_STATS_TYPE_READ_THROUGHPUT:
list_head = &conf->thru_list[IOS_STATS_THRU_READ];
- index = IOS_STATS_THRU_READ;
+ index = IOS_STATS_THRU_READ;
break;
case IOS_STATS_TYPE_WRITE_THROUGHPUT:
list_head = &conf->thru_list[IOS_STATS_THRU_WRITE];
@@ -1151,44 +1070,39 @@ io_stats_dump_stats_to_dict (xlator_t *this, dict_t *resp,
snprintf (key, 256, "%s-%d", "filename", cnt);
ret = dict_set_str (resp, key, entry->iosstat->filename);
if (ret)
- goto unlock_list_head;
+ goto out;
snprintf (key, 256, "%s-%d", "value",cnt);
ret = dict_set_uint64 (resp, key, entry->value);
if (ret)
- goto unlock_list_head;
+ goto out;
if (index != IOS_STATS_THRU_MAX) {
snprintf (key, 256, "%s-%d", "time-sec", cnt);
- ret = dict_set_int32 (resp, key,
+ ret = dict_set_int32 (resp, key,
entry->iosstat->thru_counters[index].time.tv_sec);
if (ret)
- goto unlock_list_head;
+ goto out;
snprintf (key, 256, "%s-%d", "time-usec", cnt);
- ret = dict_set_int32 (resp, key,
+ ret = dict_set_int32 (resp, key,
entry->iosstat->thru_counters[index].time.tv_usec);
if (ret)
- goto unlock_list_head;
+ goto out;
}
if (cnt == list_cnt)
break;
}
}
-unlock_list_head:
UNLOCK (&list_head->lock);
- /* ret is !=0 if some dict operation in the above critical region
- * failed. */
- if (ret)
- goto out;
+
ret = dict_set_int32 (resp, "members", cnt);
out:
return ret;
}
-
int
io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
struct ios_fd *iosfd = NULL;
char *path = NULL;
@@ -1221,10 +1135,8 @@ io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
LOCK (&conf->lock);
{
conf->cumulative.nr_opens++;
- if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens) {
+ if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens)
conf->cumulative.max_nr_opens = conf->cumulative.nr_opens;
- conf->cumulative.max_openfd_time = iosfd->opened_at;
- }
}
UNLOCK (&conf->lock);
@@ -1241,21 +1153,21 @@ io_stats_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
UPDATE_PROFILE_STATS (frame, CREATE);
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct ios_fd *iosfd = NULL;
char *path = NULL;
struct ios_stat *iosstat = NULL;
struct ios_conf *conf = NULL;
- conf = this->private;
+ conf = this->private;
path = frame->local;
frame->local = NULL;
@@ -1279,26 +1191,15 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ios_fd_ctx_set (fd, this, iosfd);
ios_inode_ctx_get (fd->inode, this, &iosstat);
- if (!iosstat) {
- iosstat = GF_CALLOC (1, sizeof (*iosstat),
- gf_io_stats_mt_ios_stat);
- if (iosstat) {
- iosstat->filename = gf_strdup (path);
- uuid_copy (iosstat->gfid, fd->inode->gfid);
- LOCK_INIT (&iosstat->lock);
- ios_inode_ctx_set (fd->inode, this, iosstat);
- }
- }
LOCK (&conf->lock);
{
conf->cumulative.nr_opens++;
- if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens) {
+ if (conf->cumulative.nr_opens > conf->cumulative.max_nr_opens)
conf->cumulative.max_nr_opens = conf->cumulative.nr_opens;
- conf->cumulative.max_openfd_time = iosfd->opened_at;
- }
}
UNLOCK (&conf->lock);
+
if (iosstat) {
BUMP_STATS (iosstat, IOS_STATS_TYPE_OPEN);
iosstat = NULL;
@@ -1306,7 +1207,7 @@ io_stats_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
UPDATE_PROFILE_STATS (frame, OPEN);
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
@@ -1314,10 +1215,10 @@ unwind:
int
io_stats_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
UPDATE_PROFILE_STATS (frame, STAT);
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
return 0;
}
@@ -1326,7 +1227,7 @@ int
io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count,
- struct iatt *buf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *buf, struct iobref *iobref)
{
int len = 0;
fd_t *fd = NULL;
@@ -1350,7 +1251,7 @@ io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, buf, iobref, xdata);
+ vector, count, buf, iobref);
return 0;
}
@@ -1359,7 +1260,7 @@ io_stats_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
struct ios_stat *iosstat = NULL;
inode_t *inode = NULL;
@@ -1371,13 +1272,13 @@ io_stats_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ios_inode_ctx_get (inode, this, &iosstat);
if (iosstat) {
BUMP_STATS (iosstat, IOS_STATS_TYPE_WRITE);
- BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_WRITE);
+ BUMP_THROUGHPUT (iosstat, IOS_STATS_THRU_WRITE);
inode = NULL;
iosstat = NULL;
}
}
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -1387,7 +1288,7 @@ io_stats_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *buf)
{
struct ios_stat *iosstat = NULL;
inode_t *inode = frame->local;
@@ -1403,17 +1304,17 @@ io_stats_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
iosstat = NULL;
}
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf);
return 0;
}
int
io_stats_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *buf)
{
UPDATE_PROFILE_STATS (frame, READDIR);
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf);
return 0;
}
@@ -1421,10 +1322,10 @@ io_stats_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
UPDATE_PROFILE_STATS (frame, FSYNC);
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -1432,10 +1333,10 @@ io_stats_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
UPDATE_PROFILE_STATS (frame, SETATTR);
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop, xdata);
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop);
return 0;
}
@@ -1443,11 +1344,11 @@ io_stats_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, UNLINK);
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1457,12 +1358,12 @@ int
io_stats_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
UPDATE_PROFILE_STATS (frame, RENAME);
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf,
preoldparent, postoldparent,
- prenewparent, postnewparent, xdata);
+ prenewparent, postnewparent);
return 0;
}
@@ -1470,10 +1371,10 @@ io_stats_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *buf,
- struct iatt *sbuf, dict_t *xdata)
+ struct iatt *sbuf)
{
UPDATE_PROFILE_STATS (frame, READLINK);
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, sbuf, xdata);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, sbuf);
return 0;
}
@@ -1482,10 +1383,10 @@ int
io_stats_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
+ dict_t *xattr, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, LOOKUP);
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xdata,
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xattr,
postparent);
return 0;
}
@@ -1495,11 +1396,11 @@ int
io_stats_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, SYMLINK);
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1508,11 +1409,11 @@ int
io_stats_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, MKNOD);
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1521,8 +1422,7 @@ int
io_stats_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
struct ios_stat *iosstat = NULL;
char *path = frame->local;
@@ -1540,11 +1440,8 @@ io_stats_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
unwind:
- /* local is assigned with path */
- GF_FREE (frame->local);
- frame->local = NULL;
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1553,28 +1450,28 @@ int
io_stats_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, LINK);
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
io_stats_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, FLUSH);
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
int
io_stats_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct ios_stat *iosstat = NULL;
int ret = -1;
@@ -1590,7 +1487,7 @@ io_stats_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
BUMP_STATS (iosstat, IOS_STATS_TYPE_OPENDIR);
unwind:
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
return 0;
}
@@ -1598,13 +1495,13 @@ unwind:
int
io_stats_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
UPDATE_PROFILE_STATS (frame, RMDIR);
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1612,100 +1509,71 @@ io_stats_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
UPDATE_PROFILE_STATS (frame, TRUNCATE);
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ prebuf, postbuf);
return 0;
}
int
io_stats_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
UPDATE_PROFILE_STATS (frame, STATFS);
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
return 0;
}
int
io_stats_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, SETXATTR);
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
int
io_stats_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
UPDATE_PROFILE_STATS (frame, GETXATTR);
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
io_stats_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, REMOVEXATTR);
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-io_stats_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- UPDATE_PROFILE_STATS (frame, FSETXATTR);
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-io_stats_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- UPDATE_PROFILE_STATS (frame, FGETXATTR);
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-}
-
-
-int
-io_stats_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- UPDATE_PROFILE_STATS (frame, FREMOVEXATTR);
- STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
return 0;
}
int
io_stats_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, FSYNCDIR);
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
return 0;
}
int
io_stats_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, ACCESS);
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
return 0;
}
@@ -1713,92 +1581,92 @@ io_stats_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
io_stats_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
UPDATE_PROFILE_STATS (frame, FTRUNCATE);
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ prebuf, postbuf);
return 0;
}
int
io_stats_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
UPDATE_PROFILE_STATS (frame, FSTAT);
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int
io_stats_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
UPDATE_PROFILE_STATS (frame, LK);
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
return 0;
}
int
io_stats_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, ENTRYLK);
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
return 0;
}
int
io_stats_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
UPDATE_PROFILE_STATS (frame, XATTROP);
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
return 0;
}
int
io_stats_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
UPDATE_PROFILE_STATS (frame, FXATTROP);
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
return 0;
}
int
io_stats_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, INODELK);
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
return 0;
}
int
io_stats_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_entrylk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
+ volume, loc, basename, cmd, type);
return 0;
}
int
io_stats_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock)
{
START_FOP_LATENCY (frame);
@@ -1806,122 +1674,128 @@ io_stats_inodelk (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_inodelk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->inodelk,
- volume, loc, cmd, flock, xdata);
+ volume, loc, cmd, flock);
return 0;
}
int
io_stats_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
UPDATE_PROFILE_STATS (frame, FINODELK);
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
return 0;
}
int
-io_stats_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+io_stats_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_finodelk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->finodelk,
- volume, fd, cmd, flock, xdata);
+ volume, fd, cmd, flock);
return 0;
}
int
-io_stats_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+io_stats_xattrop (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_xattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
- loc, flags, dict, xdata);
+ loc, flags, dict);
+
return 0;
}
int
-io_stats_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+io_stats_fxattrop (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_fxattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fxattrop,
- fd, flags, dict, xdata);
+ fd, flags, dict);
+
return 0;
}
int
io_stats_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc, dict_t *xattr_req)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xdata);
+ loc, xattr_req);
+
return 0;
}
int
-io_stats_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+io_stats_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_stat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->stat,
- loc, xdata);
+ loc);
+
return 0;
}
int
io_stats_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
+ loc_t *loc, size_t size)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_readlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
- loc, size, xdata);
+ loc, size);
+
return 0;
}
int
-io_stats_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t dev, mode_t umask, dict_t *xdata)
+io_stats_mknod (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dev_t dev, dict_t *params)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, dev, umask, xdata);
+ loc, mode, dev, params);
+
return 0;
}
int
io_stats_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dict_t *params)
{
frame->local = gf_strdup (loc->path);
@@ -1930,112 +1804,117 @@ io_stats_mkdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
+ loc, mode, params);
return 0;
}
int
io_stats_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
+ loc_t *loc)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
+ loc);
return 0;
}
int
io_stats_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
+ loc_t *loc, int flags)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
+ loc, flags);
+
return 0;
}
int
-io_stats_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+io_stats_symlink (call_frame_t *frame, xlator_t *this,
+ const char *linkpath, loc_t *loc, dict_t *params)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
+ linkpath, loc, params);
+
return 0;
}
int
io_stats_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_rename_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
+ oldloc, newloc);
+
return 0;
}
int
io_stats_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+ loc_t *oldloc, loc_t *newloc)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_link_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
+ oldloc, newloc);
return 0;
}
int
io_stats_setattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ loc_t *loc, struct iatt *stbuf, int32_t valid)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setattr,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
+
return 0;
}
int
io_stats_truncate (call_frame_t *frame, xlator_t *this,
- loc_t *loc, off_t offset, dict_t *xdata)
+ loc_t *loc, off_t offset)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_truncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
+ loc, offset);
+
return 0;
}
int
-io_stats_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+io_stats_open (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, int32_t flags, fd_t *fd, int32_t wbflags)
{
frame->local = gf_strdup (loc->path);
@@ -2044,7 +1923,7 @@ io_stats_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, io_stats_open_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
+ loc, flags, fd, wbflags);
return 0;
}
@@ -2052,7 +1931,7 @@ io_stats_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
io_stats_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata)
+ fd_t *fd, dict_t *params)
{
frame->local = gf_strdup (loc->path);
@@ -2061,14 +1940,14 @@ io_stats_create (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
}
int
io_stats_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ fd_t *fd, size_t size, off_t offset)
{
frame->local = fd;
@@ -2077,7 +1956,7 @@ io_stats_readv (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_readv_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
@@ -2086,7 +1965,7 @@ int
io_stats_writev (call_frame_t *frame, xlator_t *this,
fd_t *fd, struct iovec *vector,
int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
int len = 0;
@@ -2094,13 +1973,14 @@ io_stats_writev (call_frame_t *frame, xlator_t *this,
frame->local = fd->inode;
len = iov_length (vector, count);
+
BUMP_WRITE (fd, len);
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
}
@@ -2108,42 +1988,42 @@ io_stats_writev (call_frame_t *frame, xlator_t *this,
int
io_stats_statfs (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_statfs_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
+ loc);
return 0;
}
int
io_stats_flush (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
+ fd);
return 0;
}
int
io_stats_fsync (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t flags, dict_t *xdata)
+ fd_t *fd, int32_t flags)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_fsync_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
- fd, flags, xdata);
+ fd, flags);
return 0;
}
@@ -2157,12 +2037,16 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
const char *path;
} *stub;
xlator_t *this = NULL;
+ inode_t *inode = NULL;
+ const char *path = NULL;
char *filename = NULL;
FILE *logfp = NULL;
struct ios_dump_args args = {0};
stub = data;
this = stub->this;
+ inode = stub->inode;
+ path = stub->path;
filename = alloca (value->len + 1);
memset (filename, 0, value->len + 1);
@@ -2170,10 +2054,6 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
if (fnmatch ("*io*stat*dump", key, 0) == 0) {
- if (!strncmp (filename, "", 1)) {
- gf_log (this->name, GF_LOG_ERROR, "No filename given");
- return;
- }
logfp = fopen (filename, "w+");
GF_ASSERT (logfp);
if (!logfp) {
@@ -2192,7 +2072,7 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
int
io_stats_setxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
struct {
xlator_t *this;
@@ -2211,85 +2091,43 @@ io_stats_setxattr (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_setxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
+ loc, dict, flags);
return 0;
}
int
io_stats_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_getxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
+ loc, name);
return 0;
}
int
io_stats_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_removexattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-}
-
+ loc, name);
-int
-io_stats_fsetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- START_FOP_LATENCY (frame);
-
- STACK_WIND (frame, io_stats_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
-}
-
-
-int
-io_stats_fgetxattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- START_FOP_LATENCY (frame);
-
- STACK_WIND (frame, io_stats_fgetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
- return 0;
-}
-
-
-int
-io_stats_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- START_FOP_LATENCY (frame);
-
- STACK_WIND (frame, io_stats_fremovexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
return 0;
}
int
io_stats_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+ loc_t *loc, fd_t *fd)
{
START_FOP_LATENCY (frame);
@@ -2297,13 +2135,13 @@ io_stats_opendir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, io_stats_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
+ loc, fd);
return 0;
}
int
io_stats_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
+ off_t offset)
{
frame->local = fd->inode;
START_FOP_LATENCY (frame);
@@ -2311,105 +2149,108 @@ io_stats_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
STACK_WIND (frame, io_stats_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
+ fd, size, offset);
+
return 0;
}
int
io_stats_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, dict_t *xdata)
+ fd_t *fd, size_t size, off_t offset)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, offset, xdata);
+ fd, size, offset);
+
return 0;
}
int
io_stats_fsyncdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t datasync, dict_t *xdata)
+ fd_t *fd, int32_t datasync)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_fsyncdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsyncdir,
- fd, datasync, xdata);
+ fd, datasync);
return 0;
}
int
io_stats_access (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t mask, dict_t *xdata)
+ loc_t *loc, int32_t mask)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_access_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->access,
- loc, mask, xdata);
+ loc, mask);
return 0;
}
int
io_stats_ftruncate (call_frame_t *frame, xlator_t *this,
- fd_t *fd, off_t offset, dict_t *xdata)
+ fd_t *fd, off_t offset)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_ftruncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
- fd, offset, xdata);
+ fd, offset);
+
return 0;
}
int
io_stats_fsetattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ fd_t *fd, struct iatt *stbuf, int32_t valid)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
return 0;
}
int
io_stats_fstat (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
+ fd);
return 0;
}
int
io_stats_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *lock)
{
START_FOP_LATENCY (frame);
STACK_WIND (frame, io_stats_lk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lk,
- fd, cmd, lock, xdata);
+ fd, cmd, lock);
return 0;
}
@@ -2426,7 +2267,7 @@ io_stats_release (xlator_t *this, fd_t *fd)
LOCK (&conf->lock);
{
- conf->cumulative.nr_opens--;
+ conf->cumulative.nr_opens--;
}
UNLOCK (&conf->lock);
@@ -2434,7 +2275,8 @@ io_stats_release (xlator_t *this, fd_t *fd)
if (iosfd) {
io_stats_dump_fd (this, iosfd);
- GF_FREE (iosfd->filename);
+ if (iosfd->filename)
+ GF_FREE (iosfd->filename);
GF_FREE (iosfd);
}
@@ -2459,137 +2301,86 @@ io_stats_forget (xlator_t *this, inode_t *inode)
return 0;
}
-static int
-ios_init_top_stats (struct ios_conf *conf)
+int
+iostats_configure_options (xlator_t *this, dict_t *options,
+ struct ios_conf *conf)
{
- int i = 0;
+ int ret = 0;
+ char *log_str = NULL;
+ GF_ASSERT (this);
+ GF_ASSERT (options);
GF_ASSERT (conf);
- for (i = 0; i <IOS_STATS_TYPE_MAX; i++) {
- conf->list[i].iosstats = GF_CALLOC (1,
- sizeof(*conf->list[i].iosstats),
- gf_io_stats_mt_ios_stat);
-
- if (!conf->list[i].iosstats)
- return -1;
-
- INIT_LIST_HEAD(&conf->list[i].iosstats->list);
- LOCK_INIT (&conf->list[i].lock);
+ ret = dict_get_str_boolean (options, "dump-fd-stats", _gf_false);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'dump-fd-stats' takes only boolean arguments");
+ } else {
+ conf->dump_fd_stats = ret;
+ if (conf->dump_fd_stats)
+ gf_log (this->name, GF_LOG_DEBUG, "enabling dump-fd-stats");
+ else
+ gf_log (this->name, GF_LOG_DEBUG, "disabling dump-fd-stats");
}
- for (i = 0; i < IOS_STATS_THRU_MAX; i ++) {
- conf->thru_list[i].iosstats = GF_CALLOC (1,
- sizeof (*conf->thru_list[i].iosstats),
- gf_io_stats_mt_ios_stat);
-
- if (!conf->thru_list[i].iosstats)
- return -1;
-
- INIT_LIST_HEAD(&conf->thru_list[i].iosstats->list);
- LOCK_INIT (&conf->thru_list[i].lock);
+ ret = dict_get_str_boolean (options, "count-fop-hits", _gf_false);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'count-fop-hits' takes only boolean arguments");
+ } else {
+ conf->count_fop_hits = ret;
+ if (conf->count_fop_hits)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "enabling count-fop-hits");
+ else
+ gf_log (this->name, GF_LOG_DEBUG,
+ "disabling count-fop-hits");
}
- return 0;
-}
-
-static void
-ios_destroy_top_stats (struct ios_conf *conf)
-{
- int i = 0;
- struct ios_stat_head *list_head = NULL;
- struct ios_stat_list *entry = NULL;
- struct ios_stat_list *tmp = NULL;
- struct ios_stat_list *list = NULL;
- struct ios_stat *stat = NULL;
-
- GF_ASSERT (conf);
-
- LOCK (&conf->lock);
-
- conf->cumulative.nr_opens = 0;
- conf->cumulative.max_nr_opens = 0;
- conf->cumulative.max_openfd_time.tv_sec = 0;
- conf->cumulative.max_openfd_time.tv_usec = 0;
-
- for (i = 0; i < IOS_STATS_TYPE_MAX; i++) {
- list_head = &conf->list[i];
- if (!list_head)
- continue;
- list_for_each_entry_safe (entry, tmp,
- &list_head->iosstats->list, list) {
- list = entry;
- stat = list->iosstat;
- ios_stat_unref (stat);
- list_del (&list->list);
- GF_FREE (list);
- list_head->members--;
+ ret = dict_get_str_boolean (options, "latency-measurement", 0);
+ if (ret != -1) {
+ if (conf->measure_latency != ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "changing latency measurement from %d to %d",
+ conf->measure_latency, ret);
}
+ conf->measure_latency = ret;
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'latency-measurement' takes only boolean arguments");
}
- for (i = 0; i < IOS_STATS_THRU_MAX; i++) {
- list_head = &conf->thru_list[i];
- if (!list_head)
- continue;
- list_for_each_entry_safe (entry, tmp,
- &list_head->iosstats->list, list) {
- list = entry;
- stat = list->iosstat;
- ios_stat_unref (stat);
- list_del (&list->list);
- GF_FREE (list);
- list_head->members--;
+ ret = dict_get_str (options, "log-level", &log_str);
+ if (!ret) {
+ if (!is_gf_log_command(this, "trusted.glusterfs.set-log-level",
+ log_str)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "changing log-level to %s", log_str);
}
}
-
- UNLOCK (&conf->lock);
-
- return;
+ return 0;
}
int
reconfigure (xlator_t *this, dict_t *options)
{
struct ios_conf *conf = NULL;
- int ret = -1;
- char *sys_log_str = NULL;
- int sys_log_level = -1;
- char *log_str = NULL;
- int log_level = -1;
+ glusterfs_ctx_t *ctx = NULL;
if (!this || !this->private)
- goto out;
+ return -1;
conf = this->private;
- GF_OPTION_RECONF ("dump-fd-stats", conf->dump_fd_stats, options, bool,
- out);
-
- GF_OPTION_RECONF ("count-fop-hits", conf->count_fop_hits, options, bool,
- out);
-
- GF_OPTION_RECONF ("latency-measurement", conf->measure_latency,
- options, bool, out);
-
- GF_OPTION_RECONF ("sys-log-level", sys_log_str, options, str, out);
- if (sys_log_str) {
- sys_log_level = glusterd_check_log_level (sys_log_str);
- set_sys_log_level (sys_log_level);
- }
-
- GF_OPTION_RECONF ("log-level", log_str, options, str, out);
- if (log_str) {
- log_level = glusterd_check_log_level (log_str);
- gf_log_set_loglevel (log_level);
- }
+ iostats_configure_options (this, options, conf);
+ ctx = glusterfs_ctx_get ();
+ if (!ctx)
+ return -1;
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_DEBUG, "reconfigure returning %d", ret);
- return ret;
+ return 0;
}
-
int32_t
mem_acct_init (xlator_t *this)
{
@@ -2612,19 +2403,16 @@ mem_acct_init (xlator_t *this)
int
init (xlator_t *this)
{
+ dict_t *options = NULL;
struct ios_conf *conf = NULL;
- char *sys_log_str = NULL;
- int sys_log_level = -1;
- char *log_str = NULL;
- int log_level = -1;
- int ret = -1;
+ int i = 0;
if (!this)
return -1;
- if (!this->children) {
+ if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
- "io_stats translator requires atleast one subvolume");
+ "io_stats translator requires one subvolume");
return -1;
}
@@ -2636,6 +2424,8 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
+ options = this->options;
+
conf = GF_CALLOC (1, sizeof(*conf), gf_io_stats_mt_ios_conf);
if (!conf) {
@@ -2649,33 +2439,40 @@ init (xlator_t *this)
gettimeofday (&conf->cumulative.started_at, NULL);
gettimeofday (&conf->incremental.started_at, NULL);
- ret = ios_init_top_stats (conf);
- if (ret)
- return -1;
+ for (i = 0; i <IOS_STATS_TYPE_MAX; i++) {
+ conf->list[i].iosstats = GF_CALLOC (1,
+ sizeof(*conf->list[i].iosstats),
+ gf_io_stats_mt_ios_stat);
- GF_OPTION_INIT ("dump-fd-stats", conf->dump_fd_stats, bool, out);
+ if (!conf->list[i].iosstats) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return -1;
+ }
- GF_OPTION_INIT ("count-fop-hits", conf->count_fop_hits, bool, out);
+ INIT_LIST_HEAD(&conf->list[i].iosstats->list);
+ LOCK_INIT (&conf->list[i].lock);
+ }
- GF_OPTION_INIT ("latency-measurement", conf->measure_latency,
- bool, out);
+ for (i = 0; i < IOS_STATS_THRU_MAX; i ++) {
+ conf->thru_list[i].iosstats = GF_CALLOC (1,
+ sizeof (*conf->thru_list[i].iosstats),
+ gf_io_stats_mt_ios_stat);
- GF_OPTION_INIT ("sys-log-level", sys_log_str, str, out);
- if (sys_log_str) {
- sys_log_level = glusterd_check_log_level (sys_log_str);
- set_sys_log_level (sys_log_level);
- }
+ if (!conf->thru_list[i].iosstats) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Out of memory");
+ return -1;
+ }
- GF_OPTION_INIT ("log-level", log_str, str, out);
- if (log_str) {
- log_level = glusterd_check_log_level (log_str);
- gf_log_set_loglevel (log_level);
+ INIT_LIST_HEAD(&conf->thru_list[i].iosstats->list);
+ LOCK_INIT (&conf->thru_list[i].lock);
}
+ iostats_configure_options (this, options, conf);
this->private = conf;
- ret = 0;
-out:
- return ret;
+
+ return 0;
}
@@ -2693,8 +2490,6 @@ fini (xlator_t *this)
return;
this->private = NULL;
- ios_destroy_top_stats (conf);
-
GF_FREE(conf);
gf_log (this->name, GF_LOG_INFO,
@@ -2703,6 +2498,34 @@ fini (xlator_t *this)
}
int
+validate_options (xlator_t *this, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
+
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
+
+out:
+
+ return ret;
+}
+int
notify (xlator_t *this, int32_t event, void *data, ...)
{
int ret = 0;
@@ -2721,28 +2544,6 @@ notify (xlator_t *this, int32_t event, void *data, ...)
va_end (ap);
switch (event) {
case GF_EVENT_TRANSLATOR_INFO:
- ret = dict_get_str_boolean (dict, "clear-stats", _gf_false);
- if (ret) {
- ret = dict_set_int32 (output, "top-op", top_op);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set top-op in dict");
- goto out;
- }
- ios_destroy_top_stats (this->private);
- ret = ios_init_top_stats (this->private);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to reset top stats");
- ret = dict_set_int32 (output, "stats-cleared",
- ret ? 0 : 1);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to set stats-cleared"
- " in dict");
- goto out;
- }
-
ret = dict_get_int32 (dict, "top-op", &top_op);
if (!ret) {
ret = dict_get_int32 (dict, "list-cnt", &list_cnt);
@@ -2806,9 +2607,6 @@ struct xlator_fops fops = {
.setxattr = io_stats_setxattr,
.getxattr = io_stats_getxattr,
.removexattr = io_stats_removexattr,
- .fsetxattr = io_stats_fsetxattr,
- .fgetxattr = io_stats_fgetxattr,
- .fremovexattr = io_stats_fremovexattr,
.opendir = io_stats_opendir,
.readdir = io_stats_readdir,
.readdirp = io_stats_readdirp,
@@ -2837,47 +2635,16 @@ struct xlator_cbks cbks = {
struct volume_options options[] = {
{ .key = {"dump-fd-stats"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "If on stats related to file-operations would be "
- "tracked inside GlusterFS data-structures."
},
{ .key = { "latency-measurement" },
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "If on stats related to the latency of each operation "
- "would be tracked inside GlusterFS data-structures. "
},
{ .key = {"count-fop-hits"},
.type = GF_OPTION_TYPE_BOOL,
},
{ .key = {"log-level"},
.type = GF_OPTION_TYPE_STR,
- .value = { "DEBUG", "WARNING", "ERROR", "INFO",
- "CRITICAL", "NONE", "TRACE"}
- },
-
- /* These are synthetic entries to assist validation of CLI's *
- * volume set command */
- { .key = {"client-log-level"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "INFO",
- .description = "Changes the log-level of the clients",
- .value = { "DEBUG", "WARNING", "ERROR", "INFO",
- "CRITICAL", "NONE", "TRACE"}
- },
- { .key = {"sys-log-level"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "CRITICAL",
- .description = "Gluster's syslog log-level",
- .value = { "WARNING", "ERROR", "CRITICAL"}
+ .value = { "DEBUG", "WARNING", "ERROR", "CRITICAL", "NONE", "TRACE"}
},
- { .key = {"brick-log-level"},
- .type = GF_OPTION_TYPE_STR,
- .default_value = "INFO",
- .description = "Changes the log-level of the bricks",
- .value = { "DEBUG", "WARNING", "ERROR", "INFO",
- "CRITICAL", "NONE", "TRACE"}
- },
- { .key = {NULL} },
-
+ { .key = {NULL} },
};
diff --git a/xlators/debug/trace/src/trace.c b/xlators/debug/trace/src/trace.c
index 97f61ca59..9541a64ab 100644
--- a/xlators/debug/trace/src/trace.c
+++ b/xlators/debug/trace/src/trace.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -46,20 +46,30 @@ int trace_log_level = GF_LOG_INFO;
static char *
trace_stat_to_str (struct iatt *buf)
{
- char *statstr = NULL;
- char atime_buf[64] = {0,};
- char mtime_buf[64] = {0,};
- char ctime_buf[64] = {0,};
- int asprint_ret_value = 0;
+ char *statstr = NULL;
+ char atime_buf[256] = {0,};
+ char mtime_buf[256] = {0,};
+ char ctime_buf[256] = {0,};
+ int asprint_ret_value = 0;
+ uint64_t ia_time = 0;
if (!buf) {
statstr = NULL;
goto out;
}
- gf_time_fmt (atime_buf, sizeof atime_buf, buf->ia_atime, gf_timefmt_bdT);
- gf_time_fmt (mtime_buf, sizeof mtime_buf, buf->ia_mtime, gf_timefmt_bdT);
- gf_time_fmt (ctime_buf, sizeof ctime_buf, buf->ia_ctime, gf_timefmt_bdT);
+ ia_time = buf->ia_atime;
+ strftime (atime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
+
+ ia_time = buf->ia_mtime;
+ strftime (mtime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
+
+ ia_time = buf->ia_ctime;
+ strftime (ctime_buf, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
+
asprint_ret_value = gf_asprintf (&statstr,
"gfid=%s ino=%"PRIu64", mode=%o, "
"nlink=%"GF_PRI_NLINK", uid=%u, "
@@ -86,7 +96,7 @@ int
trace_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *statstr = NULL;
char *preparentstr = NULL;
@@ -105,9 +115,12 @@ trace_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
uuid_utoa (inode->gfid), op_ret, fd,
statstr, preparentstr, postparentstr);
- GF_FREE (statstr);
- GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (statstr)
+ GF_FREE (statstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
/* for 'release' log */
fd_ctx_set (fd, this, 0);
@@ -120,14 +133,14 @@ trace_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
trace_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
if (trace_fop_names[GF_FOP_OPEN].enabled) {
@@ -141,14 +154,14 @@ trace_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx_set (fd, this, 0);
frame->local = NULL;
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
int
trace_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
char *statstr = NULL;
if (trace_fop_names[GF_FOP_STAT].enabled) {
@@ -159,7 +172,8 @@ trace_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local),
op_ret, statstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
@@ -168,7 +182,7 @@ trace_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
return 0;
}
@@ -176,7 +190,7 @@ trace_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *buf, struct iobref *iobref, dict_t *xdata)
+ int32_t count, struct iatt *buf, struct iobref *iobref)
{
char *statstr = NULL;
@@ -188,7 +202,8 @@ trace_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local),
op_ret, statstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
@@ -199,7 +214,7 @@ trace_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- buf, iobref, xdata);
+ buf, iobref);
return 0;
}
@@ -207,7 +222,7 @@ trace_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
char *preopstr = NULL;
char *postopstr = NULL;
@@ -223,9 +238,11 @@ trace_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
preopstr, postopstr);
- GF_FREE (preopstr);
+ if (preopstr)
+ GF_FREE (preopstr);
- GF_FREE (postopstr);
+ if (postopstr)
+ GF_FREE (postopstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -235,7 +252,7 @@ trace_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -243,7 +260,7 @@ trace_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *buf)
{
if (trace_fop_names[GF_FOP_READDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -252,7 +269,7 @@ trace_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, buf);
return 0;
}
@@ -260,7 +277,7 @@ trace_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *buf)
{
if (trace_fop_names[GF_FOP_READDIRP].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -269,7 +286,7 @@ trace_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, buf);
return 0;
}
@@ -278,7 +295,7 @@ trace_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
char *preopstr = NULL;
char *postopstr = NULL;
@@ -294,9 +311,11 @@ trace_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
preopstr, postopstr);
- GF_FREE (preopstr);
+ if (preopstr)
+ GF_FREE (preopstr);
- GF_FREE (postopstr);
+ if (postopstr)
+ GF_FREE (postopstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -306,7 +325,7 @@ trace_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -315,7 +334,7 @@ trace_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpre, struct iatt *statpost)
{
char *preopstr = NULL;
char *postopstr = NULL;
@@ -331,9 +350,11 @@ trace_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
preopstr, postopstr);
- GF_FREE (preopstr);
+ if (preopstr)
+ GF_FREE (preopstr);
- GF_FREE (postopstr);
+ if (postopstr)
+ GF_FREE (postopstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
@@ -342,7 +363,7 @@ trace_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost, xdata);
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost);
return 0;
}
@@ -350,7 +371,7 @@ trace_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpre, struct iatt *statpost)
{
char *preopstr = NULL;
char *postopstr = NULL;
@@ -366,9 +387,11 @@ trace_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
preopstr, postopstr);
- GF_FREE (preopstr);
+ if (preopstr)
+ GF_FREE (preopstr);
- GF_FREE (postopstr);
+ if (postopstr)
+ GF_FREE (postopstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
@@ -378,7 +401,7 @@ trace_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno,
- statpre, statpost, xdata);
+ statpre, statpost);
return 0;
}
@@ -386,7 +409,7 @@ trace_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *preparentstr = NULL;
char *postparentstr = NULL;
@@ -402,9 +425,11 @@ trace_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local), op_ret, preparentstr,
postparentstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d)",
@@ -414,7 +439,7 @@ trace_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -423,7 +448,7 @@ int
trace_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent, dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
char *statstr = NULL;
char *preoldparentstr = NULL;
@@ -448,15 +473,17 @@ trace_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
preoldparentstr, postoldparentstr,
prenewparentstr, postnewparentstr);
- GF_FREE (statstr);
-
- GF_FREE (preoldparentstr);
+ if (preoldparentstr)
+ GF_FREE (preoldparentstr);
- GF_FREE (postoldparentstr);
+ if (postoldparentstr)
+ GF_FREE (postoldparentstr);
- GF_FREE (prenewparentstr);
+ if (prenewparentstr)
+ GF_FREE (prenewparentstr);
- GF_FREE (postnewparentstr);
+ if (postnewparentstr)
+ GF_FREE (postnewparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -468,7 +495,7 @@ trace_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf,
preoldparent, postoldparent,
- prenewparent, postnewparent, xdata);
+ prenewparent, postnewparent);
return 0;
}
@@ -476,7 +503,7 @@ trace_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- const char *buf, struct iatt *stbuf, dict_t *xdata)
+ const char *buf, struct iatt *stbuf)
{
char *statstr = NULL;
@@ -495,11 +522,12 @@ trace_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local),
op_ret, op_errno);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
}
frame->local = NULL;
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, stbuf, xdata);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, buf, stbuf);
return 0;
}
@@ -508,7 +536,7 @@ int
trace_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
+ dict_t *xattr, struct iatt *postparent)
{
char *statstr = NULL;
char *postparentstr = NULL;
@@ -524,8 +552,10 @@ trace_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (inode->gfid),
op_ret, statstr, postparentstr);
- GF_FREE (statstr);
- GF_FREE (postparentstr);
+ if (statstr)
+ GF_FREE (statstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
/* For 'forget' */
inode_ctx_put (inode, this, 0);
@@ -539,7 +569,7 @@ trace_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
+ xattr, postparent);
return 0;
}
@@ -548,7 +578,7 @@ int
trace_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *statstr = NULL;
char *preparentstr = NULL;
@@ -567,11 +597,14 @@ trace_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (inode->gfid),
op_ret, statstr, preparentstr, postparentstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
@@ -582,7 +615,7 @@ trace_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -591,7 +624,7 @@ int
trace_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *statstr = NULL;
char *preparentstr = NULL;
@@ -610,11 +643,14 @@ trace_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (inode->gfid),
op_ret, statstr, preparentstr, postparentstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": (op_ret=%d, op_errno=%d)",
@@ -624,7 +660,7 @@ trace_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -633,7 +669,7 @@ int
trace_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *statstr = NULL;
char *preparentstr = NULL;
@@ -652,11 +688,14 @@ trace_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (inode->gfid),
op_ret, statstr, preparentstr, postparentstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": (op_ret=%d, op_errno=%d)",
@@ -666,7 +705,7 @@ trace_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -675,7 +714,7 @@ int
trace_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *statstr = NULL;
char *preparentstr = NULL;
@@ -693,11 +732,14 @@ trace_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
statstr, preparentstr, postparentstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -708,14 +750,14 @@ trace_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
trace_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_FLUSH].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -725,14 +767,14 @@ trace_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
int
trace_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
if (trace_fop_names[GF_FOP_OPENDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -746,7 +788,7 @@ trace_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_ctx_set (fd, this, 0);
frame->local = NULL;
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
return 0;
}
@@ -754,7 +796,7 @@ trace_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
char *preparentstr = NULL;
char *postparentstr = NULL;
@@ -770,9 +812,11 @@ trace_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local),
op_ret, preparentstr, postparentstr);
- GF_FREE (preparentstr);
+ if (preparentstr)
+ GF_FREE (preparentstr);
- GF_FREE (postparentstr);
+ if (postparentstr)
+ GF_FREE (postparentstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -783,7 +827,7 @@ trace_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -791,7 +835,7 @@ trace_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
char *preopstr = NULL;
char *postopstr = NULL;
@@ -807,9 +851,11 @@ trace_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret, preopstr,
postopstr);
- GF_FREE (preopstr);
+ if (preopstr)
+ GF_FREE (preopstr);
- GF_FREE (postopstr);
+ if (postopstr)
+ GF_FREE (postopstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -819,14 +865,14 @@ trace_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
trace_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
if (trace_fop_names[GF_FOP_STATFS].enabled) {
if (op_ret >= 0) {
@@ -846,14 +892,14 @@ trace_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
return 0;
}
int
trace_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_SETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -863,14 +909,14 @@ trace_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
int
trace_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
if (trace_fop_names[GF_FOP_GETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -880,14 +926,14 @@ trace_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
trace_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_FSETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -897,14 +943,14 @@ trace_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
return 0;
}
int
trace_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
if (trace_fop_names[GF_FOP_FGETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -914,14 +960,14 @@ trace_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
trace_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -931,7 +977,7 @@ trace_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
return 0;
}
@@ -939,7 +985,7 @@ trace_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -949,14 +995,14 @@ trace_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
return 0;
}
int
trace_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_ACCESS].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -966,7 +1012,7 @@ trace_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
return 0;
}
@@ -974,7 +1020,7 @@ trace_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *prebuf, struct iatt *postbuf)
{
char *prebufstr = NULL;
char *postbufstr = NULL;
@@ -990,9 +1036,11 @@ trace_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, op_ret,
prebufstr, postbufstr);
- GF_FREE (prebufstr);
+ if (prebufstr)
+ GF_FREE (prebufstr);
- GF_FREE (postbufstr);
+ if (postbufstr)
+ GF_FREE (postbufstr);
} else {
gf_log (this->name, GF_LOG_INFO,
@@ -1003,14 +1051,14 @@ trace_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
trace_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
char *statstr = NULL;
@@ -1022,7 +1070,8 @@ trace_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->root->unique, uuid_utoa (frame->local),
op_ret, statstr);
- GF_FREE (statstr);
+ if (statstr)
+ GF_FREE (statstr);
} else {
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s op_ret=%d, op_errno=%d",
@@ -1032,14 +1081,14 @@ trace_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int
trace_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
if (trace_fop_names[GF_FOP_LK].enabled) {
if (op_ret >= 0) {
@@ -1058,7 +1107,7 @@ trace_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
return 0;
}
@@ -1066,7 +1115,7 @@ trace_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_ENTRYLK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1076,13 +1125,13 @@ trace_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
return 0;
}
int
trace_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_FENTRYLK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1092,14 +1141,14 @@ trace_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
return 0;
}
int
trace_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
if (trace_fop_names[GF_FOP_XATTROP].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1109,14 +1158,14 @@ trace_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
return 0;
}
int
trace_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
if (trace_fop_names[GF_FOP_FXATTROP].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1126,14 +1175,14 @@ trace_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
return 0;
}
int
trace_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_INODELK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1143,13 +1192,13 @@ trace_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
return 0;
}
int
trace_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (trace_fop_names[GF_FOP_FINODELK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1158,7 +1207,7 @@ trace_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
frame->local = NULL;
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
return 0;
}
@@ -1166,7 +1215,7 @@ trace_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum, dict_t *xdata)
+ uint32_t weak_checksum, uint8_t *strong_checksum)
{
if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1176,7 +1225,7 @@ trace_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
+ strong_checksum);
return 0;
}
@@ -1186,7 +1235,7 @@ trace_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
trace_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
if (trace_fop_names[GF_FOP_ENTRYLK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1202,14 +1251,14 @@ trace_entrylk (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_entrylk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
+ volume, loc, basename, cmd, type);
return 0;
}
int
trace_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ loc_t *loc, int32_t cmd, struct gf_flock *flock)
{
char *cmd_str = NULL;
char *type_str = NULL;
@@ -1271,14 +1320,14 @@ trace_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
STACK_WIND (frame, trace_inodelk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->inodelk,
- volume, loc, cmd, flock, xdata);
+ volume, loc, cmd, flock);
return 0;
}
int
trace_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
char *cmd_str = NULL, *type_str = NULL;
@@ -1338,14 +1387,14 @@ trace_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
STACK_WIND (frame, trace_finodelk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->finodelk,
- volume, fd, cmd, flock, xdata);
+ volume, fd, cmd, flock);
return 0;
}
int
trace_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
if (trace_fop_names[GF_FOP_XATTROP].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1358,7 +1407,7 @@ trace_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, trace_xattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
- loc, flags, dict, xdata);
+ loc, flags, dict);
return 0;
}
@@ -1366,7 +1415,7 @@ trace_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
trace_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
if (trace_fop_names[GF_FOP_FXATTROP].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1379,7 +1428,7 @@ trace_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_fxattrop_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fxattrop,
- fd, flags, dict, xdata);
+ fd, flags, dict);
return 0;
}
@@ -1387,7 +1436,7 @@ trace_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
trace_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc, dict_t *xattr_req)
{
if (trace_fop_names[GF_FOP_LOOKUP].enabled) {
/* TODO: print all the keys mentioned in xattr_req */
@@ -1401,14 +1450,14 @@ trace_lookup (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xdata);
+ loc, xattr_req);
return 0;
}
int
-trace_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+trace_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
if (trace_fop_names[GF_FOP_STAT].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1421,14 +1470,14 @@ trace_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
STACK_WIND (frame, trace_stat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->stat,
- loc, xdata);
+ loc);
return 0;
}
int
-trace_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
+trace_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
{
if (trace_fop_names[GF_FOP_READLINK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1441,7 +1490,7 @@ trace_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, di
STACK_WIND (frame, trace_readlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
- loc, size, xdata);
+ loc, size);
return 0;
}
@@ -1449,20 +1498,19 @@ trace_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, di
int
trace_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t dev, mode_t umask, dict_t *xdata)
+ mode_t mode, dev_t dev, dict_t *params)
{
if (trace_fop_names[GF_FOP_MKNOD].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s path=%s mode=0%o umask=0%o "
- "dev=%"GF_PRI_DEV")",
+ "%"PRId64": gfid=%s path=%s mode=%d dev=%"GF_PRI_DEV")",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- loc->path, mode, umask, dev);
+ loc->path, mode, dev);
}
STACK_WIND (frame, trace_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, dev, umask, xdata);
+ loc, mode, dev, params);
return 0;
}
@@ -1470,46 +1518,44 @@ trace_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
trace_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
if (trace_fop_names[GF_FOP_MKDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s path=%s mode=0%o umask=0%o",
+ "%"PRId64": gfid=%s path=%s mode=%d",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- loc->path, mode, umask);
+ loc->path, mode);
}
STACK_WIND (frame, trace_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
+ loc, mode, params);
return 0;
}
int
-trace_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+trace_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
if (trace_fop_names[GF_FOP_UNLINK].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s path=%s flag=%d",
+ "%"PRId64": gfid=%s path=%s",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- loc->path, xflag);
+ loc->path);
frame->local = loc->inode->gfid;
}
STACK_WIND (frame, trace_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
+ loc);
return 0;
}
int
-trace_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+trace_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
if (trace_fop_names[GF_FOP_RMDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1522,7 +1568,7 @@ trace_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
STACK_WIND (frame, trace_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
+ loc, flags);
return 0;
}
@@ -1530,27 +1576,26 @@ trace_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
int
trace_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
if (trace_fop_names[GF_FOP_SYMLINK].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s linkpath=%s, path=%s umask=0%o",
+ "%"PRId64": gfid=%s linkpath=%s, path=%s",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- linkpath, loc->path, umask);
+ linkpath, loc->path);
}
STACK_WIND (frame, trace_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
+ linkpath, loc, params);
return 0;
}
int
-trace_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+trace_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
char oldgfid[50] = {0,};
char newgfid[50] = {0,};
@@ -1573,15 +1618,14 @@ trace_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
STACK_WIND (frame, trace_rename_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
+ oldloc, newloc);
return 0;
}
int
-trace_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+trace_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
char oldgfid[50] = {0,};
char newgfid[50] = {0,};
@@ -1604,17 +1648,18 @@ trace_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
STACK_WIND (frame, trace_link_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
+ oldloc, newloc);
return 0;
}
int
trace_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
- char actime_str[64] = {0,};
- char modtime_str[64] = {0,};
+ uint64_t ia_time = 0;
+ char actime_str[256] = {0,};
+ char modtime_str[256] = {0,};
if (trace_fop_names[GF_FOP_SETATTR].enabled) {
if (valid & GF_SET_ATTR_MODE) {
@@ -1632,10 +1677,13 @@ trace_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) {
- gf_time_fmt (actime_str, sizeof actime_str,
- stbuf->ia_atime, gf_timefmt_bdT);
- gf_time_fmt (modtime_str, sizeof modtime_str,
- stbuf->ia_mtime, gf_timefmt_bdT);
+ ia_time = stbuf->ia_atime;
+ strftime (actime_str, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
+
+ ia_time = stbuf->ia_mtime;
+ strftime (modtime_str, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s path=%s ia_atime=%s, ia_mtime=%s",
@@ -1648,7 +1696,7 @@ trace_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, trace_setattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setattr,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
return 0;
}
@@ -1656,10 +1704,11 @@ trace_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
- char actime_str[64] = {0,};
- char modtime_str[64] = {0,};
+ uint64_t ia_time = 0;
+ char actime_str[256] = {0,};
+ char modtime_str[256] = {0,};
if (trace_fop_names[GF_FOP_FSETATTR].enabled) {
if (valid & GF_SET_ATTR_MODE) {
@@ -1677,10 +1726,13 @@ trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) {
- gf_time_fmt (actime_str, sizeof actime_str,
- stbuf->ia_atime, gf_timefmt_bdT);
- gf_time_fmt (modtime_str, sizeof modtime_str,
- stbuf->ia_mtime, gf_timefmt_bdT);
+ ia_time = stbuf->ia_atime;
+ strftime (actime_str, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
+
+ ia_time = stbuf->ia_mtime;
+ strftime (modtime_str, 256, "[%b %d %H:%M:%S]",
+ localtime ((time_t *)&ia_time));
gf_log (this->name, GF_LOG_INFO,
"%"PRId64": gfid=%s fd=%p ia_atime=%s, ia_mtime=%s",
@@ -1693,7 +1745,7 @@ trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_fsetattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
return 0;
}
@@ -1701,7 +1753,7 @@ trace_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
trace_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
if (trace_fop_names[GF_FOP_TRUNCATE].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1714,7 +1766,7 @@ trace_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, trace_truncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
+ loc, offset);
return 0;
}
@@ -1722,63 +1774,58 @@ trace_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
int
trace_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+ int32_t flags, fd_t *fd, int32_t wbflags)
{
if (trace_fop_names[GF_FOP_OPEN].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s path=%s flags=%d fd=%p",
+ "%"PRId64": gfid=%s path=%s flags=%d fd=%p wbflags=%d",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- loc->path, flags, fd);
+ loc->path, flags, fd, wbflags);
frame->local = loc->inode->gfid;
}
STACK_WIND (frame, trace_open_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
+ loc, flags, fd, wbflags);
return 0;
}
int
trace_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
- dict_t *xdata)
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
if (trace_fop_names[GF_FOP_CREATE].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s path=%s fd=%p flags=0%o mode=0%o "
- "umask=0%o",
+ "%"PRId64": gfid=%s path=%s, fd=%p, flags=0%o mode=0%o",
frame->root->unique, uuid_utoa (loc->inode->gfid),
- loc->path, fd, flags, mode, umask);
+ loc->path, fd, flags, mode);
}
STACK_WIND (frame, trace_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
-
+ loc, flags, mode, fd, params);
return 0;
}
int
trace_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ size_t size, off_t offset)
{
if (trace_fop_names[GF_FOP_READ].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", "
- "offset=%"PRId64" flags=0%x)",
- frame->root->unique, uuid_utoa (fd->inode->gfid),
- fd, size, offset, flags);
+ "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ frame->root->unique, uuid_utoa (fd->inode->gfid), fd, size, offset);
frame->local = fd->inode->gfid;
}
STACK_WIND (frame, trace_readv_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
@@ -1786,27 +1833,26 @@ trace_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
trace_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count,
- off_t offset, uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ off_t offset, struct iobref *iobref)
{
if (trace_fop_names[GF_FOP_WRITE].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s fd=%p, count=%d, offset=%"PRId64
- " flag=0%x)",
+ "%"PRId64": gfid=%s fd=%p, count=%d, offset=%"PRId64")",
frame->root->unique, uuid_utoa (fd->inode->gfid),
- fd, count, offset, flags);
+ fd, count, offset);
frame->local = fd->inode->gfid;
}
STACK_WIND (frame, trace_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
}
int
-trace_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+trace_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
if (trace_fop_names[GF_FOP_STATFS].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1818,13 +1864,13 @@ trace_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
STACK_WIND (frame, trace_statfs_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
+ loc);
return 0;
}
int
-trace_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+trace_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
if (trace_fop_names[GF_FOP_FLUSH].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1836,13 +1882,13 @@ trace_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
STACK_WIND (frame, trace_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
+ fd);
return 0;
}
int
-trace_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+trace_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
if (trace_fop_names[GF_FOP_FSYNC].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1854,14 +1900,14 @@ trace_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_
STACK_WIND (frame, trace_fsync_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
- fd, flags, xdata);
+ fd, flags);
return 0;
}
int
trace_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata)
+ loc_t *loc, dict_t *dict, int32_t flags)
{
if (trace_fop_names[GF_FOP_SETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1874,14 +1920,14 @@ trace_setxattr (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_setxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
+ loc, dict, flags);
return 0;
}
int
trace_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
if (trace_fop_names[GF_FOP_GETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1894,14 +1940,14 @@ trace_getxattr (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_getxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
+ loc, name);
return 0;
}
int
trace_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
+ loc_t *loc, const char *name)
{
if (trace_fop_names[GF_FOP_REMOVEXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1914,14 +1960,14 @@ trace_removexattr (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_removexattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
+ loc, name);
return 0;
}
int
-trace_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata)
+trace_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
if (trace_fop_names[GF_FOP_OPENDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1934,27 +1980,26 @@ trace_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t
STACK_WIND (frame, trace_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
+ loc, fd);
return 0;
}
int
trace_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
+ off_t offset)
{
if (trace_fop_names[GF_FOP_READDIRP].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", "
- "offset=%"PRId64" dict=%p",
+ "%"PRId64": gfid=%s fd=%p, size=%"GF_PRI_SIZET", offset=%"PRId64,
frame->root->unique, uuid_utoa (fd->inode->gfid),
- fd, size, offset, dict);
+ fd, size, offset);
frame->local = fd->inode->gfid;
}
STACK_WIND (frame, trace_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
+ fd, size, offset);
return 0;
}
@@ -1962,7 +2007,7 @@ trace_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
int
trace_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
+ size_t size, off_t offset)
{
if (trace_fop_names[GF_FOP_READDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1975,7 +2020,7 @@ trace_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, offset, xdata);
+ fd, size, offset);
return 0;
}
@@ -1983,7 +2028,7 @@ trace_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
trace_fsyncdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t datasync, dict_t *xdata)
+ fd_t *fd, int32_t datasync)
{
if (trace_fop_names[GF_FOP_FSYNCDIR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -1996,13 +2041,13 @@ trace_fsyncdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_fsyncdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsyncdir,
- fd, datasync, xdata);
+ fd, datasync);
return 0;
}
int
-trace_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dict_t *xdata)
+trace_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
{
if (trace_fop_names[GF_FOP_ACCESS].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2015,14 +2060,14 @@ trace_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask, dic
STACK_WIND (frame, trace_access_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->access,
- loc, mask, xdata);
+ loc, mask);
return 0;
}
int32_t
trace_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
+ int32_t len)
{
if (trace_fop_names[GF_FOP_RCHECKSUM].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2035,7 +2080,7 @@ trace_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
STACK_WIND (frame, trace_rchecksum_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rchecksum,
- fd, offset, len, xdata);
+ fd, offset, len);
return 0;
@@ -2044,7 +2089,7 @@ trace_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
int32_t
trace_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
fd_t *fd, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
+ entrylk_type type)
{
if (trace_fop_names[GF_FOP_FENTRYLK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2060,14 +2105,14 @@ trace_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
STACK_WIND (frame, trace_fentrylk_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
+ volume, fd, basename, cmd, type);
return 0;
}
int32_t
trace_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
if (trace_fop_names[GF_FOP_FGETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2080,13 +2125,13 @@ trace_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_fgetxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
+ fd, name);
return 0;
}
int32_t
trace_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
if (trace_fop_names[GF_FOP_FSETXATTR].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2099,13 +2144,13 @@ trace_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_fsetxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
+ fd, dict, flags);
return 0;
}
int
trace_ftruncate (call_frame_t *frame, xlator_t *this,
- fd_t *fd, off_t offset, dict_t *xdata)
+ fd_t *fd, off_t offset)
{
if (trace_fop_names[GF_FOP_FTRUNCATE].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2118,14 +2163,14 @@ trace_ftruncate (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, trace_ftruncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
- fd, offset, xdata);
+ fd, offset);
return 0;
}
int
-trace_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+trace_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
if (trace_fop_names[GF_FOP_FSTAT].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2137,14 +2182,14 @@ trace_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
STACK_WIND (frame, trace_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
+ fd);
return 0;
}
int
trace_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ int32_t cmd, struct gf_flock *lock)
{
if (trace_fop_names[GF_FOP_LK].enabled) {
gf_log (this->name, GF_LOG_INFO,
@@ -2159,7 +2204,7 @@ trace_lk (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, trace_lk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lk,
- fd, cmd, lock, xdata);
+ fd, cmd, lock);
return 0;
}
@@ -2170,7 +2215,8 @@ trace_forget (xlator_t *this, inode_t *inode)
he should know about 'forget' too */
if (trace_fop_names[GF_FOP_LOOKUP].enabled) {
gf_log (this->name, GF_LOG_INFO,
- "gfid=%s", uuid_utoa (inode->gfid));
+ "gfid=%s ino=%"PRIu64,
+ uuid_utoa (inode->gfid), inode->ino);
}
return 0;
}
diff --git a/xlators/encryption/rot-13/src/rot-13.c b/xlators/encryption/rot-13/src/rot-13.c
index 697465fd3..a7e9c3c14 100644
--- a/xlators/encryption/rot-13/src/rot-13.c
+++ b/xlators/encryption/rot-13/src/rot-13.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -68,15 +68,14 @@ rot13_readv_cbk (call_frame_t *frame,
struct iovec *vector,
int32_t count,
struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
rot_13_private_t *priv = (rot_13_private_t *)this->private;
if (priv->decrypt_read)
rot13_iovec (vector, count);
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count, stbuf, iobref);
return 0;
}
@@ -85,13 +84,13 @@ rot13_readv (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
STACK_WIND (frame,
rot13_readv_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
@@ -102,10 +101,9 @@ rot13_writev_cbk (call_frame_t *frame,
int32_t op_ret,
int32_t op_errno,
struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -114,20 +112,20 @@ rot13_writev (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iovec *vector,
- int32_t count,
- off_t offset, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
+ int32_t count,
+ off_t offset,
+ struct iobref *iobref)
{
rot_13_private_t *priv = (rot_13_private_t *)this->private;
if (priv->encrypt_write)
rot13_iovec (vector, count);
- STACK_WIND (frame,
+ STACK_WIND (frame,
rot13_writev_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->writev,
- fd, vector, count, offset, flags,
- iobref, xdata);
+ fd, vector, count, offset,
+ iobref);
return 0;
}
diff --git a/xlators/encryption/rot-13/src/rot-13.h b/xlators/encryption/rot-13/src/rot-13.h
index 8ef8162ae..f8f0517b9 100644
--- a/xlators/encryption/rot-13/src/rot-13.h
+++ b/xlators/encryption/rot-13/src/rot-13.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am
index be48f93fa..96e503938 100644
--- a/xlators/features/Makefile.am
+++ b/xlators/features/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = locks quota read-only mac-compat quiesce marker index # trash path-converter # filter
+SUBDIRS = locks trash quota read-only access-control mac-compat quiesce marker#path-converter # filter
CLEANFILES =
diff --git a/xlators/features/index/Makefile.am b/xlators/features/access-control/Makefile.am
index a985f42a8..a985f42a8 100644
--- a/xlators/features/index/Makefile.am
+++ b/xlators/features/access-control/Makefile.am
diff --git a/xlators/features/access-control/src/Makefile.am b/xlators/features/access-control/src/Makefile.am
new file mode 100644
index 000000000..6ab8cc4ec
--- /dev/null
+++ b/xlators/features/access-control/src/Makefile.am
@@ -0,0 +1,13 @@
+xlator_LTLIBRARIES = access-control.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
+access_control_la_LDFLAGS = -module -avoidversion
+access_control_la_SOURCES = access-control.c
+access_control_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = access-control.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\
+ -L$(xlatordir)/
+
+CLEANFILES =
diff --git a/xlators/features/access-control/src/access-control.c b/xlators/features/access-control/src/access-control.c
new file mode 100644
index 000000000..1dca5ac27
--- /dev/null
+++ b/xlators/features/access-control/src/access-control.c
@@ -0,0 +1,2060 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "access-control.h"
+#include "xlator.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "iatt.h"
+
+/* Careful, this function erases the stub from frame->local. Dont call this if
+ * a subsequent callback requires retaining access to the stub. This should be
+ * called at the end of all access-control related operations, i.e. once the
+ * frame will be handed off to the actual fop and the next callback that will
+ * be called is the default callback. IOW, the function where call_resume is
+ * called.
+ * NOTE: this is required because FRAME_DESTROY tries to free frame->local if
+ * it finds it to be non-NULL.
+ */
+call_stub_t *
+__get_frame_stub (call_frame_t *fr)
+{
+ call_stub_t *st = NULL;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, fr, out);
+
+ st = fr->local;
+ fr->local = NULL;
+out:
+ gf_log (ACTRL, GF_LOG_TRACE, "Returning %p", st);
+ return st;
+}
+
+void
+ac_set_accesstype_str (int access, char *str, size_t len)
+{
+ char *read = "read ";
+ char *write = "write ";
+ char *exec = "exec ";
+ char *dontcare = "don'tcare ";
+
+ GF_ASSERT (len > (strlen (read) + strlen (write) +
+ strlen (exec) + strlen (dontcare)));
+ GF_ASSERT (str);
+ if (access & ACCTEST_READ) {
+ snprintf (str, len, "%s", read);
+ len -= strlen (read);
+ }
+ if (access & ACCTEST_WRITE) {
+ snprintf (str, len, "%s", write);
+ len -= strlen (write);
+ }
+ if (access & ACCTEST_EXEC) {
+ snprintf (str, len, "%s", exec);
+ len -= strlen (exec);
+ }
+ if (access & ACCTEST_DONTCARE) {
+ snprintf (str, len, "%s", dontcare);
+ len -= strlen (dontcare);
+ }
+}
+
+int
+ac_test_owner_access (struct iatt *ia, uid_t uid, int accesstest)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, ia, out);
+
+ /* First test permissions using the uid. */
+ if (ia->ia_uid != uid) {
+ ret = -1;
+ gf_log (ACTRL, GF_LOG_TRACE, "UID mismatch (orig: %d, user: %d)",
+ ia->ia_uid, uid);
+ goto out;
+ }
+
+ /* At this point we know, the uid matches that of the stat structure, so
+ * if the caller does not care, we should return success.
+ */
+ if (ac_test_dontcare (accesstest)) {
+ ret = 0;
+ gf_log (ACTRL, GF_LOG_TRACE, "Access test marked as don't care");
+ goto out;
+ }
+
+ if (ac_test_read (accesstest))
+ ret = IA_PROT_RUSR (ia->ia_prot);
+
+ if (ac_test_write (accesstest))
+ ret = IA_PROT_WUSR (ia->ia_prot);
+
+ if (ac_test_exec (accesstest))
+ ret = IA_PROT_XUSR (ia->ia_prot);
+
+ /* For failed access test for owner, we need to return EACCES */
+ if (!ret)
+ ret = -1;
+ else
+ ret = 0;
+out:
+ if (0 == ret)
+ gf_log (ACTRL, GF_LOG_TRACE, "Owner access allowed");
+ else
+ gf_log (ACTRL, GF_LOG_TRACE, "Owner access not allowed");
+ return ret;
+}
+
+
+int
+ac_test_group_access (struct iatt *ia, gid_t gid, gid_t *auxgids, int auxcount,
+ int accesstest)
+{
+ int ret = -1;
+ int testgid = -1;
+ int x = 0;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, ia, out);
+
+ /* First, determine which gid to test against. This will be determined
+ * by first checking which of the gids given to us match the gid in the
+ * stat. If none match, then we go to checking with others as the user.
+ */
+
+ /* If we are only given the primary gid. Dont depend on @auxgids
+ * being NULL since I know users of this function can pass statically
+ * allocated arrays which cant be NULL and yet contain no valid gids.
+ */
+
+ if ((ia->ia_gid != gid) && (auxcount == 0)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "GID mismatch (orig: %d, user: %d)",
+ ia->ia_gid, gid);
+ ret = -1;
+ goto out;
+ }
+
+ if (ia->ia_gid == gid)
+ testgid = gid;
+ else {
+ for (; x < auxcount; ++x) {
+ if (ia->ia_gid == auxgids[x]) {
+ testgid = ia->ia_gid;
+ break;
+ }
+ }
+ }
+
+ /* None of the gids match with the gid in the stat. */
+ if (testgid == -1) {
+ gf_log (ACTRL, GF_LOG_TRACE, "None of the gids match with gid "
+ "on the stat");
+ ret = -1;
+ goto out;
+ }
+
+ /* At this point, at least one gid matches that in the stat, now we must
+ * check whether the caller is interested in the access check at all.
+ */
+ if (ac_test_dontcare (accesstest)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "Access test marked as don't care");
+ ret = 0;
+ goto out;
+ }
+
+ if (ac_test_read (accesstest))
+ ret = IA_PROT_RGRP (ia->ia_prot);
+
+ if (ac_test_write (accesstest))
+ ret = IA_PROT_WGRP (ia->ia_prot);
+
+ if (ac_test_exec (accesstest))
+ ret = IA_PROT_XGRP (ia->ia_prot);
+
+ if (!ret)
+ ret = -1;
+ else
+ ret = 0;
+
+out:
+ if (0 == ret)
+ gf_log (ACTRL, GF_LOG_TRACE, "Group access allowed");
+ else
+ gf_log (ACTRL, GF_LOG_TRACE, "Group access not allowed");
+ return ret;
+}
+
+
+int
+ac_test_other_access (struct iatt *ia, int accesstest)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, ia, out);
+ ret = 0;
+
+ if (ac_test_read (accesstest))
+ ret = IA_PROT_ROTH (ia->ia_prot);
+
+ if (ac_test_write (accesstest))
+ ret = IA_PROT_WOTH (ia->ia_prot);
+
+ if (ac_test_exec (accesstest))
+ ret = IA_PROT_XOTH (ia->ia_prot);
+
+ if (!ret)
+ ret = -1;
+ else
+ ret = 0;
+
+out:
+ if (0 == ret)
+ gf_log (ACTRL, GF_LOG_TRACE, "Other access allowed");
+ else
+ gf_log (ACTRL, GF_LOG_TRACE, "Other access not allowed");
+ return ret;
+}
+
+
+/* Returns -1 on a failed access test with @operrno set to the relevant error
+ * number.
+ */
+int
+ac_test_access (struct iatt *ia, uid_t uid, gid_t gid, gid_t *auxgids,
+ int auxcount, int accesstest, int testwho, int *operrno)
+{
+ int ret = -1;
+ char accesstest_str[32] = {0};
+
+ GF_VALIDATE_OR_GOTO (ACTRL, ia, out);
+ GF_VALIDATE_OR_GOTO (ACTRL, operrno, out);
+
+ ac_set_accesstype_str (accesstest, accesstest_str,
+ sizeof (accesstest_str));
+ gf_log (ACTRL, GF_LOG_TRACE, "Testing for accesstypes %s",
+ accesstest_str);
+ if ((uid == 0) && (gid == 0)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "Root has access");
+ return 0;
+ }
+
+ if (ac_test_owner (testwho)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "Testing owner access");
+ ret = ac_test_owner_access (ia, uid, accesstest);
+ }
+
+ if (ret == 0) {
+ goto out;
+ }
+
+ if (ac_test_group (testwho)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "Testing group access");
+ ret = ac_test_group_access (ia, gid, auxgids, auxcount,
+ accesstest);
+ }
+
+ if (ret == 0) {
+ goto out;
+ }
+
+ if (ac_test_other (testwho)) {
+ gf_log (ACTRL, GF_LOG_TRACE, "Testing other access");
+ ret = ac_test_other_access (ia, accesstest);
+ }
+
+out:
+ if (ret == -1) {
+ gf_log (ACTRL, GF_LOG_TRACE, "No access allowed");
+ *operrno = EPERM;
+ }
+
+ return ret;
+}
+
+
+int
+ac_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
+{
+ int ret = -EFAULT;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, loc, out);
+
+ if (inode) {
+ loc->inode = inode_ref (inode);
+ loc->ino = inode->ino;
+ }
+
+ if (parent)
+ loc->parent = inode_ref (parent);
+
+ loc->path = gf_strdup (path);
+ if (!loc->path) {
+ goto loc_wipe;
+ }
+
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name) {
+ loc->name++;
+ } else {
+ gf_log (ACTRL, GF_LOG_ERROR, "path: %s, doesn't have '/'",
+ loc->path);
+ goto loc_wipe;
+ }
+
+ ret = 0;
+loc_wipe:
+ if (ret < 0) {
+ if (inode)
+ gf_log (ACTRL, GF_LOG_ERROR, "location fill failed for "
+ "inode: %s", uuid_utoa (inode->gfid));
+ loc_wipe (loc);
+ }
+out:
+ gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+
+int
+ac_inode_loc_fill (inode_t *inode, loc_t *loc)
+{
+ char *resolvedpath = NULL;
+ inode_t *parent = NULL;
+ int ret = -EFAULT;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, inode, out);
+ GF_VALIDATE_OR_GOTO (ACTRL, loc, out);
+
+ if ((inode) && (inode->ino == 1)) {
+ goto ignore_parent;
+ }
+
+ parent = inode_parent (inode, 0, NULL);
+ GF_VALIDATE_OR_GOTO (ACTRL, parent, err);
+
+ignore_parent:
+ ret = inode_path (inode, NULL, &resolvedpath);
+ if (ret < 0) {
+ gf_log (ACTRL, GF_LOG_ERROR, "Unable to get path for inode: %s",
+ uuid_utoa (inode->gfid));
+ goto err;
+ }
+
+ ret = ac_loc_fill (loc, inode, parent, resolvedpath);
+ if (ret < 0)
+ goto err;
+
+err:
+ if (parent)
+ inode_unref (parent);
+
+ if (resolvedpath)
+ GF_FREE (resolvedpath);
+
+out:
+ gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+
+int
+ac_parent_loc_fill (loc_t *parentloc, loc_t *childloc)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (ACTRL, parentloc, out);
+ GF_VALIDATE_OR_GOTO (ACTRL, childloc, out);
+
+ ret = ac_inode_loc_fill (childloc->parent, parentloc);
+out:
+ gf_log (ACTRL, GF_LOG_TRACE, "Returning %d", ret);
+ return ret;
+}
+
+
+int32_t
+ac_truncate_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset)
+{
+ STACK_WIND (frame, default_truncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
+ return 0;
+}
+
+
+int32_t
+ac_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "truncate failed with "
+ "error: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ac_truncate_resume (frame, this, loc, offset);
+ return 0;
+ }
+ stub = fop_truncate_stub (frame, ac_truncate_resume, loc, offset);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_truncate_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc);
+
+ ret = 0;
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "truncate failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (truncate, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_access_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ STACK_WIND (frame, default_access_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access, loc, mask);
+ return 0;
+}
+
+
+int32_t
+ac_access_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+ int32_t mask = 0;
+ int acctest = 0;
+
+ stub = __get_frame_stub (frame);
+ mask = stub->args.access.mask;
+
+ /* If mask requests test for file existence then do not
+ * return a failure with ENOENT, instead return a failed
+ * access test.
+ */
+ if (op_ret == -1) {
+ if (mask & F_OK)
+ op_errno = EACCES;
+ else
+ op_errno = errno;
+
+ goto out;
+ }
+
+ if (R_OK & mask)
+ acctest |= ACCTEST_READ;
+ else if (W_OK & mask)
+ acctest |= ACCTEST_WRITE;
+ else if (X_OK & mask)
+ acctest |= ACCTEST_EXEC;
+ else
+ acctest = 0;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ acctest, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "access failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (access, frame, -1, op_errno);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ac_access_resume (frame, this, loc, mask);
+ return 0;
+ }
+ stub = fop_access_stub (frame, ac_access_resume, loc, mask);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_access_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "access failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (access, frame, -1, -ret);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_readlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ size_t size)
+{
+ STACK_WIND (frame, default_readlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink, loc, size);
+ return 0;
+}
+
+
+int32_t
+ac_readlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_READ, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "readlink failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ac_readlink_resume (frame, this, loc, size);
+ return 0;
+ }
+ stub = fop_readlink_stub (frame, ac_readlink_resume, loc, size);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_readlink_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "readlink failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (readlink, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int
+ac_mknod_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, dict_t *params)
+{
+ STACK_WIND (frame, default_mknod_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, params);
+ return 0;
+}
+
+
+int32_t
+ac_mknod_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "mknod failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, dict_t *params)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_mknod_resume (frame, this, loc, mode, rdev, params);
+ return 0;
+ }
+ stub = fop_mknod_stub (frame, ac_mknod_resume, loc, mode, rdev, params);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_mknod_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase any stored frame before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "mknod failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (mknod, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+ }
+
+ return 0;
+}
+
+
+int
+ac_mkdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *params)
+{
+ STACK_WIND (frame, default_mkdir_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ return 0;
+}
+
+
+int32_t
+ac_mkdir_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ /* On a failed write test on parent dir, we need to return
+ * EACCES, not EPERM that is returned by default by
+ * ac_test_access.
+ */
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "mkdir failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *params)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_mkdir_resume (frame, this, loc, mode, params);
+ return 0;
+ }
+ stub = fop_mkdir_stub (frame, ac_mkdir_resume, loc, mode, params);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_mkdir_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "mkdir failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (mkdir, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_unlink_resume (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink, loc);
+ return 0;
+}
+
+
+int32_t
+ac_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "unlink failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_unlink_resume (frame, this, loc);
+ return 0;
+ }
+ stub = fop_unlink_stub (frame, ac_unlink_resume, loc);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_unlink_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "unlink failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (unlink, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int
+ac_rmdir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+{
+ STACK_WIND (frame, default_rmdir_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ return 0;
+}
+
+
+int32_t
+ac_rmdir_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "rmdir failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_rmdir_resume (frame, this, loc, flags);
+ return 0;
+ }
+ stub = fop_rmdir_stub (frame, ac_rmdir_resume, loc, flags);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_rmdir_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "rmdir failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (rmdir, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_symlink_resume (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, dict_t *params)
+{
+ STACK_WIND (frame, default_symlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink, linkname, loc, params);
+ return 0;
+}
+
+
+int32_t
+ac_symlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "symlink failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, dict_t *params)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_symlink_resume (frame, this, linkname, loc, params);
+ return 0;
+ }
+ stub = fop_symlink_stub (frame, ac_symlink_resume, linkname, loc,
+ params);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_symlink_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "symlink failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (symlink, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_rename_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ STACK_WIND (frame, default_rename_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ return 0;
+}
+
+
+int32_t
+ac_rename_dst_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid,
+ frame->root->gid, frame->root->groups,
+ frame->root->ngrps, ACCTEST_WRITE,
+ ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_rename_src_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+ loc_t parentloc = {0, };
+
+ stub = frame->local;
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid,
+ frame->root->gid, frame->root->groups,
+ frame->root->ngrps, ACCTEST_WRITE,
+ ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ op_ret = ac_parent_loc_fill (&parentloc, &stub->args.rename.new);
+ if (op_ret < 0) {
+ op_errno = -EFAULT;
+ goto out;
+ }
+
+ STACK_WIND (frame, ac_rename_dst_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+
+out:
+ if (op_ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_rename_resume (frame, this, oldloc, newloc);
+ return 0;
+ }
+ stub = fop_rename_stub (frame, ac_rename_resume, oldloc, newloc);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, oldloc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_rename_src_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "rename failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (rename, frame, -1, -ret, NULL, NULL, NULL,
+ NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_link_resume (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ STACK_WIND (frame, default_link_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ return 0;
+}
+
+
+int32_t
+ac_link_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ /* By default ac_test_access sets the op_errno to EPERM
+ * but in the case of link, we need to return EACCES to meet
+ * posix requirements when a write permission is not available
+ * for the new directory.
+ */
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "link failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_link_resume (frame, this, oldloc, newloc);
+ return 0;
+ }
+ stub = fop_link_stub (frame, ac_link_resume, oldloc, newloc);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, newloc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_link_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "link failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (link, frame, -1, -ret, NULL, NULL, NULL,
+ NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_create_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
+{
+ STACK_WIND (frame, default_create_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create, loc, flags, mode,
+ fd, params);
+ return 0;
+}
+
+
+int32_t
+ac_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "create failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd, dict_t *params)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+
+ if (__is_fuse_call (frame)) {
+ ac_create_resume (frame, this, loc, flags, mode, fd, params);
+ return 0;
+ }
+ stub = fop_create_stub (frame, ac_create_resume, loc, flags, mode,
+ fd, params);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ ret = ac_parent_loc_fill (&parentloc, loc);
+ if (ret < 0)
+ goto out;
+
+ STACK_WIND (frame, ac_create_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "create failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (create, frame, -1, -ret, NULL, NULL, NULL,
+ NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_open_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
+{
+ STACK_WIND (frame, default_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ return 0;
+}
+
+
+int32_t
+ac_open_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_open_create (call_stub_t *stub)
+{
+ int ret = -EFAULT;
+ loc_t parentloc = {0, };
+ xlator_t *this = NULL;
+
+ if (!stub)
+ return ret;
+
+ ret = ac_parent_loc_fill (&parentloc, &stub->args.open.loc);
+ if (ret < 0)
+ goto out;
+
+ this = stub->frame->this;
+ STACK_WIND (stub->frame, ac_open_create_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &parentloc);
+ loc_wipe (&parentloc);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+int32_t
+ac_open_only_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+ int acctest = 0;
+ int32_t flags = 0;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ flags = stub->args.open.flags;
+ /* The permissions we test for depend on how the open needs to be
+ * performed. */
+ if ((flags & O_ACCMODE) == O_RDONLY)
+ acctest = ACCTEST_READ;
+ else if (((flags & O_ACCMODE) == O_RDWR) ||
+ ((flags & O_ACCMODE) == O_WRONLY))
+ acctest = ACCTEST_WRITE;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ acctest, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int
+ac_open_only (call_stub_t *stub)
+{
+ int ret = -EFAULT;
+ xlator_t *this = NULL;
+
+ if (!stub)
+ return ret;
+
+ this = stub->frame->this;
+ STACK_WIND (stub->frame, ac_open_only_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, &stub->args.open.loc);
+ return 0;
+}
+
+int32_t
+ac_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_open_resume (frame, this, loc, flags, fd, wbflags);
+ return 0;
+ }
+
+ stub = fop_open_stub (frame, ac_open_resume, loc, flags, fd, wbflags);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ /* If we are not supposed to create the file then there is no need to
+ * check the parent dir permissions. */
+ if (flags & O_CREAT)
+ ret = ac_open_create (stub);
+ else
+ ret = ac_open_only (stub);
+
+out:
+ if (ret < 0) {
+ /* Erase the stored stub before unwinding. */
+ stub = __get_frame_stub (frame);
+ if (stub)
+ call_stub_destroy (stub);
+ gf_log (this->name, GF_LOG_ERROR, "open failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (open, frame, -1, -ret, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_readv_resume (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ STACK_WIND (frame, default_readv_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readv, fd, size, offset);
+ return 0;
+}
+
+
+int32_t
+ac_readv_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_READ, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "readv failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL,
+ NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_readv_resume (frame, this, fd, size, offset);
+ return 0;
+ }
+
+ stub = fop_readv_stub (frame, ac_readv_resume, fd, size, offset);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_readv_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "readv failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (readv, frame, -1, -ret, NULL, 0, NULL,
+ NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_writev_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref)
+{
+ STACK_WIND (frame, default_writev_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->writev, fd, vector, count, offset,
+ iobref);
+ return 0;
+}
+
+
+int32_t
+ac_writev_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1) {
+ op_errno = EACCES;
+ goto out;
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "writev failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t offset, struct iobref *iobref)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_writev_resume (frame, this, fd, vector, count,
+ offset, iobref);
+ return 0;
+ }
+
+ stub = fop_writev_stub (frame, ac_writev_resume, fd, vector, count,
+ offset, iobref);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_writev_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "writev failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (writev, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_opendir_resume (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+{
+ STACK_WIND (frame, default_opendir_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir, loc, fd);
+ return 0;
+}
+
+
+int32_t
+ac_opendir_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_READ, ACCTEST_ANY, &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "opendir failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+int32_t
+ac_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_opendir_resume (frame, this, loc, fd);
+ return 0;
+ }
+
+ stub = fop_opendir_stub (frame, ac_opendir_resume, loc, fd);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_opendir_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "opendir failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (opendir, frame, -1, -ret, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_setattr_resume (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *buf, int32_t valid)
+{
+ STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setattr, loc, buf, valid);
+ return 0;
+}
+
+
+int32_t
+ac_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+ int32_t valid = 0;
+ struct iatt *setbuf = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY,
+ &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ valid = stub->args.setattr.valid;
+ setbuf = &stub->args.setattr.stbuf;
+ if (gf_attr_uid_set (valid) || gf_attr_gid_set (valid)) {
+ /* chown returns EPERM if the operation would change the
+ * ownership, but the effective user ID is not the
+ * super-user and the process is not an owner of the file.
+ * Ref: posix-testsuite/chown/07.t
+ */
+ if ((frame->root->uid != 0) && (gf_attr_uid_set (valid))) {
+ if (buf->ia_uid != setbuf->ia_uid) {
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+ }
+
+ /* non-super-user can modify file group if he is owner of a
+ * file and gid he is setting is in his groups list.
+ * Ref: posix-testsuite/chown/00.t
+ */
+ if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) {
+ if (frame->root->uid != buf->ia_uid) {
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+
+ op_ret = ac_test_access (setbuf, 0, frame->root->gid,
+ frame->root->groups,
+ frame->root->ngrps,
+ ACCTEST_DONTCARE,
+ ACCTEST_GROUP, &op_errno);
+ if (op_ret == -1)
+ goto out;
+ }
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "setattr failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+int32_t
+ac_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc, struct iatt *buf,
+ int32_t valid)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_setattr_resume (frame, this, loc, buf, valid);
+ return 0;
+ }
+
+ stub = fop_setattr_stub (frame, ac_setattr_resume, loc, buf, valid);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_setattr_stat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->stat, loc);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "setattr failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (setattr, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *buf, int32_t valid)
+{
+ STACK_WIND (frame, default_fsetattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsetattr, fd, buf, valid);
+ return 0;
+}
+
+
+int32_t
+ac_fsetattr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
+{
+ call_stub_t *stub = NULL;
+ int32_t valid = 0;
+ struct iatt *setbuf = NULL;
+
+ stub = __get_frame_stub (frame);
+ if (op_ret == -1)
+ goto out;
+
+ op_ret = ac_test_access (buf, frame->root->uid, frame->root->gid,
+ frame->root->groups, frame->root->ngrps,
+ ACCTEST_WRITE, ACCTEST_ANY,
+ &op_errno);
+ if (op_ret == -1)
+ goto out;
+
+ valid = stub->args.fsetattr.valid;
+ setbuf = &stub->args.fsetattr.stbuf;
+ if (gf_attr_uid_set (valid) && gf_attr_gid_set (valid)) {
+ /* chown returns EPERM if the operation would change the
+ * ownership, but the effective user ID is not the
+ * super-user and the process is not an owner of the file.
+ * Ref: posix-testsuite/chown/07.t
+ */
+ if ((frame->root->uid != 0) && (gf_attr_uid_set (valid))) {
+ if (buf->ia_uid != setbuf->ia_uid) {
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+ }
+
+ /* non-super-user can modify file group if he is owner of a
+ * file and gid he is setting is in his groups list.
+ * Ref: posix-testsuite/chown/00.t
+ */
+ if ((frame->root->uid != 0) && (gf_attr_gid_set (valid))) {
+ if (frame->root->uid != buf->ia_uid) {
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ }
+
+ op_ret = ac_test_access (buf, 0, frame->root->gid,
+ frame->root->groups,
+ frame->root->ngrps,
+ ACCTEST_DONTCARE,
+ ACCTEST_GROUP, &op_errno);
+ if (op_ret == -1)
+ goto out;
+ }
+ }
+
+ call_resume (stub);
+out:
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "fsetattr failed with error: %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL);
+ if (stub)
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+int32_t
+ac_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iatt *buf,
+ int32_t valid)
+{
+ call_stub_t *stub = NULL;
+ int ret = -EFAULT;
+
+ if (__is_fuse_call (frame)) {
+ ret = ac_fsetattr_resume (frame, this, fd, buf, valid);
+ return 0;
+ }
+
+ stub = fop_fsetattr_stub (frame, ac_fsetattr_resume, fd, buf, valid);
+ if (!stub) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ frame->local = stub;
+ STACK_WIND (frame, ac_fsetattr_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ ret = 0;
+
+out:
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "fsetattr failed with error: %s",
+ strerror (-ret));
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, -ret, NULL, NULL);
+ }
+
+ return 0;
+}
+
+
+struct xlator_fops fops = {
+ .truncate = ac_truncate,
+ .access = ac_access,
+ .readlink = ac_readlink,
+ .mknod = ac_mknod,
+ .mkdir = ac_mkdir,
+ .unlink = ac_unlink,
+ .rmdir = ac_rmdir,
+ .symlink = ac_symlink,
+ .rename = ac_rename,
+ .link = ac_link,
+ .create = ac_create,
+ .open = ac_open,
+/*
+ * Allow Writes and Reads to proceed without permission checks because:
+ * a. We expect that when the fds are opened, thats when the perm checks happen
+ * depending on the read/write mode used.
+ *
+ * b. In case of nfs clients, we expect the nfs clients to perform the checks
+ * based on getattr/access nfs requests.
+ *
+ * Keep these functions around in case we ever run into a nfs client that
+ * depends on nfs server to perform these checks. Till then, just remove the
+ * references from here instead.
+ .readv = ac_readv,
+ .writev = ac_writev,
+*/
+ .opendir = ac_opendir,
+ .setattr = ac_setattr,
+ .fsetattr = ac_fsetattr,
+};
+
+int
+init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: access-control not configured with "
+ "exactly one child");
+ goto out;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ return;
+}
+
+struct xlator_cbks cbks = {
+};
diff --git a/xlators/features/access-control/src/access-control.h b/xlators/features/access-control/src/access-control.h
new file mode 100644
index 000000000..8e2d6b6b9
--- /dev/null
+++ b/xlators/features/access-control/src/access-control.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __ACCESS_CONTROL_H_
+#define __ACCESS_CONTROL_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define ACTRL "access-control"
+#define ACCTEST_READ 0x1
+#define ACCTEST_WRITE 0x2
+#define ACCTEST_EXEC 0x4
+#define ACCTEST_DONTCARE 0x8
+
+/* Note if the caller is only interested in ownership test i.e. one of the below
++ * in combination with GF_ACCTEST_DONTCARE, then only one type of user's owner
++ * ship can be tested with one call to gf_test_access, i.e. we can only
++ * check of either owner and group, if both need to be tested for a specific
++ * (uid, gid) pair then two calls will be needed.
++ */
+#define ACCTEST_OWNER 0x1
+#define ACCTEST_GROUP 0x2
+#define ACCTEST_OTHER 0x4
+
+/* Signifies any user, as long as we get access. */
+#define ACCTEST_ANY (ACCTEST_OWNER | ACCTEST_GROUP | ACCTEST_OTHER)
+
+#define ac_test_owner(acc) ((acc) & ACCTEST_OWNER)
+#define ac_test_group(acc) ((acc) & ACCTEST_GROUP)
+#define ac_test_other(acc) ((acc) & ACCTEST_OTHER)
+#define ac_test_dontcare(acc) ((acc) & ACCTEST_DONTCARE)
+#define ac_test_read(acc) ((acc) & ACCTEST_READ)
+#define ac_test_write(acc) ((acc) & ACCTEST_WRITE)
+#define ac_test_exec(acc) ((acc) & ACCTEST_EXEC)
+#endif
diff --git a/xlators/features/filter/src/filter-mem-types.h b/xlators/features/filter/src/filter-mem-types.h
index de2cb9665..3078266b1 100644
--- a/xlators/features/filter/src/filter-mem-types.h
+++ b/xlators/features/filter/src/filter-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/filter/src/filter.c b/xlators/features/filter/src/filter.c
index eda042f35..13a3e7cf2 100644
--- a/xlators/features/filter/src/filter.c
+++ b/xlators/features/filter/src/filter.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/index/src/Makefile.am b/xlators/features/index/src/Makefile.am
deleted file mode 100644
index 5d037c7ec..000000000
--- a/xlators/features/index/src/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-xlator_LTLIBRARIES = index.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-
-index_la_LDFLAGS = -module -avoidversion
-
-index_la_SOURCES = index.c
-index_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = index.h index-mem-types.h
-
-AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -I$(top_srcdir)/rpc/xdr/src \
- -I$(top_srcdir)/rpc/rpc-lib/src -shared -nostartfiles $(GF_CFLAGS)
-
-CLEANFILES =
diff --git a/xlators/features/index/src/index-mem-types.h b/xlators/features/index/src/index-mem-types.h
deleted file mode 100644
index 964f3b090..000000000
--- a/xlators/features/index/src/index-mem-types.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef __QUIESCE_MEM_TYPES_H__
-#define __QUIESCE_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_index_mem_types_ {
- gf_index_mt_priv_t = gf_common_mt_end + 1,
- gf_index_inode_ctx_t = gf_common_mt_end + 2,
- gf_index_fd_ctx_t = gf_common_mt_end + 3,
- gf_index_mt_end
-};
-#endif
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c
deleted file mode 100644
index 7be09fadf..000000000
--- a/xlators/features/index/src/index.c
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "index.h"
-#include "options.h"
-#include "glusterfs3-xdr.h"
-
-#define XATTROP_SUBDIR "xattrop"
-
-call_stub_t *
-__index_dequeue (struct list_head *callstubs)
-{
- call_stub_t *stub = NULL;
-
- if (!list_empty (callstubs)) {
- stub = list_entry (callstubs->next, call_stub_t, list);
- list_del_init (&stub->list);
- }
-
- return stub;
-}
-
-inline static void
-__index_enqueue (struct list_head *callstubs, call_stub_t *stub)
-{
- list_add_tail (&stub->list, callstubs);
-}
-
-static void
-worker_enqueue (xlator_t *this, call_stub_t *stub)
-{
- index_priv_t *priv = NULL;
-
- priv = this->private;
- pthread_mutex_lock (&priv->mutex);
- {
- __index_enqueue (&priv->callstubs, stub);
- pthread_cond_signal (&priv->cond);
- }
- pthread_mutex_unlock (&priv->mutex);
-}
-
-void *
-index_worker (void *data)
-{
- index_priv_t *priv = NULL;
- xlator_t *this = NULL;
- call_stub_t *stub = NULL;
- int ret = 0;
-
- THIS = data;
- this = data;
- priv = this->private;
-
- for (;;) {
- pthread_mutex_lock (&priv->mutex);
- {
- while (list_empty (&priv->callstubs)) {
- ret = pthread_cond_wait (&priv->cond,
- &priv->mutex);
- }
-
- stub = __index_dequeue (&priv->callstubs);
- }
- pthread_mutex_unlock (&priv->mutex);
-
- if (stub) /* guard against spurious wakeups */
- call_resume (stub);
- }
-
- return NULL;
-}
-int
-__index_inode_ctx_get (inode_t *inode, xlator_t *this, index_inode_ctx_t **ctx)
-{
- int ret = 0;
- index_inode_ctx_t *ictx = NULL;
- uint64_t tmpctx = 0;
-
- ret = __inode_ctx_get (inode, this, &tmpctx);
- if (!ret) {
- ictx = (index_inode_ctx_t*) (long) tmpctx;
- goto out;
- }
- ictx = GF_CALLOC (1, sizeof (*ictx), gf_index_inode_ctx_t);
- if (!ictx) {
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (&ictx->callstubs);
- ret = __inode_ctx_put (inode, this, (uint64_t)ictx);
- if (ret) {
- GF_FREE (ictx);
- ictx = NULL;
- goto out;
- }
-out:
- if (ictx)
- *ctx = ictx;
- return ret;
-}
-
-int
-index_inode_ctx_get (inode_t *inode, xlator_t *this, index_inode_ctx_t **ctx)
-{
- int ret = 0;
-
- LOCK (&inode->lock);
- {
- ret = __index_inode_ctx_get (inode, this, ctx);
- }
- UNLOCK (&inode->lock);
-
- return ret;
-}
-
-static void
-make_index_dir_path (char *base, const char *subdir,
- char *index_dir, size_t len)
-{
- snprintf (index_dir, len, "%s/%s", base, subdir);
-}
-
-int
-index_dir_create (xlator_t *this, const char *subdir)
-{
- int ret = 0;
- struct stat st = {0};
- char fullpath[PATH_MAX] = {0};
- char path[PATH_MAX] = {0};
- char *dir = NULL;
- index_priv_t *priv = NULL;
- size_t len = 0;
- size_t pathlen = 0;
-
- priv = this->private;
- make_index_dir_path (priv->index_basepath, subdir, fullpath,
- sizeof (fullpath));
- ret = stat (fullpath, &st);
- if (!ret) {
- if (!S_ISDIR (st.st_mode))
- ret = -2;
- goto out;
- }
-
- pathlen = strlen (fullpath);
- if ((pathlen > 1) && fullpath[pathlen - 1] == '/')
- fullpath[pathlen - 1] = '\0';
- dir = strchr (fullpath, '/');
- while (dir) {
- dir = strchr (dir + 1, '/');
- if (dir)
- len = pathlen - strlen (dir);
- else
- len = pathlen;
- strncpy (path, fullpath, len);
- path[len] = '\0';
- ret = mkdir (path, 0600);
- if (ret && (errno != EEXIST))
- goto out;
- }
- ret = 0;
-out:
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s: Failed to "
- "create (%s)", priv->index_basepath, subdir,
- strerror (errno));
- } else if (ret == -2) {
- gf_log (this->name, GF_LOG_ERROR, "%s/%s: Failed to create, "
- "path exists, not a directory ", priv->index_basepath,
- subdir);
- }
- return ret;
-}
-
-void
-index_get_index (index_priv_t *priv, uuid_t index)
-{
- LOCK (&priv->lock);
- {
- uuid_copy (index, priv->index);
- }
- UNLOCK (&priv->lock);
-}
-
-void
-index_generate_index (index_priv_t *priv, uuid_t index)
-{
- LOCK (&priv->lock);
- {
- //To prevent duplicate generates.
- //This method fails if number of contending threads is greater
- //than MAX_LINK count of the fs
- if (!uuid_compare (priv->index, index))
- uuid_generate (priv->index);
- uuid_copy (index, priv->index);
- }
- UNLOCK (&priv->lock);
-}
-
-static void
-make_index_path (char *base, const char *subdir, uuid_t index,
- char *index_path, size_t len)
-{
- make_index_dir_path (base, subdir, index_path, len);
- snprintf (index_path + strlen (index_path), len - strlen (index_path),
- "/%s-%s", subdir, uuid_utoa (index));
-}
-
-static void
-make_gfid_path (char *base, const char *subdir, uuid_t gfid,
- char *gfid_path, size_t len)
-{
- make_index_dir_path (base, subdir, gfid_path, len);
- snprintf (gfid_path + strlen (gfid_path), len - strlen (gfid_path),
- "/%s", uuid_utoa (gfid));
-}
-
-static void
-make_file_path (char *base, const char *subdir, const char *filename,
- char *file_path, size_t len)
-{
- make_index_dir_path (base, subdir, file_path, len);
- snprintf (file_path + strlen (file_path), len - strlen (file_path),
- "/%s", filename);
-}
-
-static void
-check_delete_stale_index_file (xlator_t *this, char *filename)
-{
- int ret = 0;
- struct stat st = {0};
- char filepath[PATH_MAX] = {0};
- index_priv_t *priv = NULL;
-
- priv = this->private;
- make_file_path (priv->index_basepath, XATTROP_SUBDIR,
- filename, filepath, sizeof (filepath));
- ret = stat (filepath, &st);
- if (!ret && st.st_nlink == 1)
- unlink (filepath);
-}
-
-static int
-index_fill_readdir (fd_t *fd, DIR *dir, off_t off,
- size_t size, gf_dirent_t *entries)
-{
- off_t in_case = -1;
- size_t filled = 0;
- int count = 0;
- char entrybuf[sizeof(struct dirent) + 256 + 8];
- struct dirent *entry = NULL;
- int32_t this_size = -1;
- gf_dirent_t *this_entry = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- if (!off) {
- rewinddir (dir);
- } else {
- seekdir (dir, off);
- }
-
- while (filled <= size) {
- in_case = telldir (dir);
-
- if (in_case == -1) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "telldir failed on dir=%p: %s",
- dir, strerror (errno));
- goto out;
- }
-
- errno = 0;
- entry = NULL;
- readdir_r (dir, (struct dirent *)entrybuf, &entry);
-
- if (!entry) {
- if (errno == EBADF) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "readdir failed on dir=%p: %s",
- dir, strerror (errno));
- goto out;
- }
- break;
- }
-
- if (!strncmp (entry->d_name, XATTROP_SUBDIR"-",
- strlen (XATTROP_SUBDIR"-"))) {
- check_delete_stale_index_file (this, entry->d_name);
- continue;
- }
-
- this_size = max (sizeof (gf_dirent_t),
- sizeof (gfs3_dirplist))
- + strlen (entry->d_name) + 1;
-
- if (this_size + filled > size) {
- seekdir (dir, in_case);
- break;
- }
-
- this_entry = gf_dirent_for_name (entry->d_name);
-
- if (!this_entry) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "could not create gf_dirent for entry %s: (%s)",
- entry->d_name, strerror (errno));
- goto out;
- }
- this_entry->d_off = telldir (dir);
- this_entry->d_ino = entry->d_ino;
-
- list_add_tail (&this_entry->list, &entries->list);
-
- filled += this_size;
- count ++;
- }
-
- if ((!readdir (dir) && (errno == 0)))
- /* Indicate EOF */
- errno = ENOENT;
-out:
- return count;
-}
-
-int
-index_add (xlator_t *this, uuid_t gfid, const char *subdir)
-{
- int32_t op_errno = 0;
- char gfid_path[PATH_MAX] = {0};
- char index_path[PATH_MAX] = {0};
- int ret = 0;
- uuid_t index = {0};
- index_priv_t *priv = NULL;
- struct stat st = {0};
- int fd = 0;
-
- priv = this->private;
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !uuid_is_null (gfid),
- out, op_errno, EINVAL);
-
- make_gfid_path (priv->index_basepath, subdir, gfid,
- gfid_path, sizeof (gfid_path));
-
- ret = stat (gfid_path, &st);
- if (!ret)
- goto out;
- index_get_index (priv, index);
- make_index_path (priv->index_basepath, subdir,
- index, index_path, sizeof (index_path));
- ret = link (index_path, gfid_path);
- if (!ret || (errno == EEXIST)) {
- ret = 0;
- goto out;
- }
-
- op_errno = errno;
- if (op_errno == ENOENT) {
- ret = index_dir_create (this, subdir);
- if (ret)
- goto out;
- } else if (op_errno == EMLINK) {
- index_generate_index (priv, index);
- make_index_path (priv->index_basepath, subdir,
- index, index_path, sizeof (index_path));
- } else {
- goto out;
- }
-
- fd = creat (index_path, 0);
- if ((fd < 0) && (errno != EEXIST)) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "%s: Not able to "
- "create index (%s)", uuid_utoa (gfid),
- strerror (errno));
- goto out;
- }
-
- if (fd >= 0)
- close (fd);
-
- ret = link (index_path, gfid_path);
- if (ret && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_ERROR, "%s: Not able to "
- "add to index (%s)", uuid_utoa (gfid),
- strerror (errno));
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-index_del (xlator_t *this, uuid_t gfid, const char *subdir)
-{
- int32_t op_errno __attribute__((unused)) = 0;
- index_priv_t *priv = NULL;
- int ret = 0;
- char gfid_path[PATH_MAX] = {0};
-
- priv = this->private;
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, !uuid_is_null (gfid),
- out, op_errno, EINVAL);
- make_gfid_path (priv->index_basepath, subdir, gfid,
- gfid_path, sizeof (gfid_path));
- ret = unlink (gfid_path);
- if (ret && (errno != ENOENT)) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: failed to delete from index (%s)",
- gfid_path, strerror (errno));
- ret = -errno;
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-void
-_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
-{
- data_pair_t *trav = NULL;
- gf_boolean_t zero_xattr = _gf_true;
- index_inode_ctx_t *ctx = NULL;
- int ret = 0;
-
- trav = xattr->members_list;
- while (trav && inode) {
- if (mem_0filled ((const char*)trav->value->data,
- trav->value->len)) {
- zero_xattr = _gf_false;
- break;
- }
- trav = trav->next;
- }
- ret = index_inode_ctx_get (inode, this, &ctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Not able to %s %s -> index",
- zero_xattr?"add":"del", uuid_utoa (inode->gfid));
- goto out;
- }
- if (zero_xattr) {
- if (ctx->state == NOTIN)
- goto out;
- ret = index_del (this, inode->gfid, XATTROP_SUBDIR);
- if (!ret)
- ctx->state = NOTIN;
- } else {
- if (ctx->state == IN)
- goto out;
- ret = index_add (this, inode->gfid, XATTROP_SUBDIR);
- if (!ret)
- ctx->state = IN;
- }
-out:
- return;
-}
-
-void
-fop_xattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
-{
- _xattrop_index_action (this, inode, xattr);
-}
-
-void
-fop_fxattrop_index_action (xlator_t *this, inode_t *inode, dict_t *xattr)
-{
- _xattrop_index_action (this, inode, xattr);
-}
-
-inline gf_boolean_t
-index_xattrop_track (loc_t *loc, gf_xattrop_flags_t flags, dict_t *dict)
-{
- return (flags == GF_XATTROP_ADD_ARRAY);
-}
-
-inline gf_boolean_t
-index_fxattrop_track (fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict)
-{
- return (flags == GF_XATTROP_ADD_ARRAY);
-}
-
-int
-__index_fd_ctx_get (fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx)
-{
- int ret = 0;
- index_fd_ctx_t *fctx = NULL;
- uint64_t tmpctx = 0;
- char index_dir[PATH_MAX] = {0};
- index_priv_t *priv = NULL;
-
- priv = this->private;
- if (uuid_compare (fd->inode->gfid, priv->xattrop_vgfid)) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = __fd_ctx_get (fd, this, &tmpctx);
- if (!ret) {
- fctx = (index_fd_ctx_t*) (long) tmpctx;
- goto out;
- }
-
- fctx = GF_CALLOC (1, sizeof (*fctx), gf_index_fd_ctx_t);
- if (!fctx) {
- ret = -ENOMEM;
- goto out;
- }
-
- make_index_dir_path (priv->index_basepath, XATTROP_SUBDIR,
- index_dir, sizeof (index_dir));
- fctx->dir = opendir (index_dir);
- if (!fctx->dir) {
- ret = -errno;
- GF_FREE (fctx);
- fctx = NULL;
- goto out;
- }
-
- ret = __fd_ctx_set (fd, this, (uint64_t)(long)fctx);
- if (ret) {
- GF_FREE (fctx);
- fctx = NULL;
- ret = -EINVAL;
- goto out;
- }
-out:
- if (fctx)
- *ctx = fctx;
- return ret;
-}
-
-int
-index_fd_ctx_get (fd_t *fd, xlator_t *this, index_fd_ctx_t **ctx)
-{
- int ret = 0;
- LOCK (&fd->lock);
- {
- ret = __index_fd_ctx_get (fd, this, ctx);
- }
- UNLOCK (&fd->lock);
- return ret;
-}
-
-//new - Not NULL means start a fop
-//new - NULL means done processing the fop
-void
-index_queue_process (xlator_t *this, inode_t *inode, call_stub_t *new)
-{
- call_stub_t *stub = NULL;
- index_inode_ctx_t *ctx = NULL;
- int ret = 0;
- call_frame_t *frame = NULL;
-
- LOCK (&inode->lock);
- {
- ret = __index_inode_ctx_get (inode, this, &ctx);
- if (ret)
- goto unlock;
-
- if (new) {
- __index_enqueue (&ctx->callstubs, new);
- new = NULL;
- } else {
- ctx->processing = _gf_false;
- }
-
- if (!ctx->processing) {
- stub = __index_dequeue (&ctx->callstubs);
- if (stub)
- ctx->processing = _gf_true;
- else
- ctx->processing = _gf_false;
- }
- }
-unlock:
- UNLOCK (&inode->lock);
-
- if (ret && new) {
- frame = new->frame;
- if (new->fop == GF_FOP_XATTROP) {
- INDEX_STACK_UNWIND (xattrop, frame, -1, ENOMEM,
- NULL, NULL);
- } else if (new->fop == GF_FOP_FXATTROP) {
- INDEX_STACK_UNWIND (fxattrop, frame, -1, ENOMEM,
- NULL, NULL);
- }
- call_stub_destroy (new);
- } else if (stub) {
- call_resume (stub);
- }
- return;
-}
-
-int32_t
-index_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = inode_ref (frame->local);
- if (op_ret < 0)
- goto out;
- fop_xattrop_index_action (this, frame->local, xattr);
-out:
- INDEX_STACK_UNWIND (xattrop, frame, op_ret, op_errno, xattr, xdata);
- index_queue_process (this, inode, NULL);
- inode_unref (inode);
-
- return 0;
-}
-
-int32_t
-index_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
-{
- inode_t *inode = NULL;
-
- inode = inode_ref (frame->local);
- if (op_ret < 0)
- goto out;
-
- fop_fxattrop_index_action (this, frame->local, xattr);
-out:
- INDEX_STACK_UNWIND (fxattrop, frame, op_ret, op_errno, xattr, xdata);
- index_queue_process (this, inode, NULL);
- inode_unref (inode);
-
- return 0;
-}
-
-int
-index_xattrop_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
-{
- STACK_WIND (frame, index_xattrop_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->xattrop, loc, optype, xattr,
- xdata);
- return 0;
-}
-
-int
-index_fxattrop_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
-{
- STACK_WIND (frame, index_fxattrop_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fxattrop, fd, optype, xattr,
- xdata);
- return 0;
-}
-
-int32_t
-index_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- if (!index_xattrop_track (loc, flags, dict))
- goto out;
-
- frame->local = inode_ref (loc->inode);
- stub = fop_xattrop_stub (frame, index_xattrop_wrapper,
- loc, flags, dict, xdata);
- if (!stub) {
- INDEX_STACK_UNWIND (xattrop, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
-
- index_queue_process (this, loc->inode, stub);
- return 0;
-out:
- STACK_WIND (frame, default_xattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, loc, flags, dict, xdata);
- return 0;
-}
-
-int32_t
-index_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- if (!index_fxattrop_track (fd, flags, dict))
- goto out;
-
- frame->local = inode_ref (fd->inode);
- stub = fop_fxattrop_stub (frame, index_fxattrop_wrapper,
- fd, flags, dict, xdata);
- if (!stub) {
- INDEX_STACK_UNWIND (fxattrop, frame, -1, ENOMEM, NULL, xdata);
- return 0;
- }
-
- index_queue_process (this, fd->inode, stub);
- return 0;
-out:
- STACK_WIND (frame, default_fxattrop_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict, xdata);
- return 0;
-}
-
-int32_t
-index_getxattr_wrapper (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- index_priv_t *priv = NULL;
- dict_t *xattr = NULL;
- int ret = 0;
-
- priv = this->private;
-
- xattr = dict_new ();
- if (!xattr) {
- ret = -ENOMEM;
- goto done;
- }
-
- ret = dict_set_static_bin (xattr, (char*)name, priv->xattrop_vgfid,
- sizeof (priv->xattrop_vgfid));
- if (ret) {
- ret = -ENOMEM;
- gf_log (THIS->name, GF_LOG_ERROR, "xattrop index "
- "gfid set failed");
- goto done;
- }
-done:
- if (ret)
- STACK_UNWIND_STRICT (getxattr, frame, -1, -ret, xattr, xdata);
- else
- STACK_UNWIND_STRICT (getxattr, frame, 0, 0, xattr, xdata);
-
- if (xattr)
- dict_unref (xattr);
-
- return 0;
-}
-
-int32_t
-index_lookup_wrapper (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr_req)
-{
- index_priv_t *priv = NULL;
- struct stat lstatbuf = {0};
- int ret = 0;
- int32_t op_errno = EINVAL;
- int32_t op_ret = -1;
- char path[PATH_MAX] = {0};
- struct iatt stbuf = {0, };
- struct iatt postparent = {0,};
- dict_t *xattr = NULL;
- gf_boolean_t is_dir = _gf_false;
-
- priv = this->private;
-
- VALIDATE_OR_GOTO (loc, done);
- if (!uuid_compare (loc->gfid, priv->xattrop_vgfid)) {
- make_index_dir_path (priv->index_basepath, XATTROP_SUBDIR,
- path, sizeof (path));
- is_dir = _gf_true;
- } else if (!uuid_compare (loc->pargfid, priv->xattrop_vgfid)) {
- make_file_path (priv->index_basepath, XATTROP_SUBDIR,
- loc->name, path, sizeof (path));
- }
-
- ret = lstat (path, &lstatbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Stat failed on index dir "
- "(%s)", strerror (errno));
- op_errno = errno;
- goto done;
- } else if (!S_ISDIR (lstatbuf.st_mode) && is_dir) {
- gf_log (this->name, GF_LOG_DEBUG, "Stat failed on index dir, "
- "not a directory");
- op_errno = ENOENT;
- goto done;
- }
- xattr = dict_new ();
- if (!xattr) {
- op_errno = ENOMEM;
- goto done;
- }
-
- iatt_from_stat (&stbuf, &lstatbuf);
- if (is_dir)
- uuid_copy (stbuf.ia_gfid, priv->xattrop_vgfid);
- else
- uuid_generate (stbuf.ia_gfid);
- stbuf.ia_ino = -1;
- op_ret = 0;
-done:
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno,
- loc->inode, &stbuf, xattr, &postparent);
- if (xattr)
- dict_unref (xattr);
- return 0;
-}
-
-int32_t
-index_readdir_wrapper (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t off, dict_t *xdata)
-{
- index_fd_ctx_t *fctx = NULL;
- DIR *dir = NULL;
- int ret = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int count = 0;
- gf_dirent_t entries;
-
- INIT_LIST_HEAD (&entries.list);
-
- ret = index_fd_ctx_get (fd, this, &fctx);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "pfd is NULL, fd=%p", fd);
- op_errno = -ret;
- goto done;
- }
-
- dir = fctx->dir;
-
- if (!dir) {
- gf_log (this->name, GF_LOG_WARNING,
- "dir is NULL for fd=%p", fd);
- op_errno = EINVAL;
- goto done;
- }
-
- count = index_fill_readdir (fd, dir, off, size, &entries);
-
- /* pick ENOENT to indicate EOF */
- op_errno = errno;
- op_ret = count;
-done:
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, &entries, xdata);
- gf_dirent_free (&entries);
- return 0;
-}
-
-int
-index_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,
- dict_t *xdata)
-{
- index_priv_t *priv = NULL;
- int32_t op_ret = 0;
- int32_t op_errno = 0;
- int ret = 0;
- struct iatt preparent = {0};
- struct iatt postparent = {0};
- char index_dir[PATH_MAX] = {0};
- struct stat lstatbuf = {0};
- uuid_t gfid = {0};
-
- priv = this->private;
- make_index_dir_path (priv->index_basepath, XATTROP_SUBDIR,
- index_dir, sizeof (index_dir));
- ret = lstat (index_dir, &lstatbuf);
- if (ret < 0) {
- op_ret = -1;
- op_errno = errno;
- goto done;
- }
-
- iatt_from_stat (&preparent, &lstatbuf);
- uuid_copy (preparent.ia_gfid, priv->xattrop_vgfid);
- preparent.ia_ino = -1;
- uuid_parse (loc->name, gfid);
- ret = index_del (this, gfid, XATTROP_SUBDIR);
- if (ret < 0) {
- op_ret = -1;
- op_errno = -ret;
- goto done;
- }
- memset (&lstatbuf, 0, sizeof (lstatbuf));
- ret = lstat (index_dir, &lstatbuf);
- if (ret < 0) {
- op_ret = -1;
- op_errno = errno;
- goto done;
- }
- iatt_from_stat (&postparent, &lstatbuf);
- uuid_copy (postparent.ia_gfid, priv->xattrop_vgfid);
- postparent.ia_ino = -1;
-done:
- INDEX_STACK_UNWIND (unlink, frame, op_ret, op_errno, &preparent,
- &postparent, xdata);
- return 0;
-}
-
-int32_t
-index_getxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
-
- if (!name || strcmp (GF_XATTROP_INDEX_GFID, name))
- goto out;
-
- stub = fop_getxattr_stub (frame, index_getxattr_wrapper, loc, name,
- xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
- worker_enqueue (this, stub);
- return 0;
-out:
- STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
- return 0;
-}
-
-int32_t
-index_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xattr_req)
-{
- call_stub_t *stub = NULL;
- index_priv_t *priv = NULL;
-
- priv = this->private;
-
- if (uuid_compare (loc->gfid, priv->xattrop_vgfid) &&
- uuid_compare (loc->pargfid, priv->xattrop_vgfid))
- goto normal;
-
- stub = fop_lookup_stub (frame, index_lookup_wrapper, loc, xattr_req);
- if (!stub) {
- STACK_UNWIND_STRICT (lookup, frame, -1, ENOMEM, loc->inode,
- NULL, NULL, NULL);
- return 0;
- }
- worker_enqueue (this, stub);
- return 0;
-normal:
- STACK_WIND (frame, default_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
-
- return 0;
-}
-
-int32_t
-index_readdir (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t off, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- index_priv_t *priv = NULL;
-
- priv = this->private;
- if (uuid_compare (fd->inode->gfid, priv->xattrop_vgfid))
- goto out;
- stub = fop_readdir_stub (frame, index_readdir_wrapper, fd, size, off,
- xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM, NULL, NULL);
- return 0;
- }
- worker_enqueue (this, stub);
- return 0;
-out:
- STACK_WIND (frame, default_readdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readdir, fd, size, off, xdata);
- return 0;
-}
-
-int
-index_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- index_priv_t *priv = NULL;
-
- priv = this->private;
- if (uuid_compare (loc->pargfid, priv->xattrop_vgfid))
- goto out;
-
- stub = fop_unlink_stub (frame, index_unlink_wrapper, loc, xflag, xdata);
- if (!stub) {
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL,
- NULL);
- return 0;
- }
- worker_enqueue (this, stub);
- return 0;
-out:
- STACK_WIND (frame, default_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- return 0;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_index_mt_end + 1);
-
- return ret;
-}
-
-int
-init (xlator_t *this)
-{
- int ret = -1;
- index_priv_t *priv = NULL;
- pthread_t thread;
- pthread_attr_t w_attr;
- gf_boolean_t mutex_inited = _gf_false;
- gf_boolean_t cond_inited = _gf_false;
- gf_boolean_t attr_inited = _gf_false;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "'index' not configured with exactly one child");
- goto out;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
-
- priv = GF_CALLOC (1, sizeof (*priv), gf_index_mt_priv_t);
- if (!priv)
- goto out;
-
- LOCK_INIT (&priv->lock);
- if ((ret = pthread_cond_init(&priv->cond, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_cond_init failed (%d)", ret);
- goto out;
- }
- cond_inited = _gf_true;
-
- if ((ret = pthread_mutex_init(&priv->mutex, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_mutex_init failed (%d)", ret);
- goto out;
- }
- mutex_inited = _gf_true;
-
- if ((ret = pthread_attr_init (&w_attr)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_attr_init failed (%d)", ret);
- goto out;
- }
- attr_inited = _gf_true;
-
- ret = pthread_attr_setstacksize (&w_attr, INDEX_THREAD_STACK_SIZE);
- if (ret == EINVAL) {
- gf_log (this->name, GF_LOG_WARNING,
- "Using default thread stack size");
- }
- GF_OPTION_INIT ("index-base", priv->index_basepath, path, out);
- uuid_generate (priv->index);
- uuid_generate (priv->xattrop_vgfid);
- INIT_LIST_HEAD (&priv->callstubs);
-
- this->private = priv;
- ret = pthread_create (&thread, &w_attr, index_worker, this);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "Failed to create "
- "worker thread, aborting");
- goto out;
- }
- ret = 0;
-out:
- if (ret) {
- if (cond_inited)
- pthread_cond_destroy (&priv->cond);
- if (mutex_inited)
- pthread_mutex_destroy (&priv->mutex);
- if (priv)
- GF_FREE (priv);
- this->private = NULL;
- }
- if (attr_inited)
- pthread_attr_destroy (&w_attr);
- return ret;
-}
-
-void
-fini (xlator_t *this)
-{
- index_priv_t *priv = NULL;
-
- priv = this->private;
- if (!priv)
- goto out;
- this->private = NULL;
- LOCK_DESTROY (&priv->lock);
- pthread_cond_destroy (&priv->cond);
- pthread_mutex_destroy (&priv->mutex);
- GF_FREE (priv);
-out:
- return;
-}
-
-int
-index_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t tmp_cache = 0;
- if (!inode_ctx_del (inode, this, &tmp_cache))
- GF_FREE ((index_inode_ctx_t*) (long)tmp_cache);
-
- return 0;
-}
-
-int32_t
-index_releasedir (xlator_t *this, fd_t *fd)
-{
- index_fd_ctx_t *fctx = NULL;
- uint64_t ctx = 0;
- int ret = 0;
-
- ret = fd_ctx_del (fd, this, &ctx);
- if (ret < 0)
- goto out;
-
- fctx = (index_fd_ctx_t*) (long) ctx;
- if (fctx->dir)
- closedir (fctx->dir);
-
- GF_FREE (fctx);
-out:
- return 0;
-}
-
-int32_t
-index_release (xlator_t *this, fd_t *fd)
-{
- index_fd_ctx_t *fctx = NULL;
- uint64_t ctx = 0;
- int ret = 0;
-
- ret = fd_ctx_del (fd, this, &ctx);
- if (ret < 0)
- goto out;
-
- fctx = (index_fd_ctx_t*) (long) ctx;
- GF_FREE (fctx);
-out:
- return 0;
-}
-
-int
-notify (xlator_t *this, int event, void *data, ...)
-{
- int ret = 0;
- ret = default_notify (this, event, data);
- return ret;
-}
-
-struct xlator_fops fops = {
- .xattrop = index_xattrop,
- .fxattrop = index_fxattrop,
-
- //interface functions follow
- .getxattr = index_getxattr,
- .lookup = index_lookup,
- .readdir = index_readdir,
- .unlink = index_unlink
-};
-
-struct xlator_dumpops dumpops = {
-};
-
-struct xlator_cbks cbks = {
- .forget = index_forget,
- .release = index_release,
- .releasedir = index_releasedir
-};
-
-struct volume_options options[] = {
- { .key = {"index-base" },
- .type = GF_OPTION_TYPE_PATH,
- .description = "path where the index files need to be stored",
- },
- { .key = {NULL} },
-};
diff --git a/xlators/features/index/src/index.h b/xlators/features/index/src/index.h
deleted file mode 100644
index 36bc9acb7..000000000
--- a/xlators/features/index/src/index.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef __INDEX_H__
-#define __INDEX_H__
-
-#include "xlator.h"
-#include "call-stub.h"
-#include "defaults.h"
-#include "byte-order.h"
-#include "common-utils.h"
-#include "index-mem-types.h"
-
-#define INDEX_THREAD_STACK_SIZE ((size_t)(1024*1024))
-
-typedef enum {
- UNKNOWN,
- IN,
- NOTIN
-} index_state_t;
-
-typedef struct index_inode_ctx {
- gf_boolean_t processing;
- struct list_head callstubs;
- index_state_t state;
-} index_inode_ctx_t;
-
-typedef struct index_fd_ctx {
- DIR *dir;
-} index_fd_ctx_t;
-
-typedef struct index_priv {
- char *index_basepath;
- uuid_t index;
- gf_lock_t lock;
- uuid_t xattrop_vgfid;//virtual gfid of the xattrop index dir
- struct list_head callstubs;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} index_priv_t;
-
-#define INDEX_STACK_UNWIND(fop, frame, params ...) \
-do { \
- if (frame) { \
- inode_t *_inode = frame->local; \
- frame->local = NULL; \
- inode_unref (_inode); \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
-} while (0)
-
-#endif
diff --git a/xlators/features/locks/src/Makefile.am b/xlators/features/locks/src/Makefile.am
index e39676826..53dd3aa5d 100644
--- a/xlators/features/locks/src/Makefile.am
+++ b/xlators/features/locks/src/Makefile.am
@@ -3,14 +3,12 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
locks_la_LDFLAGS = -module -avoidversion
-locks_la_SOURCES = common.c posix.c entrylk.c inodelk.c reservelk.c \
- clear.c
-locks_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+locks_la_SOURCES = common.c posix.c entrylk.c inodelk.c reservelk.c
+locks_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = locks.h common.h locks-mem-types.h clear.h
+noinst_HEADERS = locks.h common.h locks-mem-types.h
-AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \
- -fno-strict-aliasing -D$(GF_HOST_OS) \
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -fno-strict-aliasing -D$(GF_HOST_OS) \
-I$(top_srcdir)/libglusterfs/src $(GF_CFLAGS) -shared -nostartfiles
CLEANFILES =
@@ -19,4 +17,4 @@ uninstall-local:
rm -f $(DESTDIR)$(xlatordir)/posix-locks.so
install-data-hook:
- ln -sf locks.so $(DESTDIR)$(xlatordir)/posix-locks.so
+ ln -sf locks.so $(DESTDIR)$(xlatordir)/posix-locks.so \ No newline at end of file
diff --git a/xlators/features/locks/src/clear.c b/xlators/features/locks/src/clear.c
deleted file mode 100644
index 015a9fe72..000000000
--- a/xlators/features/locks/src/clear.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pthread.h>
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "compat.h"
-#include "xlator.h"
-#include "inode.h"
-#include "logging.h"
-#include "common-utils.h"
-
-#include "locks.h"
-#include "common.h"
-#include "statedump.h"
-#include "clear.h"
-
-int
-clrlk_get_kind (char *kind)
-{
- char *clrlk_kinds[CLRLK_KIND_MAX] = {"dummy", "blocked", "granted",
- "all"};
- int ret_kind = CLRLK_KIND_MAX;
- int i = 0;
-
- for (i = CLRLK_BLOCKED; i < CLRLK_KIND_MAX; i++) {
- if (!strcmp (clrlk_kinds[i], kind)) {
- ret_kind = i;
- break;
- }
- }
-
- return ret_kind;
-}
-
-int
-clrlk_get_type (char *type)
-{
- char *clrlk_types[CLRLK_TYPE_MAX] = {"inode", "entry", "posix"};
- int ret_type = CLRLK_TYPE_MAX;
- int i = 0;
-
- for (i = CLRLK_INODE; i < CLRLK_TYPE_MAX; i++) {
- if (!strcmp (clrlk_types[i], type)) {
- ret_type = i;
- break;
- }
- }
-
- return ret_type;
-}
-
-int
-clrlk_get_lock_range (char *range_str, struct gf_flock *ulock,
- gf_boolean_t *chk_range)
-{
- int ret = -1;
-
- if (!chk_range)
- goto out;
-
- if (!range_str) {
- ret = 0;
- *chk_range = _gf_false;
- goto out;
- }
-
- if (sscanf (range_str, "%hd,%"PRId64"-""%"PRId64, &ulock->l_whence,
- &ulock->l_start, &ulock->l_len) != 3) {
- goto out;
- }
-
- ret = 0;
- *chk_range = _gf_true;
-out:
- return ret;
-}
-
-int
-clrlk_parse_args (const char* cmd, clrlk_args *args)
-{
- char *opts = NULL;
- char *cur = NULL;
- char *tok = NULL;
- char *sptr = NULL;
- char *free_ptr = NULL;
- char kw[KW_MAX] = {[KW_TYPE] = 't',
- [KW_KIND] = 'k',
- };
- int ret = -1;
- int i = 0;
-
- GF_ASSERT (cmd);
- free_ptr = opts = GF_CALLOC (1, strlen (cmd), gf_common_mt_char);
- if (!opts)
- goto out;
-
- if (sscanf (cmd, GF_XATTR_CLRLK_CMD".%s", opts) < 1) {
- ret = -1;
- goto out;
- }
-
- /*clr_lk_prefix.ttype.kkind.args, args - type specific*/
- cur = opts;
- for (i = 0; i < KW_MAX && (tok = strtok_r (cur, ".", &sptr));
- cur = NULL, i++) {
- if (tok[0] != kw[i]) {
- ret = -1;
- goto out;
- }
- if (i == KW_TYPE)
- args->type = clrlk_get_type (tok+1);
- if (i == KW_KIND)
- args->kind = clrlk_get_kind (tok+1);
- }
-
- if ((args->type == CLRLK_TYPE_MAX) || (args->kind == CLRLK_KIND_MAX))
- goto out;
-
- /*optional args, neither range nor basename can 'legally' contain
- * "/" in them*/
- tok = strtok_r (NULL, "/", &sptr);
- if (tok)
- args->opts = gf_strdup (tok);
-
- ret = 0;
-out:
- GF_FREE (free_ptr);
- return ret;
-}
-
-int
-clrlk_clear_posixlk (xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args,
- int *blkd, int *granted, int *op_errno)
-{
- posix_lock_t *plock = NULL;
- posix_lock_t *tmp = NULL;
- struct gf_flock ulock = {0, };
- int ret = -1;
- int bcount = 0;
- int gcount = 0;
- gf_boolean_t chk_range = _gf_false;
-
- if (clrlk_get_lock_range (args->opts, &ulock, &chk_range)) {
- *op_errno = EINVAL;
- goto out;
- }
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (plock, tmp, &pl_inode->ext_list,
- list) {
- if ((plock->blocked &&
- !(args->kind & CLRLK_BLOCKED)) ||
- (!plock->blocked &&
- !(args->kind & CLRLK_GRANTED)))
- continue;
-
- if (chk_range &&
- (plock->user_flock.l_whence != ulock.l_whence
- || plock->user_flock.l_start != ulock.l_start
- || plock->user_flock.l_len != ulock.l_len))
- continue;
-
- list_del_init (&plock->list);
- if (plock->blocked) {
- bcount++;
- pl_trace_out (this, plock->frame, NULL, NULL,
- F_SETLKW, &plock->user_flock,
- -1, EAGAIN, NULL);
-
- STACK_UNWIND_STRICT (lk, plock->frame, -1, EAGAIN,
- &plock->user_flock, NULL);
-
- } else {
- gcount++;
- }
- GF_FREE (plock);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
- grant_blocked_locks (this, pl_inode);
- ret = 0;
-out:
- *blkd = bcount;
- *granted = gcount;
- return ret;
-}
-
-/* Returns 0 on success and -1 on failure */
-int
-clrlk_clear_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom,
- clrlk_args *args, int *blkd, int *granted, int *op_errno)
-{
- pl_inode_lock_t *ilock = NULL;
- pl_inode_lock_t *tmp = NULL;
- struct gf_flock ulock = {0, };
- int ret = -1;
- int bcount = 0;
- int gcount = 0;
- gf_boolean_t chk_range = _gf_false;
- struct list_head released;
-
- INIT_LIST_HEAD (&released);
- if (clrlk_get_lock_range (args->opts, &ulock, &chk_range)) {
- *op_errno = EINVAL;
- goto out;
- }
-
- if (args->kind & CLRLK_BLOCKED)
- goto blkd;
-
- if (args->kind & CLRLK_GRANTED)
- goto granted;
-
-blkd:
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (ilock, tmp, &dom->blocked_inodelks,
- blocked_locks) {
- if (chk_range &&
- (ilock->user_flock.l_whence != ulock.l_whence
- || ilock->user_flock.l_start != ulock.l_start
- || ilock->user_flock.l_len != ulock.l_len))
- continue;
-
- bcount++;
- list_del_init (&ilock->blocked_locks);
- list_add (&ilock->blocked_locks, &released);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- list_for_each_entry_safe (ilock, tmp, &released, blocked_locks) {
- list_del_init (&ilock->blocked_locks);
- pl_trace_out (this, ilock->frame, NULL, NULL, F_SETLKW,
- &ilock->user_flock, -1, EAGAIN,
- ilock->volume);
- STACK_UNWIND_STRICT (inodelk, ilock->frame, -1,
- EAGAIN, NULL);
- //No need to take lock as the locks are only in one list
- __pl_inodelk_unref (ilock);
- }
-
- if (!(args->kind & CLRLK_GRANTED)) {
- ret = 0;
- goto out;
- }
-
-granted:
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (ilock, tmp, &dom->inodelk_list,
- list) {
- if (chk_range &&
- (ilock->user_flock.l_whence != ulock.l_whence
- || ilock->user_flock.l_start != ulock.l_start
- || ilock->user_flock.l_len != ulock.l_len))
- continue;
-
- gcount++;
- list_del_init (&ilock->list);
- list_add (&ilock->list, &released);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- list_for_each_entry_safe (ilock, tmp, &released, list) {
- list_del_init (&ilock->list);
- //No need to take lock as the locks are only in one list
- __pl_inodelk_unref (ilock);
- }
-
- ret = 0;
-out:
- grant_blocked_inode_locks (this, pl_inode, dom);
- *blkd = bcount;
- *granted = gcount;
- return ret;
-}
-
-/* Returns 0 on success and -1 on failure */
-int
-clrlk_clear_entrylk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom,
- clrlk_args *args, int *blkd, int *granted, int *op_errno)
-{
- pl_entry_lock_t *elock = NULL;
- pl_entry_lock_t *tmp = NULL;
- int bcount = 0;
- int gcount = 0;
- int ret = -1;
- struct list_head removed;
- struct list_head released;
-
- INIT_LIST_HEAD (&released);
- if (args->kind & CLRLK_BLOCKED)
- goto blkd;
-
- if (args->kind & CLRLK_GRANTED)
- goto granted;
-
-blkd:
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (elock, tmp, &dom->blocked_entrylks,
- blocked_locks) {
- if (args->opts) {
- if (!elock->basename ||
- strcmp (elock->basename, args->opts))
- continue;
- }
-
- bcount++;
-
- list_del_init (&elock->blocked_locks);
- list_add_tail (&elock->blocked_locks, &released);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- list_for_each_entry_safe (elock, tmp, &released, blocked_locks) {
- list_del_init (&elock->blocked_locks);
- entrylk_trace_out (this, elock->frame, elock->volume, NULL, NULL,
- elock->basename, ENTRYLK_LOCK, elock->type,
- -1, EAGAIN);
- STACK_UNWIND_STRICT (entrylk, elock->frame, -1, EAGAIN, NULL);
- GF_FREE ((char *) elock->basename);
- GF_FREE (elock);
- }
-
- if (!(args->kind & CLRLK_GRANTED)) {
- ret = 0;
- goto out;
- }
-
-granted:
- INIT_LIST_HEAD (&removed);
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (elock, tmp, &dom->entrylk_list,
- domain_list) {
- if (args->opts) {
- if (!elock->basename ||
- strcmp (elock->basename, args->opts))
- continue;
- }
-
- gcount++;
- list_del_init (&elock->domain_list);
- list_add_tail (&elock->domain_list, &removed);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
-
- list_for_each_entry_safe (elock, tmp, &removed, domain_list) {
- grant_blocked_entry_locks (this, pl_inode, elock, dom);
- }
-
- ret = 0;
-out:
- *blkd = bcount;
- *granted = gcount;
- return ret;
-}
-
-int
-clrlk_clear_lks_in_all_domains (xlator_t *this, pl_inode_t *pl_inode,
- clrlk_args *args, int *blkd, int *granted,
- int *op_errno)
-{
- pl_dom_list_t *dom = NULL;
- int ret = -1;
- int tmp_bcount = 0;
- int tmp_gcount = 0;
-
- if (list_empty (&pl_inode->dom_list)) {
- ret = 0;
- goto out;
- }
-
- list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
- tmp_bcount = tmp_gcount = 0;
-
- switch (args->type)
- {
- case CLRLK_INODE:
- ret = clrlk_clear_inodelk (this, pl_inode, dom, args,
- &tmp_bcount, &tmp_gcount,
- op_errno);
- if (ret)
- goto out;
- break;
- case CLRLK_ENTRY:
- ret = clrlk_clear_entrylk (this, pl_inode, dom, args,
- &tmp_bcount, &tmp_gcount,
- op_errno);
- if (ret)
- goto out;
- break;
- }
-
- *blkd += tmp_bcount;
- *granted += tmp_gcount;
- }
-
- ret = 0;
-out:
- return ret;
-}
diff --git a/xlators/features/locks/src/clear.h b/xlators/features/locks/src/clear.h
deleted file mode 100644
index 95572a971..000000000
--- a/xlators/features/locks/src/clear.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __CLEAR_H__
-#define __CLEAR_H__
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "compat-errno.h"
-#include "stack.h"
-#include "call-stub.h"
-#include "locks.h"
-
-typedef enum {
- CLRLK_INODE,
- CLRLK_ENTRY,
- CLRLK_POSIX,
- CLRLK_TYPE_MAX
-} clrlk_type;
-
-typedef enum {
- CLRLK_BLOCKED = 1,
- CLRLK_GRANTED,
- CLRLK_ALL,
- CLRLK_KIND_MAX
-} clrlk_kind;
-
-typedef enum {
- KW_TYPE,
- KW_KIND,
- /*add new keywords here*/
- KW_MAX
-} clrlk_opts;
-
-struct _clrlk_args;
-typedef struct _clrlk_args clrlk_args;
-
-struct _clrlk_args {
- int type;
- int kind;
- char *opts;
-};
-
-int
-clrlk_get__kind (char *kind);
-int
-clrlk_get_type (char *type);
-int
-clrlk_get_lock_range (char *range_str, struct gf_flock *ulock,
- gf_boolean_t *chk_range);
-int
-clrlk_parse_args (const char* cmd, clrlk_args *args);
-
-int
-clrlk_clear_posixlk (xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args,
- int *blkd, int *granted, int *op_errno);
-int
-clrlk_clear_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom,
- clrlk_args *args, int *blkd, int *granted, int *op_errno);
-int
-clrlk_clear_entrylk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom,
- clrlk_args *args, int *blkd, int *granted, int *op_errno);
-int
-clrlk_clear_lks_in_all_domains (xlator_t *this, pl_inode_t *pl_inode,
- clrlk_args *args, int *blkd, int *granted,
- int *op_errno);
-#endif /* __CLEAR_H__ */
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c
index 542043fe1..a2c6245d6 100644
--- a/xlators/features/locks/src/common.c
+++ b/xlators/features/locks/src/common.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -46,7 +46,7 @@ static int
pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
posix_lock_t *old_lock);
static pl_dom_list_t *
-__allocate_domain (const char *volume)
+allocate_domain (const char *volume)
{
pl_dom_list_t *dom = NULL;
@@ -88,19 +88,17 @@ get_domain (pl_inode_t *pl_inode, const char *volume)
GF_VALIDATE_OR_GOTO (POSIX_LOCKS, pl_inode, out);
GF_VALIDATE_OR_GOTO (POSIX_LOCKS, volume, out);
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
- if (strcmp (dom->domain, volume) == 0)
- goto unlock;
- }
+ list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
+ if (strcmp (dom->domain, volume) == 0)
+ goto found;
+
- dom = __allocate_domain (volume);
- if (dom)
- list_add (&dom->inode_list, &pl_inode->dom_list);
}
-unlock:
- pthread_mutex_unlock (&pl_inode->mutex);
+
+ dom = allocate_domain (volume);
+ if (dom)
+ list_add (&dom->inode_list, &pl_inode->dom_list);
+found:
if (dom) {
gf_log (POSIX_LOCKS, GF_LOG_TRACE, "Domain %s found", volume);
} else {
@@ -145,9 +143,9 @@ __pl_inode_is_empty (pl_inode_t *pl_inode)
void
pl_print_locker (char *str, int size, xlator_t *this, call_frame_t *frame)
{
- snprintf (str, size, "Pid=%llu, lk-owner=%s, Transport=%p, Frame=%llu",
+ snprintf (str, size, "Pid=%llu, lk-owner=%llu, Transport=%p, Frame=%llu",
(unsigned long long) frame->root->pid,
- lkowner_utoa (&frame->root->lk_owner),
+ (unsigned long long) frame->root->lk_owner,
(void *)frame->root->trans,
(unsigned long long) frame->root->unique);
}
@@ -178,17 +176,18 @@ pl_print_lockee (char *str, int size, fd_t *fd, loc_t *loc)
ipath = NULL;
}
- snprintf (str, size, "gfid=%s, fd=%p, path=%s",
- uuid_utoa (inode->gfid), fd,
+ snprintf (str, size, "ino=%llu, fd=%p, path=%s",
+ (unsigned long long) inode->ino, fd,
ipath ? ipath : "<nul>");
- GF_FREE (ipath);
+ if (ipath)
+ GF_FREE (ipath);
}
void
pl_print_lock (char *str, int size, int cmd,
- struct gf_flock *flock, gf_lkowner_t *owner)
+ struct gf_flock *flock, uint64_t owner)
{
char *cmd_str = NULL;
char *type_str = NULL;
@@ -236,11 +235,11 @@ pl_print_lock (char *str, int size, int cmd,
}
snprintf (str, size, "lock=FCNTL, cmd=%s, type=%s, "
- "start=%llu, len=%llu, pid=%llu, lk-owner=%s",
+ "start=%llu, len=%llu, pid=%llu, lk-owner=%llu",
cmd_str, type_str, (unsigned long long) flock->l_start,
(unsigned long long) flock->l_len,
(unsigned long long) flock->l_pid,
- lkowner_utoa (owner));
+ (unsigned long long) owner);
}
@@ -263,7 +262,7 @@ pl_trace_in (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
if (domain)
pl_print_inodelk (pl_lock, 256, cmd, flock, domain);
else
- pl_print_lock (pl_lock, 256, cmd, flock, &frame->root->lk_owner);
+ pl_print_lock (pl_lock, 256, cmd, flock, frame->root->lk_owner);
gf_log (this->name, GF_LOG_INFO,
"[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}",
@@ -313,7 +312,7 @@ pl_trace_out (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
if (domain)
pl_print_inodelk (pl_lock, 256, cmd, flock, domain);
else
- pl_print_lock (pl_lock, 256, cmd, flock, &frame->root->lk_owner);
+ pl_print_lock (pl_lock, 256, cmd, flock, frame->root->lk_owner);
pl_print_verdict (verdict, 32, op_ret, op_errno);
@@ -343,7 +342,7 @@ pl_trace_block (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
if (domain)
pl_print_inodelk (pl_lock, 256, cmd, flock, domain);
else
- pl_print_lock (pl_lock, 256, cmd, flock, &frame->root->lk_owner);
+ pl_print_lock (pl_lock, 256, cmd, flock, frame->root->lk_owner);
gf_log (this->name, GF_LOG_INFO,
"[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}",
@@ -401,7 +400,6 @@ pl_update_refkeeper (xlator_t *this, inode_t *inode)
pl_inode_t *pl_inode = NULL;
int is_empty = 0;
int need_unref = 0;
- int need_ref = 0;
pl_inode = pl_inode_get (this, inode);
@@ -415,17 +413,13 @@ pl_update_refkeeper (xlator_t *this, inode_t *inode)
}
if (!is_empty && !pl_inode->refkeeper) {
- need_ref = 1;
- pl_inode->refkeeper = inode;
+ pl_inode->refkeeper = inode_ref (inode);
}
}
pthread_mutex_unlock (&pl_inode->mutex);
if (need_unref)
inode_unref (inode);
-
- if (need_ref)
- inode_ref (inode);
}
@@ -436,36 +430,32 @@ pl_inode_get (xlator_t *this, inode_t *inode)
pl_inode_t *pl_inode = NULL;
int ret = 0;
- LOCK (&inode->lock);
- {
- ret = __inode_ctx_get (inode, this, &tmp_pl_inode);
- if (ret == 0) {
- pl_inode = (pl_inode_t *)(long)tmp_pl_inode;
- goto unlock;
- }
- pl_inode = GF_CALLOC (1, sizeof (*pl_inode),
- gf_locks_mt_pl_inode_t);
- if (!pl_inode) {
- goto unlock;
- }
+ ret = inode_ctx_get (inode, this,&tmp_pl_inode);
+ if (ret == 0) {
+ pl_inode = (pl_inode_t *)(long)tmp_pl_inode;
+ goto out;
+ }
+ pl_inode = GF_CALLOC (1, sizeof (*pl_inode),
+ gf_locks_mt_pl_inode_t);
+ if (!pl_inode) {
+ goto out;
+ }
- gf_log (this->name, GF_LOG_TRACE,
- "Allocating new pl inode");
+ gf_log (this->name, GF_LOG_TRACE,
+ "Allocating new pl inode");
- pthread_mutex_init (&pl_inode->mutex, NULL);
+ pthread_mutex_init (&pl_inode->mutex, NULL);
- INIT_LIST_HEAD (&pl_inode->dom_list);
- INIT_LIST_HEAD (&pl_inode->ext_list);
- INIT_LIST_HEAD (&pl_inode->rw_list);
- INIT_LIST_HEAD (&pl_inode->reservelk_list);
- INIT_LIST_HEAD (&pl_inode->blocked_reservelks);
- INIT_LIST_HEAD (&pl_inode->blocked_calls);
+ INIT_LIST_HEAD (&pl_inode->dom_list);
+ INIT_LIST_HEAD (&pl_inode->ext_list);
+ INIT_LIST_HEAD (&pl_inode->rw_list);
+ INIT_LIST_HEAD (&pl_inode->reservelk_list);
+ INIT_LIST_HEAD (&pl_inode->blocked_reservelks);
+ INIT_LIST_HEAD (&pl_inode->blocked_calls);
- __inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode));
- }
-unlock:
- UNLOCK (&inode->lock);
+ inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode));
+out:
return pl_inode;
}
@@ -473,7 +463,7 @@ unlock:
/* Create a new posix_lock_t */
posix_lock_t *
new_posix_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
- gf_lkowner_t *owner, fd_t *fd)
+ uint64_t owner, fd_t *fd)
{
posix_lock_t *lock = NULL;
@@ -499,7 +489,7 @@ new_posix_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
lock->fd_num = fd_to_fdnum (fd);
lock->fd = fd;
lock->client_pid = client_pid;
- lock->owner = *owner;
+ lock->owner = owner;
INIT_LIST_HEAD (&lock->list);
@@ -543,11 +533,6 @@ posix_lock_to_flock (posix_lock_t *lock, struct gf_flock *flock)
static void
__insert_lock (pl_inode_t *pl_inode, posix_lock_t *lock)
{
- if (lock->blocked)
- gettimeofday (&lock->blkd_time, NULL);
- else
- gettimeofday (&lock->granted_time, NULL);
-
list_add_tail (&lock->list, &pl_inode->ext_list);
return;
@@ -574,8 +559,8 @@ int
same_owner (posix_lock_t *l1, posix_lock_t *l2)
{
- return (is_same_lkowner (&l1->owner, &l2->owner) &&
- (l1->transport == l2->transport));
+ return ((l1->owner == l2->owner) &&
+ (l1->transport == l2->transport));
}
@@ -782,8 +767,6 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
struct _values v = { .locks = {0, 0, 0} };
list_for_each_entry_safe (conf, t, &pl_inode->ext_list, list) {
- if (conf->blocked)
- continue;
if (!locks_overlap (conf, lock))
continue;
@@ -801,8 +784,6 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
__destroy_lock (conf);
__destroy_lock (lock);
- INIT_LIST_HEAD (&sum->list);
- posix_lock_to_flock (sum, &sum->user_flock);
__insert_and_merge (pl_inode, sum);
return;
@@ -830,8 +811,6 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock)
continue;
INIT_LIST_HEAD (&v.locks[i]->list);
- posix_lock_to_flock (v.locks[i],
- &v.locks[i]->user_flock);
__insert_and_merge (pl_inode,
v.locks[i]);
}
@@ -900,9 +879,10 @@ __grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode, struct list_head *g
posix_lock_to_flock (l, &conf->user_flock);
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => Granted",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => Granted",
l->fl_type == F_UNLCK ? "Unlock" : "Lock",
- l->client_pid, lkowner_utoa (&l->owner),
+ l->client_pid,
+ l->owner,
l->user_flock.l_start,
l->user_flock.l_len);
@@ -938,8 +918,7 @@ grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode)
pl_trace_out (this, lock->frame, NULL, NULL, F_SETLKW,
&lock->user_flock, 0, 0, NULL);
- STACK_UNWIND_STRICT (lk, lock->frame, 0, 0,
- &lock->user_flock, NULL);
+ STACK_UNWIND (lock->frame, 0, 0, &lock->user_flock);
GF_FREE (lock);
}
@@ -969,7 +948,7 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
unlock_lock = new_posix_lock (&flock, old_lock->transport,
- old_lock->client_pid, &old_lock->owner,
+ old_lock->client_pid, old_lock->owner,
old_lock->fd);
GF_VALIDATE_OR_GOTO (this->name, unlock_lock, out);
ret = 0;
@@ -984,8 +963,7 @@ pl_send_prelock_unlock (xlator_t *this, pl_inode_t *pl_inode,
pl_trace_out (this, lock->frame, NULL, NULL, F_SETLKW,
&lock->user_flock, 0, 0, NULL);
- STACK_UNWIND_STRICT (lk, lock->frame, 0, 0,
- &lock->user_flock, NULL);
+ STACK_UNWIND (lock->frame, 0, 0, &lock->user_flock);
GF_FREE (lock);
}
@@ -1023,19 +1001,19 @@ pl_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
if (__is_lock_grantable (pl_inode, lock)) {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => OK",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => OK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
__insert_and_merge (pl_inode, lock);
} else if (can_block) {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => Blocked",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => Blocked",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
lock->blocked = 1;
@@ -1043,10 +1021,10 @@ pl_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
ret = -1;
} else {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => NOK",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => NOK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
errno = EAGAIN;
diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h
index 97faa5b92..b13f44bc2 100644
--- a/xlators/features/locks/src/common.h
+++ b/xlators/features/locks/src/common.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -20,28 +20,9 @@
#ifndef __COMMON_H__
#define __COMMON_H__
-#include "lkowner.h"
-/*dump locks format strings */
-#define RANGE_FMT "type=%s, whence=%hd, start=%llu, len=%llu"
-#define ENTRY_FMT "type=%s on basename=%s"
-#define DUMP_GEN_FMT "pid = %llu, owner=%s, transport=%p, "
-#define GRNTD_AT "granted at %s"
-#define BLKD_AT "blocked at %s"
-#define DUMP_BLKD_FMT DUMP_GEN_FMT", "BLKD_AT
-#define DUMP_GRNTD_FMT DUMP_GEN_FMT", "GRNTD_AT
-#define DUMP_BLKD_GRNTD_FMT DUMP_GEN_FMT", "BLKD_AT", "GRNTD_AT
-#define ENTRY_BLKD_FMT ENTRY_FMT", "DUMP_BLKD_FMT
-#define ENTRY_GRNTD_FMT ENTRY_FMT", "DUMP_GRNTD_FMT
-#define ENTRY_BLKD_GRNTD_FMT ENTRY_FMT", "DUMP_BLKD_GRNTD_FMT
-
-#define RANGE_BLKD_FMT RANGE_FMT", "DUMP_BLKD_FMT
-#define RANGE_GRNTD_FMT RANGE_FMT", "DUMP_GRNTD_FMT
-#define RANGE_BLKD_GRNTD_FMT RANGE_FMT", "DUMP_BLKD_GRNTD_FMT
-
-#define SET_FLOCK_PID(flock, lock) ((flock)->l_pid = lock->client_pid)
posix_lock_t *
new_posix_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
- gf_lkowner_t *owner, fd_t *fd);
+ uint64_t owner, fd_t *fd);
pl_inode_t *
pl_inode_get (xlator_t *this, inode_t *inode);
@@ -79,7 +60,7 @@ void
__delete_inode_lock (pl_inode_lock_t *lock);
void
-__pl_inodelk_unref (pl_inode_lock_t *lock);
+__destroy_inode_lock (pl_inode_lock_t *lock);
void
grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
@@ -88,13 +69,9 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
void pl_update_refkeeper (xlator_t *this, inode_t *inode);
int32_t
-__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode);
-int32_t
get_inodelk_count (xlator_t *this, inode_t *inode);
int32_t
-__get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode);
-int32_t
get_entrylk_count (xlator_t *this, inode_t *inode);
void pl_trace_in (xlator_t *this, call_frame_t *frame, fd_t *fd, loc_t *loc,
@@ -153,6 +130,4 @@ pl_verify_reservelk (xlator_t *this, pl_inode_t *pl_inode,
posix_lock_t *lock, int can_block);
int
pl_reserve_unlock (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *reqlock);
-uint32_t
-check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename);
#endif /* __COMMON_H__ */
diff --git a/xlators/features/locks/src/entrylk.c b/xlators/features/locks/src/entrylk.c
index 69a04b53d..e58c1a2c3 100644
--- a/xlators/features/locks/src/entrylk.c
+++ b/xlators/features/locks/src/entrylk.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -35,8 +35,7 @@
static pl_entry_lock_t *
new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type,
- void *trans, pid_t client_pid, gf_lkowner_t *owner,
- const char *volume)
+ void *trans, pid_t client_pid, uint64_t owner, const char *volume)
{
pl_entry_lock_t *newlock = NULL;
@@ -47,12 +46,12 @@ new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type,
goto out;
}
- newlock->basename = basename ? gf_strdup (basename) : NULL;
- newlock->type = type;
- newlock->trans = trans;
- newlock->volume = volume;
- newlock->client_pid = client_pid;
- newlock->owner = *owner;
+ newlock->basename = basename ? gf_strdup (basename) : NULL;
+ newlock->type = type;
+ newlock->trans = trans;
+ newlock->volume = volume;
+ newlock->client_pid = client_pid;
+ newlock->owner = owner;
INIT_LIST_HEAD (&newlock->domain_list);
INIT_LIST_HEAD (&newlock->blocked_locks);
@@ -82,11 +81,11 @@ names_conflict (const char *n1, const char *n2)
}
-static inline int
+static int
__same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2)
{
- return (is_same_lkowner (&l1->owner, &l2->owner) &&
+ return ((l1->owner == l2->owner) &&
(l1->trans == l2->trans));
}
@@ -321,13 +320,15 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
pl_entry_lock_t *conf = NULL;
void *trans = NULL;
pid_t client_pid = 0;
- int ret = -EINVAL;
+ uint64_t owner = 0;
+
+ int ret = -EINVAL;
trans = frame->root->trans;
client_pid = frame->root->pid;
+ owner = frame->root->lk_owner;
- lock = new_entrylk_lock (pinode, basename, type, trans, client_pid,
- &frame->root->lk_owner, dom->domain);
+ lock = new_entrylk_lock (pinode, basename, type, trans, client_pid, owner, dom->domain);
if (!lock) {
ret = -ENOMEM;
goto out;
@@ -341,13 +342,13 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
if (conf) {
ret = -EAGAIN;
if (nonblock){
- GF_FREE ((char *)lock->basename);
+ if (lock->basename)
+ GF_FREE ((char *)lock->basename);
GF_FREE (lock);
goto out;
}
- gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
gf_log (this->name, GF_LOG_TRACE,
@@ -360,7 +361,8 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) {
ret = -EAGAIN;
if (nonblock) {
- GF_FREE ((char *) lock->basename);
+ if (lock->basename)
+ GF_FREE ((char *) lock->basename);
GF_FREE (lock);
goto out;
@@ -368,7 +370,6 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
lock->frame = frame;
lock->this = this;
- gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks);
gf_log (this->name, GF_LOG_TRACE,
@@ -383,7 +384,6 @@ __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type,
switch (type) {
case ENTRYLK_WRLCK:
- gettimeofday (&lock->granted_time, NULL);
list_add_tail (&lock->domain_list, &dom->entrylk_list);
break;
@@ -439,32 +439,6 @@ out:
return ret_lock;
}
-uint32_t
-check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename)
-{
- uint32_t entrylk = 0;
- pl_inode_t *pinode = 0;
- pl_dom_list_t *dom = NULL;
- pl_entry_lock_t *conf = NULL;
-
- pinode = pl_inode_get (this, parent);
- if (!pinode)
- goto out;
- pthread_mutex_lock (&pinode->mutex);
- {
- list_for_each_entry (dom, &pinode->dom_list, inode_list) {
- conf = __lock_grantable (dom, basename, ENTRYLK_WRLCK);
- if (conf && conf->basename) {
- entrylk = 1;
- break;
- }
- }
- }
- pthread_mutex_unlock (&pinode->mutex);
-
-out:
- return entrylk;
-}
void
__grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
@@ -497,7 +471,8 @@ __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
} else {
gf_log (this->name, GF_LOG_DEBUG,
"should never happen");
- GF_FREE ((char *)bl->basename);
+ if (bl->basename)
+ GF_FREE ((char *)bl->basename);
GF_FREE (bl);
}
}
@@ -528,7 +503,7 @@ grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode,
lock->basename, ENTRYLK_LOCK, lock->type,
0, 0);
- STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL);
+ STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0);
}
@@ -596,9 +571,10 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode,
list_for_each_entry_safe (lock, tmp, &released, blocked_locks) {
list_del_init (&lock->blocked_locks);
- STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN, NULL);
+ STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN);
- GF_FREE ((char *)lock->basename);
+ if (lock->basename)
+ GF_FREE ((char *)lock->basename);
GF_FREE (lock);
}
@@ -606,9 +582,10 @@ release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode,
list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
list_del_init (&lock->blocked_locks);
- STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL);
+ STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0);
- GF_FREE ((char *)lock->basename);
+ if (lock->basename)
+ GF_FREE ((char *)lock->basename);
GF_FREE (lock);
}
@@ -621,10 +598,12 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, inode_t *inode, const char *basename,
entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd)
{
+ uint64_t owner = 0;
int32_t op_ret = -1;
int32_t op_errno = 0;
void * transport = NULL;
+ pid_t pid = -1;
pl_inode_t * pinode = NULL;
int ret = -1;
@@ -647,9 +626,11 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type);
+ pid = frame->root->pid;
+ owner = frame->root->lk_owner;
transport = frame->root->trans;
- if (frame->root->lk_owner.len == 0) {
+ if (owner == 0) {
/*
this is a special case that means release
all locks from this transport
@@ -690,7 +671,6 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
break;
case ENTRYLK_LOCK_NB:
- unwind = 1;
pthread_mutex_lock (&pinode->mutex);
{
ret = __lock_name (pinode, basename, type,
@@ -698,11 +678,11 @@ pl_common_entrylk (call_frame_t *frame, xlator_t *this,
}
pthread_mutex_unlock (&pinode->mutex);
- if (ret < 0) {
+ if (ret < 0)
op_errno = -ret;
- goto out;
- }
+ unwind = 1;
+ goto out;
break;
case ENTRYLK_UNLOCK:
@@ -731,7 +711,7 @@ out:
entrylk_trace_out (this, frame, volume, fd, loc, basename,
cmd, type, op_ret, op_errno);
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, NULL);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
} else {
entrylk_trace_block (this, frame, volume, fd, loc, basename,
cmd, type);
@@ -777,7 +757,7 @@ pl_fentrylk (call_frame_t *frame, xlator_t *this,
}
-int32_t
+static int32_t
__get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode)
{
int32_t count = 0;
@@ -786,10 +766,24 @@ __get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode)
list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
list_for_each_entry (lock, &dom->entrylk_list, domain_list) {
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ " XATTR DEBUG"
+ " domain: %s %s on %s state = Active",
+ dom->domain,
+ lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
+ "ENTRYLK_WRLCK", lock->basename);
count++;
}
list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ " XATTR DEBUG"
+ " domain: %s %s on %s state = Blocked",
+ dom->domain,
+ lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
+ "ENTRYLK_WRLCK", lock->basename);
count++;
}
diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c
index 8ac039fba..bc59ea858 100644
--- a/xlators/features/locks/src/inodelk.c
+++ b/xlators/features/locks/src/inodelk.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -33,28 +33,20 @@
#include "locks.h"
#include "common.h"
-inline void
+void
__delete_inode_lock (pl_inode_lock_t *lock)
{
list_del (&lock->list);
}
-static inline void
-__pl_inodelk_ref (pl_inode_lock_t *lock)
-{
- lock->ref++;
-}
-
-inline void
-__pl_inodelk_unref (pl_inode_lock_t *lock)
+void
+__destroy_inode_lock (pl_inode_lock_t *lock)
{
- lock->ref--;
- if (!lock->ref)
- GF_FREE (lock);
+ GF_FREE (lock);
}
/* Check if 2 inodelks are conflicting on type. Only 2 shared locks don't conflict */
-static inline int
+static int
inodelk_type_conflict (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
if (l2->fl_type == F_WRLCK || l1->fl_type == F_WRLCK)
@@ -128,10 +120,9 @@ inodelk_overlap (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
}
/* Returns true if the 2 inodelks have the same owner */
-static inline int
-same_inodelk_owner (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
+static int same_inodelk_owner (pl_inode_lock_t *l1, pl_inode_lock_t *l2)
{
- return (is_same_lkowner (&l1->owner, &l2->owner) &&
+ return ((l1->owner == l2->owner) &&
(l1->transport == l2->transport));
}
@@ -152,8 +143,7 @@ __inodelk_grantable (pl_dom_list_t *dom, pl_inode_lock_t *lock)
if (list_empty (&dom->inodelk_list))
goto out;
list_for_each_entry (l, &dom->inodelk_list, list){
- if (inodelk_conflict (lock, l) &&
- !same_inodelk_owner (lock, l)) {
+ if (inodelk_conflict (lock, l)) {
ret = l;
goto out;
}
@@ -168,7 +158,7 @@ __blocked_lock_conflict (pl_dom_list_t *dom, pl_inode_lock_t *lock)
pl_inode_lock_t *l = NULL;
pl_inode_lock_t *ret = NULL;
- if (list_empty (&dom->blocked_inodelks))
+ if (list_empty (&dom->blocked_entrylks))
return NULL;
list_for_each_entry (l, &dom->blocked_inodelks, blocked_locks) {
@@ -187,12 +177,12 @@ __owner_has_lock (pl_dom_list_t *dom, pl_inode_lock_t *newlock)
{
pl_inode_lock_t *lock = NULL;
- list_for_each_entry (lock, &dom->inodelk_list, list) {
+ list_for_each_entry (lock, &dom->entrylk_list, list) {
if (same_inodelk_owner (lock, newlock))
return 1;
}
- list_for_each_entry (lock, &dom->blocked_inodelks, blocked_locks) {
+ list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks) {
if (same_inodelk_owner (lock, newlock))
return 1;
}
@@ -217,14 +207,13 @@ __lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
if (can_block == 0)
goto out;
- gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_inodelks);
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => Blocked",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => Blocked",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
@@ -237,24 +226,21 @@ __lock_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
if (can_block == 0)
goto out;
- gettimeofday (&lock->blkd_time, NULL);
list_add_tail (&lock->blocked_locks, &dom->blocked_inodelks);
gf_log (this->name, GF_LOG_TRACE,
"Lock is grantable, but blocking to prevent starvation");
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Blocked",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Blocked",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
goto out;
}
- __pl_inodelk_ref (lock);
- gettimeofday (&lock->granted_time, NULL);
list_add (&lock->list, &dom->inodelk_list);
ret = 0;
@@ -298,22 +284,20 @@ __inode_unlock_lock (xlator_t *this, pl_inode_lock_t *lock, pl_dom_list_t *dom)
conf = find_matching_inodelk (lock, dom);
if (!conf) {
- gf_log (this->name, GF_LOG_ERROR,
- " Matching lock not found for unlock %llu-%llu, by %s "
- "on %p", (unsigned long long)lock->fl_start,
- (unsigned long long)lock->fl_end,
- lkowner_utoa (&lock->owner), lock->transport);
+ gf_log (this->name, GF_LOG_DEBUG,
+ " Matching lock not found for unlock");
goto out;
}
__delete_inode_lock (conf);
gf_log (this->name, GF_LOG_DEBUG,
- " Matching lock found for unlock %llu-%llu, by %s on %p",
- (unsigned long long)lock->fl_start,
- (unsigned long long)lock->fl_end, lkowner_utoa (&lock->owner),
- lock->transport);
+ " Matching lock found for unlock");
+ __destroy_inode_lock (lock);
+
out:
return conf;
+
+
}
static void
__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode,
@@ -351,6 +335,11 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *
INIT_LIST_HEAD (&granted);
+ if (list_empty (&dom->blocked_inodelks)) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "No blocked locks to be granted for domain: %s", dom->domain);
+ }
+
pthread_mutex_lock (&pl_inode->mutex);
{
__grant_blocked_inode_locks (this, pl_inode, &granted, dom);
@@ -359,27 +348,19 @@ grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *
list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Granted",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Granted",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
pl_trace_out (this, lock->frame, NULL, NULL, F_SETLKW,
&lock->user_flock, 0, 0, lock->volume);
- STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0, NULL);
+ STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0);
}
- pthread_mutex_lock (&pl_inode->mutex);
- {
- list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) {
- list_del_init (&lock->blocked_locks);
- __pl_inodelk_unref (lock);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
}
/* Release all inodelks from this transport */
@@ -392,11 +373,12 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
pl_inode_t * pinode = NULL;
+ struct list_head granted;
struct list_head released;
char *path = NULL;
- char *file = NULL;
+ INIT_LIST_HEAD (&granted);
INIT_LIST_HEAD (&released);
pinode = pl_inode_get (this, inode);
@@ -410,60 +392,58 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom,
list_del_init (&l->blocked_locks);
- inode_path (inode, NULL, &path);
- if (path)
- file = path;
- else
- file = uuid_utoa (inode->gfid);
+ if (inode_path (inode, NULL, &path) < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode_path failed");
+ goto unlock;
+ }
- gf_log (this->name, GF_LOG_DEBUG,
- "releasing blocking lock on %s held by "
- "{transport=%p, pid=%"PRId64" lk-owner=%s}",
- file, trans, (uint64_t) l->client_pid,
- lkowner_utoa (&l->owner));
+ gf_log (this->name, GF_LOG_TRACE,
+ "releasing lock on %s held by "
+ "{transport=%p, pid=%"PRId64" lk-owner=%"PRIu64"}",
+ path, trans,
+ (uint64_t) l->client_pid,
+ l->owner);
list_add (&l->blocked_locks, &released);
- if (path) {
- GF_FREE (path);
- path = NULL;
- }
+
}
list_for_each_entry_safe (l, tmp, &dom->inodelk_list, list) {
if (l->transport != trans)
continue;
- inode_path (inode, NULL, &path);
- if (path)
- file = path;
- else
- file = uuid_utoa (inode->gfid);
+ __delete_inode_lock (l);
+ __destroy_inode_lock (l);
- gf_log (this->name, GF_LOG_DEBUG,
- "releasing granted lock on %s held by "
- "{transport=%p, pid=%"PRId64" lk-owner=%s}",
- file, trans, (uint64_t) l->client_pid,
- lkowner_utoa (&l->owner));
-
- if (path) {
- GF_FREE (path);
- path = NULL;
+
+ if (inode_path (inode, NULL, &path) < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "inode_path failed");
+ goto unlock;
}
- __delete_inode_lock (l);
- __pl_inodelk_unref (l);
+ gf_log (this->name, GF_LOG_TRACE,
+ "releasing lock on %s held by "
+ "{transport=%p, pid=%"PRId64" lk-owner=%"PRIu64"}",
+ path, trans,
+ (uint64_t) l->client_pid,
+ l->owner);
+
+
}
}
- GF_FREE (path);
+unlock:
+ if (path)
+ GF_FREE (path);
pthread_mutex_unlock (&pinode->mutex);
list_for_each_entry_safe (l, tmp, &released, blocked_locks) {
list_del_init (&l->blocked_locks);
- STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN, NULL);
- //No need to take lock as the locks are only in one list
- __pl_inodelk_unref (l);
+ STACK_UNWIND_STRICT (inodelk, l->frame, -1, EAGAIN);
+ GF_FREE (l);
}
grant_blocked_inode_locks (this, pinode, dom);
@@ -477,47 +457,47 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock,
{
int ret = -EINVAL;
pl_inode_lock_t *retlock = NULL;
- gf_boolean_t unref = _gf_true;
pthread_mutex_lock (&pl_inode->mutex);
{
if (lock->fl_type != F_UNLCK) {
ret = __lock_inodelk (this, pl_inode, lock, can_block, dom);
- if (ret == 0) {
+ if (ret == 0)
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => OK",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => OK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->fl_start,
lock->fl_end);
- } else if (ret == -EAGAIN) {
+
+ if (ret == -EAGAIN)
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => NOK",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => NOK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
- if (can_block)
- unref = _gf_false;
- }
- } else {
- retlock = __inode_unlock_lock (this, lock, dom);
- if (!retlock) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Bad Unlock issued on Inode lock");
- ret = -EINVAL;
- goto out;
- }
- __pl_inodelk_unref (retlock);
- ret = 0;
+ goto out;
+ }
+
+
+ retlock = __inode_unlock_lock (this, lock, dom);
+ if (!retlock) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Bad Unlock issued on Inode lock");
+ ret = -EINVAL;
+ goto out;
}
+ __destroy_inode_lock (retlock);
+
+ ret = 0;
+
+
}
out:
- if (unref)
- __pl_inodelk_unref (lock);
pthread_mutex_unlock (&pl_inode->mutex);
grant_blocked_inode_locks (this, pl_inode, dom);
return ret;
@@ -526,7 +506,7 @@ out:
/* Create a new inode_lock_t */
pl_inode_lock_t *
new_inode_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
- gf_lkowner_t *owner, const char *volume)
+ uint64_t owner, const char *volume)
{
pl_inode_lock_t *lock = NULL;
@@ -547,12 +527,11 @@ new_inode_lock (struct gf_flock *flock, void *transport, pid_t client_pid,
lock->transport = transport;
lock->client_pid = client_pid;
+ lock->owner = owner;
lock->volume = volume;
- lock->owner = *owner;
INIT_LIST_HEAD (&lock->list);
INIT_LIST_HEAD (&lock->blocked_locks);
- __pl_inodelk_ref (lock);
return lock;
}
@@ -563,15 +542,16 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, inode_t *inode, int32_t cmd,
struct gf_flock *flock, loc_t *loc, fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int ret = -1;
- int can_block = 0;
- pid_t client_pid = -1;
- void * transport = NULL;
- pl_inode_t * pinode = NULL;
- pl_inode_lock_t * reqlock = NULL;
- pl_dom_list_t * dom = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int ret = -1;
+ int can_block = 0;
+ void * transport = NULL;
+ pid_t client_pid = -1;
+ uint64_t owner = -1;
+ pl_inode_t * pinode = NULL;
+ pl_inode_lock_t * reqlock = NULL;
+ pl_dom_list_t * dom = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (inode, unwind);
@@ -586,6 +566,7 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
transport = frame->root->trans;
client_pid = frame->root->pid;
+ owner = frame->root->lk_owner;
pinode = pl_inode_get (this, inode);
if (!pinode) {
@@ -594,12 +575,8 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
}
dom = get_domain (pinode, volume);
- if (!dom) {
- op_errno = ENOMEM;
- goto unwind;
- }
- if (frame->root->lk_owner.len == 0) {
+ if (owner == 0) {
/*
special case: this means release all locks
from this transport
@@ -613,8 +590,7 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
goto unwind;
}
- reqlock = new_inode_lock (flock, transport, client_pid,
- &frame->root->lk_owner, volume);
+ reqlock = new_inode_lock (flock, transport, client_pid, owner, volume);
if (!reqlock) {
op_ret = -1;
@@ -639,13 +615,14 @@ pl_common_inodelk (call_frame_t *frame, xlator_t *this,
can_block, dom);
if (ret < 0) {
- if ((can_block) && (F_UNLCK != flock->l_type)) {
+ if (can_block) {
pl_trace_block (this, frame, fd, loc,
cmd, flock, volume);
goto out;
}
gf_log (this->name, GF_LOG_TRACE, "returning EAGAIN");
op_errno = -ret;
+ __destroy_inode_lock (reqlock);
goto unwind;
}
break;
@@ -667,7 +644,7 @@ unwind:
pl_trace_out (this, frame, fd, loc, cmd, flock, op_ret, op_errno, volume);
}
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, NULL);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
out:
return 0;
}
@@ -694,7 +671,7 @@ pl_finodelk (call_frame_t *frame, xlator_t *this,
}
-int32_t
+static int32_t
__get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode)
{
int32_t count = 0;
@@ -703,9 +680,34 @@ __get_inodelk_count (xlator_t *this, pl_inode_t *pl_inode)
list_for_each_entry (dom, &pl_inode->dom_list, inode_list) {
list_for_each_entry (lock, &dom->inodelk_list, list) {
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ " XATTR DEBUG"
+ " domain: %s %s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" "
+ "state = Active",
+ dom->domain,
+ lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ lock->client_pid,
+ lock->owner,
+ lock->user_flock.l_start,
+ lock->user_flock.l_len);
+
count++;
}
+
list_for_each_entry (lock, &dom->blocked_inodelks, blocked_locks) {
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ " XATTR DEBUG"
+ " domain: %s %s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" "
+ "state = Blocked",
+ dom->domain,
+ lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ lock->client_pid,
+ lock->owner,
+ lock->user_flock.l_start,
+ lock->user_flock.l_len);
+
count++;
}
diff --git a/xlators/features/locks/src/locks-mem-types.h b/xlators/features/locks/src/locks-mem-types.h
index 5b29cbc72..c4e9e9761 100644
--- a/xlators/features/locks/src/locks-mem-types.h
+++ b/xlators/features/locks/src/locks-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -32,6 +32,7 @@ enum gf_locks_mem_types_ {
gf_locks_mt_truncate_ops,
gf_locks_mt_pl_rw_req_t,
gf_locks_mt_posix_locks_private_t,
+ gf_locks_mt_pl_local_t,
gf_locks_mt_pl_fdctx_t,
gf_locks_mt_end
};
diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h
index f64c26902..5a37c68f6 100644
--- a/xlators/features/locks/src/locks.h
+++ b/xlators/features/locks/src/locks.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -30,8 +30,6 @@
#include "call-stub.h"
#include "locks-mem-types.h"
-#include "lkowner.h"
-
#define POSIX_LOCKS "posix-locks"
struct __pl_fd;
@@ -50,22 +48,18 @@ struct __posix_lock {
fd_t *fd;
call_frame_t *frame;
- struct timeval blkd_time; /*time at which lock was queued into blkd list*/
- struct timeval granted_time; /*time at which lock was queued into active list*/
-
/* These two together serve to uniquely identify each process
across nodes */
void *transport; /* to identify client node */
- gf_lkowner_t owner;
pid_t client_pid; /* pid of client process */
+ uint64_t owner; /* lock owner from fuse */
};
typedef struct __posix_lock posix_lock_t;
struct __pl_inode_lock {
struct list_head list;
struct list_head blocked_locks; /* list_head pointing to blocked_inodelks */
- int ref;
short fl_type;
off_t fl_start;
@@ -79,15 +73,12 @@ struct __pl_inode_lock {
call_frame_t *frame;
- struct timeval blkd_time; /*time at which lock was queued into blkd list*/
- struct timeval granted_time; /*time at which lock was queued into active list*/
-
/* These two together serve to uniquely identify each process
across nodes */
void *transport; /* to identify client node */
- gf_lkowner_t owner;
pid_t client_pid; /* pid of client process */
+ uint64_t owner;
};
typedef struct __pl_inode_lock pl_inode_lock_t;
@@ -120,12 +111,9 @@ struct __entry_lock {
const char *basename;
entrylk_type type;
- struct timeval blkd_time; /*time at which lock was queued into blkd list*/
- struct timeval granted_time; /*time at which lock was queued into active list*/
-
- void *trans;
- gf_lkowner_t owner;
+ void *trans;
pid_t client_pid; /* pid of client process */
+ uint64_t owner;
};
typedef struct __entry_lock pl_entry_lock_t;
@@ -165,14 +153,6 @@ typedef struct {
gf_boolean_t entrylk_count_req;
gf_boolean_t inodelk_count_req;
gf_boolean_t posixlk_count_req;
- gf_boolean_t parent_entrylk_req;
-
- /* used by {f,}truncate */
- loc_t loc;
- fd_t *fd;
- off_t offset;
- dict_t *xdata;
- enum {TRUNCATE, FTRUNCATE} op;
} pl_local_t;
typedef struct {
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index e48fa204e..67f026b16 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -37,7 +37,6 @@
#include "locks.h"
#include "common.h"
#include "statedump.h"
-#include "clear.h"
#ifndef LLONG_MAX
#define LLONG_MAX LONG_LONG_MAX /* compat with old gcc */
@@ -49,6 +48,13 @@
void do_blocked_rw (pl_inode_t *);
static int __rw_allowable (pl_inode_t *, posix_lock_t *, glusterfs_fop_t);
+struct _truncate_ops {
+ loc_t loc;
+ fd_t *fd;
+ off_t offset;
+ enum {TRUNCATE, FTRUNCATE} op;
+};
+
static pl_fdctx_t *
pl_new_fdctx ()
{
@@ -102,22 +108,17 @@ out:
int
pl_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- pl_local_t *local = NULL;
+ struct _truncate_ops *local = NULL;
local = frame->local;
if (local->op == TRUNCATE)
loc_wipe (&local->loc);
- if (local->xdata)
- dict_unref (local->xdata);
- if (local->fd)
- fd_unref (local->fd);
-
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno,
- prebuf, postbuf, xdata);
+ prebuf, postbuf);
return 0;
}
@@ -125,7 +126,7 @@ pl_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int
truncate_allowed (pl_inode_t *pl_inode,
void *transport, pid_t client_pid,
- gf_lkowner_t *owner, off_t offset)
+ uint64_t owner, off_t offset)
{
posix_lock_t *l = NULL;
posix_lock_t region = {.list = {0, }, };
@@ -135,7 +136,7 @@ truncate_allowed (pl_inode_t *pl_inode,
region.fl_end = LLONG_MAX;
region.transport = transport;
region.client_pid = client_pid;
- region.owner = *owner;
+ region.owner = owner;
pthread_mutex_lock (&pl_inode->mutex);
{
@@ -158,11 +159,10 @@ truncate_allowed (pl_inode_t *pl_inode,
static int
truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
posix_locks_private_t *priv = NULL;
- pl_local_t *local = NULL;
+ struct _truncate_ops *local = NULL;
inode_t *inode = NULL;
pl_inode_t *pl_inode = NULL;
@@ -192,7 +192,7 @@ truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (priv->mandatory
&& pl_inode->mandatory
&& !truncate_allowed (pl_inode, frame->root->trans,
- frame->root->pid, &frame->root->lk_owner,
+ frame->root->pid, frame->root->lk_owner,
local->offset)) {
op_ret = -1;
op_errno = EAGAIN;
@@ -203,12 +203,12 @@ truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
case TRUNCATE:
STACK_WIND (frame, pl_truncate_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->truncate,
- &local->loc, local->offset, local->xdata);
+ &local->loc, local->offset);
break;
case FTRUNCATE:
STACK_WIND (frame, pl_truncate_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->ftruncate,
- local->fd, local->offset, local->xdata);
+ local->fd, local->offset);
break;
}
@@ -219,42 +219,37 @@ unwind:
"error: %s", op_ret, strerror (op_errno));
if (local->op == TRUNCATE)
loc_wipe (&local->loc);
- if (local->xdata)
- dict_unref (local->xdata);
- if (local->fd)
- fd_unref (local->fd);
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, buf, NULL, xdata);
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, buf, NULL);
return 0;
}
int
pl_truncate (call_frame_t *frame, xlator_t *this,
- loc_t *loc, off_t offset, dict_t *xdata)
+ loc_t *loc, off_t offset)
{
- pl_local_t *local = NULL;
+ struct _truncate_ops *local = NULL;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (struct _truncate_ops),
+ gf_locks_mt_truncate_ops);
GF_VALIDATE_OR_GOTO (this->name, local, unwind);
local->op = TRUNCATE;
local->offset = offset;
loc_copy (&local->loc, loc);
- if (xdata)
- local->xdata = dict_ref (xdata);
frame->local = local;
STACK_WIND (frame, truncate_stat_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->stat, loc, NULL);
+ FIRST_CHILD (this)->fops->stat, loc);
return 0;
unwind:
gf_log (this->name, GF_LOG_ERROR, "truncate for %s failed with ret: %d, "
"error: %s", loc->path, -1, strerror (ENOMEM));
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -262,54 +257,32 @@ unwind:
int
pl_ftruncate (call_frame_t *frame, xlator_t *this,
- fd_t *fd, off_t offset, dict_t *xdata)
+ fd_t *fd, off_t offset)
{
- pl_local_t *local = NULL;
+ struct _truncate_ops *local = NULL;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (struct _truncate_ops),
+ gf_locks_mt_truncate_ops);
GF_VALIDATE_OR_GOTO (this->name, local, unwind);
local->op = FTRUNCATE;
local->offset = offset;
- local->fd = fd_ref (fd);
- if (xdata)
- local->xdata = dict_ref (xdata);
+ local->fd = fd;
frame->local = local;
STACK_WIND (frame, truncate_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ FIRST_CHILD(this)->fops->fstat, fd);
return 0;
unwind:
gf_log (this->name, GF_LOG_ERROR, "ftruncate failed with ret: %d, "
"error: %s", -1, strerror (ENOMEM));
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
-int
-pl_locks_by_fd (pl_inode_t *pl_inode, fd_t *fd)
-{
- posix_lock_t *l = NULL;
- int found = 0;
-
- pthread_mutex_lock (&pl_inode->mutex);
- {
-
- list_for_each_entry (l, &pl_inode->ext_list, list) {
- if ((l->fd_num == fd_to_fdnum(fd))) {
- found = 1;
- break;
- }
- }
-
- }
- pthread_mutex_unlock (&pl_inode->mutex);
- return found;
-}
-
static void
delete_locks_of_fd (xlator_t *this, pl_inode_t *pl_inode, fd_t *fd)
{
@@ -339,8 +312,7 @@ delete_locks_of_fd (xlator_t *this, pl_inode_t *pl_inode, fd_t *fd)
list_for_each_entry_safe (l, tmp, &blocked_list, list) {
list_del_init(&l->list);
- STACK_UNWIND_STRICT (lk, l->frame, -1, EAGAIN, &l->user_flock,
- NULL);
+ STACK_UNWIND_STRICT (lk, l->frame, -1, EAGAIN, &l->user_flock);
__destroy_lock (l);
}
@@ -352,7 +324,7 @@ delete_locks_of_fd (xlator_t *this, pl_inode_t *pl_inode, fd_t *fd)
static void
__delete_locks_of_owner (pl_inode_t *pl_inode,
- void *transport, gf_lkowner_t *owner)
+ void *transport, uint64_t owner)
{
posix_lock_t *tmp = NULL;
posix_lock_t *l = NULL;
@@ -360,16 +332,14 @@ __delete_locks_of_owner (pl_inode_t *pl_inode,
/* TODO: what if it is a blocked lock with pending l->frame */
list_for_each_entry_safe (l, tmp, &pl_inode->ext_list, list) {
- if (l->blocked)
- continue;
- if ((l->transport == transport) &&
- is_same_lkowner (&l->owner, owner)) {
+ if ((l->transport == transport)
+ && (l->owner == owner)) {
gf_log ("posix-locks", GF_LOG_TRACE,
" Flushing lock"
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" state: %s",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" state: %s",
l->fl_type == F_UNLCK ? "Unlock" : "Lock",
l->client_pid,
- lkowner_utoa (&l->owner),
+ l->owner,
l->user_flock.l_start,
l->user_flock.l_len,
l->blocked == 1 ? "Blocked" : "Active");
@@ -382,120 +352,13 @@ __delete_locks_of_owner (pl_inode_t *pl_inode,
return;
}
-
-int32_t
-pl_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
- return 0;
-
-}
-
-int32_t
-pl_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- int op_errno = EINVAL;
- int op_ret = -1;
- int32_t bcount = 0;
- int32_t gcount = 0;
- char key[PATH_MAX] = {0, };
- char *lk_summary = NULL;
- pl_inode_t *pl_inode = NULL;
- dict_t *dict = NULL;
- clrlk_args args = {0,};
-
- if (!name)
- goto usual;
-
- if (strncmp (name, GF_XATTR_CLRLK_CMD, strlen (GF_XATTR_CLRLK_CMD)))
- goto usual;
-
- if (clrlk_parse_args (name, &args)) {
- op_errno = EINVAL;
- goto out;
- }
-
- dict = dict_new ();
- if (!dict) {
- op_errno = ENOMEM;
- goto out;
- }
-
- pl_inode = pl_inode_get (this, loc->inode);
- if (!pl_inode) {
- op_errno = ENOMEM;
- goto out;
- }
-
- switch (args.type) {
- case CLRLK_INODE:
- case CLRLK_ENTRY:
- op_ret = clrlk_clear_lks_in_all_domains (this, pl_inode,
- &args, &bcount,
- &gcount,
- &op_errno);
- if (op_ret)
- goto out;
- break;
- case CLRLK_POSIX:
- op_ret = clrlk_clear_posixlk (this, pl_inode, &args,
- &bcount, &gcount,
- &op_errno);
- if (op_ret)
- goto out;
- break;
- case CLRLK_TYPE_MAX:
- op_errno = EINVAL;
- goto out;
- }
-
- if (!gcount && !bcount) {
- if (gf_asprintf (&lk_summary, "No locks cleared.") == -1) {
- op_errno = ENOMEM;
- goto out;
- }
- } else if (gf_asprintf (&lk_summary, "%s: %s blocked locks=%d "
- "granted locks=%d", this->name,
- (args.type == CLRLK_INODE)? "inode":
- (args.type == CLRLK_ENTRY)? "entry":
- (args.type == CLRLK_POSIX)? "posix": " ",
- bcount, gcount) == -1) {
- op_errno = ENOMEM;
- goto out;
- }
-
- strncpy (key, name, strlen (name));
- if (dict_set_dynstr (dict, key, lk_summary)) {
- op_errno = ENOMEM;
- goto out;
- }
-
- op_ret = 0;
-out:
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
-
- GF_FREE (args.opts);
- if (op_ret && lk_summary)
- GF_FREE (lk_summary);
- if (dict)
- dict_unref (dict);
- return 0;
-
-usual:
- STACK_WIND (frame, pl_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
- return 0;
-}
-
int32_t
pl_opendir_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd, dict_t *xdata)
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
{
pl_fdctx_t *fdctx = NULL;
@@ -514,28 +377,28 @@ unwind:
frame,
op_ret,
op_errno,
- fd, xdata);
+ fd);
return 0;
}
int32_t
pl_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+ loc_t *loc, fd_t *fd)
{
STACK_WIND (frame,
pl_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
+ loc, fd);
return 0;
}
int
pl_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
@@ -543,21 +406,24 @@ pl_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
pl_flush (call_frame_t *frame, xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
- pl_inode_t *pl_inode = NULL;
+ pl_inode_t *pl_inode = NULL;
+ uint64_t owner = -1;
+
+ owner = frame->root->lk_owner;
pl_inode = pl_inode_get (this, fd->inode);
if (!pl_inode) {
gf_log (this->name, GF_LOG_DEBUG, "Could not get inode.");
- STACK_UNWIND_STRICT (flush, frame, -1, EBADFD, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, EBADFD);
return 0;
}
pl_trace_flush (this, frame, fd);
- if (frame->root->lk_owner.len == 0) {
+ if (owner == 0) {
/* Handle special case when protocol/server sets lk-owner to zero.
* This usually happens due to a client disconnection. Hence, free
* all locks opened with this fd.
@@ -571,7 +437,7 @@ pl_flush (call_frame_t *frame, xlator_t *this,
pthread_mutex_lock (&pl_inode->mutex);
{
__delete_locks_of_owner (pl_inode, frame->root->trans,
- &frame->root->lk_owner);
+ owner);
}
pthread_mutex_unlock (&pl_inode->mutex);
@@ -581,14 +447,14 @@ pl_flush (call_frame_t *frame, xlator_t *this,
wind:
STACK_WIND (frame, pl_flush_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
+ FIRST_CHILD(this)->fops->flush, fd);
return 0;
}
int
pl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
pl_fdctx_t *fdctx = NULL;
@@ -603,7 +469,7 @@ pl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
unwind:
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
@@ -611,11 +477,12 @@ unwind:
int
pl_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
+ /* why isn't O_TRUNC being handled ? */
STACK_WIND (frame, pl_open_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->open,
- loc, flags, fd, xdata);
+ loc, flags & ~O_TRUNC, fd, wbflags);
return 0;
}
@@ -625,7 +492,7 @@ int
pl_create_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret, int32_t op_errno,
fd_t *fd, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
pl_fdctx_t *fdctx = NULL;
@@ -641,7 +508,7 @@ pl_create_cbk (call_frame_t *frame, void *cookie,
unwind:
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -649,12 +516,11 @@ unwind:
int
pl_create (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
- dict_t *xdata)
+ loc_t *loc, int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
STACK_WIND (frame, pl_create_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
}
@@ -663,10 +529,10 @@ int
pl_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,
- vector, count, stbuf, iobref, xdata);
+ vector, count, stbuf, iobref);
return 0;
}
@@ -674,10 +540,9 @@ pl_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
pl_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -735,12 +600,12 @@ __rw_allowable (pl_inode_t *pl_inode, posix_lock_t *region,
int
-pl_readv_cont (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+pl_readv_cont (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, size_t size, off_t offset)
{
STACK_WIND (frame, pl_readv_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
@@ -748,7 +613,7 @@ pl_readv_cont (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
int
pl_readv (call_frame_t *frame, xlator_t *this,
- fd_t *fd, size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ fd_t *fd, size_t size, off_t offset)
{
posix_locks_private_t *priv = NULL;
pl_inode_t *pl_inode = NULL;
@@ -795,8 +660,7 @@ pl_readv (call_frame_t *frame, xlator_t *this,
}
rw->stub = fop_readv_stub (frame, pl_readv_cont,
- fd, size, offset, flags,
- xdata);
+ fd, size, offset);
if (!rw->stub) {
op_errno = ENOMEM;
op_ret = -1;
@@ -816,12 +680,12 @@ pl_readv (call_frame_t *frame, xlator_t *this,
if (wind_needed) {
STACK_WIND (frame, pl_readv_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
}
if (op_ret == -1)
STACK_UNWIND_STRICT (readv, frame, -1, op_errno,
- NULL, 0, NULL, NULL, NULL);
+ NULL, 0, NULL, NULL);
return 0;
}
@@ -830,11 +694,11 @@ pl_readv (call_frame_t *frame, xlator_t *this,
int
pl_writev_cont (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
STACK_WIND (frame, pl_writev_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
}
@@ -843,7 +707,7 @@ pl_writev_cont (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
posix_locks_private_t *priv = NULL;
pl_inode_t *pl_inode = NULL;
@@ -853,6 +717,7 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
int op_errno = 0;
char wind_needed = 1;
+
priv = this->private;
pl_inode = pl_inode_get (this, fd->inode);
@@ -890,7 +755,7 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
rw->stub = fop_writev_stub (frame, pl_writev_cont,
fd, vector, count, offset,
- flags, iobref, xdata);
+ iobref);
if (!rw->stub) {
op_errno = ENOMEM;
op_ret = -1;
@@ -910,11 +775,10 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (wind_needed)
STACK_WIND (frame, pl_writev_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
if (op_ret == -1)
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -941,7 +805,7 @@ lock_dup (posix_lock_t *lock)
posix_lock_t *new_lock = NULL;
new_lock = new_posix_lock (&lock->user_flock, lock->transport,
- lock->client_pid, &lock->owner,
+ lock->client_pid, lock->owner,
(fd_t *)lock->fd_num);
return new_lock;
}
@@ -1098,20 +962,22 @@ unlock:
int
pl_lk (call_frame_t *frame, xlator_t *this,
- fd_t *fd, int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *flock)
{
- void *transport = NULL;
- pid_t client_pid = 0;
- pl_inode_t *pl_inode = NULL;
- int op_ret = 0;
- int op_errno = 0;
- int can_block = 0;
- posix_lock_t *reqlock = NULL;
- posix_lock_t *conf = NULL;
- int ret = 0;
+ void *transport = NULL;
+ pid_t client_pid = 0;
+ uint64_t owner = 0;
+ pl_inode_t *pl_inode = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+ int can_block = 0;
+ posix_lock_t *reqlock = NULL;
+ posix_lock_t *conf = NULL;
+ int ret = 0;
transport = frame->root->trans;
client_pid = frame->root->pid;
+ owner = frame->root->lk_owner;
if ((flock->l_start < 0) || (flock->l_len < 0)) {
op_ret = -1;
@@ -1127,7 +993,7 @@ pl_lk (call_frame_t *frame, xlator_t *this,
}
reqlock = new_posix_lock (flock, transport, client_pid,
- &frame->root->lk_owner, fd);
+ owner, fd);
if (!reqlock) {
op_ret = -1;
@@ -1236,7 +1102,7 @@ pl_lk (call_frame_t *frame, xlator_t *this,
can_block);
if (ret == -1) {
- if ((can_block) && (F_UNLCK != flock->l_type)) {
+ if (can_block) {
pl_trace_block (this, frame, fd, NULL, cmd, flock, NULL);
goto out;
}
@@ -1244,22 +1110,13 @@ pl_lk (call_frame_t *frame, xlator_t *this,
op_ret = -1;
op_errno = EAGAIN;
__destroy_lock (reqlock);
-
- } else if ((0 == ret) && (F_UNLCK == flock->l_type)) {
- /* For NLM's last "unlock on fd" detection */
- if (pl_locks_by_fd (pl_inode, fd))
- flock->l_type = F_RDLCK;
- else
- flock->l_type = F_UNLCK;
}
}
unwind:
pl_trace_out (this, frame, fd, NULL, cmd, flock, op_ret, op_errno, NULL);
pl_update_refkeeper (this, fd->inode);
-
-
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock, xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock);
out:
return 0;
}
@@ -1336,7 +1193,7 @@ pl_forget (xlator_t *this,
list_for_each_entry_safe (ino_l, ino_tmp, &dom->inodelk_list, list) {
__delete_inode_lock (ino_l);
- __pl_inodelk_unref (ino_l);
+ __destroy_inode_lock (ino_l);
}
list_splice_init (&dom->blocked_inodelks, &inodelks_released);
@@ -1350,7 +1207,8 @@ pl_forget (xlator_t *this,
list_for_each_entry_safe (entry_l, entry_tmp, &dom->entrylk_list, domain_list) {
list_del_init (&entry_l->domain_list);
- GF_FREE ((char *)entry_l->basename);
+ if (entry_l->basename)
+ GF_FREE ((char *)entry_l->basename);
GF_FREE (entry_l);
}
@@ -1369,21 +1227,21 @@ pl_forget (xlator_t *this,
list_for_each_entry_safe (ext_l, ext_tmp, &posixlks_released, list) {
- STACK_UNWIND_STRICT (lk, ext_l->frame, -1, 0,
- &ext_l->user_flock, NULL);
+ STACK_UNWIND_STRICT (lk, ext_l->frame, -1, 0, &ext_l->user_flock);
__destroy_lock (ext_l);
}
list_for_each_entry_safe (ino_l, ino_tmp, &inodelks_released, blocked_locks) {
- STACK_UNWIND_STRICT (inodelk, ino_l->frame, -1, 0, NULL);
- __pl_inodelk_unref (ino_l);
+ STACK_UNWIND_STRICT (inodelk, ino_l->frame, -1, 0);
+ __destroy_inode_lock (ino_l);
}
list_for_each_entry_safe (entry_l, entry_tmp, &entrylks_released, blocked_locks) {
- STACK_UNWIND_STRICT (entrylk, entry_l->frame, -1, 0, NULL);
- GF_FREE ((char *)entry_l->basename);
+ STACK_UNWIND_STRICT (entrylk, entry_l->frame, -1, 0);
+ if (entry_l->basename)
+ GF_FREE ((char *)entry_l->basename);
GF_FREE (entry_l);
}
@@ -1418,7 +1276,6 @@ pl_release (xlator_t *this, fd_t *fd)
"Releasing all locks with fd %p", fd);
delete_locks_of_fd (this, pl_inode, fd);
- pl_update_refkeeper (this, fd->inode);
ret = fd_ctx_del (fd, this, &tmp);
if (ret) {
@@ -1459,7 +1316,7 @@ out:
return ret;
}
-int32_t
+static int32_t
__get_posixlk_count (xlator_t *this, pl_inode_t *pl_inode)
{
posix_lock_t *lock = NULL;
@@ -1467,6 +1324,16 @@ __get_posixlk_count (xlator_t *this, pl_inode_t *pl_inode)
list_for_each_entry (lock, &pl_inode->ext_list, list) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ " XATTR DEBUG"
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" state: %s",
+ lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
+ lock->client_pid,
+ lock->owner,
+ lock->user_flock.l_start,
+ lock->user_flock.l_len,
+ lock->blocked == 1 ? "Blocked" : "Active");
+
count++;
}
@@ -1499,24 +1366,6 @@ out:
}
void
-pl_parent_entrylk_xattr_fill (xlator_t *this, inode_t *parent,
- char *basename, dict_t *dict)
-{
- uint32_t entrylk = 0;
- int ret = -1;
-
- if (!parent || !basename || !strlen (basename))
- goto out;
- entrylk = check_entrylk_on_basename (this, parent, basename);
-out:
- ret = dict_set_uint32 (dict, GLUSTERFS_PARENT_ENTRYLK, entrylk);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- " dict_set failed on key %s", GLUSTERFS_PARENT_ENTRYLK);
- }
-}
-
-void
pl_entrylk_xattr_fill (xlator_t *this, inode_t *inode,
dict_t *dict)
{
@@ -1572,55 +1421,50 @@ pl_lookup_cbk (call_frame_t *frame,
int32_t op_errno,
inode_t *inode,
struct iatt *buf,
- dict_t *xdata,
+ dict_t *dict,
struct iatt *postparent)
{
pl_local_t *local = NULL;
GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
- if (op_ret)
+ if (op_ret) {
goto out;
+ }
local = frame->local;
- if (local->parent_entrylk_req)
- pl_parent_entrylk_xattr_fill (this, local->loc.parent,
- (char*)local->loc.name, xdata);
if (local->entrylk_count_req)
- pl_entrylk_xattr_fill (this, inode, xdata);
+ pl_entrylk_xattr_fill (this, inode, dict);
if (local->inodelk_count_req)
- pl_inodelk_xattr_fill (this, inode, xdata);
+ pl_inodelk_xattr_fill (this, inode, dict);
if (local->posixlk_count_req)
- pl_posixlk_xattr_fill (this, inode, xdata);
+ pl_posixlk_xattr_fill (this, inode, dict);
-out:
- local = frame->local;
frame->local = NULL;
- if (local != NULL) {
- loc_wipe (&local->loc);
- mem_put (local);
- }
+ if (local != NULL)
+ GF_FREE (local);
+out:
STACK_UNWIND_STRICT (
lookup,
frame,
- op_ret,
- op_errno,
- inode,
- buf,
- xdata,
- postparent);
+ op_ret,
+ op_errno,
+ inode,
+ buf,
+ dict,
+ postparent);
return 0;
}
int32_t
pl_lookup (call_frame_t *frame,
- xlator_t *this,
- loc_t *loc,
- dict_t *xdata)
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xattr_req)
{
pl_local_t *local = NULL;
int ret = -1;
@@ -1629,106 +1473,39 @@ pl_lookup (call_frame_t *frame,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_locks_mt_pl_local_t);
GF_VALIDATE_OR_GOTO (this->name, local, out);
- if (xdata) {
- if (dict_get (xdata, GLUSTERFS_ENTRYLK_COUNT))
+ if (xattr_req) {
+ if (dict_get (xattr_req, GLUSTERFS_ENTRYLK_COUNT))
local->entrylk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_INODELK_COUNT))
+ if (dict_get (xattr_req, GLUSTERFS_INODELK_COUNT))
local->inodelk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_POSIXLK_COUNT))
+ if (dict_get (xattr_req, GLUSTERFS_POSIXLK_COUNT))
local->posixlk_count_req = 1;
- if (dict_get (xdata, GLUSTERFS_PARENT_ENTRYLK))
- local->parent_entrylk_req = 1;
}
frame->local = local;
- loc_copy (&local->loc, loc);
STACK_WIND (frame,
pl_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xdata);
+ loc,
+ xattr_req);
ret = 0;
out:
if (ret == -1)
- STACK_UNWIND_STRICT (lookup, frame, -1, 0, NULL,
- NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (lookup, frame, -1, 0, NULL, NULL, NULL, NULL);
return 0;
}
-int
-pl_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata)
-{
- pl_local_t *local = NULL;
- gf_dirent_t *entry = NULL;
-
- local = frame->local;
-
- if (op_ret <= 0)
- goto unwind;
-
- list_for_each_entry (entry, &entries->list, list) {
- if (local->entrylk_count_req)
- pl_entrylk_xattr_fill (this, entry->inode, entry->dict);
- if (local->inodelk_count_req)
- pl_inodelk_xattr_fill (this, entry->inode, entry->dict);
- if (local->posixlk_count_req)
- pl_posixlk_xattr_fill (this, entry->inode, entry->dict);
- }
-
-unwind:
- frame->local = NULL;
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
-
- if (local)
- mem_put (local);
-
- return 0;
-}
-
-int
-pl_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
-{
- pl_local_t *local = NULL;
-
- local = mem_get0 (this->local_pool);
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- if (dict) {
- if (dict_get (dict, GLUSTERFS_ENTRYLK_COUNT))
- local->entrylk_count_req = 1;
- if (dict_get (dict, GLUSTERFS_INODELK_COUNT))
- local->inodelk_count_req = 1;
- if (dict_get (dict, GLUSTERFS_POSIXLK_COUNT))
- local->posixlk_count_req = 1;
- }
-
- frame->local = local;
-
- STACK_WIND (frame, pl_readdirp_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
-
- return 0;
-out:
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL, NULL);
- return 0;
-}
-
void
pl_dump_lock (char *str, int size, struct gf_flock *flock,
- gf_lkowner_t *owner, void *trans, time_t *granted_time,
- time_t *blkd_time, gf_boolean_t active)
+ uint64_t owner, void *trans)
{
- char *type_str = NULL;
- char granted[32] = {0,};
- char blocked[32] = {0,};
+ char *type_str = NULL;
switch (flock->l_type) {
case F_RDLCK:
@@ -1745,35 +1522,13 @@ pl_dump_lock (char *str, int size, struct gf_flock *flock,
break;
}
- if (active) {
- if (blkd_time && *blkd_time == 0) {
- snprintf (str, size, RANGE_GRNTD_FMT,
- type_str, flock->l_whence,
- (unsigned long long) flock->l_start,
- (unsigned long long) flock->l_len,
- (unsigned long long) flock->l_pid,
- lkowner_utoa (owner), trans,
- ctime_r (granted_time, granted));
- } else {
- snprintf (str, size, RANGE_BLKD_GRNTD_FMT,
- type_str, flock->l_whence,
- (unsigned long long) flock->l_start,
- (unsigned long long) flock->l_len,
- (unsigned long long) flock->l_pid,
- lkowner_utoa (owner), trans,
- ctime_r (blkd_time, blocked),
- ctime_r (granted_time, granted));
- }
- }
- else {
- snprintf (str, size, RANGE_BLKD_FMT,
- type_str, flock->l_whence,
- (unsigned long long) flock->l_start,
- (unsigned long long) flock->l_len,
- (unsigned long long) flock->l_pid,
- lkowner_utoa (owner), trans,
- ctime_r (blkd_time, blocked));
- }
+ snprintf (str, size, "type=%s, start=%llu, len=%llu, pid=%llu, lk-owner=%llu, transport=%p",
+ type_str, (unsigned long long) flock->l_start,
+ (unsigned long long) flock->l_len,
+ (unsigned long long) flock->l_pid,
+ (unsigned long long) owner,
+ trans);
+
}
@@ -1782,10 +1537,8 @@ __dump_entrylks (pl_inode_t *pl_inode)
{
pl_dom_list_t *dom = NULL;
pl_entry_lock_t *lock = NULL;
- char blocked[32] = {0,};
- char granted[32] = {0,};
- int count = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
+ int count = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
char tmp[256];
@@ -1794,7 +1547,7 @@ __dump_entrylks (pl_inode_t *pl_inode)
count = 0;
gf_proc_dump_build_key(key,
- "lock-dump.domain",
+ "xlator.feature.locks.lock-dump.domain",
"domain");
gf_proc_dump_write(key, "%s", dom->domain);
@@ -1802,23 +1555,12 @@ __dump_entrylks (pl_inode_t *pl_inode)
gf_proc_dump_build_key(key,
"xlator.feature.locks.lock-dump.domain.entrylk",
- "entrylk[%d](ACTIVE)", count );
- if (lock->blkd_time.tv_sec == 0 && lock->blkd_time.tv_usec == 0) {
- snprintf (tmp, 256, ENTRY_GRNTD_FMT,
- lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
- "ENTRYLK_WRLCK", lock->basename,
- (unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
- ctime_r (&lock->granted_time.tv_sec, granted));
- } else {
- snprintf (tmp, 256, ENTRY_BLKD_GRNTD_FMT,
- lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
- "ENTRYLK_WRLCK", lock->basename,
- (unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
- ctime_r (&lock->blkd_time.tv_sec, blocked),
- ctime_r (&lock->granted_time.tv_sec, granted));
- }
+ "entrylk[%d](ACTIVE)",count );
+ snprintf (tmp, 256," %s on %s owner=%llu, transport=%p",
+ lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
+ "ENTRYLK_WRLCK", lock->basename,
+ (unsigned long long) lock->owner,
+ lock->trans);
gf_proc_dump_write(key, tmp);
@@ -1829,13 +1571,10 @@ __dump_entrylks (pl_inode_t *pl_inode)
gf_proc_dump_build_key(key,
"xlator.feature.locks.lock-dump.domain.entrylk",
- "entrylk[%d](BLOCKED)", count );
- snprintf (tmp, 256, ENTRY_BLKD_FMT,
+ "entrylk[%d](BLOCKED)",count );
+ snprintf (tmp, 256," %s on %s state = Blocked",
lock->type == ENTRYLK_RDLCK ? "ENTRYLK_RDLCK" :
- "ENTRYLK_WRLCK", lock->basename,
- (unsigned long long) lock->client_pid,
- lkowner_utoa (&lock->owner), lock->trans,
- ctime_r (&lock->blkd_time.tv_sec, blocked));
+ "ENTRYLK_WRLCK", lock->basename);
gf_proc_dump_write(key, tmp);
@@ -1872,23 +1611,18 @@ __dump_inodelks (pl_inode_t *pl_inode)
count = 0;
gf_proc_dump_build_key(key,
- "lock-dump.domain",
+ "xlator.feature.locks.lock-dump.domain",
"domain");
gf_proc_dump_write(key, "%s", dom->domain);
list_for_each_entry (lock, &dom->inodelk_list, list) {
gf_proc_dump_build_key(key,
- "inodelk",
+ "xlator.feature.locks.lock-dump.domain.inodelk",
"inodelk[%d](ACTIVE)",count );
- SET_FLOCK_PID (&lock->user_flock, lock);
pl_dump_lock (tmp, 256, &lock->user_flock,
- &lock->owner,
- lock->transport,
- &lock->granted_time.tv_sec,
- &lock->blkd_time.tv_sec,
- _gf_true);
+ lock->owner, lock->transport);
gf_proc_dump_write(key, tmp);
count++;
@@ -1897,14 +1631,10 @@ __dump_inodelks (pl_inode_t *pl_inode)
list_for_each_entry (lock, &dom->blocked_inodelks, blocked_locks) {
gf_proc_dump_build_key(key,
- "inodelk",
+ "xlator.feature.locks.lock-dump.domain.inodelk",
"inodelk[%d](BLOCKED)",count );
- SET_FLOCK_PID (&lock->user_flock, lock);
pl_dump_lock (tmp, 256, &lock->user_flock,
- &lock->owner,
- lock->transport,
- 0, &lock->blkd_time.tv_sec,
- _gf_false);
+ lock->owner, lock->transport);
gf_proc_dump_write(key, tmp);
count++;
@@ -1936,20 +1666,20 @@ __dump_posixlks (pl_inode_t *pl_inode)
list_for_each_entry (lock, &pl_inode->ext_list, list) {
- SET_FLOCK_PID (&lock->user_flock, lock);
gf_proc_dump_build_key(key,
- "posixlk",
+ "xlator.feature.locks.lock-dump.domain.posixlk",
"posixlk[%d](%s)",
count,
lock->blocked ? "BLOCKED" : "ACTIVE");
pl_dump_lock (tmp, 256, &lock->user_flock,
- &lock->owner, lock->transport,
- &lock->granted_time.tv_sec, &lock->blkd_time.tv_sec,
- (lock->blocked)? _gf_false: _gf_true);
+ lock->owner, lock->transport);
gf_proc_dump_write(key, tmp);
count++;
}
+
+
+
}
void
@@ -1970,84 +1700,79 @@ pl_dump_inode_priv (xlator_t *this, inode_t *inode)
int ret = -1;
uint64_t tmp_pl_inode = 0;
pl_inode_t *pl_inode = NULL;
- char *pathname = NULL;
- gf_boolean_t section_added = _gf_false;
+ char key[GF_DUMP_MAX_BUF_LEN];
int count = 0;
- if (!inode) {
- errno = EINVAL;
- goto out;
- }
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
- ret = TRY_LOCK (&inode->lock);
- if (ret)
- goto out;
- {
- ret = __inode_ctx_get (inode, this, &tmp_pl_inode);
- if (ret)
- goto unlock;
- }
-unlock:
- UNLOCK (&inode->lock);
- if (ret)
+ ret = inode_ctx_get (inode, this, &tmp_pl_inode);
+
+ if (ret != 0)
goto out;
pl_inode = (pl_inode_t *)(long)tmp_pl_inode;
+
if (!pl_inode) {
ret = -1;
goto out;
}
- gf_proc_dump_add_section("xlator.features.locks.%s.inode", this->name);
- section_added = _gf_true;
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.inode",
+ "%ld.mandatory",inode->ino);
+ gf_proc_dump_write(key, "%d", pl_inode->mandatory);
- /*We are safe to call __inode_path since we have the
- * inode->table->lock */
- __inode_path (inode, NULL, &pathname);
- if (pathname)
- gf_proc_dump_write ("path", "%s", pathname);
- gf_proc_dump_write("mandatory", "%d", pl_inode->mandatory);
+ count = get_entrylk_count (this, inode);
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.entrylk-count",
+ "%ld.entrylk-count", inode->ino);
+ gf_proc_dump_write(key, "%d", count);
- ret = pthread_mutex_trylock (&pl_inode->mutex);
- if (ret)
- goto out;
- {
- count = __get_entrylk_count (this, pl_inode);
- if (count) {
- gf_proc_dump_write("entrylk-count", "%d", count);
- __dump_entrylks (pl_inode);
- }
+ dump_entrylks(pl_inode);
- count = __get_inodelk_count (this, pl_inode);
- if (count) {
- gf_proc_dump_write("inodelk-count", "%d", count);
- __dump_inodelks (pl_inode);
- }
+ count = get_inodelk_count (this, inode);
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.inodelk-count",
+ "%ld.inodelk-count", inode->ino);
+ gf_proc_dump_write(key, "%d", count);
+
+ dump_inodelks(pl_inode);
+
+ count = get_posixlk_count (this, inode);
+ gf_proc_dump_build_key(key,
+ "xlator.feature.locks.posixlk-count",
+ "%ld.posixlk-count", inode->ino);
+ gf_proc_dump_write(key, "%d", count);
+
+ dump_posixlks(pl_inode);
- count = __get_posixlk_count (this, pl_inode);
- if (count) {
- gf_proc_dump_write("posixlk-count", "%d", count);
- __dump_posixlks (pl_inode);
- }
- }
- pthread_mutex_unlock (&pl_inode->mutex);
out:
- GF_FREE (pathname);
-
- if (ret && inode) {
- if (!section_added)
- gf_proc_dump_add_section ("xlator.features.locks.%s."
- "inode", this->name);
- gf_proc_dump_write ("Unable to print lock state", "(Lock "
- "acquisition failure) %s",
- uuid_utoa (inode->gfid));
- }
return ret;
}
+
+
+/*
+ * pl_dump_inode - inode dump function for posix locks
+ *
+ */
+int
+pl_dump_inode (xlator_t *this)
+{
+
+ GF_ASSERT (this);
+
+ if (this->itable) {
+ inode_table_dump(this->itable,
+ "xlator.features.locks.inode_table");
+ }
+
+ return 0;
+}
+
int32_t
mem_acct_init (xlator_t *this)
{
@@ -2116,20 +1841,13 @@ init (xlator_t *this)
}
}
- this->local_pool = mem_pool_new (pl_local_t, 32);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
this->private = priv;
ret = 0;
out:
if (ret) {
- GF_FREE (priv);
+ if (priv)
+ GF_FREE (priv);
}
return ret;
}
@@ -2152,23 +1870,21 @@ fini (xlator_t *this)
int
pl_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock,
- dict_t *xdata);
+ const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *flock);
int
pl_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock,
- dict_t *xdata);
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *flock);
int
pl_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
+ entrylk_cmd cmd, entrylk_type type);
int
pl_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata);
+ entrylk_cmd cmd, entrylk_type type);
struct xlator_fops fops = {
.lookup = pl_lookup,
@@ -2185,8 +1901,6 @@ struct xlator_fops fops = {
.fentrylk = pl_fentrylk,
.flush = pl_flush,
.opendir = pl_opendir,
- .readdirp = pl_readdirp,
- .getxattr = pl_getxattr,
};
struct xlator_dumpops dumpops = {
diff --git a/xlators/features/locks/src/reservelk.c b/xlators/features/locks/src/reservelk.c
index 11b724bc5..61110df79 100644
--- a/xlators/features/locks/src/reservelk.c
+++ b/xlators/features/locks/src/reservelk.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006, 2007, 2008 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -81,10 +81,10 @@ out:
return ret_lock;
}
-static inline int
+static int
__same_owner_reservelk (posix_lock_t *l1, posix_lock_t *l2)
{
- return (is_same_lkowner (&l1->owner, &l2->owner));
+ return ((l1->owner == l2->owner));
}
@@ -187,10 +187,10 @@ __lock_reservelk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
list_add_tail (&lock->list, &pl_inode->blocked_reservelks);
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) lk-owner:%s %"PRId64" - %"PRId64" => Blocked",
+ "%s (pid=%d) lk-owner:%"PRIu64" %"PRId64" - %"PRId64" => Blocked",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
@@ -292,15 +292,14 @@ grant_blocked_reserve_locks (xlator_t *this, pl_inode_t *pl_inode)
list_for_each_entry_safe (lock, tmp, &granted, list) {
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => Granted",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Granted",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
- STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock,
- NULL);
+ STACK_UNWIND_STRICT (lk, lock->frame, 0, 0, &lock->user_flock);
}
}
@@ -377,9 +376,7 @@ grant_blocked_lock_calls (xlator_t *this, pl_inode_t *pl_inode)
pl_trace_out (this, lock->frame, fd, NULL, cmd,
&lock->user_flock, -1, EAGAIN, NULL);
pl_update_refkeeper (this, fd->inode);
- STACK_UNWIND_STRICT (lk, lock->frame, -1,
- EAGAIN, &lock->user_flock,
- NULL);
+ STACK_UNWIND_STRICT (lk, lock->frame, -1, EAGAIN, &lock->user_flock);
__destroy_lock (lock);
}
}
@@ -432,18 +429,18 @@ pl_reserve_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock,
ret = __lock_reservelk (this, pl_inode, lock, can_block);
if (ret < 0)
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => NOK",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => NOK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len);
else
gf_log (this->name, GF_LOG_TRACE,
- "%s (pid=%d) (lk-owner=%s) %"PRId64" - %"PRId64" => OK",
+ "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => OK",
lock->fl_type == F_UNLCK ? "Unlock" : "Lock",
lock->client_pid,
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->fl_start,
lock->fl_end);
diff --git a/xlators/features/locks/tests/unit-test.c b/xlators/features/locks/tests/unit-test.c
index e95612ad4..48c9f3012 100644
--- a/xlators/features/locks/tests/unit-test.c
+++ b/xlators/features/locks/tests/unit-test.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/mac-compat/src/mac-compat.c b/xlators/features/mac-compat/src/mac-compat.c
index cce621e67..b1277ec16 100644
--- a/xlators/features/mac-compat/src/mac-compat.c
+++ b/xlators/features/mac-compat/src/mac-compat.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -57,8 +57,7 @@ static int32_t apple_xattr_len[] = {
int32_t
maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
intptr_t ax = (intptr_t)this->private;
int i = 0;
@@ -81,7 +80,7 @@ maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
}
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
@@ -89,7 +88,7 @@ maccomp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
intptr_t ax = GF_XATTR_NONE;
int i = 0;
@@ -110,14 +109,14 @@ maccomp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
STACK_WIND (frame, maccomp_getxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr,
- loc, name, xdata);
+ loc, name);
return 0;
}
int32_t
maccomp_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
intptr_t ax = GF_XATTR_NONE;
int i = 0;
@@ -138,21 +137,21 @@ maccomp_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, maccomp_getxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fgetxattr,
- fd, name, xdata);
+ fd, name);
return 0;
}
int32_t
maccomp_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
intptr_t ax = (intptr_t)this->private;
if (op_ret == -1 && ax != GF_XATTR_NONE)
op_ret = op_errno = 0;
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
@@ -160,7 +159,7 @@ maccomp_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
intptr_t ax = GF_XATTR_NONE;
int i = 0;
@@ -178,14 +177,14 @@ maccomp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
STACK_WIND (frame, maccomp_setxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
+ loc, dict, flags);
return 0;
}
int32_t
maccomp_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
intptr_t ax = GF_XATTR_NONE;
int i = 0;
@@ -203,7 +202,7 @@ maccomp_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
STACK_WIND (frame, maccomp_setxattr_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
+ fd, dict, flags);
return 0;
}
diff --git a/xlators/features/marker/src/marker-common.c b/xlators/features/marker/src/marker-common.c
index a413781bc..9d27167fc 100644
--- a/xlators/features/marker/src/marker-common.c
+++ b/xlators/features/marker/src/marker-common.c
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -42,7 +42,7 @@ int32_t
marker_force_inode_ctx_get (inode_t *inode, xlator_t *this,
marker_inode_ctx_t **ctx)
{
- int32_t ret = -1;
+ int32_t ret = -1;
uint64_t ctx_int = 0;
LOCK (&inode->lock);
@@ -71,16 +71,16 @@ unlock: UNLOCK (&inode->lock);
void
marker_filter_quota_xattr (dict_t *dict, char *key,
- data_t *value, void *data)
+ data_t *value, void *data)
{
- int ret = -1;
+ int ret = -1;
- GF_VALIDATE_OR_GOTO ("marker", dict, out);
- GF_VALIDATE_OR_GOTO ("marker", key, out);
+ GF_VALIDATE_OR_GOTO ("marker", dict, out);
+ GF_VALIDATE_OR_GOTO ("marker", key, out);
- ret = fnmatch ("trusted.glusterfs.quota*", key, 0);
- if (ret == 0)
- dict_del (dict, key);
+ ret = fnmatch ("trusted.glusterfs.quota*", key, 0);
+ if (ret == 0)
+ dict_del (dict, key);
out:
- return;
+ return;
}
diff --git a/xlators/features/marker/src/marker-common.h b/xlators/features/marker/src/marker-common.h
index 0a7ee2619..2533571c1 100644
--- a/xlators/features/marker/src/marker-common.h
+++ b/xlators/features/marker/src/marker-common.h
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
diff --git a/xlators/features/marker/src/marker-mem-types.h b/xlators/features/marker/src/marker-mem-types.h
index 2f49c0d9d..847bfa67c 100644
--- a/xlators/features/marker/src/marker-mem-types.h
+++ b/xlators/features/marker/src/marker-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,12 +23,14 @@
#include "mem-types.h"
enum gf_marker_mem_types_ {
- gf_marker_mt_marker_conf_t = gf_common_mt_end + 1,
+ gf_marker_mt_marker_local_t = gf_common_mt_end + 1,
+ gf_marker_mt_marker_conf_t,
gf_marker_mt_loc_t,
gf_marker_mt_volume_mark,
gf_marker_mt_int64_t,
gf_marker_mt_quota_inode_ctx_t,
gf_marker_mt_marker_inode_ctx_t,
+ gf_marker_mt_quota_local_t,
gf_marker_mt_inode_contribution_t,
gf_marker_mt_end
};
diff --git a/xlators/features/marker/src/marker-quota-helper.c b/xlators/features/marker/src/marker-quota-helper.c
index 8d4ff7786..fba2cdd3f 100644
--- a/xlators/features/marker/src/marker-quota-helper.c
+++ b/xlators/features/marker/src/marker-quota-helper.c
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -28,19 +28,16 @@
#include "marker-mem-types.h"
int
-mq_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
+quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
{
int ret = -1;
- GF_VALIDATE_OR_GOTO ("marker", loc, out);
- GF_VALIDATE_OR_GOTO ("marker", inode, out);
- GF_VALIDATE_OR_GOTO ("marker", path, out);
- /* Not checking for parent because while filling
- * loc of root, parent will be NULL
- */
+ if (!loc)
+ return ret;
if (inode) {
loc->inode = inode_ref (inode);
+ loc->ino = inode->ino;
}
if (parent)
@@ -62,13 +59,13 @@ mq_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
loc_wipe:
if (ret < 0)
loc_wipe (loc);
-out:
+
return ret;
}
int32_t
-mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)
+quota_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)
{
char *resolvedpath = NULL;
inode_t *parent = NULL;
@@ -77,7 +74,7 @@ mq_inode_loc_fill (const char *parent_gfid, inode_t *inode, loc_t *loc)
if ((!inode) || (!loc))
return ret;
- if ((inode) && __is_root_gfid (inode->gfid)) {
+ if ((inode) && (inode->ino == 1)) {
loc->parent = NULL;
goto ignore_parent;
}
@@ -96,7 +93,7 @@ ignore_parent:
if (ret < 0)
goto err;
- ret = mq_loc_fill (loc, inode, parent, resolvedpath);
+ ret = quota_loc_fill (loc, inode, parent, resolvedpath);
if (ret < 0)
goto err;
@@ -111,7 +108,7 @@ err:
quota_inode_ctx_t *
-mq_alloc_inode_ctx ()
+quota_alloc_inode_ctx ()
{
int32_t ret = -1;
quota_inode_ctx_t *ctx = NULL;
@@ -122,7 +119,6 @@ mq_alloc_inode_ctx ()
ctx->size = 0;
ctx->dirty = 0;
- ctx->updation_status = _gf_false;
LOCK_INIT (&ctx->lock);
INIT_LIST_HEAD (&ctx->contribution_head);
out:
@@ -130,13 +126,13 @@ out:
}
inode_contribution_t *
-mq_get_contribution_node (inode_t *inode, quota_inode_ctx_t *ctx)
+get_contribution_node (inode_t *inode, quota_inode_ctx_t *ctx)
{
inode_contribution_t *contri = NULL;
inode_contribution_t *temp = NULL;
- if (!inode || !ctx)
- goto out;
+ GF_VALIDATE_OR_GOTO ("marker", inode, out);
+ GF_VALIDATE_OR_GOTO ("marker", ctx, out);
list_for_each_entry (temp, &ctx->contribution_head, contri_list) {
if (uuid_compare (temp->gfid, inode->gfid) == 0) {
@@ -150,8 +146,8 @@ out:
int32_t
-mq_delete_contribution_node (dict_t *dict, char *key,
- inode_contribution_t *contribution)
+delete_contribution_node (dict_t *dict, char *key,
+ inode_contribution_t *contribution)
{
if (dict_get (dict, key) != NULL)
goto out;
@@ -163,17 +159,13 @@ out:
inode_contribution_t *
-__mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc)
+__add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc)
{
int32_t ret = 0;
inode_contribution_t *contribution = NULL;
- if (!loc->parent)
- goto out;
-
list_for_each_entry (contribution, &ctx->contribution_head, contri_list) {
- if (loc->parent &&
- uuid_compare (contribution->gfid, loc->parent->gfid) == 0) {
+ if (uuid_compare (contribution->gfid, loc->parent->gfid) == 0) {
goto out;
}
}
@@ -186,9 +178,6 @@ __mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *l
uuid_copy (contribution->gfid, loc->parent->gfid);
- LOCK_INIT (&contribution->lock);
- INIT_LIST_HEAD (&contribution->contri_list);
-
list_add_tail (&contribution->contri_list, &ctx->contribution_head);
out:
@@ -197,7 +186,7 @@ out:
inode_contribution_t *
-mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc)
+add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc)
{
inode_contribution_t *contribution = NULL;
@@ -209,7 +198,7 @@ mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc
LOCK (&ctx->lock);
{
- contribution = __mq_add_new_contribution_node (this, ctx, loc);
+ contribution = __add_new_contribution_node (this, ctx, loc);
}
UNLOCK (&ctx->lock);
@@ -218,8 +207,8 @@ mq_add_new_contribution_node (xlator_t *this, quota_inode_ctx_t *ctx, loc_t *loc
int32_t
-mq_dict_set_contribution (xlator_t *this, dict_t *dict,
- loc_t *loc)
+dict_set_contribution (xlator_t *this, dict_t *dict,
+ loc_t *loc)
{
int32_t ret = -1;
char contri_key [512] = {0, };
@@ -227,7 +216,6 @@ mq_dict_set_contribution (xlator_t *this, dict_t *dict,
GF_VALIDATE_OR_GOTO ("marker", this, out);
GF_VALIDATE_OR_GOTO ("marker", dict, out);
GF_VALIDATE_OR_GOTO ("marker", loc, out);
- GF_VALIDATE_OR_GOTO ("marker", loc->parent, out);
GET_CONTRI_KEY (contri_key, loc->parent->gfid, ret);
if (ret < 0) {
@@ -250,8 +238,8 @@ out:
int32_t
-mq_inode_ctx_get (inode_t *inode, xlator_t *this,
- quota_inode_ctx_t **ctx)
+quota_inode_ctx_get (inode_t *inode, xlator_t *this,
+ quota_inode_ctx_t **ctx)
{
int32_t ret = -1;
uint64_t ctx_int = 0;
@@ -284,7 +272,7 @@ out:
quota_inode_ctx_t *
-__mq_inode_ctx_new (inode_t *inode, xlator_t *this)
+__quota_inode_ctx_new (inode_t *inode, xlator_t *this)
{
int32_t ret = -1;
quota_inode_ctx_t *quota_ctx = NULL;
@@ -300,7 +288,7 @@ __mq_inode_ctx_new (inode_t *inode, xlator_t *this)
LOCK (&inode->lock);
{
if (mark_ctx->quota_ctx == NULL) {
- quota_ctx = mq_alloc_inode_ctx ();
+ quota_ctx = quota_alloc_inode_ctx ();
if (quota_ctx == NULL) {
ret = -1;
goto unlock;
@@ -320,23 +308,29 @@ out:
quota_inode_ctx_t *
-mq_inode_ctx_new (inode_t * inode, xlator_t *this)
+quota_inode_ctx_new (inode_t * inode, xlator_t *this)
{
- return __mq_inode_ctx_new (inode, this);
+ return __quota_inode_ctx_new (inode, this);
}
quota_local_t *
-mq_local_new ()
+quota_local_new ()
{
+ int32_t ret = -1;
quota_local_t *local = NULL;
- local = mem_get0 (THIS->local_pool);
- if (!local)
+ QUOTA_ALLOC (local, quota_local_t, ret);
+ if (ret < 0)
goto out;
local->ref = 1;
+ local->delta = 0;
+ local->err = 0;
LOCK_INIT (&local->lock);
+ memset (&local->loc, 0, sizeof (loc_t));
+ memset (&local->parent_loc, 0, sizeof (loc_t));
+
local->ctx = NULL;
local->contri = NULL;
@@ -345,7 +339,7 @@ out:
}
quota_local_t *
-mq_local_ref (quota_local_t *local)
+quota_local_ref (quota_local_t *local)
{
LOCK (&local->lock);
{
@@ -358,15 +352,14 @@ mq_local_ref (quota_local_t *local)
int32_t
-mq_local_unref (xlator_t *this, quota_local_t *local)
+quota_local_unref (xlator_t *this, quota_local_t *local)
{
- int32_t ref = 0;
if (local == NULL)
goto out;
- QUOTA_SAFE_DECREMENT (&local->lock, local->ref, ref);
+ QUOTA_SAFE_DECREMENT (&local->lock, local->ref);
- if (ref != 0)
+ if (local->ref > 0)
goto out;
if (local->fd != NULL)
@@ -377,39 +370,6 @@ mq_local_unref (xlator_t *this, quota_local_t *local)
loc_wipe (&local->parent_loc);
LOCK_DESTROY (&local->lock);
-
- mem_put (local);
out:
return 0;
}
-
-
-inode_contribution_t *
-mq_get_contribution_from_loc (xlator_t *this, loc_t *loc)
-{
- int32_t ret = 0;
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contribution = NULL;
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "cannot get marker-quota context from inode "
- "(gfid:%s, path:%s)",
- uuid_utoa (loc->inode->gfid), loc->path);
- goto err;
- }
-
- contribution = mq_get_contribution_node (loc->parent, ctx);
- if (contribution == NULL) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "inode (gfid:%s, path:%s) has "
- "no contribution towards parent (gfid:%s)",
- uuid_utoa (loc->inode->gfid),
- loc->path, uuid_utoa (loc->parent->gfid));
- goto err;
- }
-
-err:
- return contribution;
-}
diff --git a/xlators/features/marker/src/marker-quota-helper.h b/xlators/features/marker/src/marker-quota-helper.h
index e019fbd52..9a24c8c3d 100644
--- a/xlators/features/marker/src/marker-quota-helper.h
+++ b/xlators/features/marker/src/marker-quota-helper.h
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -22,8 +22,7 @@
#define _CONFIG_H
#include "config.h"
#endif
-
-#include "marker.h"
+#include "marker-quota.h"
#define QUOTA_FREE_CONTRIBUTION_NODE(_contribution) \
do { \
@@ -38,46 +37,40 @@
UNLOCK (lock); \
} while (0)
-#define QUOTA_SAFE_DECREMENT(lock, var, value) \
- do { \
- LOCK (lock); \
- { \
- value = --var; \
- } \
- UNLOCK (lock); \
+#define QUOTA_SAFE_DECREMENT(lock, var) \
+ do { \
+ LOCK (lock); \
+ var --; \
+ UNLOCK (lock); \
} while (0)
inode_contribution_t *
-mq_add_new_contribution_node (xlator_t *, quota_inode_ctx_t *, loc_t *);
+add_new_contribution_node (xlator_t *, quota_inode_ctx_t *, loc_t *);
int32_t
-mq_dict_set_contribution (xlator_t *, dict_t *, loc_t *);
+dict_set_contribution (xlator_t *, dict_t *, loc_t *);
quota_inode_ctx_t *
-mq_inode_ctx_new (inode_t *, xlator_t *);
+quota_inode_ctx_new (inode_t *, xlator_t *);
int32_t
-mq_inode_ctx_get (inode_t *, xlator_t *, quota_inode_ctx_t **);
+quota_inode_ctx_get (inode_t *, xlator_t *, quota_inode_ctx_t **);
int32_t
-mq_delete_contribution_node (dict_t *, char *, inode_contribution_t *);
+delete_contribution_node (dict_t *, char *, inode_contribution_t *);
int32_t
-mq_inode_loc_fill (const char *, inode_t *, loc_t *);
+quota_inode_loc_fill (const char *, inode_t *, loc_t *);
quota_local_t *
-mq_local_new ();
+quota_local_new ();
quota_local_t *
-mq_local_ref (quota_local_t *);
+quota_local_ref (quota_local_t *);
int32_t
-mq_local_unref (xlator_t *, quota_local_t *);
+quota_local_unref (xlator_t *, quota_local_t *);
inode_contribution_t *
-mq_get_contribution_node (inode_t *, quota_inode_ctx_t *);
-
-inode_contribution_t *
-mq_get_contribution_from_loc (xlator_t *this, loc_t *loc);
-
+get_contribution_node (inode_t *, quota_inode_ctx_t *);
#endif
diff --git a/xlators/features/marker/src/marker-quota.c b/xlators/features/marker/src/marker-quota.c
index fdce7129e..68a8a26c6 100644
--- a/xlators/features/marker/src/marker-quota.c
+++ b/xlators/features/marker/src/marker-quota.c
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -30,115 +30,11 @@
#include "marker-quota.h"
#include "marker-quota-helper.h"
-int
-mq_loc_copy (loc_t *dst, loc_t *src)
-{
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("marker", dst, out);
- GF_VALIDATE_OR_GOTO ("marker", src, out);
-
- if (src->inode == NULL ||
- src->path == NULL) {
- gf_log ("marker", GF_LOG_WARNING,
- "src loc is not valid");
- goto out;
- }
-
- ret = loc_copy (dst, src);
-out:
- return ret;
-}
-
-int32_t
-mq_get_local_err (quota_local_t *local,
- int32_t *val)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("marker", local, out);
- GF_VALIDATE_OR_GOTO ("marker", val, out);
-
- LOCK (&local->lock);
- {
- *val = local->err;
- }
- UNLOCK (&local->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-mq_get_ctx_updation_status (quota_inode_ctx_t *ctx,
- gf_boolean_t *status)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("marker", ctx, out);
- GF_VALIDATE_OR_GOTO ("marker", status, out);
-
- LOCK (&ctx->lock);
- {
- *status = ctx->updation_status;
- }
- UNLOCK (&ctx->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int32_t
-mq_set_ctx_updation_status (quota_inode_ctx_t *ctx,
- gf_boolean_t status)
-{
- int32_t ret = -1;
-
- if (ctx == NULL)
- goto out;
-
- LOCK (&ctx->lock);
- {
- ctx->updation_status = status;
- }
- UNLOCK (&ctx->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-mq_test_and_set_ctx_updation_status (quota_inode_ctx_t *ctx,
- gf_boolean_t *status)
-{
- int32_t ret = -1;
- gf_boolean_t temp = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("marker", ctx, out);
- GF_VALIDATE_OR_GOTO ("marker", status, out);
-
- LOCK (&ctx->lock);
- {
- temp = *status;
- *status = ctx->updation_status;
- ctx->updation_status = temp;
- }
- UNLOCK (&ctx->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
void
mq_assign_lk_owner (xlator_t *this, call_frame_t *frame)
{
marker_conf_t *conf = NULL;
- uint64_t lk_owner = 0;
+ uint64_t lk_owner = 0;
conf = this->private;
@@ -152,15 +48,15 @@ mq_assign_lk_owner (xlator_t *this, call_frame_t *frame)
}
UNLOCK (&conf->lock);
- set_lk_owner_from_uint64 (&frame->root->lk_owner, lk_owner);
+ frame->root->lk_owner = lk_owner;
return;
}
int32_t
-mq_loc_fill_from_name (xlator_t *this, loc_t *newloc, loc_t *oldloc,
- uint64_t ino, char *name)
+loc_fill_from_name (xlator_t *this, loc_t *newloc, loc_t *oldloc,
+ uint64_t ino, char *name)
{
int32_t ret = -1;
int32_t len = 0;
@@ -171,6 +67,8 @@ mq_loc_fill_from_name (xlator_t *this, loc_t *newloc, loc_t *oldloc,
GF_VALIDATE_OR_GOTO ("marker", oldloc, out);
GF_VALIDATE_OR_GOTO ("marker", name, out);
+ newloc->ino = ino;
+
newloc->inode = inode_new (oldloc->inode->table);
if (!newloc->inode) {
@@ -179,7 +77,6 @@ mq_loc_fill_from_name (xlator_t *this, loc_t *newloc, loc_t *oldloc,
}
newloc->parent = inode_ref (oldloc->inode);
- uuid_copy (newloc->pargfid, oldloc->inode->gfid);
len = strlen (oldloc->path);
@@ -207,29 +104,36 @@ out:
}
int32_t
-mq_dirty_inode_updation_done (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+dirty_inode_updation_done (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
+ quota_local_t *local = NULL;
+
+ local = frame->local;
+
+ if (!local->err)
+ QUOTA_SAFE_DECREMENT (&local->lock, local->ref);
+ else
+ frame->local = NULL;
+
QUOTA_STACK_DESTROY (frame, this);
return 0;
}
int32_t
-mq_release_lock_on_dirty_inode (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+release_lock_on_dirty_inode (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- struct gf_flock lock = {0, };
+ struct gf_flock lock;
quota_local_t *local = NULL;
- loc_t loc = {0, };
- int ret = -1;
local = frame->local;
if (op_ret == -1) {
local->err = -1;
- mq_dirty_inode_updation_done (frame, NULL, this, 0, 0, NULL);
+ dirty_inode_updation_done (frame, NULL, this, 0, 0);
return 0;
}
@@ -243,50 +147,32 @@ mq_release_lock_on_dirty_inode (call_frame_t *frame, void *cookie, xlator_t *thi
lock.l_len = 0;
lock.l_pid = 0;
- ret = loc_copy (&loc, &local->loc);
- if (ret == -1) {
- local->err = -1;
- frame->local = NULL;
- mq_dirty_inode_updation_done (frame, NULL, this, 0, 0, NULL);
- return 0;
- }
-
- if (local->loc.inode == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "Inode is NULL, so can't stackwind.");
- goto out;
- }
-
STACK_WIND (frame,
- mq_dirty_inode_updation_done,
+ dirty_inode_updation_done,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- this->name, &loc, F_SETLKW, &lock, NULL);
-
- loc_wipe (&loc);
-
- return 0;
-out:
- mq_dirty_inode_updation_done (frame, NULL, this, -1, 0, NULL);
+ this->name, &local->loc, F_SETLKW, &lock);
return 0;
}
int32_t
-mq_mark_inode_undirty (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+mark_inode_undirty (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- int32_t ret = -1;
- int64_t *size = NULL;
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
+ int32_t ret = -1;
+ int64_t *size = NULL;
+ dict_t *newdict = NULL;
+ quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
local = (quota_local_t *) frame->local;
if (op_ret == -1)
goto err;
+ priv = (marker_conf_t *) this->private;
+
if (!dict)
goto wind;
@@ -294,11 +180,7 @@ mq_mark_inode_undirty (call_frame_t *frame, void *cookie, xlator_t *this,
if (ret)
goto wind;
- LOCK (&local->ctx->lock);
- {
- local->ctx->size = ntoh64 (*size);
- }
- UNLOCK (&local->ctx->lock);
+ local->ctx->size = ntoh64 (*size);
wind:
newdict = dict_new ();
@@ -309,21 +191,17 @@ wind:
if (ret)
goto err;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
- STACK_WIND (frame, mq_release_lock_on_dirty_inode,
+ STACK_WIND (frame, release_lock_on_dirty_inode,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- &local->loc, newdict, 0, NULL);
+ &local->loc, newdict, 0);
ret = 0;
err:
if (op_ret == -1 || ret == -1) {
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
}
if (newdict)
@@ -333,21 +211,24 @@ err:
}
int32_t
-mq_update_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict, struct iatt *postparent)
+update_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
int32_t ret = -1;
dict_t *new_dict = NULL;
int64_t *size = NULL;
int64_t *delta = NULL;
quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
local = frame->local;
if (op_ret == -1)
goto err;
+ priv = this->private;
+
if (dict == NULL) {
gf_log (this->name, GF_LOG_WARNING,
"Dict is null while updating the size xattr %s",
@@ -379,14 +260,9 @@ mq_update_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
if (ret)
goto err;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND (frame, mq_mark_inode_undirty, FIRST_CHILD(this),
+ STACK_WIND (frame, mark_inode_undirty, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop, &local->loc,
- GF_XATTROP_ADD_ARRAY64, new_dict, NULL);
+ GF_XATTROP_ADD_ARRAY64, new_dict);
ret = 0;
@@ -394,7 +270,7 @@ err:
if (op_ret == -1 || ret == -1) {
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
}
if (new_dict)
@@ -404,37 +280,17 @@ err:
}
int32_t
-mq_test_and_set_local_err(quota_local_t *local,
- int32_t *val)
+get_dirty_inode_size (call_frame_t *frame, xlator_t *this)
{
- int tmp = 0;
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("marker", local, out);
- GF_VALIDATE_OR_GOTO ("marker", val, out);
-
- LOCK (&local->lock);
- {
- tmp = local->err;
- local->err = *val;
- *val = tmp;
- }
- UNLOCK (&local->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-mq_get_dirty_inode_size (call_frame_t *frame, xlator_t *this)
-{
- int32_t ret = -1;
- dict_t *dict = NULL;
- quota_local_t *local = NULL;
+ int32_t ret = -1;
+ dict_t *dict = NULL;
+ quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
local = (quota_local_t *) frame->local;
+ priv = (marker_conf_t *) this->private;
+
dict = dict_new ();
if (!dict) {
ret = -1;
@@ -445,12 +301,7 @@ mq_get_dirty_inode_size (call_frame_t *frame, xlator_t *this)
if (ret)
goto err;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND (frame, mq_update_size_xattr, FIRST_CHILD(this),
+ STACK_WIND (frame, update_size_xattr, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, &local->loc, dict);
ret =0;
@@ -458,31 +309,28 @@ err:
if (ret) {
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
}
- if (dict)
- dict_unref (dict);
-
return 0;
}
int32_t
-mq_get_child_contribution (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- dict_t *dict,
- struct iatt *postparent)
+get_child_contribution (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ dict_t *dict,
+ struct iatt *postparent)
{
- int32_t ret = -1;
- int32_t val = 0;
- char contri_key [512] = {0, };
- int64_t *contri = NULL;
- quota_local_t *local = NULL;
+ int32_t ret = -1;
+ int32_t val = 0;
+ char contri_key [512] = {0, };
+ int64_t *contri = NULL;
+ quota_local_t *local = NULL;
local = frame->local;
@@ -491,20 +339,17 @@ mq_get_child_contribution (call_frame_t *frame,
QUOTA_STACK_DESTROY (frame, this);
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- strerror (op_errno));
- val = -2;
- if (!mq_test_and_set_local_err (local, &val) &&
- val != -2)
- mq_release_lock_on_dirty_inode (local->frame, NULL,
- this, 0, 0, NULL);
+ gf_log (this->name, GF_LOG_ERROR, "%s", strerror (op_errno));
+
+ local->err = -2;
+
+ release_lock_on_dirty_inode (local->frame, NULL, this, 0, 0);
- goto exit;
+ goto out;
}
- ret = mq_get_local_err (local, &val);
- if (!ret && val == -2)
- goto exit;
+ if (local->err)
+ goto out;
GET_CONTRI_KEY (contri_key, local->loc.inode->gfid, ret);
if (ret < 0)
@@ -523,83 +368,76 @@ out:
}
UNLOCK (&local->lock);
- if (val == 0) {
- mq_dirty_inode_readdir (local->frame, NULL, this,
- 0, 0, NULL, NULL);
+ if (val== 0) {
+ if (local->err) {
+ QUOTA_SAFE_DECREMENT (&local->lock, local->ref);
+
+ quota_local_unref (this, local);
+ } else
+ quota_dirty_inode_readdir (local->frame, NULL, this,
+ 0, 0, NULL);
}
- mq_local_unref (this, local);
return 0;
-exit:
- mq_local_unref (this, local);
- return 0;
}
int32_t
-mq_readdir_cbk (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- gf_dirent_t *entries, dict_t *xdata)
+quota_readdir_cbk (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ gf_dirent_t *entries)
{
- char contri_key [512] = {0, };
- int32_t ret = 0;
- int32_t val = 0;
- off_t offset = 0;
- int32_t count = 0;
- dict_t *dict = NULL;
- quota_local_t *local = NULL;
- gf_dirent_t *entry = NULL;
- call_frame_t *newframe = NULL;
- loc_t loc = {0, };
-
- local = mq_local_ref (frame->local);
+ char contri_key [512] = {0, };
+ loc_t loc;
+ int32_t ret = 0;
+ off_t offset = 0;
+ int32_t count = 0;
+ dict_t *dict = NULL;
+ quota_local_t *local = NULL;
+ gf_dirent_t *entry = NULL;
+ call_frame_t *newframe = NULL;
+
+ local = frame->local;
if (op_ret == -1) {
gf_log (this->name, GF_LOG_DEBUG,
"readdir failed %s", strerror (op_errno));
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
- goto end;
+ return 0;
} else if (op_ret == 0) {
- mq_get_dirty_inode_size (frame, this);
+ get_dirty_inode_size (frame, this);
- goto end;
+ return 0;
}
local->dentry_child_count = 0;
list_for_each_entry (entry, (&entries->list), list) {
- gf_log (this->name, GF_LOG_DEBUG, "entry = %s", entry->d_name);
-
- if ((!strcmp (entry->d_name, ".")) || (!strcmp (entry->d_name,
- ".."))) {
- gf_log (this->name, GF_LOG_DEBUG, "entry = %s",
- entry->d_name);
- continue;
- }
-
- offset = entry->d_off;
- count++;
- }
-
- if (count == 0) {
- mq_get_dirty_inode_size (frame, this);
- goto end;
+ gf_log (this->name, GF_LOG_DEBUG, "entry = %s", entry->d_name);
+ if ((!strcmp (entry->d_name, ".")) || (!strcmp (entry->d_name,
+ ".."))) {
+ gf_log (this->name, GF_LOG_DEBUG, "entry = %s",
+ entry->d_name);
+ continue;
+ }
+ count++;
}
local->frame = frame;
- LOCK (&local->lock);
- {
- local->dentry_child_count = count;
- local->d_off = offset;
+ if (count > 0) {
+ LOCK (&local->lock);
+ {
+ local->dentry_child_count = count;
+ }
+ UNLOCK (&local->lock);
}
- UNLOCK (&local->lock);
list_for_each_entry (entry, (&entries->list), list) {
@@ -609,32 +447,22 @@ mq_readdir_cbk (call_frame_t *frame,
".."))) {
gf_log (this->name, GF_LOG_DEBUG, "entry = %s",
entry->d_name);
+ offset = entry->d_off;
continue;
}
- ret = mq_loc_fill_from_name (this, &loc, &local->loc,
- entry->d_ino, entry->d_name);
+ ret = loc_fill_from_name (this, &loc, &local->loc,
+ entry->d_ino, entry->d_name);
if (ret < 0)
goto out;
- ret = 0;
-
- LOCK (&local->lock);
- {
- if (local->err != -2) {
- newframe = copy_frame (frame);
- if (!newframe) {
- ret = -1;
- }
- } else
- ret = -1;
- }
- UNLOCK (&local->lock);
-
- if (ret == -1)
+ newframe = copy_frame (frame);
+ if (!newframe) {
+ ret = -1;
goto out;
+ }
- newframe->local = mq_local_ref (local);
+ newframe->local = local;
dict = dict_new ();
if (!dict) {
@@ -651,7 +479,7 @@ mq_readdir_cbk (call_frame_t *frame,
goto out;
STACK_WIND (newframe,
- mq_get_child_contribution,
+ get_child_contribution,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
&loc, dict);
@@ -660,8 +488,6 @@ mq_readdir_cbk (call_frame_t *frame,
loc_wipe (&loc);
- newframe = NULL;
-
out:
if (dict) {
dict_unref (dict);
@@ -669,35 +495,46 @@ mq_readdir_cbk (call_frame_t *frame,
}
if (ret) {
- val = -2;
- mq_test_and_set_local_err (local, &val);
+ LOCK (&local->lock);
+ {
+ if (local->dentry_child_count == 0)
+ local->err = -1;
+ else
+ local->err = -2;
+ }
+ UNLOCK (&local->lock);
if (newframe) {
newframe->local = NULL;
- mq_local_unref(this, local);
+
QUOTA_STACK_DESTROY (newframe, this);
}
break;
}
}
+ gf_log (this->name, GF_LOG_DEBUG, "offset before =%"PRIu64,
+ local->d_off);
+ local->d_off +=offset;
+ gf_log (this->name, GF_LOG_DEBUG, "offset after = %"PRIu64,
+ local->d_off);
- if (ret && val != -2) {
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
- }
-end:
- mq_local_unref (this, local);
+ if (ret)
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
+
+ else if (count == 0 )
+ get_dirty_inode_size (frame, this);
return 0;
}
int32_t
-mq_dirty_inode_readdir (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- fd_t *fd, dict_t *xdata)
+quota_dirty_inode_readdir (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ fd_t *fd)
{
quota_local_t *local = NULL;
@@ -705,7 +542,7 @@ mq_dirty_inode_readdir (call_frame_t *frame,
if (op_ret == -1) {
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
return 0;
}
@@ -713,29 +550,30 @@ mq_dirty_inode_readdir (call_frame_t *frame,
local->fd = fd_ref (fd);
STACK_WIND (frame,
- mq_readdir_cbk,
+ quota_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- local->fd, READDIR_BUF, local->d_off, xdata);
+ local->fd, READDIR_BUF, local->d_off);
return 0;
}
int32_t
-mq_check_if_still_dirty (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- inode_t *inode,
- struct iatt *buf,
- dict_t *dict,
- struct iatt *postparent)
+check_if_still_dirty (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ inode_t *inode,
+ struct iatt *buf,
+ dict_t *dict,
+ struct iatt *postparent)
{
int8_t dirty = -1;
int32_t ret = -1;
fd_t *fd = NULL;
quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
local = frame->local;
@@ -745,9 +583,11 @@ mq_check_if_still_dirty (call_frame_t *frame,
goto err;
}
+ priv = this->private;
+
if (!dict) {
- ret = -1;
- goto err;
+ ret = -1;
+ goto err;
}
ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty);
@@ -756,7 +596,7 @@ mq_check_if_still_dirty (call_frame_t *frame,
//the inode is not dirty anymore
if (dirty == 0) {
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
return 0;
}
@@ -765,44 +605,39 @@ mq_check_if_still_dirty (call_frame_t *frame,
local->d_off = 0;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
STACK_WIND(frame,
- mq_dirty_inode_readdir,
+ quota_dirty_inode_readdir,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- &local->loc, fd, NULL);
+ &local->loc, fd);
ret = 0;
err:
if (op_ret == -1 || ret == -1) {
local->err = -1;
- mq_release_lock_on_dirty_inode (frame, NULL, this, 0, 0, NULL);
- }
-
- if (fd != NULL) {
- fd_unref (fd);
+ release_lock_on_dirty_inode (frame, NULL, this, 0, 0);
}
return 0;
}
int32_t
-mq_get_dirty_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+get_dirty_xattr (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- int32_t ret = -1;
- dict_t *xattr_req = NULL;
- quota_local_t *local = NULL;
+ int32_t ret = -1;
+ dict_t *xattr_req = NULL;
+ quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
if (op_ret == -1) {
- mq_dirty_inode_updation_done (frame, NULL, this, 0, 0, NULL);
+ dirty_inode_updation_done (frame, NULL, this, 0, 0);
return 0;
}
+ priv = (marker_conf_t *) this->private;
+
local = frame->local;
xattr_req = dict_new ();
@@ -815,13 +650,8 @@ mq_get_dirty_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
if (ret)
goto err;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
STACK_WIND (frame,
- mq_check_if_still_dirty,
+ check_if_still_dirty,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
&local->loc,
@@ -831,7 +661,7 @@ mq_get_dirty_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
err:
if (ret) {
local->err = -1;
- mq_release_lock_on_dirty_inode(frame, NULL, this, 0, 0, NULL);
+ release_lock_on_dirty_inode(frame, NULL, this, 0, 0);
}
if (xattr_req)
@@ -840,27 +670,17 @@ err:
return 0;
}
-/* return 1 when dirty updation started
- * 0 other wise
- */
int32_t
-mq_update_dirty_inode (xlator_t *this,
- loc_t *loc,
- quota_inode_ctx_t *ctx,
- inode_contribution_t *contribution)
+update_dirty_inode (xlator_t *this,
+ loc_t *loc,
+ quota_inode_ctx_t *ctx,
+ inode_contribution_t *contribution)
{
int32_t ret = -1;
quota_local_t *local = NULL;
- gf_boolean_t status = _gf_false;
struct gf_flock lock = {0, };
call_frame_t *frame = NULL;
- ret = mq_get_ctx_updation_status (ctx, &status);
- if (ret == -1 || status == _gf_true) {
- ret = 0;
- goto out;
- }
-
frame = create_frame (this, this->ctx->pool);
if (frame == NULL) {
ret = -1;
@@ -869,12 +689,13 @@ mq_update_dirty_inode (xlator_t *this,
mq_assign_lk_owner (this, frame);
- local = mq_local_new ();
+ local = quota_local_new ();
if (local == NULL)
goto fr_destroy;
frame->local = local;
- ret = mq_loc_copy (&local->loc, loc);
+
+ ret = loc_copy (&local->loc, loc);
if (ret < 0)
goto fr_destroy;
@@ -887,22 +708,15 @@ mq_update_dirty_inode (xlator_t *this,
lock.l_start = 0;
lock.l_len = 0;
- if (local->loc.inode == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_WARNING,
- "Inode is NULL, so can't stackwind.");
- goto fr_destroy;
- }
-
STACK_WIND (frame,
- mq_get_dirty_xattr,
+ get_dirty_xattr,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->loc, F_SETLKW, &lock, NULL);
- return 1;
+ this->name, &local->loc, F_SETLKW, &lock);
+ return 0;
fr_destroy:
- QUOTA_STACK_DESTROY (frame, this);
+ QUOTA_STACK_DESTROY (frame, this);
out:
return 0;
@@ -910,8 +724,8 @@ out:
int32_t
-mq_inode_creation_done (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+quota_inode_creation_done (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
quota_local_t *local = NULL;
@@ -920,88 +734,50 @@ mq_inode_creation_done (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
- if (local != NULL) {
- mq_initiate_quota_txn (this, &local->loc);
- }
-
QUOTA_STACK_DESTROY (frame, this);
return 0;
}
-
-int32_t
-mq_xattr_creation_release_lock (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- struct gf_flock lock = {0, };
- quota_local_t *local = NULL;
-
- local = frame->local;
-
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_pid = 0;
-
- STACK_WIND (frame,
- mq_inode_creation_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->loc,
- F_SETLKW, &lock, NULL);
-
- return 0;
-}
-
-
int32_t
-mq_create_dirty_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+create_dirty_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
int32_t ret = -1;
dict_t *newdict = NULL;
quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
- if (op_ret < 0) {
+ if (op_ret == -1 && op_errno == ENOTCONN)
goto err;
- }
local = frame->local;
+ priv = (marker_conf_t *) this->private;
+
if (local->loc.inode->ia_type == IA_IFDIR) {
newdict = dict_new ();
- if (!newdict) {
+ if (!newdict)
goto err;
- }
ret = dict_set_int8 (newdict, QUOTA_DIRTY_KEY, 0);
- if (ret == -1) {
+ if (ret == -1)
goto err;
- }
-
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
- GF_UUID_ASSERT (local->loc.gfid);
- STACK_WIND (frame, mq_xattr_creation_release_lock,
+ STACK_WIND (frame, quota_inode_creation_done,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- &local->loc, newdict, 0, NULL);
- } else {
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
- }
+ &local->loc, newdict, 0);
+ } else
+ quota_inode_creation_done (frame, NULL, this, 0, 0);
ret = 0;
err:
- if (ret < 0) {
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
- }
+ if (ret == -1)
+ quota_inode_creation_done (frame, NULL, this, -1, 0);
- if (newdict != NULL)
+ if (newdict)
dict_unref (newdict);
return 0;
@@ -1009,28 +785,30 @@ err:
int32_t
-mq_create_xattr (xlator_t *this, call_frame_t *frame)
+quota_set_inode_xattr (xlator_t *this, loc_t *loc)
{
int32_t ret = 0;
int64_t *value = NULL;
int64_t *size = NULL;
dict_t *dict = NULL;
char key[512] = {0, };
+ call_frame_t *frame = NULL;
quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
quota_inode_ctx_t *ctx = NULL;
inode_contribution_t *contri = NULL;
- if (frame == NULL || this == NULL)
+ if (loc == NULL || this == NULL)
return 0;
- local = frame->local;
+ priv = (marker_conf_t *) this->private;
- ret = mq_inode_ctx_get (local->loc.inode, this, &ctx);
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret < 0) {
- ctx = mq_inode_ctx_new (local->loc.inode, this);
+ ctx = quota_inode_ctx_new (loc->inode, this);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "mq_inode_ctx_new failed");
+ "quota_inode_ctx_new failed");
ret = -1;
goto out;
}
@@ -1040,267 +818,106 @@ mq_create_xattr (xlator_t *this, call_frame_t *frame)
if (!dict)
goto out;
- if (local->loc.inode->ia_type == IA_IFDIR) {
+ if (loc->inode->ia_type == IA_IFDIR) {
QUOTA_ALLOC_OR_GOTO (size, int64_t, ret, err);
ret = dict_set_bin (dict, QUOTA_SIZE_KEY, size, 8);
if (ret < 0)
goto free_size;
}
- if (strcmp (local->loc.path, "/") != 0) {
- contri = mq_add_new_contribution_node (this, ctx, &local->loc);
- if (contri == NULL)
- goto err;
-
- QUOTA_ALLOC_OR_GOTO (value, int64_t, ret, err);
- GET_CONTRI_KEY (key, local->loc.parent->gfid, ret);
-
- ret = dict_set_bin (dict, key, value, 8);
- if (ret < 0)
- goto free_value;
- }
-
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND (frame, mq_create_dirty_xattr, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->xattrop, &local->loc,
- GF_XATTROP_ADD_ARRAY64, dict, NULL);
- ret = 0;
-
-free_size:
- if (ret < 0) {
- GF_FREE (size);
- }
-
-free_value:
- if (ret < 0) {
- GF_FREE (value);
- }
-
-err:
- dict_unref (dict);
-
-out:
- if (ret < 0) {
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
- }
-
- return 0;
-}
-
-
-int32_t
-mq_check_n_set_inode_xattr (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *dict,
- struct iatt *postparent)
-{
- quota_local_t *local = NULL;
- int64_t *size = NULL, *contri = NULL;
- int8_t dirty = 0;
- int32_t ret = 0;
- char contri_key[512] = {0, };
-
- if (op_ret < 0) {
- goto out;
- }
-
- local = frame->local;
-
- ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0)
- goto create_xattr;
-
- ret = dict_get_int8 (dict, QUOTA_DIRTY_KEY, &dirty);
- if (ret < 0)
- goto create_xattr;
-
- //check contribution xattr if not root
- if (strcmp (local->loc.path, "/") != 0) {
- GET_CONTRI_KEY (contri_key, local->loc.parent->gfid, ret);
- if (ret < 0)
- goto out;
-
- ret = dict_get_bin (dict, contri_key, (void **) &contri);
- if (ret < 0)
- goto create_xattr;
- }
-
-out:
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
- return 0;
-
-create_xattr:
- if (uuid_is_null (local->loc.gfid)) {
- uuid_copy (local->loc.gfid, buf->ia_gfid);
- }
-
- mq_create_xattr (this, frame);
- return 0;
-}
-
-
-int32_t
-mq_get_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- dict_t *xattr_req = NULL;
- quota_local_t *local = NULL;
- int32_t ret = 0;
-
- if (op_ret < 0) {
- goto lock_err;
- }
-
- local = frame->local;
-
- xattr_req = dict_new ();
- if (xattr_req == NULL) {
- goto err;
- }
+ //if '/' then dont set contribution xattr
+ if (strcmp (loc->path, "/") == 0)
+ goto wind;
- ret = mq_req_xattr (this, &local->loc, xattr_req);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "cannot request xattr");
+ contri = add_new_contribution_node (this, ctx, loc);
+ if (contri == NULL)
goto err;
- }
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
+ QUOTA_ALLOC_OR_GOTO (value, int64_t, ret, err);
+ GET_CONTRI_KEY (key, loc->parent->gfid, ret);
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND (frame, mq_check_n_set_inode_xattr, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, &local->loc, xattr_req);
-
- dict_unref (xattr_req);
-
- return 0;
-
-err:
- mq_xattr_creation_release_lock (frame, NULL, this, 0, 0, NULL);
-
- if (xattr_req)
- dict_unref (xattr_req);
- return 0;
-
-lock_err:
- mq_inode_creation_done (frame, NULL, this, 0, 0, NULL);
- return 0;
-}
-
-
-int32_t
-mq_set_inode_xattr (xlator_t *this, loc_t *loc)
-{
- struct gf_flock lock = {0, };
- quota_local_t *local = NULL;
- int32_t ret = 0;
- call_frame_t *frame = NULL;
+ ret = dict_set_bin (dict, key, value, 8);
+ if (ret < 0)
+ goto free_value;
+wind:
frame = create_frame (this, this->ctx->pool);
if (!frame) {
ret = -1;
goto err;
}
- local = mq_local_new ();
- if (local == NULL) {
- goto err;
- }
+ local = quota_local_new ();
+ if (local == NULL)
+ goto free_size;
- frame->local = local;
+ local->ctx = ctx;
+
+ local->contri = contri;
ret = loc_copy (&local->loc, loc);
- if (ret < 0) {
- goto err;
- }
+ if (ret < 0)
+ quota_local_unref (this, local);
frame->local = local;
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
+ STACK_WIND (frame, create_dirty_xattr, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, &local->loc,
+ GF_XATTROP_ADD_ARRAY64, dict);
+ ret = 0;
- STACK_WIND (frame,
- mq_get_xattr,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->loc, F_SETLKW, &lock, NULL);
+free_size:
+ if (ret < 0)
+ GF_FREE (size);
- return 0;
+free_value:
+ if (ret < 0)
+ GF_FREE (value);
err:
- QUOTA_STACK_DESTROY (frame, this);
+ dict_unref (dict);
+
+out:
+ if (ret < 0)
+ quota_inode_creation_done (NULL, NULL, this, -1, 0);
return 0;
}
int32_t
-mq_get_parent_inode_local (xlator_t *this, quota_local_t *local)
+get_parent_inode_local (xlator_t *this, quota_local_t *local)
{
- int32_t ret = -1;
+ int32_t ret;
quota_inode_ctx_t *ctx = NULL;
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", local, out);
-
- local->contri = NULL;
-
loc_wipe (&local->loc);
- ret = mq_loc_copy (&local->loc, &local->parent_loc);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "loc copy failed");
- goto out;
- }
+ loc_copy (&local->loc, &local->parent_loc);
loc_wipe (&local->parent_loc);
- ret = mq_inode_loc_fill (NULL, local->loc.parent,
- &local->parent_loc);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "failed to build parent loc of %s",
- local->loc.path);
- goto out;
- }
+ quota_inode_loc_fill (NULL, local->loc.parent, &local->parent_loc);
- ret = mq_inode_ctx_get (local->loc.inode, this, &ctx);
- if (ret < 0) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "inode ctx get failed");
- goto out;
- }
+ ret = quota_inode_ctx_get (local->loc.inode, this, &ctx);
+ if (ret < 0)
+ return -1;
local->ctx = ctx;
- if (list_empty (&ctx->contribution_head)) {
- gf_log_callingfn (this->name, GF_LOG_WARNING,
- "contribution node list is empty which "
- "is an error");
- ret = -1;
- goto out;
- }
-
local->contri = (inode_contribution_t *) ctx->contribution_head.next;
- ret = 0;
-out:
- return ret;
+ return 0;
}
int32_t
-mq_xattr_updation_done (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+xattr_updation_done (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
{
QUOTA_STACK_DESTROY (frame, this);
return 0;
@@ -1308,22 +925,19 @@ mq_xattr_updation_done (call_frame_t *frame,
int32_t
-mq_inodelk_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+quota_inodelk_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
- int32_t ret = 0;
- gf_boolean_t status = _gf_false;
- quota_local_t *local = NULL;
+ int32_t ret = 0;
+ quota_local_t *local = NULL;
local = frame->local;
if (op_ret == -1 || local->err) {
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG,
- "unlocking failed on path (%s)(%s)",
- local->parent_loc.path, strerror (op_errno));
- }
- mq_xattr_updation_done (frame, NULL, this, 0, 0, NULL, NULL);
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_INFO),
+ "lock setting failed (%s)", strerror (op_errno));
+ xattr_updation_done (frame, NULL, this, 0, 0, NULL);
return 0;
}
@@ -1331,25 +945,16 @@ mq_inodelk_cbk (call_frame_t *frame, void *cookie,
gf_log (this->name, GF_LOG_DEBUG,
"inodelk released on %s", local->parent_loc.path);
- if ((strcmp (local->parent_loc.path, "/") == 0)
- || (local->delta == 0)) {
- mq_xattr_updation_done (frame, NULL, this, 0, 0, NULL, NULL);
+ if (strcmp (local->parent_loc.path, "/") == 0) {
+ xattr_updation_done (frame, NULL, this, 0, 0, NULL);
} else {
- ret = mq_get_parent_inode_local (this, local);
+ ret = get_parent_inode_local (this, local);
if (ret < 0) {
- mq_xattr_updation_done (frame, NULL, this, 0, 0, NULL,
- NULL);
+ xattr_updation_done (frame, NULL, this, 0, 0, NULL);
goto out;
}
- status = _gf_true;
-
- ret = mq_test_and_set_ctx_updation_status (local->ctx, &status);
- if (ret == 0 && status == _gf_false) {
- mq_get_lock_on_parent (frame, this);
- } else {
- mq_xattr_updation_done (frame, NULL, this, 0, 0, NULL,
- NULL);
- }
+
+ get_lock_on_parent (frame, this);
}
out:
return 0;
@@ -1358,27 +963,18 @@ out:
//now release lock on the parent inode
int32_t
-mq_release_parent_lock (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+quota_release_parent_lock (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
{
int32_t ret = 0;
+ struct gf_flock lock;
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
- struct gf_flock lock = {0, };
local = frame->local;
- if (local->err != 0) {
- gf_log_callingfn (this->name,
- (local->err == ENOENT) ? GF_LOG_DEBUG
- : GF_LOG_WARNING,
- "An operation during quota updation "
- "of path (%s) failed (%s)", local->loc.path,
- strerror (local->err));
- }
-
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
+ ret = quota_inode_ctx_get (local->parent_loc.inode, this, &ctx);
if (ret < 0)
goto wind;
@@ -1388,12 +984,6 @@ mq_release_parent_lock (call_frame_t *frame, void *cookie,
}
UNLOCK (&ctx->lock);
- if (local->parent_loc.inode == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Invalid parent inode.");
- goto err;
- }
-
wind:
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
@@ -1402,33 +992,30 @@ wind:
lock.l_pid = 0;
STACK_WIND (frame,
- mq_inodelk_cbk,
+ quota_inodelk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
this->name, &local->parent_loc,
- F_SETLKW, &lock, NULL);
+ F_SETLKW, &lock);
return 0;
-err:
- mq_xattr_updation_done (frame, NULL, this,
- 0, 0 , NULL, NULL);
- return 0;
}
int32_t
-mq_mark_undirty (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+quota_mark_undirty (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
{
int32_t ret = -1;
int64_t *size = NULL;
dict_t *newdict = NULL;
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
+ marker_conf_t *priv = NULL;
local = frame->local;
@@ -1440,19 +1027,17 @@ mq_mark_undirty (call_frame_t *frame,
goto err;
}
- //update the size of the parent inode
+ priv = this->private;
+
+ //update the size of the parent inode
if (dict != NULL) {
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
- if (ret < 0) {
- op_errno = EINVAL;
+ ret = quota_inode_ctx_get (local->parent_loc.inode, this, &ctx);
+ if (ret < 0)
goto err;
- }
ret = dict_get_bin (dict, QUOTA_SIZE_KEY, (void **) &size);
- if (ret < 0) {
- op_errno = EINVAL;
+ if (ret < 0)
goto err;
- }
LOCK (&ctx->lock);
{
@@ -1465,32 +1050,26 @@ mq_mark_undirty (call_frame_t *frame,
}
newdict = dict_new ();
- if (!newdict) {
- op_errno = ENOMEM;
+
+ if (!newdict)
goto err;
- }
ret = dict_set_int8 (newdict, QUOTA_DIRTY_KEY, 0);
- if (ret == -1) {
- op_errno = -ret;
+ if (ret == -1)
goto err;
- }
- uuid_copy (local->parent_loc.gfid, local->parent_loc.inode->gfid);
- GF_UUID_ASSERT (local->parent_loc.gfid);
-
- STACK_WIND (frame, mq_release_parent_lock,
+ STACK_WIND (frame, quota_release_parent_lock,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- &local->parent_loc, newdict, 0, NULL);
+ &local->parent_loc, newdict, 0);
ret = 0;
err:
if (op_ret == -1 || ret == -1) {
- local->err = op_errno;
+ local->err = 1;
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
+ quota_release_parent_lock (frame, NULL, this, 0, 0);
}
if (newdict)
@@ -1501,16 +1080,17 @@ err:
int32_t
-mq_update_parent_size (call_frame_t *frame,
- void *cookie,
- xlator_t *this,
- int32_t op_ret,
- int32_t op_errno,
- dict_t *dict, dict_t *xdata)
+quota_update_parent_size (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ dict_t *dict)
{
int64_t *size = NULL;
int32_t ret = -1;
dict_t *newdict = NULL;
+ marker_conf_t *priv = NULL;
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -1518,36 +1098,29 @@ mq_update_parent_size (call_frame_t *frame,
if (op_ret == -1) {
gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
- GF_LOG_WARNING),
+ GF_LOG_ERROR),
"xattrop call failed: %s", strerror (op_errno));
goto err;
}
- LOCK (&local->contri->lock);
- {
- local->contri->contribution += local->delta;
- }
- UNLOCK (&local->contri->lock);
+ local->contri->contribution += local->delta;
gf_log (this->name, GF_LOG_DEBUG, "%s %"PRId64 "%"PRId64,
local->loc.path, local->ctx->size,
local->contri->contribution);
- if (dict == NULL) {
- op_errno = EINVAL;
+ priv = this->private;
+
+ if (dict == NULL)
goto err;
- }
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
- if (ret < 0) {
- op_errno = EINVAL;
+ ret = quota_inode_ctx_get (local->parent_loc.inode, this, &ctx);
+ if (ret < 0)
goto err;
- }
newdict = dict_new ();
if (!newdict) {
- op_errno = ENOMEM;
ret = -1;
goto err;
}
@@ -1557,28 +1130,21 @@ mq_update_parent_size (call_frame_t *frame,
*size = hton64 (local->delta);
ret = dict_set_bin (newdict, QUOTA_SIZE_KEY, size, 8);
- if (ret < 0) {
- op_errno = -ret;
+ if (ret < 0)
goto err;
- }
-
- if (uuid_is_null (local->parent_loc.gfid))
- uuid_copy (local->parent_loc.gfid,
- local->parent_loc.inode->gfid);
- GF_UUID_ASSERT (local->parent_loc.gfid);
STACK_WIND (frame,
- mq_mark_undirty,
+ quota_mark_undirty,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
&local->parent_loc,
GF_XATTROP_ADD_ARRAY64,
- newdict, NULL);
+ newdict);
ret = 0;
err:
if (op_ret == -1 || ret < 0) {
- local->err = op_errno;
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
+ local->err = 1;
+ quota_release_parent_lock (frame, NULL, this, 0, 0);
}
if (newdict)
@@ -1588,125 +1154,103 @@ err:
}
int32_t
-mq_update_inode_contribution (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *dict,
- struct iatt *postparent)
+quota_update_inode_contribution (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *dict,
+ struct iatt *postparent)
{
- int32_t ret = -1;
- int64_t *size = NULL, size_int = 0, contri_int = 0;
- int64_t *contri = NULL;
- int64_t *delta = NULL;
+ int32_t ret = -1;
+ int64_t *size = NULL;
+ int64_t *contri = NULL;
+ int64_t *delta = NULL;
char contri_key [512] = {0, };
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contribution = NULL;
+ dict_t *newdict = NULL;
+ quota_local_t *local = NULL;
+ quota_inode_ctx_t *ctx = NULL;
+ marker_conf_t *priv = NULL;
+ inode_contribution_t *contribution = NULL;
local = frame->local;
if (op_ret == -1) {
gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
GF_LOG_WARNING),
- "failed to get size and contribution of path (%s)(%s)",
- local->loc.path, strerror (op_errno));
+ "failed to get size and contribution with %s error",
+ strerror (op_errno));
goto err;
}
+ priv = this->private;
+
ctx = local->ctx;
contribution = local->contri;
//prepare to update size & contribution of the inode
GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
- if (ret == -1) {
- op_errno = ENOMEM;
+ if (ret == -1)
goto err;
- }
LOCK (&ctx->lock);
{
if (local->loc.inode->ia_type == IA_IFDIR ) {
ret = dict_get_bin (dict, QUOTA_SIZE_KEY,
(void **) &size);
- if (ret < 0) {
- op_errno = EINVAL;
+ if (ret < 0)
goto unlock;
- }
ctx->size = ntoh64 (*size);
} else
ctx->size = buf->ia_blocks * 512;
- size_int = ctx->size;
- }
-unlock:
- UNLOCK (&ctx->lock);
-
- if (ret < 0) {
- goto err;
- }
-
- ret = dict_get_bin (dict, contri_key, (void **) &contri);
-
- LOCK (&contribution->lock);
- {
+ ret = dict_get_bin (dict, contri_key, (void **) &contri);
if (ret < 0)
contribution->contribution = 0;
else
contribution->contribution = ntoh64 (*contri);
- contri_int = contribution->contribution;
+ ret = 0;
}
- UNLOCK (&contribution->lock);
-
- gf_log (this->name, GF_LOG_DEBUG, "%s %"PRId64 "%"PRId64,
- local->loc.path, size_int, contri_int);
-
- local->delta = size_int - contri_int;
+unlock:
+ UNLOCK (&ctx->lock);
- if (local->delta == 0) {
- mq_mark_undirty (frame, NULL, this, 0, 0, NULL, NULL);
- return 0;
- }
+ if (ret < 0)
+ goto err;
+ gf_log (this->name, GF_LOG_DEBUG, "%s %"PRId64 "%"PRId64,
+ local->loc.path, ctx->size, contribution->contribution);
newdict = dict_new ();
if (newdict == NULL) {
- op_errno = ENOMEM;
ret = -1;
goto err;
}
+ local->delta = ctx->size - contribution->contribution;
+
QUOTA_ALLOC_OR_GOTO (delta, int64_t, ret, err);
*delta = hton64 (local->delta);
ret = dict_set_bin (newdict, contri_key, delta, 8);
if (ret < 0) {
- op_errno = -ret;
ret = -1;
goto err;
}
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
STACK_WIND (frame,
- mq_update_parent_size,
+ quota_update_parent_size,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop,
&local->loc,
GF_XATTROP_ADD_ARRAY64,
- newdict, NULL);
+ newdict);
ret = 0;
err:
if (op_ret == -1 || ret < 0) {
- local->err = op_errno;
+ local->err = 1;
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
+ quota_release_parent_lock (frame, NULL, this, 0, 0);
}
if (newdict)
@@ -1716,23 +1260,22 @@ err:
}
int32_t
-mq_fetch_child_size_and_contri (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+quota_fetch_child_size_and_contri (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
{
- int32_t ret = -1;
+ int32_t ret = -1;
char contri_key [512] = {0, };
- dict_t *newdict = NULL;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
+ dict_t *newdict = NULL;
+ quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
+ quota_inode_ctx_t *ctx = NULL;
local = frame->local;
if (op_ret == -1) {
- gf_log (this->name, (op_errno == ENOENT) ? GF_LOG_DEBUG
- : GF_LOG_WARNING,
- "couldnt mark inode corresponding to path (%s) dirty "
- "(%s)", local->parent_loc.path, strerror (op_errno));
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s couldnt mark dirty", local->parent_loc.path);
goto err;
}
@@ -1741,12 +1284,12 @@ mq_fetch_child_size_and_contri (call_frame_t *frame, void *cookie,
gf_log (this->name, GF_LOG_DEBUG, "%s marked dirty", local->parent_loc.path);
+ priv = this->private;
+
//update parent ctx
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
- if (ret == -1) {
- op_errno = EINVAL;
+ ret = quota_inode_ctx_get (local->parent_loc.inode, this, &ctx);
+ if (ret == -1)
goto err;
- }
LOCK (&ctx->lock);
{
@@ -1755,52 +1298,29 @@ mq_fetch_child_size_and_contri (call_frame_t *frame, void *cookie,
UNLOCK (&ctx->lock);
newdict = dict_new ();
- if (newdict == NULL) {
- op_errno = ENOMEM;
+ if (newdict == NULL)
goto err;
- }
if (local->loc.inode->ia_type == IA_IFDIR) {
ret = dict_set_int64 (newdict, QUOTA_SIZE_KEY, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict_set failed.");
- goto err;
- }
}
GET_CONTRI_KEY (contri_key, local->contri->gfid, ret);
- if (ret < 0) {
- op_errno = ENOMEM;
+ if (ret < 0)
goto err;
- }
ret = dict_set_int64 (newdict, contri_key, 0);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "dict_set failed.");
- goto err;
- }
-
- mq_set_ctx_updation_status (local->ctx, _gf_false);
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND (frame, mq_update_inode_contribution, FIRST_CHILD(this),
+ STACK_WIND (frame, quota_update_inode_contribution, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, &local->loc, newdict);
ret = 0;
err:
- if ((op_ret == -1) || (ret < 0)) {
- local->err = op_errno;
-
- mq_set_ctx_updation_status (local->ctx, _gf_false);
+ if (op_ret == -1 || ret == -1) {
+ local->err = 1;
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
+ quota_release_parent_lock (frame, NULL, this, 0, 0);
}
if (newdict)
@@ -1810,25 +1330,24 @@ err:
}
int32_t
-mq_markdirty (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret, int32_t op_errno, dict_t *xdata)
+quota_markdirty (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
int32_t ret = -1;
dict_t *dict = NULL;
quota_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
local = frame->local;
if (op_ret == -1){
- gf_log (this->name, (op_errno == ENOENT) ? GF_LOG_DEBUG
- : GF_LOG_WARNING, "acquiring locks failed on %s (%s)",
+ gf_log (this->name, GF_LOG_ERROR,
+ "lock setting failed on %s (%s)",
local->parent_loc.path, strerror (op_errno));
- local->err = op_errno;
-
- mq_set_ctx_updation_status (local->ctx, _gf_false);
+ local->err = 1;
- mq_inodelk_cbk (frame, NULL, this, 0, 0, NULL);
+ quota_inodelk_cbk (frame, NULL, this, 0, 0);
return 0;
}
@@ -1836,6 +1355,8 @@ mq_markdirty (call_frame_t *frame, void *cookie,
gf_log (this->name, GF_LOG_TRACE,
"inodelk succeeded on %s", local->parent_loc.path);
+ priv = this->private;
+
dict = dict_new ();
if (!dict) {
ret = -1;
@@ -1846,23 +1367,17 @@ mq_markdirty (call_frame_t *frame, void *cookie,
if (ret == -1)
goto err;
- uuid_copy (local->parent_loc.gfid,
- local->parent_loc.inode->gfid);
- GF_UUID_ASSERT (local->parent_loc.gfid);
-
- STACK_WIND (frame, mq_fetch_child_size_and_contri,
+ STACK_WIND (frame, quota_fetch_child_size_and_contri,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setxattr,
- &local->parent_loc, dict, 0, NULL);
+ &local->parent_loc, dict, 0);
ret = 0;
err:
if (ret == -1) {
local->err = 1;
- mq_set_ctx_updation_status (local->ctx, _gf_false);
-
- mq_release_parent_lock (frame, NULL, this, 0, 0, NULL);
+ quota_release_parent_lock (frame, NULL, this, 0, 0);
}
if (dict)
@@ -1873,9 +1388,9 @@ err:
int32_t
-mq_get_lock_on_parent (call_frame_t *frame, xlator_t *this)
+get_lock_on_parent (call_frame_t *frame, xlator_t *this)
{
- struct gf_flock lock = {0, };
+ struct gf_flock lock;
quota_local_t *local = NULL;
GF_VALIDATE_OR_GOTO ("marker", frame, fr_destroy);
@@ -1884,37 +1399,30 @@ mq_get_lock_on_parent (call_frame_t *frame, xlator_t *this)
gf_log (this->name, GF_LOG_DEBUG, "taking lock on %s",
local->parent_loc.path);
- if (local->parent_loc.inode == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "parent inode is not valid, aborting "
- "transaction.");
- goto fr_destroy;
- }
-
lock.l_len = 0;
lock.l_start = 0;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
STACK_WIND (frame,
- mq_markdirty,
+ quota_markdirty,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc, F_SETLKW, &lock, NULL);
+ this->name, &local->parent_loc, F_SETLKW, &lock);
return 0;
fr_destroy:
QUOTA_STACK_DESTROY (frame, this);
- return -1;
+ return 0;
}
int
-mq_start_quota_txn (xlator_t *this, loc_t *loc,
- quota_inode_ctx_t *ctx,
- inode_contribution_t *contri)
+start_quota_txn (xlator_t *this, loc_t *loc,
+ quota_inode_ctx_t *ctx,
+ inode_contribution_t *contri)
{
int32_t ret = -1;
call_frame_t *frame = NULL;
@@ -1926,52 +1434,46 @@ mq_start_quota_txn (xlator_t *this, loc_t *loc,
mq_assign_lk_owner (this, frame);
- local = mq_local_new ();
+ local = quota_local_new ();
if (local == NULL)
goto fr_destroy;
frame->local = local;
- ret = mq_loc_copy (&local->loc, loc);
+ ret = loc_copy (&local->loc, loc);
if (ret < 0)
goto fr_destroy;
- ret = mq_inode_loc_fill (NULL, local->loc.parent,
- &local->parent_loc);
+ ret = quota_inode_loc_fill (NULL, local->loc.parent,
+ &local->parent_loc);
if (ret < 0)
goto fr_destroy;
local->ctx = ctx;
local->contri = contri;
- ret = mq_get_lock_on_parent (frame, this);
- if (ret == -1)
- goto err;
+ get_lock_on_parent (frame, this);
return 0;
fr_destroy:
QUOTA_STACK_DESTROY (frame, this);
-err:
- mq_set_ctx_updation_status (ctx, _gf_false);
+err:
return -1;
}
int
-mq_initiate_quota_txn (xlator_t *this, loc_t *loc)
+initiate_quota_txn (xlator_t *this, loc_t *loc)
{
- int32_t ret = -1;
- gf_boolean_t status = _gf_false;
- quota_inode_ctx_t *ctx = NULL;
+ int32_t ret = -1;
+ quota_inode_ctx_t *ctx = NULL;
inode_contribution_t *contribution = NULL;
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO ("marker", loc, out);
- GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
+ VALIDATE_OR_GOTO (loc, out);
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
"inode ctx get failed, aborting quota txn");
@@ -1979,74 +1481,55 @@ mq_initiate_quota_txn (xlator_t *this, loc_t *loc)
goto out;
}
- contribution = mq_get_contribution_node (loc->parent, ctx);
+ contribution = get_contribution_node (loc->parent, ctx);
if (contribution == NULL)
goto out;
- /* To improve performance, donot start another transaction
- * if one is already in progress for same inode
- */
- status = _gf_true;
-
- ret = mq_test_and_set_ctx_updation_status (ctx, &status);
- if (ret < 0)
- goto out;
-
- if (status == _gf_false) {
- mq_start_quota_txn (this, loc, ctx, contribution);
- }
-
- ret = 0;
+ start_quota_txn (this, loc, ctx, contribution);
out:
- return ret;
+ return 0;
}
-/* int32_t */
-/* validate_inode_size_contribution (xlator_t *this, loc_t *loc, int64_t size, */
-/* int64_t contribution) */
-/* { */
-/* if (size != contribution) { */
-/* mq_initiate_quota_txn (this, loc); */
-/* } */
+int32_t
+validate_inode_size_contribution (xlator_t *this,
+ loc_t *loc,
+ quota_inode_ctx_t *ctx,
+ inode_contribution_t *contribution)
+{
+ if (ctx->size != contribution->contribution)
+ initiate_quota_txn (this, loc);
-/* return 0; */
-/* } */
+ return 0;
+}
int32_t
-mq_inspect_directory_xattr (xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- struct iatt buf)
+inspect_directory_xattr (xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ struct iatt buf)
{
- int32_t ret = 0;
- int8_t dirty = -1;
- int64_t *size = NULL, size_int = 0;
- int64_t *contri = NULL, contri_int = 0;
- char contri_key [512] = {0, };
- gf_boolean_t not_root = _gf_false;
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contribution = NULL;
-
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ int32_t ret = 0;
+ int8_t dirty = -1;
+ int64_t *size = NULL;
+ int64_t *contri = NULL;
+ char contri_key [512] = {0, };
+ marker_conf_t *priv = NULL;
+ gf_boolean_t not_root = _gf_false;
+ quota_inode_ctx_t *ctx = NULL;
+ inode_contribution_t *contribution = NULL;
+
+ priv = this->private;
+
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret < 0) {
- ctx = mq_inode_ctx_new (loc->inode, this);
+ ctx = quota_inode_ctx_new (loc->inode, this);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "mq_inode_ctx_new failed");
- ret = -1;
- goto err;
- }
- }
-
- if (strcmp (loc->path, "/") != 0) {
- contribution = mq_add_new_contribution_node (this, ctx, loc);
- if (contribution == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot add a new contribution node");
+ "quota_inode_ctx_new failed");
ret = -1;
- goto err;
+ goto out;
}
}
@@ -2061,6 +1544,13 @@ mq_inspect_directory_xattr (xlator_t *this,
if (strcmp (loc->path, "/") != 0) {
not_root = _gf_true;
+ contribution = add_new_contribution_node (this, ctx, loc);
+ if (contribution == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "cannot add a new contributio node");
+ goto out;
+ }
+
GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
if (ret < 0)
goto out;
@@ -2069,79 +1559,69 @@ mq_inspect_directory_xattr (xlator_t *this,
if (ret < 0)
goto out;
- LOCK (&contribution->lock);
- {
- contribution->contribution = ntoh64 (*contri);
- contri_int = contribution->contribution;
- }
- UNLOCK (&contribution->lock);
+ contribution->contribution = ntoh64 (*contri);
}
- LOCK (&ctx->lock);
- {
- ctx->size = ntoh64 (*size);
- ctx->dirty = dirty;
- size_int = ctx->size;
- }
- UNLOCK (&ctx->lock);
+ ctx->size = ntoh64 (*size);
gf_log (this->name, GF_LOG_DEBUG, "size=%"PRId64
- " contri=%"PRId64, size_int, contri_int);
+ " contri=%"PRId64, ctx->size,
+ contribution?contribution->contribution:0);
- if (dirty) {
- ret = mq_update_dirty_inode (this, loc, ctx, contribution);
- }
-
- if ((!dirty || ret == 0) && (not_root == _gf_true) &&
- (size_int != contri_int)) {
- mq_initiate_quota_txn (this, loc);
+ ctx->dirty = dirty;
+ if (ctx->dirty == 1) {
+ update_dirty_inode (this, loc, ctx, contribution);
+ } else if (not_root == _gf_true &&
+ ctx->size != contribution->contribution) {
+ initiate_quota_txn (this, loc);
}
ret = 0;
out:
if (ret)
- mq_set_inode_xattr (this, loc);
-err:
- return ret;
+ quota_set_inode_xattr (this, loc);
+
+ return 0;
}
int32_t
-mq_inspect_file_xattr (xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- struct iatt buf)
+inspect_file_xattr (xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ struct iatt buf)
{
- int32_t ret = -1;
- uint64_t contri_int = 0, size = 0;
- int64_t *contri_ptr = NULL;
+ int32_t ret = -1;
+ uint64_t contri_int = 0;
+ int64_t *contri_ptr = NULL;
char contri_key [512] = {0, };
- quota_inode_ctx_t *ctx = NULL;
- inode_contribution_t *contribution = NULL;
+ marker_conf_t *priv = NULL;
+ quota_inode_ctx_t *ctx = NULL;
+ inode_contribution_t *contribution = NULL;
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ priv = this->private;
+
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret < 0) {
- ctx = mq_inode_ctx_new (loc->inode, this);
+ ctx = quota_inode_ctx_new (loc->inode, this);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "mq_inode_ctx_new failed");
+ "quota_inode_ctx_new failed");
ret = -1;
goto out;
}
}
- contribution = mq_add_new_contribution_node (this, ctx, loc);
+ contribution = add_new_contribution_node (this, ctx, loc);
if (contribution == NULL)
goto out;
LOCK (&ctx->lock);
{
ctx->size = 512 * buf.ia_blocks;
- size = ctx->size;
}
UNLOCK (&ctx->lock);
- list_for_each_entry (contribution, &ctx->contribution_head,
- contri_list) {
+ list_for_each_entry (contribution, &ctx->contribution_head, contri_list) {
GET_CONTRI_KEY (contri_key, contribution->gfid, ret);
if (ret < 0)
continue;
@@ -2150,21 +1630,16 @@ mq_inspect_file_xattr (xlator_t *this,
if (ret == 0) {
contri_ptr = (int64_t *)(unsigned long)contri_int;
- LOCK (&contribution->lock);
- {
- contribution->contribution = ntoh64 (*contri_ptr);
- contri_int = contribution->contribution;
- }
- UNLOCK (&contribution->lock);
+ contribution->contribution = ntoh64 (*contri_ptr);
gf_log (this->name, GF_LOG_DEBUG,
- "size=%"PRId64 " contri=%"PRId64, size, contri_int);
+ "size=%"PRId64 " contri=%"PRId64, ctx->size,
+ contribution->contribution);
- if (size != contri_int) {
- mq_initiate_quota_txn (this, loc);
- }
+ ret = validate_inode_size_contribution
+ (this, loc, ctx, contribution);
} else
- mq_initiate_quota_txn (this, loc);
+ initiate_quota_txn (this, loc);
}
out:
@@ -2172,38 +1647,40 @@ out:
}
int32_t
-mq_xattr_state (xlator_t *this,
- loc_t *loc,
- dict_t *dict,
- struct iatt buf)
+quota_xattr_state (xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ struct iatt buf)
{
if (buf.ia_type == IA_IFREG ||
buf.ia_type == IA_IFLNK) {
- mq_inspect_file_xattr (this, loc, dict, buf);
+ k ++;
+ inspect_file_xattr (this, loc, dict, buf);
} else if (buf.ia_type == IA_IFDIR)
- mq_inspect_directory_xattr (this, loc, dict, buf);
+ inspect_directory_xattr (this, loc, dict, buf);
return 0;
}
int32_t
-mq_req_xattr (xlator_t *this,
- loc_t *loc,
- dict_t *dict)
+quota_req_xattr (xlator_t *this,
+ loc_t *loc,
+ dict_t *dict)
{
int32_t ret = -1;
+ marker_conf_t *priv = NULL;
GF_VALIDATE_OR_GOTO ("marker", this, out);
+ GF_VALIDATE_OR_GOTO ("marker", loc, out);
GF_VALIDATE_OR_GOTO ("marker", dict, out);
- if (!loc)
- goto set_size;
+ priv = this->private;
//if not "/" then request contribution
if (strcmp (loc->path, "/") == 0)
goto set_size;
- ret = mq_dict_set_contribution (this, dict, loc);
+ ret = dict_set_contribution (this, dict, loc);
if (ret == -1)
goto out;
@@ -2228,8 +1705,8 @@ out:
int32_t
-mq_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+quota_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
QUOTA_STACK_DESTROY (frame, this);
@@ -2237,84 +1714,58 @@ mq_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
int32_t
-_mq_inode_remove_done (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+quota_inode_remove_done (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- int32_t ret = 0;
- char contri_key [512] = {0, };
- quota_local_t *local = NULL;
+ int32_t ret = 0;
+ char contri_key [512] = {0, };
+ quota_local_t *local = NULL;
local = (quota_local_t *) frame->local;
if (op_ret == -1 || local->err == -1) {
- mq_removexattr_cbk (frame, NULL, this, -1, 0, NULL);
+ quota_removexattr_cbk (frame, NULL, this, -1, 0);
return 0;
}
- frame->local = NULL;
-
if (local->hl_count > 1) {
GET_CONTRI_KEY (contri_key, local->contri->gfid, ret);
- STACK_WIND (frame, mq_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- &local->loc, contri_key, NULL);
+ STACK_WIND (frame, quota_removexattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr,
+ &local->loc, contri_key);
ret = 0;
- } else {
- mq_removexattr_cbk (frame, NULL, this, 0, 0, NULL);
}
if (strcmp (local->parent_loc.path, "/") != 0) {
- ret = mq_get_parent_inode_local (this, local);
- if (ret < 0)
- goto out;
+ get_parent_inode_local (this, local);
- mq_start_quota_txn (this, &local->loc, local->ctx, local->contri);
+ start_quota_txn (this, &local->loc, local->ctx, local->contri);
}
-out:
- mq_local_unref (this, local);
+
+ quota_local_unref (this, local);
return 0;
}
int32_t
mq_inode_remove_done (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- int32_t ret = -1;
- struct gf_flock lock = {0, };
- quota_inode_ctx_t *ctx = NULL;
- quota_local_t *local = NULL;
- int64_t contribution = 0;
+ int32_t ret;
+ struct gf_flock lock;
+ quota_inode_ctx_t *ctx;
+ quota_local_t *local = NULL;
local = frame->local;
if (op_ret == -1)
local->err = -1;
- ret = mq_inode_ctx_get (local->parent_loc.inode, this, &ctx);
-
- LOCK (&local->contri->lock);
- {
- contribution = local->contri->contribution;
- }
- UNLOCK (&local->contri->lock);
-
- if (contribution == local->size) {
- if (ret == 0) {
- LOCK (&ctx->lock);
- {
- ctx->size -= contribution;
- }
- UNLOCK (&ctx->lock);
+ ret = quota_inode_ctx_get (local->parent_loc.inode, this, &ctx);
+ if (ret == 0)
+ ctx->size -= local->contri->contribution;
- LOCK (&local->contri->lock);
- {
- local->contri->contribution = 0;
- }
- UNLOCK (&local->contri->lock);
- }
- }
+ local->contri->contribution = 0;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
@@ -2323,22 +1774,24 @@ mq_inode_remove_done (call_frame_t *frame, void *cookie, xlator_t *this,
lock.l_pid = 0;
STACK_WIND (frame,
- _mq_inode_remove_done,
+ quota_inode_remove_done,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
this->name, &local->parent_loc,
- F_SETLKW, &lock, NULL);
+ F_SETLKW, &lock);
return 0;
}
-int32_t
-mq_reduce_parent_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+static int32_t
+mq_reduce_parent_size_xattr (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno)
{
int32_t ret = -1;
int64_t *size = NULL;
dict_t *dict = NULL;
+ marker_conf_t *priv = NULL;
quota_local_t *local = NULL;
+ inode_contribution_t *contribution = NULL;
local = frame->local;
if (op_ret == -1) {
@@ -2350,6 +1803,10 @@ mq_reduce_parent_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
VALIDATE_OR_GOTO (local->contri, err);
+ priv = this->private;
+
+ contribution = local->contri;
+
dict = dict_new ();
if (dict == NULL) {
ret = -1;
@@ -2358,36 +1815,35 @@ mq_reduce_parent_size_xattr (call_frame_t *frame, void *cookie, xlator_t *this,
QUOTA_ALLOC_OR_GOTO (size, int64_t, ret, err);
- *size = hton64 (-local->size);
+ *size = hton64 (-contribution->contribution);
+
ret = dict_set_bin (dict, QUOTA_SIZE_KEY, size, 8);
if (ret < 0)
goto err;
- uuid_copy (local->parent_loc.gfid,
- local->parent_loc.inode->gfid);
- GF_UUID_ASSERT (local->parent_loc.gfid);
STACK_WIND (frame, mq_inode_remove_done, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->xattrop, &local->parent_loc,
- GF_XATTROP_ADD_ARRAY64, dict, NULL);
+ GF_XATTROP_ADD_ARRAY64, dict);
dict_unref (dict);
return 0;
err:
local->err = 1;
- mq_inode_remove_done (frame, NULL, this, -1, 0, NULL, NULL);
+ mq_inode_remove_done (frame, NULL, this, -1, 0, NULL);
if (dict)
dict_unref (dict);
return 0;
}
int32_t
-mq_reduce_parent_size (xlator_t *this, loc_t *loc, int64_t contri)
+reduce_parent_size (xlator_t *this, loc_t *loc)
{
int32_t ret = -1;
struct gf_flock lock = {0,};
call_frame_t *frame = NULL;
+ marker_conf_t *priv = NULL;
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
inode_contribution_t *contribution = NULL;
@@ -2395,43 +1851,30 @@ mq_reduce_parent_size (xlator_t *this, loc_t *loc, int64_t contri)
GF_VALIDATE_OR_GOTO ("marker", this, out);
GF_VALIDATE_OR_GOTO ("marker", loc, out);
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ priv = this->private;
+
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret < 0)
goto out;
- contribution = mq_get_contribution_node (loc->parent, ctx);
+ contribution = get_contribution_node (loc->parent, ctx);
if (contribution == NULL)
goto out;
- local = mq_local_new ();
+ local = quota_local_new ();
if (local == NULL) {
ret = -1;
goto out;
}
- if (contri >= 0) {
- local->size = contri;
- } else {
- LOCK (&contribution->lock);
- {
- local->size = contribution->contribution;
- }
- UNLOCK (&contribution->lock);
- }
-
- if (local->size == 0) {
- ret = 0;
- goto out;
- }
-
- ret = mq_loc_copy (&local->loc, loc);
+ ret = loc_copy (&local->loc, loc);
if (ret < 0)
goto out;
local->ctx = ctx;
local->contri = contribution;
- ret = mq_inode_loc_fill (NULL, loc->parent, &local->parent_loc);
+ ret = quota_inode_loc_fill (NULL, loc->parent, &local->parent_loc);
if (ret < 0)
goto out;
@@ -2450,25 +1893,18 @@ mq_reduce_parent_size (xlator_t *this, loc_t *loc, int64_t contri)
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
- if (local->parent_loc.inode == NULL) {
- ret = -1;
- gf_log (this->name, GF_LOG_DEBUG,
- "Inode is NULL, so can't stackwind.");
- goto out;
- }
-
STACK_WIND (frame,
mq_reduce_parent_size_xattr,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc, F_SETLKW, &lock, NULL);
- local = NULL;
+ this->name, &local->parent_loc, F_SETLKW, &lock);
ret = 0;
out:
- if (local != NULL)
- mq_local_unref (this, local);
-
+ if (ret < 0) {
+ quota_local_unref (this, local);
+ GF_FREE (local);
+ }
return ret;
}
@@ -2476,12 +1912,14 @@ out:
int32_t
init_quota_priv (xlator_t *this)
{
+ strcpy (volname, "quota");
+
return 0;
}
int32_t
-mq_rename_update_newpath (xlator_t *this, loc_t *loc)
+quota_rename_update_newpath (xlator_t *this, loc_t *loc)
{
int32_t ret = -1;
quota_inode_ctx_t *ctx = NULL;
@@ -2491,23 +1929,23 @@ mq_rename_update_newpath (xlator_t *this, loc_t *loc)
GF_VALIDATE_OR_GOTO ("marker", loc, out);
GF_VALIDATE_OR_GOTO ("marker", loc->inode, out);
- ret = mq_inode_ctx_get (loc->inode, this, &ctx);
+ ret = quota_inode_ctx_get (loc->inode, this, &ctx);
if (ret < 0)
goto out;
- contribution = mq_add_new_contribution_node (this, ctx, loc);
+ contribution = add_new_contribution_node (this, ctx, loc);
if (contribution == NULL) {
ret = -1;
goto out;
}
- mq_initiate_quota_txn (this, loc);
+ initiate_quota_txn (this, loc);
out:
return ret;
}
int32_t
-mq_forget (xlator_t *this, quota_inode_ctx_t *ctx)
+quota_forget (xlator_t *this, quota_inode_ctx_t *ctx)
{
inode_contribution_t *contri = NULL;
inode_contribution_t *next = NULL;
diff --git a/xlators/features/marker/src/marker-quota.h b/xlators/features/marker/src/marker-quota.h
index 4dd855fd7..ea54bb631 100644
--- a/xlators/features/marker/src/marker-quota.h
+++ b/xlators/features/marker/src/marker-quota.h
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -24,6 +24,7 @@
#include "config.h"
#endif
+#include "marker.h"
#include "xlator.h"
#include "marker-mem-types.h"
@@ -31,9 +32,11 @@
#define QUOTA_DIRTY_KEY "trusted.glusterfs.quota.dirty"
#define CONTRIBUTION "contri"
+#define VOL_NAME volname
#define CONTRI_KEY_MAX 512
#define READDIR_BUF 4096
+char volname [40];
#define QUOTA_STACK_DESTROY(_frame, _this) \
do { \
@@ -41,7 +44,8 @@
_local = _frame->local; \
_frame->local = NULL; \
STACK_DESTROY (_frame->root); \
- mq_local_unref (_this, _local); \
+ quota_local_unref (_this, _local); \
+ GF_FREE (_local); \
} while (0)
@@ -49,7 +53,7 @@
do { \
ret = 0; \
var = GF_CALLOC (sizeof (type), 1, \
- gf_marker_mt_##type); \
+ gf_marker_mt_##type); \
if (!var) { \
gf_log ("", GF_LOG_ERROR, \
"out of memory"); \
@@ -60,7 +64,7 @@
#define QUOTA_ALLOC_OR_GOTO(var, type, ret, label) \
do { \
var = GF_CALLOC (sizeof (type), 1, \
- gf_marker_mt_##type); \
+ gf_marker_mt_##type); \
if (!var) { \
gf_log ("", GF_LOG_ERROR, \
"out of memory"); \
@@ -70,70 +74,97 @@
ret = 0; \
} while (0);
-#define GET_CONTRI_KEY(var, _gfid, _ret) \
- do { \
- char _gfid_unparsed[40]; \
- uuid_unparse (_gfid, _gfid_unparsed); \
+#define GET_CONTRI_KEY(var, _gfid, _ret) \
+ do { \
+ char _gfid_unparsed[40]; \
+ uuid_unparse (_gfid, _gfid_unparsed); \
_ret = snprintf (var, CONTRI_KEY_MAX, QUOTA_XATTR_PREFIX \
- ".%s.%s." CONTRIBUTION, "quota", \
- _gfid_unparsed); \
+ ".%s.%s." CONTRIBUTION, VOL_NAME, \
+ _gfid_unparsed); \
} while (0);
-#define QUOTA_SAFE_INCREMENT(lock, var) \
- do { \
- LOCK (lock); \
- var ++; \
- UNLOCK (lock); \
+#define QUOTA_SAFE_INCREMENT(lock, var) \
+ do { \
+ LOCK (lock); \
+ var ++; \
+ UNLOCK (lock); \
} while (0)
+#define QUOTA_SAFE_DECREMENT(lock, var) \
+ do { \
+ LOCK (lock); \
+ var --; \
+ UNLOCK (lock); \
+ } while (0)
+
+
struct quota_inode_ctx {
- int64_t size;
- int8_t dirty;
- gf_boolean_t updation_status;
- gf_lock_t lock;
- struct list_head contribution_head;
+ int64_t size;
+ int8_t dirty;
+ gf_lock_t lock;
+ struct list_head contribution_head;
};
typedef struct quota_inode_ctx quota_inode_ctx_t;
struct inode_contribution {
struct list_head contri_list;
- int64_t contribution;
- uuid_t gfid;
- gf_lock_t lock;
+ int64_t contribution;
+ uuid_t gfid;
};
typedef struct inode_contribution inode_contribution_t;
+struct quota_local {
+ int64_t delta;
+ int64_t d_off;
+ int32_t err;
+ int32_t ref;
+ int64_t sum;
+ int32_t hl_count;
+ int32_t dentry_child_count;
+
+ fd_t *fd;
+ call_frame_t *frame;
+ gf_lock_t lock;
+
+ loc_t loc;
+ loc_t parent_loc;
+
+ quota_inode_ctx_t *ctx;
+ inode_contribution_t *contri;
+};
+typedef struct quota_local quota_local_t;
+
int32_t
-mq_get_lock_on_parent (call_frame_t *, xlator_t *);
+get_lock_on_parent (call_frame_t *, xlator_t *);
int32_t
-mq_req_xattr (xlator_t *, loc_t *, dict_t *);
+quota_req_xattr (xlator_t *, loc_t *, dict_t *);
int32_t
init_quota_priv (xlator_t *);
int32_t
-mq_xattr_state (xlator_t *, loc_t *, dict_t *, struct iatt);
+quota_xattr_state (xlator_t *, loc_t *, dict_t *, struct iatt);
int32_t
-mq_set_inode_xattr (xlator_t *, loc_t *);
+quota_set_inode_xattr (xlator_t *, loc_t *);
int
-mq_initiate_quota_txn (xlator_t *, loc_t *);
+initiate_quota_txn (xlator_t *, loc_t *);
int32_t
-mq_dirty_inode_readdir (call_frame_t *, void *, xlator_t *,
- int32_t, int32_t, fd_t *, dict_t *);
+quota_dirty_inode_readdir (call_frame_t *, void *, xlator_t *,
+ int32_t, int32_t, fd_t *);
int32_t
-mq_reduce_parent_size (xlator_t *, loc_t *, int64_t);
+reduce_parent_size (xlator_t *, loc_t *);
int32_t
-mq_rename_update_newpath (xlator_t *, loc_t *);
+quota_rename_update_newpath (xlator_t *, loc_t *);
int32_t
-mq_inspect_file_xattr (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf);
+inspect_file_xattr (xlator_t *this, loc_t *loc, dict_t *dict, struct iatt buf);
int32_t
-mq_forget (xlator_t *, quota_inode_ctx_t *);
+quota_forget (xlator_t *, quota_inode_ctx_t *);
#endif
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index 1b5abd572..041449b40 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -27,11 +27,7 @@
#include "marker.h"
#include "marker-mem-types.h"
#include "marker-quota.h"
-#include "marker-quota-helper.h"
#include "marker-common.h"
-#include "byte-order.h"
-
-#define _GF_UID_GID_CHANGED 1
void
fini (xlator_t *this);
@@ -65,26 +61,24 @@ marker_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
if (inode) {
loc->inode = inode_ref (inode);
- if (uuid_is_null (loc->gfid)) {
- uuid_copy (loc->gfid, loc->inode->gfid);
- }
+ loc->ino = inode->ino;
}
if (parent)
loc->parent = inode_ref (parent);
- if (path) {
- loc->path = gf_strdup (path);
- if (!loc->path) {
- gf_log ("loc fill", GF_LOG_ERROR, "strdup failed");
- goto loc_wipe;
- }
-
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
+ loc->path = gf_strdup (path);
+ if (!loc->path) {
+ gf_log ("loc fill", GF_LOG_ERROR, "strdup failed");
+ goto loc_wipe;
}
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+ else
+ goto loc_wipe;
+
ret = 0;
loc_wipe:
if (ret < 0)
@@ -97,14 +91,23 @@ int
marker_inode_loc_fill (inode_t *inode, loc_t *loc)
{
char *resolvedpath = NULL;
+ inode_t *parent = NULL;
int ret = -1;
- inode_t *parent = NULL;
if ((!inode) || (!loc))
return ret;
- parent = inode_parent (inode, NULL, NULL);
+ if ((inode) && (inode->ino == 1)) {
+ loc->parent = NULL;
+ goto ignore_parent;
+ }
+
+ parent = inode_parent (inode, 0, NULL);
+ if (!parent) {
+ goto err;
+ }
+ignore_parent:
ret = inode_path (inode, NULL, &resolvedpath);
if (ret < 0)
goto err;
@@ -114,10 +117,11 @@ marker_inode_loc_fill (inode_t *inode, loc_t *loc)
goto err;
err:
- if (parent)
- inode_unref (parent);
+ if (parent)
+ inode_unref (parent);
- GF_FREE (resolvedpath);
+ if (resolvedpath)
+ GF_FREE (resolvedpath);
return ret;
}
@@ -127,17 +131,8 @@ marker_trav_parent (marker_local_t *local)
{
int32_t ret = 0;
loc_t loc = {0, };
- inode_t *parent = NULL;
- int8_t need_unref = 0;
- if (!local->loc.parent) {
- parent = inode_parent (local->loc.inode, NULL, NULL);
- if (parent)
- need_unref = 1;
- } else
- parent = local->loc.parent;
-
- ret = marker_inode_loc_fill (parent, &loc);
+ ret = marker_inode_loc_fill (local->loc.parent, &loc);
if (ret < 0) {
ret = -1;
@@ -148,9 +143,6 @@ marker_trav_parent (marker_local_t *local)
local->loc = loc;
out:
- if (need_unref)
- inode_unref (parent);
-
return ret;
}
@@ -184,26 +176,24 @@ marker_local_unref (marker_local_t *local)
goto out;
loc_wipe (&local->loc);
- loc_wipe (&local->parent_loc);
if (local->oplocal) {
- marker_local_unref (local->oplocal);
- local->oplocal = NULL;
+ loc_wipe (&local->oplocal->loc);
+ GF_FREE (local->oplocal);
}
- mem_put (local);
+ GF_FREE (local);
out:
return 0;
}
int32_t
-stat_stampfile (xlator_t *this, marker_conf_t *priv,
- struct volume_mark **status)
+stat_stampfile (xlator_t *this, marker_conf_t *priv, struct volume_mark **status)
{
- struct stat buf = {0, };
- struct volume_mark *vol_mark = NULL;
+ struct stat buf;
+ struct volume_mark *vol_mark;
vol_mark = GF_CALLOC (sizeof (struct volume_mark), 1,
- gf_marker_mt_volume_mark);
+ gf_marker_mt_volume_mark);
vol_mark->major = 1;
vol_mark->minor = 0;
@@ -216,7 +206,7 @@ stat_stampfile (xlator_t *this, marker_conf_t *priv,
vol_mark->sec = htonl (buf.st_ctime);
vol_mark->usec = htonl (ST_CTIM_NSEC (&buf)/1000);
} else
- vol_mark->retval = 1;
+ vol_mark->retval = 0;
*status = vol_mark;
@@ -225,14 +215,13 @@ stat_stampfile (xlator_t *this, marker_conf_t *priv,
int32_t
marker_getxattr_stampfile_cbk (call_frame_t *frame, xlator_t *this,
- const char *name, struct volume_mark *vol_mark,
- dict_t *xdata)
+ const char *name, struct volume_mark *vol_mark)
{
- int32_t ret = -1;
+ int32_t ret;
dict_t *dict = NULL;
if (vol_mark == NULL){
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL);
goto out;
}
@@ -240,12 +229,9 @@ marker_getxattr_stampfile_cbk (call_frame_t *frame, xlator_t *this,
dict = dict_new ();
ret = dict_set_bin (dict, (char *)name, vol_mark,
- sizeof (struct volume_mark));
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "failed to set key %s",
- name);
+ sizeof (struct volume_mark));
- STACK_UNWIND_STRICT (getxattr, frame, 0, 0, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, 0, 0, dict);
dict_unref (dict);
out:
@@ -261,7 +247,7 @@ call_from_special_client (call_frame_t *frame, xlator_t *this, const char *name)
priv = (marker_conf_t *)this->private;
- if (frame->root->pid != GF_CLIENT_PID_GSYNCD || name == NULL ||
+ if (frame->root->pid != -1 || name == NULL ||
strcmp (name, MARKER_XATTR_PREFIX "." VOLUME_MARK) != 0) {
ret = _gf_false;
goto out;
@@ -269,29 +255,28 @@ call_from_special_client (call_frame_t *frame, xlator_t *this, const char *name)
stat_stampfile (this, priv, &vol_mark);
- marker_getxattr_stampfile_cbk (frame, this, name, vol_mark, NULL);
+ marker_getxattr_stampfile_cbk (frame, this, name, vol_mark);
out:
return ret;
}
int32_t
marker_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- if (cookie) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Filtering the quota extended attributes");
+ if (cookie) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Filtering the quota extended attributes");
- dict_foreach (dict, marker_filter_quota_xattr, NULL);
- }
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ dict_foreach (dict, marker_filter_quota_xattr, NULL);
+ }
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int32_t
marker_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
gf_boolean_t ret = _gf_false;
marker_conf_t *priv = NULL;
@@ -307,19 +292,19 @@ marker_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = call_from_special_client (frame, this, name);
wind:
if (ret == _gf_false) {
- if (name == NULL) {
+ if (name == NULL) {
/* Signifies that marker translator
* has to filter the quota's xattr's,
* this is to prevent afr from performing
* self healing on marker-quota xattrs'
*/
- cookie = 1;
+ cookie = 1;
}
STACK_WIND_COOKIE (frame, marker_getxattr_cbk, (void *)cookie,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr, loc,
- name, xdata);
- }
+ name);
+ }
return 0;
}
@@ -343,7 +328,7 @@ marker_setxattr_done (call_frame_t *frame)
int
marker_specific_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
int32_t ret = 0;
int32_t done = 0;
@@ -357,21 +342,15 @@ marker_specific_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- if (local) {
- if (local->loc.path && strcmp (local->loc.path, "/") == 0) {
- done = 1;
- goto out;
- }
- if (__is_root_gfid (local->loc.gfid)) {
- done = 1;
- goto out;
- }
+ if (strcmp (local->loc.path, "/") == 0) {
+ done = 1;
+ goto out;
}
ret = marker_trav_parent (local);
if (ret == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "Error occurred "
+ gf_log (this->name, GF_LOG_DEBUG, "Error occured "
"while traversing to the parent, stopping marker");
done = 1;
@@ -392,7 +371,7 @@ out:
int32_t
marker_start_setxattr (call_frame_t *frame, xlator_t *this)
{
- int32_t ret = -1;
+ int32_t ret = 0;
dict_t *dict = NULL;
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
@@ -401,43 +380,25 @@ marker_start_setxattr (call_frame_t *frame, xlator_t *this)
local = (marker_local_t*) frame->local;
- if (!local)
- goto out;
-
dict = dict_new ();
- if (!dict)
- goto out;
-
- if (local->loc.inode && uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
ret = dict_set_static_bin (dict, priv->marker_xattr,
(void *)local->timebuf, 8);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set marker xattr (%s)", local->loc.path);
- goto out;
- }
+
+ gf_log (this->name, GF_LOG_DEBUG, "path = %s", local->loc.path);
STACK_WIND (frame, marker_specific_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, &local->loc, dict, 0,
- NULL);
+ FIRST_CHILD(this)->fops->setxattr, &local->loc, dict, 0);
- ret = 0;
-out:
- if (dict)
- dict_unref (dict);
+ dict_unref (dict);
- return ret;
+ return 0;
}
void
marker_gettimeofday (marker_local_t *local)
{
- struct timeval tv = {0, };
+ struct timeval tv;
gettimeofday (&tv, NULL);
@@ -464,28 +425,21 @@ marker_create_frame (xlator_t *this, marker_local_t *local)
int32_t
marker_xtime_update_marks (xlator_t *this, marker_local_t *local)
{
- GF_VALIDATE_OR_GOTO ("marker", this, out);
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- if ((local->pid == GF_CLIENT_PID_GSYNCD) ||
- (local->pid == GF_CLIENT_PID_DEFRAG))
- goto out;
-
marker_gettimeofday (local);
marker_local_ref (local);
marker_create_frame (this, local);
-out:
+
return 0;
}
int32_t
marker_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
@@ -500,18 +454,15 @@ marker_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
+ buf, preparent, postparent);
if (op_ret == -1 || local == NULL)
goto out;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_set_inode_xattr (this, &local->loc);
+ quota_set_inode_xattr (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -524,7 +475,7 @@ out:
int
marker_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -535,7 +486,7 @@ marker_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -545,21 +496,21 @@ marker_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto err;
wind:
STACK_WIND (frame, marker_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
return 0;
err:
STACK_UNWIND_STRICT (mkdir, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
int32_t
marker_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
@@ -574,18 +525,15 @@ marker_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (op_ret == -1 || local == NULL)
goto out;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_set_inode_xattr (this, &local->loc);
+ inspect_file_xattr (this, &local->loc, NULL, *buf);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -598,7 +546,7 @@ out:
int32_t
marker_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -609,7 +557,7 @@ marker_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -619,12 +567,11 @@ marker_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
goto err;
wind:
STACK_WIND (frame, marker_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
- fd, xdata);
+ FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
+ params);
return 0;
err:
- STACK_UNWIND_STRICT (create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL, NULL);
+ STACK_UNWIND_STRICT (create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -633,7 +580,7 @@ err:
int32_t
marker_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
@@ -647,8 +594,7 @@ marker_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
if (op_ret == -1 || local == NULL)
goto out;
@@ -656,7 +602,7 @@ marker_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
+ initiate_quota_txn (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -669,12 +615,12 @@ out:
int32_t
marker_writev (call_frame_t *frame,
- xlator_t *this,
- fd_t *fd,
- struct iovec *vector,
- int32_t count,
- off_t offset, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset,
+ struct iobref *iobref)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -685,7 +631,7 @@ marker_writev (call_frame_t *frame,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -696,10 +642,10 @@ marker_writev (call_frame_t *frame,
wind:
STACK_WIND (frame, marker_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
- flags, iobref, xdata);
+ iobref);
return 0;
err:
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -707,8 +653,8 @@ err:
int32_t
marker_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
@@ -723,7 +669,7 @@ marker_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
if (op_ret == -1 || local == NULL)
goto out;
@@ -731,7 +677,7 @@ marker_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_reduce_parent_size (this, &local->loc, -1);
+ reduce_parent_size (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -742,8 +688,7 @@ out:
}
int32_t
-marker_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+marker_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -754,7 +699,7 @@ marker_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -764,10 +709,10 @@ marker_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
goto err;
wind:
STACK_WIND (frame, marker_rmdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rmdir, loc, flags, xdata);
+ FIRST_CHILD(this)->fops->rmdir, loc, flags);
return 0;
err:
- STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -775,8 +720,8 @@ err:
int32_t
marker_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
@@ -791,7 +736,7 @@ marker_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
if (op_ret == -1 || local == NULL)
goto out;
@@ -799,7 +744,7 @@ marker_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if ((priv->feature_enabled & GF_QUOTA) && (local->ia_nlink == 1))
- mq_reduce_parent_size (this, &local->loc, -1);
+ reduce_parent_size (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -812,38 +757,33 @@ out:
int32_t
marker_unlink_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
marker_local_t *local = NULL;
- local = frame->local;
if (op_ret < 0) {
goto err;
}
+ local = frame->local;
if (local == NULL) {
- op_errno = EINVAL;
goto err;
}
local->ia_nlink = buf->ia_nlink;
STACK_WIND (frame, marker_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, &local->loc, local->xflag,
- NULL);
+ FIRST_CHILD(this)->fops->unlink, &local->loc);
return 0;
err:
- frame->local = NULL;
- STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL, NULL);
- marker_local_unref (local);
+ STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL);
+
return 0;
}
int32_t
-marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -854,8 +794,8 @@ marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
if (priv->feature_enabled == 0)
goto unlink_wind;
- local = mem_get0 (this->local_pool);
- local->xflag = xflag;
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
+
MARKER_INIT_LOCAL (frame, local);
ret = loc_copy (&local->loc, loc);
@@ -863,36 +803,32 @@ marker_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
if (ret == -1)
goto err;
- if (uuid_is_null (loc->gfid) && loc->inode)
- uuid_copy (loc->gfid, loc->inode->gfid);
-
STACK_WIND (frame, marker_unlink_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
+ FIRST_CHILD(this)->fops->stat, loc);
return 0;
unlink_wind:
STACK_WIND (frame, marker_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
+ FIRST_CHILD(this)->fops->unlink, loc);
return 0;
err:
- frame->local = NULL;
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL, NULL);
- marker_local_unref (local);
+ STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL);
+
return 0;
}
int32_t
marker_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"linking a file ", strerror (op_errno));
}
@@ -901,7 +837,7 @@ marker_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (op_ret == -1 || local == NULL)
goto out;
@@ -909,7 +845,7 @@ marker_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
+ initiate_quota_txn (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -920,8 +856,7 @@ out:
}
int32_t
-marker_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+marker_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -932,7 +867,7 @@ marker_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -942,579 +877,161 @@ marker_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
goto err;
wind:
STACK_WIND (frame, marker_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
+ FIRST_CHILD(this)->fops->link, oldloc, newloc);
return 0;
err:
- STACK_UNWIND_STRICT (link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (link, frame, -1, ENOMEM, NULL, NULL, NULL, NULL);
return 0;
}
int32_t
-marker_rename_done (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+marker_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
- marker_local_t *local = NULL, *oplocal = NULL;
- loc_t newloc = {0, };
- marker_conf_t *priv = NULL;
-
- local = frame->local;
- oplocal = local->oplocal;
-
- priv = this->private;
-
- frame->local = NULL;
-
- if (op_ret < 0) {
- if (local->err == 0) {
- local->err = op_errno;
- }
-
- gf_log (this->name, GF_LOG_WARNING,
- "inodelk (UNLOCK) failed on path:%s (gfid:%s) (%s)",
- local->parent_loc.path,
- uuid_utoa (local->parent_loc.inode->gfid),
- strerror (op_errno));
- }
-
- if (local->stub != NULL) {
- call_resume (local->stub);
- local->stub = NULL;
- } else if (local->err != 0) {
- STACK_UNWIND_STRICT (rename, frame, -1, local->err, NULL, NULL,
- NULL, NULL, NULL, NULL);
- }
-
- mq_reduce_parent_size (this, &oplocal->loc, oplocal->contribution);
-
- if (local->loc.inode != NULL) {
- mq_reduce_parent_size (this, &local->loc, local->contribution);
- }
-
- newloc.inode = inode_ref (oplocal->loc.inode);
- newloc.path = gf_strdup (local->loc.path);
- newloc.name = strrchr (newloc.path, '/');
- if (newloc.name)
- newloc.name++;
- newloc.parent = inode_ref (local->loc.parent);
-
- mq_rename_update_newpath (this, &newloc);
-
- loc_wipe (&newloc);
+ marker_conf_t *priv = NULL;
+ marker_local_t *local = NULL;
+ marker_local_t *oplocal = NULL;
+ loc_t newloc = {0, };
- if (priv->feature_enabled & GF_XTIME) {
- //update marks on oldpath
- uuid_copy (local->loc.gfid, oplocal->loc.inode->gfid);
- marker_xtime_update_marks (this, oplocal);
- marker_xtime_update_marks (this, local);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
+ "renaming a file ", strerror (op_errno));
}
- marker_local_unref (local);
- marker_local_unref (oplocal);
- return 0;
-}
-
-
-int32_t
-marker_rename_release_newp_lock (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- marker_local_t *local = NULL, *oplocal = NULL;
- struct gf_flock lock = {0, };
-
- local = frame->local;
- oplocal = local->oplocal;
+ local = (marker_local_t *) frame->local;
- if (op_ret < 0) {
- if (local->err == 0) {
- local->err = op_errno;
- }
+ frame->local = NULL;
- gf_log (this->name, GF_LOG_WARNING,
- "inodelk (UNLOCK) failed on %s (gfid:%s) (%s)",
- oplocal->parent_loc.path,
- uuid_utoa (oplocal->parent_loc.inode->gfid),
- strerror (op_errno));
- }
+ STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent);
- if (local->next_lock_on == NULL) {
- marker_rename_done (frame, NULL, this, 0, 0, NULL);
+ if (op_ret == -1 || local == NULL)
goto out;
- }
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_pid = 0;
-
- STACK_WIND (frame,
- marker_rename_done,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &local->parent_loc, F_SETLKW, &lock, NULL);
-
-out:
- return 0;
-}
-
-
-int32_t
-marker_rename_release_oldp_lock (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- marker_local_t *local = NULL, *oplocal = NULL;
- struct gf_flock lock = {0, };
-
- local = frame->local;
oplocal = local->oplocal;
-
- if ((op_ret < 0) && (op_errno != ENOATTR)) {
- local->err = op_errno;
- }
-
- //Reset frame uid and gid if set.
- if (cookie == (void *) _GF_UID_GID_CHANGED)
- MARKER_RESET_UID_GID (frame, frame->root, local);
-
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
- lock.l_pid = 0;
-
- STACK_WIND (frame,
- marker_rename_release_newp_lock,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, &oplocal->parent_loc, F_SETLKW, &lock, NULL);
- return 0;
-}
-
-
-int32_t
-marker_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
-{
- marker_conf_t *priv = NULL;
- marker_local_t *local = NULL;
- marker_local_t *oplocal = NULL;
- call_stub_t *stub = NULL;
- int32_t ret = 0;
- char contri_key [512] = {0, };
- loc_t newloc = {0, };
-
- local = (marker_local_t *) frame->local;
-
- if (local != NULL) {
- oplocal = local->oplocal;
- }
+ local->oplocal = NULL;
priv = this->private;
- if (op_ret < 0) {
- if (local != NULL) {
- local->err = op_errno;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
- "renaming a file ", strerror (op_errno));
- }
-
if (priv->feature_enabled & GF_QUOTA) {
- if ((op_ret < 0) || (local == NULL)) {
- goto quota_err;
- }
-
- stub = fop_rename_cbk_stub (frame, default_rename_cbk, op_ret,
- op_errno, buf, preoldparent,
- postoldparent, prenewparent,
- postnewparent, xdata);
- if (stub == NULL) {
- local->err = ENOMEM;
- goto quota_err;
- }
+ reduce_parent_size (this, &oplocal->loc);
- local->stub = stub;
-
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = ENOMEM;
- goto quota_err;
+ if (local->loc.inode != NULL) {
+ reduce_parent_size (this, &local->loc);
}
- /* Removexattr requires uid and gid to be 0,
- * reset them in the callback.
- */
- MARKER_SET_UID_GID (frame, local, frame->root);
-
newloc.inode = inode_ref (oplocal->loc.inode);
newloc.path = gf_strdup (local->loc.path);
- newloc.name = strrchr (newloc.path, '/');
- if (newloc.name)
- newloc.name++;
+ newloc.name = gf_strdup (local->loc.name);
newloc.parent = inode_ref (local->loc.parent);
- uuid_copy (newloc.gfid, oplocal->loc.inode->gfid);
+ newloc.ino = oplocal->loc.inode->ino;
- STACK_WIND_COOKIE (frame, marker_rename_release_oldp_lock,
- frame->cookie, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- &newloc, contri_key, NULL);
+ quota_rename_update_newpath (this, &newloc);
loc_wipe (&newloc);
- } else {
- frame->local = NULL;
-
- STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
-
- if ((op_ret < 0) || (local == NULL)) {
- goto out;
- }
-
- if (priv->feature_enabled & GF_XTIME) {
- //update marks on oldpath
- uuid_copy (local->loc.gfid, oplocal->loc.inode->gfid);
- marker_xtime_update_marks (this, oplocal);
- marker_xtime_update_marks (this, local);
- }
- }
-
-out:
- if (!(priv->feature_enabled & GF_QUOTA)) {
- marker_local_unref (local);
- marker_local_unref (oplocal);
}
- return 0;
-
-quota_err:
- marker_rename_release_oldp_lock (frame, NULL, this, 0, 0, NULL);
- return 0;
-}
-
-
-int32_t
-marker_do_rename (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
-{
- marker_local_t *local = NULL, *oplocal = NULL;
- char contri_key[512] = {0, };
- int32_t ret = 0;
- int64_t *contribution = 0;
-
- local = frame->local;
- oplocal = local->oplocal;
-
- //Reset frame uid and gid if set.
- if (cookie == (void *) _GF_UID_GID_CHANGED)
- MARKER_RESET_UID_GID (frame, frame->root, local);
-
- if ((op_ret < 0) && (op_errno != ENOATTR)) {
- local->err = op_errno;
- gf_log (this->name, GF_LOG_WARNING,
- "fetching contribution values from %s (gfid:%s) "
- "failed (%s)", local->loc.path,
- uuid_utoa (local->loc.inode->gfid),
- strerror (op_errno));
- goto err;
- }
-
- if (local->loc.inode != NULL) {
- GET_CONTRI_KEY (contri_key, local->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = errno;
- goto err;
- }
-
- if (dict_get_bin (dict, contri_key,
- (void **) &contribution) == 0) {
- local->contribution = ntoh64 (*contribution);
- }
+ if (priv->feature_enabled & GF_XTIME) {
+ //update marks on oldpath
+ marker_xtime_update_marks (this, oplocal);
+ marker_xtime_update_marks (this, local);
}
-
- STACK_WIND (frame, marker_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, &oplocal->loc,
- &local->loc, NULL);
-
- return 0;
-
-err:
- marker_rename_release_oldp_lock (frame, NULL, this, 0, 0, NULL);
+out:
+ marker_local_unref (local);
+ marker_local_unref (oplocal);
return 0;
}
int32_t
-marker_get_newpath_contribution (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *dict, dict_t *xdata)
+marker_quota_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- marker_local_t *local = NULL, *oplocal = NULL;
- char contri_key[512] = {0, };
- int32_t ret = 0;
- int64_t *contribution = 0;
-
- local = frame->local;
- oplocal = local->oplocal;
-
- //Reset frame uid and gid if set.
- if (cookie == (void *) _GF_UID_GID_CHANGED)
- MARKER_RESET_UID_GID (frame, frame->root, local);
+ marker_local_t *local = NULL, *oplocal = NULL;
if ((op_ret < 0) && (op_errno != ENOATTR)) {
- local->err = op_errno;
- gf_log (this->name, GF_LOG_WARNING,
- "fetching contribution values from %s (gfid:%s) "
- "failed (%s)", oplocal->loc.path,
- uuid_utoa (oplocal->loc.inode->gfid),
- strerror (op_errno));
- goto err;
- }
-
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = errno;
- goto err;
- }
-
- if (dict_get_bin (dict, contri_key, (void **) &contribution) == 0)
- oplocal->contribution = ntoh64 (*contribution);
-
- if (local->loc.inode != NULL) {
- GET_CONTRI_KEY (contri_key, local->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = errno;
- goto err;
- }
-
- /* getxattr requires uid and gid to be 0,
- * reset them in the callback.
- */
- MARKER_SET_UID_GID (frame, local, frame->root);
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, local->loc.inode->gfid);
-
- GF_UUID_ASSERT (local->loc.gfid);
-
- STACK_WIND_COOKIE (frame, marker_do_rename,
- frame->cookie, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- &local->loc, contri_key, NULL);
- } else {
- marker_do_rename (frame, NULL, this, 0, 0, NULL, NULL);
+ goto unwind;
}
- return 0;
-err:
- marker_rename_release_oldp_lock (frame, NULL, this, 0, 0, NULL);
- return 0;
-}
-
-
-int32_t
-marker_get_oldpath_contribution (call_frame_t *frame, void *cookie,
- xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
-{
- marker_local_t *local = NULL, *oplocal = NULL;
- char contri_key[512] = {0, };
- int32_t ret = 0;
-
local = frame->local;
oplocal = local->oplocal;
- if (op_ret < 0) {
- local->err = op_errno;
- gf_log (this->name, GF_LOG_WARNING,
- "cannot hold inodelk on %s (gfid:%s) (%s)",
- local->next_lock_on->path,
- uuid_utoa (local->next_lock_on->inode->gfid),
- strerror (op_errno));
- goto lock_err;
- }
-
- GET_CONTRI_KEY (contri_key, oplocal->loc.parent->gfid, ret);
- if (ret < 0) {
- local->err = errno;
- goto quota_err;
- }
-
- /* getxattr requires uid and gid to be 0,
- * reset them in the callback.
- */
- MARKER_SET_UID_GID (frame, local, frame->root);
-
- if (uuid_is_null (oplocal->loc.gfid))
- uuid_copy (oplocal->loc.gfid,
- oplocal->loc.inode->gfid);
-
- GF_UUID_ASSERT (oplocal->loc.gfid);
-
- STACK_WIND_COOKIE (frame, marker_get_newpath_contribution,
- frame->cookie, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr,
- &oplocal->loc, contri_key, NULL);
- return 0;
-
-quota_err:
- marker_rename_release_oldp_lock (frame, NULL, this, 0, 0, NULL);
- return 0;
-
-lock_err:
- if ((local->next_lock_on == NULL)
- || (local->next_lock_on == &local->parent_loc)) {
- local->next_lock_on = NULL;
- marker_rename_release_oldp_lock (frame, NULL, this, 0, 0, NULL);
- } else {
- marker_rename_release_newp_lock (frame, NULL, this, 0, 0, NULL);
- }
-
+ STACK_WIND (frame, marker_rename_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename, &oplocal->loc,
+ &local->loc);
return 0;
-}
-
-
-int32_t
-marker_rename_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- marker_local_t *local = NULL, *oplocal = NULL;
- loc_t *loc = NULL;
- struct gf_flock lock = {0, };
- local = frame->local;
- oplocal = local->oplocal;
-
- if (op_ret < 0) {
- if (local->next_lock_on != &oplocal->parent_loc) {
- loc = &oplocal->parent_loc;
- } else {
- loc = &local->parent_loc;
- }
-
- local->err = op_errno;
- gf_log (this->name, GF_LOG_WARNING,
- "cannot hold inodelk on %s (gfid:%s) (%s)",
- loc->path, uuid_utoa (loc->inode->gfid),
- strerror (op_errno));
- goto err;
+unwind:
+ STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM, NULL,
+ NULL, NULL, NULL, NULL);
+ if (local) {
+ local->oplocal = NULL;
+ marker_local_unref (local);
+ GF_FREE (local);
}
-
- if (local->next_lock_on != NULL) {
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND (frame,
- marker_get_oldpath_contribution,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, local->next_lock_on,
- F_SETLKW, &lock, NULL);
- } else {
- marker_get_oldpath_contribution (frame, 0, this, 0, 0, NULL);
+ if (oplocal) {
+ marker_local_unref (oplocal);
+ GF_FREE (oplocal);
}
-
- return 0;
-
-err:
- marker_rename_done (frame, NULL, this, 0, 0, NULL);
return 0;
}
int32_t
marker_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
int32_t ret = 0;
marker_local_t *local = NULL;
marker_local_t *oplocal = NULL;
marker_conf_t *priv = NULL;
- struct gf_flock lock = {0, };
- loc_t *lock_on = NULL;
+ char contri_key[512] = {0,};
priv = this->private;
if (priv->feature_enabled == 0)
goto rename_wind;
- local = mem_get0 (this->local_pool);
+ GET_CONTRI_KEY (contri_key, oldloc->parent->gfid, ret);
+ if (ret < 0)
+ goto err;
+
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
- oplocal = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (oplocal, marker_local_t, err);
MARKER_INIT_LOCAL (frame, oplocal);
frame->local = local;
- local->oplocal = marker_local_ref (oplocal);
+ local->oplocal = oplocal;
ret = loc_copy (&local->loc, newloc);
- if (ret < 0)
+ if (ret == -1)
goto err;
ret = loc_copy (&oplocal->loc, oldloc);
- if (ret < 0)
- goto err;
-
- if (!(priv->feature_enabled & GF_QUOTA)) {
- goto rename_wind;
- }
-
- ret = mq_inode_loc_fill (NULL, newloc->parent, &local->parent_loc);
- if (ret < 0)
- goto err;
-
- ret = mq_inode_loc_fill (NULL, oldloc->parent, &oplocal->parent_loc);
- if (ret < 0)
+ if (ret == -1)
goto err;
- if ((newloc->inode != NULL) && (newloc->parent != oldloc->parent)
- && (uuid_compare (newloc->parent->gfid,
- oldloc->parent->gfid) < 0)) {
- lock_on = &local->parent_loc;
- local->next_lock_on = &oplocal->parent_loc;
- } else {
- lock_on = &oplocal->parent_loc;
- if ((newloc->inode != NULL) && (newloc->parent
- != oldloc->parent)) {
- local->next_lock_on = &local->parent_loc;
- }
- }
-
- lock.l_len = 0;
- lock.l_start = 0;
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
-
- STACK_WIND (frame,
- marker_rename_inodelk_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->inodelk,
- this->name, lock_on,
- F_SETLKW, &lock, NULL);
-
+ STACK_WIND (frame, marker_quota_removexattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr, oldloc, contri_key);
return 0;
rename_wind:
STACK_WIND (frame, marker_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc);
return 0;
err:
STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -1522,14 +1039,14 @@ err:
int32_t
marker_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"truncating a file ", strerror (op_errno));
}
@@ -1538,7 +1055,7 @@ marker_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
if (op_ret == -1 || local == NULL)
goto out;
@@ -1546,7 +1063,7 @@ marker_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
+ initiate_quota_txn (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -1558,8 +1075,7 @@ out:
}
int32_t
-marker_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+marker_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1570,7 +1086,7 @@ marker_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1580,10 +1096,10 @@ marker_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
goto err;
wind:
STACK_WIND (frame, marker_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
return 0;
err:
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1591,14 +1107,14 @@ err:
int32_t
marker_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"truncating a file ", strerror (op_errno));
}
@@ -1607,7 +1123,7 @@ marker_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
if (op_ret == -1 || local == NULL)
goto out;
@@ -1615,7 +1131,7 @@ marker_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_initiate_quota_txn (this, &local->loc);
+ initiate_quota_txn (this, &local->loc);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -1626,8 +1142,7 @@ out:
}
int32_t
-marker_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+marker_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1638,7 +1153,7 @@ marker_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1648,10 +1163,10 @@ marker_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
goto err;
wind:
STACK_WIND (frame, marker_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
return 0;
err:
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1659,15 +1174,15 @@ err:
int32_t
marker_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_conf_t *priv = NULL;
marker_local_t *local = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"creating symlinks ", strerror (op_errno));
}
@@ -1676,18 +1191,15 @@ marker_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (op_ret == -1 || local == NULL)
goto out;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
priv = this->private;
if (priv->feature_enabled & GF_QUOTA)
- mq_set_inode_xattr (this, &local->loc);
+ inspect_file_xattr (this, &local->loc, NULL, *buf);
if (priv->feature_enabled & GF_XTIME)
marker_xtime_update_marks (this, local);
@@ -1699,7 +1211,7 @@ out:
int
marker_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1710,7 +1222,7 @@ marker_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1720,27 +1232,26 @@ marker_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
goto err;
wind:
STACK_WIND (frame, marker_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
- xdata);
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
return 0;
err:
STACK_UNWIND_STRICT (symlink, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
int32_t
marker_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"creating symlinks ", strerror (op_errno));
}
@@ -1749,18 +1260,15 @@ marker_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
+ buf, preparent, postparent);
if (op_ret == -1 || local == NULL)
goto out;
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
priv = this->private;
if ((priv->feature_enabled & GF_QUOTA) && (S_ISREG (local->mode))) {
- mq_set_inode_xattr (this, &local->loc);
+ inspect_file_xattr (this, &local->loc, NULL, *buf);
}
if (priv->feature_enabled & GF_XTIME)
@@ -1773,7 +1281,7 @@ out:
int
marker_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *parms)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1784,7 +1292,7 @@ marker_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1796,12 +1304,11 @@ marker_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto err;
wind:
STACK_WIND (frame, marker_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
- xdata);
+ FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, parms);
return 0;
err:
STACK_UNWIND_STRICT (mknod, frame, -1, ENOMEM, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
@@ -1832,7 +1339,7 @@ call_from_sp_client_to_reset_tmfile (call_frame_t *frame,
if (data == NULL)
return -1;
- if (frame->root->pid != GF_CLIENT_PID_GSYNCD) {
+ if (frame->root->pid != -1) {
op_ret = -1;
op_errno = EPERM;
@@ -1840,7 +1347,7 @@ call_from_sp_client_to_reset_tmfile (call_frame_t *frame,
}
if (data->len == 0 || (data->len == 5 &&
- memcmp (data->data, "RESET", 5) == 0)) {
+ memcmp (data->data, "RESET", 5) == 0)) {
fd = open (priv->timestamp_file, O_WRONLY|O_TRUNC);
if (fd != -1) {
/* TODO check whether the O_TRUNC would update the
@@ -1861,7 +1368,7 @@ call_from_sp_client_to_reset_tmfile (call_frame_t *frame,
op_errno = EINVAL;
}
out:
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
@@ -1869,21 +1376,21 @@ out:
int32_t
marker_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred in "
- "setxattr ", strerror (op_errno));
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
+ "creating symlinks ", strerror (op_errno));
}
local = (marker_local_t *) frame->local;
frame->local = NULL;
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
if (op_ret == -1 || local == NULL)
goto out;
@@ -1900,7 +1407,7 @@ out:
int32_t
marker_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1915,7 +1422,7 @@ marker_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
if (ret == 0)
return 0;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1925,10 +1432,10 @@ marker_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
goto err;
wind:
STACK_WIND (frame, marker_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
+ FIRST_CHILD(this)->fops->setxattr, loc, dict, flags);
return 0;
err:
- STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM);
return 0;
}
@@ -1936,13 +1443,13 @@ err:
int32_t
marker_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_TRACE, "%s occurred while "
+ gf_log (this->name, GF_LOG_TRACE, "%s occured while "
"creating symlinks ", strerror (op_errno));
}
@@ -1950,7 +1457,7 @@ marker_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
if (op_ret == -1 || local == NULL)
goto out;
@@ -1967,7 +1474,7 @@ out:
int32_t
marker_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -1982,7 +1489,7 @@ marker_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
if (ret == 0)
return 0;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -1992,10 +1499,10 @@ marker_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
goto err;
wind:
STACK_WIND (frame, marker_fsetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
+ FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags);
return 0;
err:
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM);
return 0;
}
@@ -2003,14 +1510,14 @@ err:
int32_t
marker_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s occurred while "
+ gf_log (this->name, GF_LOG_ERROR, "%s occured while "
"creating symlinks ", strerror (op_errno));
}
@@ -2019,7 +1526,7 @@ marker_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
if (op_ret == -1 || local == NULL)
goto out;
@@ -2037,7 +1544,7 @@ out:
int32_t
marker_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -2048,7 +1555,7 @@ marker_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -2058,10 +1565,10 @@ marker_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto err;
wind:
STACK_WIND (frame, marker_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
return 0;
err:
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2069,8 +1576,8 @@ err:
int32_t
marker_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
@@ -2082,13 +1589,13 @@ marker_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == -1) {
gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
GF_LOG_ERROR),
- "%s occurred during setattr of %s",
+ "%s occured during setattr of %s",
strerror (op_errno),
(local ? local->loc.path : "<nul>"));
}
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
if (op_ret == -1 || local == NULL)
goto out;
@@ -2105,7 +1612,7 @@ out:
int32_t
marker_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -2116,7 +1623,7 @@ marker_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -2126,10 +1633,10 @@ marker_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto err;
wind:
STACK_WIND (frame, marker_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
return 0;
err:
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2137,13 +1644,13 @@ err:
int32_t
marker_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
marker_local_t *local = NULL;
marker_conf_t *priv = NULL;
if (op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "%s occurred while "
+ gf_log (this->name, GF_LOG_ERROR, "%s occured while "
"creating symlinks ", strerror (op_errno));
}
@@ -2151,7 +1658,7 @@ marker_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
if (op_ret == -1 || local == NULL)
goto out;
@@ -2168,7 +1675,7 @@ out:
int32_t
marker_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int32_t ret = 0;
marker_local_t *local = NULL;
@@ -2179,7 +1686,7 @@ marker_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -2189,10 +1696,10 @@ marker_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto err;
wind:
STACK_WIND (frame, marker_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name, xdata);
+ FIRST_CHILD(this)->fops->removexattr, loc, name);
return 0;
err:
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM);
return 0;
}
@@ -2221,19 +1728,10 @@ marker_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == -1 || local == NULL)
goto out;
- /* copy the gfid from the stat structure instead of inode,
- * since if the lookup is fresh lookup, then the inode
- * would have not yet linked to the inode table which happens
- * in protocol/server.
- */
- if (uuid_is_null (local->loc.gfid))
- uuid_copy (local->loc.gfid, buf->ia_gfid);
-
-
priv = this->private;
if (priv->feature_enabled & GF_QUOTA) {
- mq_xattr_state (this, &local->loc, dict, *buf);
+ quota_xattr_state (this, &local->loc, dict, *buf);
}
out:
@@ -2255,7 +1753,7 @@ marker_lookup (call_frame_t *frame, xlator_t *this,
if (priv->feature_enabled == 0)
goto wind;
- local = mem_get0 (this->local_pool);
+ ALLOCATE_OR_GOTO (local, marker_local_t, err);
MARKER_INIT_LOCAL (frame, local);
@@ -2264,7 +1762,7 @@ marker_lookup (call_frame_t *frame, xlator_t *this,
goto err;
if ((priv->feature_enabled & GF_QUOTA) && xattr_req)
- mq_req_xattr (this, loc, xattr_req);
+ quota_req_xattr (this, loc, xattr_req);
wind:
STACK_WIND (frame, marker_lookup_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
@@ -2275,49 +1773,6 @@ err:
return 0;
}
-int
-marker_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries,
- dict_t *xdata)
-{
- gf_dirent_t *entry = NULL;
-
- if (op_ret <= 0)
- goto unwind;
-
- list_for_each_entry (entry, &entries->list, list) {
- /* TODO: fill things */
- }
-
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
-
- return 0;
-}
-
-int
-marker_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
-{
- marker_conf_t *priv = NULL;
-
- priv = this->private;
-
- if (priv->feature_enabled == 0)
- goto wind;
-
- if ((priv->feature_enabled & GF_QUOTA) && dict)
- mq_req_xattr (this, NULL, dict);
-
-wind:
- STACK_WIND (frame, marker_readdirp_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
-
- return 0;
-}
-
-
int32_t
mem_acct_init (xlator_t *this)
{
@@ -2330,7 +1785,7 @@ mem_acct_init (xlator_t *this)
if (ret != 0) {
gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
+ "failed");
return ret;
}
@@ -2356,14 +1811,12 @@ init_xtime_priv (xlator_t *this, dict_t *options)
ret = uuid_parse (priv->volume_uuid, priv->volume_uuid_bin);
if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid volume uuid %s", priv->volume_uuid);
+ gf_log (this->name, GF_LOG_ERROR, "invalid volume uuid %s", priv->volume_uuid);
goto out;
}
ret = gf_asprintf (& (priv->marker_xattr), "%s.%s.%s",
- MARKER_XATTR_PREFIX, priv->volume_uuid,
- XTIME);
+ MARKER_XATTR_PREFIX, priv->volume_uuid, XTIME);
if (ret == -1){
priv->marker_xattr = NULL;
@@ -2418,11 +1871,14 @@ marker_xtime_priv_cleanup (xlator_t *this)
GF_VALIDATE_OR_GOTO (this->name, priv, out);
- GF_FREE (priv->volume_uuid);
+ if (priv->volume_uuid != NULL)
+ GF_FREE (priv->volume_uuid);
- GF_FREE (priv->timestamp_file);
+ if (priv->timestamp_file != NULL)
+ GF_FREE (priv->timestamp_file);
- GF_FREE (priv->marker_xattr);
+ if (priv->marker_xattr != NULL)
+ GF_FREE (priv->marker_xattr);
out:
return;
}
@@ -2554,13 +2010,6 @@ init (xlator_t *this)
}
}
- this->local_pool = mem_pool_new (marker_local_t, 128);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto err;
- }
-
return 0;
err:
marker_priv_cleanup (this);
@@ -2582,7 +2031,7 @@ marker_forget (xlator_t *this, inode_t *inode)
goto out;
}
- mq_forget (this, ctx->quota_ctx);
+ quota_forget (this, ctx->quota_ctx);
GF_FREE (ctx);
out:
@@ -2613,12 +2062,11 @@ struct xlator_fops fops = {
.setattr = marker_setattr,
.fsetattr = marker_fsetattr,
.removexattr = marker_removexattr,
- .getxattr = marker_getxattr,
- .readdirp = marker_readdirp,
+ .getxattr = marker_getxattr
};
struct xlator_cbks cbks = {
- .forget = marker_forget
+ .forget = marker_forget
};
struct volume_options options[] = {
diff --git a/xlators/features/marker/src/marker.h b/xlators/features/marker/src/marker.h
index cf0f92b79..ea1f5cc0a 100644
--- a/xlators/features/marker/src/marker.h
+++ b/xlators/features/marker/src/marker.h
@@ -1,4 +1,4 @@
-/*Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+/*Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
@@ -28,7 +28,6 @@
#include "xlator.h"
#include "defaults.h"
#include "uuid.h"
-#include "call-stub.h"
#define MARKER_XATTR_PREFIX "trusted.glusterfs"
#define XTIME "xtime"
@@ -47,8 +46,6 @@ enum {
_local->pid = _frame->root->pid; \
memset (&_local->loc, 0, sizeof (loc_t)); \
_local->ref = 1; \
- _local->uid = -1; \
- _local->gid = -1; \
LOCK_INIT (&_local->lock); \
_local->oplocal = NULL; \
} while (0)
@@ -64,66 +61,18 @@ enum {
} \
} while (0)
-#define _MARKER_SET_UID_GID(dest, src) \
- do { \
- if (src->uid != -1 && \
- src->gid != -1) { \
- dest->uid = src->uid; \
- dest->gid = src->gid; \
- } \
- } while (0)
-
-#define MARKER_SET_UID_GID(frame, dest, src) \
- do { \
- _MARKER_SET_UID_GID (dest, src); \
- frame->root->uid = 0; \
- frame->root->gid = 0; \
- frame->cookie = (void *) _GF_UID_GID_CHANGED; \
- } while (0)
-
-#define MARKER_RESET_UID_GID(frame, dest, src) \
- do { \
- _MARKER_SET_UID_GID (dest, src); \
- frame->cookie = NULL; \
- } while (0)
-
struct marker_local{
uint32_t timebuf[2];
pid_t pid;
loc_t loc;
- loc_t parent_loc;
- loc_t *next_lock_on;
- uid_t uid;
- gid_t gid;
int32_t ref;
int32_t ia_nlink;
gf_lock_t lock;
mode_t mode;
- int32_t err;
- call_stub_t *stub;
- int64_t contribution;
struct marker_local *oplocal;
-
- /* marker quota specific */
- int64_t delta;
- int64_t d_off;
- int64_t sum;
- int64_t size;
- int32_t hl_count;
- int32_t dentry_child_count;
-
- fd_t *fd;
- call_frame_t *frame;
-
- quota_inode_ctx_t *ctx;
- inode_contribution_t *contri;
-
- int xflag;
};
typedef struct marker_local marker_local_t;
-#define quota_local_t marker_local_t
-
struct marker_inode_ctx {
struct quota_inode_ctx *quota_ctx;
};
@@ -142,4 +91,5 @@ struct marker_conf{
};
typedef struct marker_conf marker_conf_t;
+int32_t k;
#endif
diff --git a/xlators/features/marker/utils/Makefile.am b/xlators/features/marker/utils/Makefile.am
index 556951d9f..84e926c00 100644
--- a/xlators/features/marker/utils/Makefile.am
+++ b/xlators/features/marker/utils/Makefile.am
@@ -1,3 +1,7 @@
-SUBDIRS = syncdaemon src
+SUBDIRS = syncdaemon
+
+gsyncddir = $(libexecdir)/glusterfs
+
+gsyncd_SCRIPTS = gsyncd
CLEANFILES =
diff --git a/xlators/features/marker/utils/gsyncd.in b/xlators/features/marker/utils/gsyncd.in
new file mode 100755
index 000000000..a7af8c0b0
--- /dev/null
+++ b/xlators/features/marker/utils/gsyncd.in
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+libexecdir=`eval echo "@libexecdir@"`
+sbindir=`eval echo "@sbindir@"`
+
+gluster="$sbindir"/gluster
+
+# glusterd service autodetection
+
+config_wanted=1
+if [ "$_GLUSTERD_CALLED_" = 1 ]; then
+ # OK, we know glusterd called us, no need to look for further config
+ config_wanted=0
+ # ... altough this conclusion should not inherit to our children
+ unset _GLUSTERD_CALLED_
+else
+ # look for a -c option -- if present, we are already configured.
+
+ for a in "$@"; do
+ # -c found, see if it has an argument
+ if [ "$one_more_arg" = 1 ]; then
+ if echo "$a" | grep -qv ^-; then
+ config_wanted=0
+ break
+ fi
+ one_more_arg=0
+ fi
+
+ if [ "$a" = -c ] || [ "$a" = --config-file ]; then
+ one_more_arg=1
+ continue
+ fi
+
+ if echo $a | grep -qE '^(-c.|--config-file=)'; then
+ config_wanted=0;
+ break
+ fi
+ done
+
+fi
+
+if [ $config_wanted = 1 ]; then
+ wd="`${gluster} system:: getwd`"
+ if [ $? -eq 0 ]; then
+ config_file="$wd/geo-replication/gsyncd.conf"
+ fi
+fi
+
+if [ -z "$config_file" ]; then
+ exec @PYTHON@ "$libexecdir"/glusterfs/python/syncdaemon/gsyncd.py "$@"
+else
+ exec @PYTHON@ "$libexecdir"/glusterfs/python/syncdaemon/gsyncd.py -c "$config_file" "$@"
+fi
diff --git a/xlators/features/marker/utils/src/Makefile.am b/xlators/features/marker/utils/src/Makefile.am
deleted file mode 100644
index 73c99cb76..000000000
--- a/xlators/features/marker/utils/src/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-gsyncddir = $(libexecdir)/glusterfs
-
-gsyncd_PROGRAMS = gsyncd
-
-gsyncd_SOURCES = gsyncd.c procdiggy.c
-
-gsyncd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-gsyncd_LDFLAGS = $(GF_LDFLAGS) $(GF_GLUSTERFS_LDFLAGS)
-
-noinst_HEADERS = procdiggy.h
-
-AM_CFLAGS = -fPIC -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\
- -I$(top_srcdir)/libglusterfs/src\
- -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DSBIN_DIR=\"$(sbindir)\" -DPYTHON=\"$(PYTHON)\"
-
-
-CLEANFILES =
-
-$(top_builddir)/libglusterfs/src/libglusterfs.la:
- $(MAKE) -C $(top_builddir)/libglusterfs/src/ all
diff --git a/xlators/features/marker/utils/src/gsyncd.c b/xlators/features/marker/utils/src/gsyncd.c
deleted file mode 100644
index 3f4c2c4b3..000000000
--- a/xlators/features/marker/utils/src/gsyncd.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/param.h> /* for PATH_MAX */
-
-
-#include "common-utils.h"
-#include "run.h"
-#include "procdiggy.h"
-
-#define _GLUSTERD_CALLED_ "_GLUSTERD_CALLED_"
-#define _GSYNCD_DISPATCHED_ "_GSYNCD_DISPATCHED_"
-#define GSYNCD_CONF "geo-replication/gsyncd.conf"
-#define GSYNCD_PY "gsyncd.py"
-#define RSYNC "rsync"
-
-int restricted = 0;
-
-static int
-duplexpand (void **buf, size_t tsiz, size_t *len)
-{
- size_t osiz = tsiz * *len;
-
- *buf = realloc (*buf, osiz << 1);
- if (!*buf)
- return -1;
-
- memset ((char *)*buf + osiz, 0, osiz);
- *len <<= 1;
-
- return 0;
-}
-
-static int
-str2argv (char *str, char ***argv)
-{
- char *p = NULL;
- char *savetok = NULL;
- int argc = 0;
- size_t argv_len = 32;
- int ret = 0;
-
- assert (str);
- str = strdup (str);
- if (!str)
- return -1;
-
- *argv = calloc (argv_len, sizeof (**argv));
- if (!*argv)
- goto error;
-
- while ((p = strtok_r (str, " ", &savetok))) {
- str = NULL;
-
- argc++;
- if (argc == argv_len) {
- ret = duplexpand ((void *)argv,
- sizeof (**argv),
- &argv_len);
- if (ret == -1)
- goto error;
- }
- (*argv)[argc - 1] = p;
- }
-
- return argc;
-
- error:
- fprintf (stderr, "out of memory\n");
- return -1;
-}
-
-static int
-invoke_gsyncd (int argc, char **argv)
-{
- char config_file[PATH_MAX] = {0,};
- size_t gluster_workdir_len = 0;
- runner_t runner = {0,};
- int i = 0;
- int j = 0;
- char *nargv[argc + 4];
-
- if (restricted) {
- size_t len;
- /* in restricted mode we forcibly use the system-wide config */
- runinit (&runner);
- runner_add_args (&runner, SBIN_DIR"/gluster",
- "--log-file=-", "system::", "getwd",
- NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- if (runner_start (&runner) == 0 &&
- fgets (config_file, PATH_MAX,
- runner_chio (&runner, STDOUT_FILENO)) != NULL &&
- (len = strlen (config_file)) &&
- config_file[len - 1] == '\n' &&
- runner_end (&runner) == 0)
- gluster_workdir_len = len - 1;
-
- if (gluster_workdir_len) {
- if (gluster_workdir_len + 1 + strlen (GSYNCD_CONF) + 1 >
- PATH_MAX)
- goto error;
- config_file[gluster_workdir_len] = '/';
- strcat (config_file, GSYNCD_CONF);
- } else
- goto error;
-
- if (setenv ("_GSYNCD_RESTRICTED_", "1", 1) == -1)
- goto error;
- }
-
- if (chdir ("/") == -1)
- goto error;
-
- j = 0;
- nargv[j++] = PYTHON;
- nargv[j++] = GSYNCD_PREFIX"/python/syncdaemon/"GSYNCD_PY;
- for (i = 1; i < argc; i++)
- nargv[j++] = argv[i];
- if (config_file[0]) {
- nargv[j++] = "-c";
- nargv[j++] = config_file;
- }
- nargv[j++] = NULL;
-
- execvp (PYTHON, nargv);
-
- fprintf (stderr, "exec of "PYTHON" failed\n");
- return 127;
-
- error:
- fprintf (stderr, "gsyncd initializaion failed\n");
- return 1;
-}
-
-
-static int
-find_gsyncd (pid_t pid, pid_t ppid, char *name, void *data)
-{
- char buf[NAME_MAX * 2] = {0,};
- char path[PATH_MAX] = {0,};
- char *p = NULL;
- int zeros = 0;
- int ret = 0;
- int fd = -1;
- pid_t *pida = (pid_t *)data;
-
- if (ppid != pida[0])
- return 0;
-
- sprintf (path, PROC"/%d/cmdline", pid);
- fd = open (path, O_RDONLY);
- if (fd == -1)
- return 0;
- ret = read (fd, buf, sizeof (buf));
- close (fd);
- if (ret == -1)
- return 0;
- for (zeros = 0, p = buf; zeros < 2 && p < buf + ret; p++)
- zeros += !*p;
-
- ret = 0;
- switch (zeros) {
- case 2:
- if ((strcmp (basename (buf), basename (PYTHON)) ||
- strcmp (basename (buf + strlen (buf) + 1), GSYNCD_PY)) == 0) {
- ret = 1;
- break;
- }
- /* fallthrough */
- case 1:
- if (strcmp (basename (buf), GSYNCD_PY) == 0)
- ret = 1;
- }
-
- if (ret == 1) {
- if (pida[1] != -1) {
- fprintf (stderr, GSYNCD_PY" sibling is not unique");
- return -1;
- }
- pida[1] = pid;
- }
-
- return 0;
-}
-
-static int
-invoke_rsync (int argc, char **argv)
-{
- int i = 0;
- char path[PATH_MAX] = {0,};
- pid_t pid = -1;
- pid_t ppid = -1;
- pid_t pida[] = {-1, -1};
- char *name = NULL;
- char buf[PATH_MAX + 1] = {0,};
- int ret = 0;
-
- assert (argv[argc] == NULL);
-
- if (argc < 2 || strcmp (argv[1], "--server") != 0)
- goto error;
-
- for (i = 2; i < argc && argv[i][0] == '-'; i++);
-
- if (!(i == argc - 2 && strcmp (argv[i], ".") == 0 && argv[i + 1][0] == '/')) {
- fprintf (stderr, "need an rsync invocation without protected args\n");
- goto error;
- }
-
- /* look up sshd we are spawned from */
- for (pid = getpid () ;; pid = ppid) {
- ppid = pidinfo (pid, &name);
- if (ppid < 0) {
- fprintf (stderr, "sshd ancestor not found\n");
- goto error;
- }
- if (strcmp (name, "sshd") == 0) {
- GF_FREE (name);
- break;
- }
- GF_FREE (name);
- }
- /* look up "ssh-sibling" gsyncd */
- pida[0] = pid;
- ret = prociter (find_gsyncd, pida);
- if (ret == -1 || pida[1] == -1) {
- fprintf (stderr, "gsyncd sibling not found\n");
- goto error;
- }
- /* check if rsync target matches gsyncd target */
- sprintf (path, PROC"/%d/cwd", pida[1]);
- ret = readlink (path, buf, sizeof (buf));
- if (ret == -1 || ret == sizeof (buf))
- goto error;
- if (strcmp (argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
- (strcmp (argv[argc - 1], path) /* match against gluster target */ &&
- strcmp (argv[argc - 1], buf) /* match against file target */) != 0) {
- fprintf (stderr, "rsync target does not match "GEOREP" session\n");
- goto error;
- }
-
- argv[0] = RSYNC;
-
- execvp (RSYNC, argv);
-
- fprintf (stderr, "exec of "RSYNC" failed\n");
- return 127;
-
- error:
- fprintf (stderr, "disallowed "RSYNC" invocation\n");
- return 1;
-}
-
-
-struct invocable {
- char *name;
- int (*invoker) (int argc, char **argv);
-};
-
-struct invocable invocables[] = {
- { "rsync", invoke_rsync },
- { "gsyncd", invoke_gsyncd },
- { NULL, NULL}
-};
-
-int
-main (int argc, char **argv)
-{
- char *evas = NULL;
- struct invocable *i = NULL;
- char *b = NULL;
- char *sargv = NULL;
-
- evas = getenv (_GLUSTERD_CALLED_);
- if (evas && strcmp (evas, "1") == 0)
- /* OK, we know glusterd called us, no need to look for further config
- * ... altough this conclusion should not inherit to our children
- */
- unsetenv (_GLUSTERD_CALLED_);
- else {
- /* we regard all gsyncd invocations unsafe
- * that do not come from glusterd and
- * therefore restrict it
- */
- restricted = 1;
-
- if (!getenv (_GSYNCD_DISPATCHED_)) {
- evas = getenv ("SSH_ORIGINAL_COMMAND");
- if (evas)
- sargv = evas;
- else {
- evas = getenv ("SHELL");
- if (evas && strcmp (basename (evas), "gsyncd") == 0 &&
- argc == 3 && strcmp (argv[1], "-c") == 0)
- sargv = argv[2];
- }
- }
-
- }
-
- if (!(sargv && restricted))
- return invoke_gsyncd (argc, argv);
-
- argc = str2argv (sargv, &argv);
- if (argc == -1 || setenv (_GSYNCD_DISPATCHED_, "1", 1) == -1) {
- fprintf (stderr, "internal error\n");
- return 1;
- }
-
- b = basename (argv[0]);
- for (i = invocables; i->name; i++) {
- if (strcmp (b, i->name) == 0)
- return i->invoker (argc, argv);
- }
-
- fprintf (stderr, "invoking %s in restricted SSH session is not allowed\n",
- b);
-
- return 1;
-}
diff --git a/xlators/features/marker/utils/src/procdiggy.c b/xlators/features/marker/utils/src/procdiggy.c
deleted file mode 100644
index 2f81db6ad..000000000
--- a/xlators/features/marker/utils/src/procdiggy.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/param.h> /* for PATH_MAX */
-
-#include "common-utils.h"
-#include "procdiggy.h"
-
-pid_t
-pidinfo (pid_t pid, char **name)
-{
- char buf[NAME_MAX * 2] = {0,};
- FILE *f = NULL;
- char path[PATH_MAX] = {0,};
- char *p = NULL;
- int ret = 0;
-
- sprintf (path, PROC"/%d/status", pid);
-
- f = fopen (path, "r");
- if (!f)
- return -1;
-
- if (name)
- *name = NULL;
- for (;;) {
- size_t len;
- memset (buf, 0, sizeof (buf));
- if (fgets (buf, sizeof (buf), f) == NULL ||
- (len = strlen (buf)) == 0 ||
- buf[len - 1] != '\n') {
- pid = -1;
- goto out;
- }
- buf[len - 1] = '\0';
-
- if (name && !*name) {
- p = strtail (buf, "Name:");
- if (p) {
- while (isspace (*++p));
- *name = gf_strdup (p);
- if (!*name) {
- pid = -2;
- goto out;
- }
- continue;
- }
- }
-
- p = strtail (buf, "PPid:");
- if (p)
- break;
- }
-
- while (isspace (*++p));
- ret = gf_string2int (p, &pid);
- if (ret == -1)
- pid = -1;
-
- out:
- fclose (f);
- if (pid == -1 && name && *name)
- GF_FREE (name);
- if (pid == -2)
- fprintf (stderr, "out of memory\n");
- return pid;
-}
-
-int
-prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data),
- void *data)
-{
- char *name = NULL;
- DIR *d = NULL;
- struct dirent *de = NULL;
- pid_t pid = -1;
- pid_t ppid = -1;
- int ret = 0;
-
- d = opendir (PROC);
- if (!d)
- return -1;
- while (errno = 0, de = readdir (d)) {
- if (gf_string2int (de->d_name, &pid) != -1 && pid >= 0) {
- ppid = pidinfo (pid, &name);
- switch (ppid) {
- case -1: continue;
- case -2: ret = -1; break;
- }
- ret = proch (pid, ppid, name, data);
- GF_FREE (name);
- if (ret)
- break;
- }
- }
- closedir (d);
- if (!de && errno) {
- fprintf (stderr, "failed to traverse "PROC" (%s)\n",
- strerror (errno));
- ret = -1;
- }
-
- return ret;
-}
diff --git a/xlators/features/marker/utils/src/procdiggy.h b/xlators/features/marker/utils/src/procdiggy.h
deleted file mode 100644
index ee87b0e39..000000000
--- a/xlators/features/marker/utils/src/procdiggy.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef __NetBSD__
-#include <sys/syslimits.h>
-#endif /* __NetBSD__ */
-
-#define PROC "/proc"
-
-pid_t pidinfo (pid_t pid, char **name);
-
-int prociter (int (*proch) (pid_t pid, pid_t ppid, char *name, void *data),
- void *data);
-
diff --git a/xlators/features/marker/utils/syncdaemon/Makefile.am b/xlators/features/marker/utils/syncdaemon/Makefile.am
index cc7cee102..ef2dc9aea 100644
--- a/xlators/features/marker/utils/syncdaemon/Makefile.am
+++ b/xlators/features/marker/utils/syncdaemon/Makefile.am
@@ -1,6 +1,5 @@
syncdaemondir = $(libexecdir)/glusterfs/python/syncdaemon
-syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py resource.py configinterface.py syncdutils.py monitor.py libcxattr.py \
- $(top_builddir)/contrib/ipaddr-py/ipaddr.py
+syncdaemon_PYTHON = gconf.py gsyncd.py __init__.py master.py README.md repce.py resource.py configinterface.py syncdutils.py monitor.py libcxattr.py
CLEANFILES =
diff --git a/xlators/features/marker/utils/syncdaemon/__codecheck.py b/xlators/features/marker/utils/syncdaemon/__codecheck.py
deleted file mode 100644
index e3386afba..000000000
--- a/xlators/features/marker/utils/syncdaemon/__codecheck.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import os
-import os.path
-import sys
-import tempfile
-import shutil
-
-ipd = tempfile.mkdtemp(prefix = 'codecheck-aux')
-
-try:
- # add a fake ipaddr module, we don't want to
- # deal with the real one (just test our code)
- f = open(os.path.join(ipd, 'ipaddr.py'), 'w')
- f.write("""
-class IPAddress(object):
- pass
-class IPNetwork(list):
- pass
-""")
- f.close()
- sys.path.append(ipd)
-
- fl = os.listdir(os.path.dirname(sys.argv[0]) or '.')
- fl.sort()
- for f in fl:
- if f[-3:] != '.py' or f[0] == '_':
- continue
- m = f[:-3]
- sys.stdout.write('importing %s ...' % m)
- __import__(m)
- print(' OK.')
-
- def sys_argv_set(a):
- sys.argv = sys.argv[:1] + a
-
- gsyncd = sys.modules['gsyncd']
- for a in [['--help'], ['--version'], ['--canonicalize-escape-url', '/foo']]:
- print('>>> invoking program with args: %s' % ' '.join(a))
- pid = os.fork()
- if not pid:
- sys_argv_set(a)
- gsyncd.main()
- _, r = os.waitpid(pid, 0)
- if r:
- raise RuntimeError('invocation failed')
-finally:
- shutil.rmtree(ipd)
diff --git a/xlators/features/marker/utils/syncdaemon/configinterface.py b/xlators/features/marker/utils/syncdaemon/configinterface.py
index e55bec519..a170b2236 100644
--- a/xlators/features/marker/utils/syncdaemon/configinterface.py
+++ b/xlators/features/marker/utils/syncdaemon/configinterface.py
@@ -6,7 +6,7 @@ except ImportError:
import re
from string import Template
-from syncdutils import escape, unescape, norm, update_file, GsyncdError
+from syncdutils import escape, unescape, norm, update_file
SECT_ORD = '__section_order__'
SECT_META = '__meta__'
@@ -16,7 +16,6 @@ re_type = type(re.compile(''))
class MultiDict(object):
- """a virtual dict-like class which functions as the union of underlying dicts"""
def __init__(self, *dd):
self.dicts = dd
@@ -32,16 +31,8 @@ class MultiDict(object):
class GConffile(object):
- """A high-level interface to ConfigParser which flattens the two-tiered
- config layout by implenting automatic section dispatch based on initial
- parameters.
-
- Also ensure section ordering in terms of their time of addition -- a compat
- hack for Python < 2.7.
- """
def _normconfig(self):
- """normalize config keys by s/-/_/g"""
for n, s in self.config._sections.items():
if n.find('__') == 0:
continue
@@ -53,13 +44,6 @@ class GConffile(object):
self.config._sections[n] = s2
def __init__(self, path, peers, *dd):
- """
- - .path: location of config file
- - .config: underlying ConfigParser instance
- - .peers: on behalf of whom we flatten .config
- (master, or master-slave url pair)
- - .auxdicts: template subtituents
- """
self.peers = peers
self.path = path
self.auxdicts = dd
@@ -68,7 +52,6 @@ class GConffile(object):
self._normconfig()
def section(self, rx=False):
- """get the section name of the section representing .peers in .config"""
peers = self.peers
if not peers:
peers = ['.', '.']
@@ -81,9 +64,6 @@ class GConffile(object):
@staticmethod
def parse_section(section):
- """retrieve peers sequence encoded by section name
- (as urls or regexen, depending on section type)
- """
sl = section.split()
st = sl.pop(0)
sl = [unescape(u) for u in sl]
@@ -103,7 +83,7 @@ class GConffile(object):
also those sections which are not registered
in SECT_ORD.
- Needed for python 2.{4,5,6} where ConfigParser
+ Needed for python 2.{4,5} where ConfigParser
cannot yet order sections/options internally.
"""
so = {}
@@ -128,15 +108,8 @@ class GConffile(object):
return ss
def update_to(self, dct, allow_unresolved=False):
- """update @dct from key/values of ours.
-
- key/values are collected from .config by filtering the regexp sections
- according to match, and from .section. The values are treated as templates,
- which are substituted from .auxdicts and (in case of regexp sections)
- match groups.
- """
if not self.peers:
- raise GsyncdError('no peers given, cannot select matching options')
+ raise RuntimeError('no peers given, cannot select matching options')
def update_from_sect(sect, mud):
for k, v in self.config._sections[sect].items():
if k == '__name__':
@@ -160,20 +133,16 @@ class GConffile(object):
if match:
update_from_sect(sect, MultiDict(dct, mad, *self.auxdicts))
if self.config.has_section(self.section()):
- update_from_sect(self.section(), MultiDict(dct, *self.auxdicts))
+ update_from_sect(self.section(), MultiDict(dct, mad, *self.auxdicts))
def get(self, opt=None):
- """print the matching key/value pairs from .config,
- or if @opt given, the value for @opt (according to the
- logic described in .update_to)
- """
d = {}
self.update_to(d, allow_unresolved = True)
if opt:
opt = norm(opt)
v = d.get(opt)
if v:
- print(v)
+ print v
else:
for k, v in d.iteritems():
if k == '__name__':
@@ -181,10 +150,6 @@ class GConffile(object):
print("%s: %s" % (k, v))
def write(self, trfn, opt, *a, **kw):
- """update on-disk config transactionally
-
- @trfn is the transaction function
- """
def mergeconf(f):
self.config = ConfigParser.RawConfigParser()
self.config.readfp(f)
@@ -198,7 +163,6 @@ class GConffile(object):
update_file(self.path, updateconf, mergeconf)
def _set(self, opt, val, rx=False):
- """set @opt to @val in .section"""
sect = self.section(rx)
if not self.config.has_section(sect):
self.config.add_section(sect)
@@ -210,15 +174,12 @@ class GConffile(object):
return True
def set(self, opt, *a, **kw):
- """perform ._set transactionally"""
self.write(self._set, opt, *a, **kw)
def _delete(self, opt, rx=False):
- """delete @opt from .section"""
sect = self.section(rx)
if self.config.has_section(sect):
return self.config.remove_option(sect, opt)
def delete(self, opt, *a, **kw):
- """perform ._delete transactionally"""
self.write(self._delete, opt, *a, **kw)
diff --git a/xlators/features/marker/utils/syncdaemon/gconf.py b/xlators/features/marker/utils/syncdaemon/gconf.py
index 146c72a18..24165b619 100644
--- a/xlators/features/marker/utils/syncdaemon/gconf.py
+++ b/xlators/features/marker/utils/syncdaemon/gconf.py
@@ -1,16 +1,11 @@
import os
class GConf(object):
- """singleton class to store globals
- shared between gsyncd modules"""
-
ssh_ctl_dir = None
ssh_ctl_args = None
cpid = None
pid_file_owned = False
- log_exit = False
permanent_handles = []
- log_metadata = {}
@classmethod
def setup_ssh_ctl(cls, ctld):
diff --git a/xlators/features/marker/utils/syncdaemon/gsyncd.py b/xlators/features/marker/utils/syncdaemon/gsyncd.py
index 9e9469469..60980f546 100644
--- a/xlators/features/marker/utils/syncdaemon/gsyncd.py
+++ b/xlators/features/marker/utils/syncdaemon/gsyncd.py
@@ -6,27 +6,20 @@ import sys
import time
import logging
import signal
+import select
import optparse
import fcntl
-import fnmatch
from optparse import OptionParser, SUPPRESS_HELP
from logging import Logger
from errno import EEXIST, ENOENT
-from ipaddr import IPAddress, IPNetwork
-
from gconf import gconf
from syncdutils import FreeObject, norm, grabpidfile, finalize, log_raise_exception
-from syncdutils import GsyncdError, select, set_term_handler
from configinterface import GConffile
import resource
from monitor import monitor
class GLogger(Logger):
- """Logger customizations for gsyncd.
-
- It implements a log format similar to that of glusterfs.
- """
def makeRecord(self, name, level, *a):
rv = Logger.makeRecord(self, name, level, *a)
@@ -58,27 +51,8 @@ class GLogger(Logger):
logging.getLogger().handlers = []
logging.basicConfig(**lprm)
- @classmethod
- def _gsyncd_loginit(cls, **kw):
- lkw = {}
- if gconf.log_level:
- lkw['level'] = gconf.log_level
- if kw.get('log_file'):
- if kw['log_file'] in ('-', '/dev/stderr'):
- lkw['stream'] = sys.stderr
- elif kw['log_file'] == '/dev/stdout':
- lkw['stream'] = sys.stdout
- else:
- lkw['filename'] = kw['log_file']
-
- cls.setup(label=kw.get('label'), **lkw)
-
- lkw.update({'saved_label': kw.get('label')})
- gconf.log_metadata = lkw
- gconf.log_exit = True
def startup(**kw):
- """set up logging, pidfile grabbing, daemonization"""
if getattr(gconf, 'pid_file', None) and kw.get('go_daemon') != 'postconn':
if not grabpidfile():
sys.stderr.write("pidfile is taken, exiting.\n")
@@ -98,21 +72,29 @@ def startup(**kw):
os.dup2(dn, f.fileno())
if getattr(gconf, 'pid_file', None):
if not grabpidfile(gconf.pid_file + '.tmp'):
- raise GsyncdError("cannot grab temporary pidfile")
+ raise RuntimeError("cannot grap temporary pidfile")
os.rename(gconf.pid_file + '.tmp', gconf.pid_file)
# wait for parent to terminate
# so we can start up with
# no messing from the dirty
# ol' bustard
- select((x,), (), ())
+ select.select((x,), (), ())
os.close(x)
- GLogger._gsyncd_loginit(**kw)
+ lkw = {}
+ if gconf.log_level:
+ lkw['level'] = gconf.log_level
+ if kw.get('log_file'):
+ if kw['log_file'] in ('-', '/dev/stderr'):
+ lkw['stream'] = sys.stderr
+ elif kw['log_file'] == '/dev/stdout':
+ lkw['stream'] = sys.stdout
+ else:
+ lkw['filename'] = kw['log_file']
+ GLogger.setup(label=kw.get('label'), **lkw)
def main():
- """main routine, signal/exception handling boilerplates"""
- gconf.starttime = time.time()
- set_term_handler()
+ signal.signal(signal.SIGTERM, lambda *a: finalize(*a, **{'exval': 1}))
GLogger.setup()
excont = FreeObject(exval = 0)
try:
@@ -124,17 +106,6 @@ def main():
finalize(exval = excont.exval)
def main_i():
- """internal main routine
-
- parse command line, decide what action will be taken;
- we can either:
- - query/manipulate configuration
- - format gsyncd urls using gsyncd's url parsing engine
- - start service in following modes, in given stages:
- - monitor: startup(), monitor()
- - master: startup(), connect_remote(), connect(), service_loop()
- - slave: startup(), connect(), service_loop()
- """
rconf = {'go_daemon': 'should'}
def store_abs(opt, optstr, val, parser):
@@ -149,40 +120,22 @@ def main_i():
return lambda o, oo, vx, p: store_local(o, oo, FreeObject(op=op, **dmake(vx)), p)
op = OptionParser(usage="%prog [options...] <master> <slave>", version="%prog 0.0.1")
- op.add_option('--gluster-command-dir', metavar='DIR', default='')
+ op.add_option('--gluster-command', metavar='CMD', default='glusterfs')
op.add_option('--gluster-log-file', metavar='LOGF', default=os.devnull, type=str, action='callback', callback=store_abs)
op.add_option('--gluster-log-level', metavar='LVL')
- op.add_option('--gluster-params', metavar='PRMS', default='')
- op.add_option('--gluster-cli-options', metavar='OPTS', default='--log-file=-')
- op.add_option('--mountbroker', metavar='LABEL')
op.add_option('-p', '--pid-file', metavar='PIDF', type=str, action='callback', callback=store_abs)
op.add_option('-l', '--log-file', metavar='LOGF', type=str, action='callback', callback=store_abs)
op.add_option('--state-file', metavar='STATF', type=str, action='callback', callback=store_abs)
- op.add_option('--ignore-deletes', default=False, action='store_true')
- op.add_option('--use-rsync-xattrs', default=False, action='store_true')
op.add_option('-L', '--log-level', metavar='LVL')
op.add_option('-r', '--remote-gsyncd', metavar='CMD', default=os.path.abspath(sys.argv[0]))
op.add_option('--volume-id', metavar='UUID')
op.add_option('--session-owner', metavar='ID')
op.add_option('-s', '--ssh-command', metavar='CMD', default='ssh')
op.add_option('--rsync-command', metavar='CMD', default='rsync')
- op.add_option('--rsync-options', metavar='OPTS', default='--sparse')
- op.add_option('--rsync-ssh-options', metavar='OPTS', default='--compress')
+ op.add_option('--rsync-extra', metavar='ARGS', default='-sS', help=SUPPRESS_HELP)
op.add_option('--timeout', metavar='SEC', type=int, default=120)
- op.add_option('--connection-timeout', metavar='SEC', type=int, default=60, help=SUPPRESS_HELP)
op.add_option('--sync-jobs', metavar='N', type=int, default=3)
op.add_option('--turns', metavar='N', type=int, default=0, help=SUPPRESS_HELP)
- op.add_option('--allow-network', metavar='IPS', default='')
- op.add_option('--state-socket-unencoded', metavar='SOCKF', type=str, action='callback', callback=store_abs)
- op.add_option('--checkpoint', metavar='LABEL', default='')
- # tunables for failover/failback mechanism:
- # None - gsyncd behaves as normal
- # blind - gsyncd works with xtime pairs to identify
- # candidates for synchronization
- # wrapup - same as normal mode but does not assign
- # xtimes to orphaned files
- # see crawl() for usage of the above tunables
- op.add_option('--special-sync-mode', type=str, help=SUPPRESS_HELP)
op.add_option('-c', '--config-file', metavar='CONF', type=str, action='callback', callback=store_local)
# duh. need to specify dest or value will be mapped to None :S
@@ -198,7 +151,7 @@ def main_i():
op.add_option('--config-' + a, metavar='OPT', type=str, dest='config', action='callback',
callback=store_local_obj(a, lambda vx: {'opt': vx}))
op.add_option('--config-get-all', dest='config', action='callback', callback=store_local_obj('get', lambda vx: {'opt': None}))
- for m in ('', '-rx', '-glob'):
+ for m in ('', '-rx'):
# call this code 'Pythonic' eh?
# have to define a one-shot local function to be able to inject (a value depending on the)
# iteration variable into the inner lambda
@@ -207,15 +160,12 @@ def main_i():
callback=store_local_obj('set', lambda vx: {'opt': vx[0], 'val': vx[1], 'rx': rx}))
op.add_option('--config-del' + m, metavar='OPT', type=str, dest='config', action='callback',
callback=store_local_obj('del', lambda vx: {'opt': vx, 'rx': rx}))
- conf_mod_opt_regex_variant(m and m[1:] or False)
+ conf_mod_opt_regex_variant(not not m)
- op.add_option('--normalize-url', dest='url_print', action='callback', callback=store_local_curry('normal'))
- op.add_option('--canonicalize-url', dest='url_print', action='callback', callback=store_local_curry('canon'))
- op.add_option('--canonicalize-escape-url', dest='url_print', action='callback', callback=store_local_curry('canon_esc'))
+ op.add_option('--canonicalize-url', dest='do_canon', action='callback', callback=store_local_curry('raw'))
+ op.add_option('--canonicalize-escape-url', dest='do_canon', action='callback', callback=store_local_curry('escaped'))
- tunables = [ norm(o.get_opt_string()[2:]) for o in op.option_list if o.callback in (store_abs, 'store_true', None) and o.get_opt_string() not in ('--version', '--help') ]
- remote_tunables = [ 'listen', 'go_daemon', 'timeout', 'session_owner', 'config_file', 'use_rsync_xattrs' ]
- rq_remote_tunables = { 'listen': True }
+ tunables = [ norm(o.get_opt_string()[2:]) for o in op.option_list if o.callback in (store_abs, None) and o.get_opt_string() not in ('--version', '--help') ]
# precedence for sources of values: 1) commandline, 2) cfg file, 3) defaults
# -- for this to work out we need to tell apart defaults from explicitly set
@@ -227,41 +177,21 @@ def main_i():
if not (len(args) == 2 or \
(len(args) == 1 and rconf.get('listen')) or \
(len(args) <= 2 and confdata) or \
- rconf.get('url_print')):
+ rconf.get('do_canon')):
sys.stderr.write("error: incorrect number of arguments\n\n")
sys.stderr.write(op.get_usage() + "\n")
sys.exit(1)
- restricted = os.getenv('_GSYNCD_RESTRICTED_')
-
- if restricted:
- allopts = {}
- allopts.update(opts.__dict__)
- allopts.update(rconf)
- bannedtuns = set(allopts.keys()) - set(remote_tunables)
- if bannedtuns:
- raise GsyncdError('following tunables cannot be set with restricted SSH invocaton: ' + \
- ', '.join(bannedtuns))
- for k, v in rq_remote_tunables.items():
- if not k in allopts or allopts[k] != v:
- raise GsyncdError('tunable %s is not set to value %s required for restricted SSH invocaton' % \
- (k, v))
-
- confrx = getattr(confdata, 'rx', None)
- if confrx:
+ if getattr(confdata, 'rx', None):
# peers are regexen, don't try to parse them
- if confrx == 'glob':
- args = [ '\A' + fnmatch.translate(a) for a in args ]
canon_peers = args
namedict = {}
else:
rscs = [resource.parse_url(u) for u in args]
- dc = rconf.get('url_print')
+ dc = rconf.get('do_canon')
if dc:
for r in rscs:
- print(r.get_url(**{'normal': {},
- 'canon': {'canonical': True},
- 'canon_esc': {'canonical': True, 'escaped': True}}[dc]))
+ print(r.get_url(canonical=True, escaped=(dc=='escaped')))
return
local = remote = None
if rscs:
@@ -269,7 +199,7 @@ def main_i():
if len(rscs) > 1:
remote = rscs[1]
if not local.can_connect_to(remote):
- raise GsyncdError("%s cannot work with %s" % (local.path, remote and remote.path))
+ raise RuntimeError("%s cannot work with %s" % (local.path, remote and remote.path))
pa = ([], [], [])
urlprms = ({}, {'canonical': True}, {'canonical': True, 'escaped': True})
for x in rscs:
@@ -295,7 +225,6 @@ def main_i():
rconf['config_file'] = os.path.join(os.path.dirname(sys.argv[0]), "conf/gsyncd.conf")
gcnf = GConffile(rconf['config_file'], canon_peers, defaults.__dict__, opts.__dict__, namedict)
- checkpoint_change = False
if confdata:
opt_ok = norm(confdata.opt) in tunables + [None]
if confdata.op == 'check':
@@ -304,46 +233,24 @@ def main_i():
else:
sys.exit(1)
elif not opt_ok:
- raise GsyncdError("not a valid option: " + confdata.opt)
+ raise RuntimeError("not a valid option: " + confdata.opt)
if confdata.op == 'get':
gcnf.get(confdata.opt)
elif confdata.op == 'set':
gcnf.set(confdata.opt, confdata.val, confdata.rx)
elif confdata.op == 'del':
gcnf.delete(confdata.opt, confdata.rx)
- # when modifying checkpoint, it's important to make a log
- # of that, so in that case we go on to set up logging even
- # if its just config invocation
- if confdata.opt == 'checkpoint' and confdata.op in ('set', 'del') and \
- not confdata.rx:
- checkpoint_change = True
- if not checkpoint_change:
- return
+ return
gconf.__dict__.update(defaults.__dict__)
gcnf.update_to(gconf.__dict__)
gconf.__dict__.update(opts.__dict__)
gconf.configinterface = gcnf
- if restricted and gconf.allow_network:
- ssh_conn = os.getenv('SSH_CONNECTION')
- if not ssh_conn:
- #legacy env var
- ssh_conn = os.getenv('SSH_CLIENT')
- if ssh_conn:
- allowed_networks = [ IPNetwork(a) for a in gconf.allow_network.split(',') ]
- client_ip = IPAddress(ssh_conn.split()[0])
- allowed = False
- for nw in allowed_networks:
- if client_ip in nw:
- allowed = True
- break
- if not allowed:
- raise GsyncdError("client IP address is not allowed")
-
ffd = rconf.get('feedback_fd')
if ffd:
- fcntl.fcntl(ffd, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ gconf.feedback_fd = ffd
+ fcntl.fcntl(int(ffd), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
#normalize loglevel
lvl0 = gconf.log_level
@@ -353,17 +260,9 @@ def main_i():
# I have _never_ _ever_ seen such an utterly braindead
# error condition
if lvl2 == "Level " + lvl1:
- raise GsyncdError('cannot recognize log level "%s"' % lvl0)
+ raise RuntimeError('cannot recognize log level "%s"' % lvl0)
gconf.log_level = lvl2
- if checkpoint_change:
- GLogger._gsyncd_loginit(log_file=gconf.log_file, label='conf')
- if confdata.op == 'set':
- logging.info('checkpoint %s set' % confdata.val)
- elif confdata.op == 'del':
- logging.info('checkpoint info was reset')
- return
-
go_daemon = rconf['go_daemon']
be_monitor = rconf.get('monitor')
@@ -386,7 +285,6 @@ def main_i():
return monitor()
logging.info("syncing: %s" % " -> ".join(peers))
- resource.Popen.init_errhandler()
if remote:
go_daemon = remote.connect_remote(go_daemon=go_daemon)
if go_daemon:
@@ -394,10 +292,10 @@ def main_i():
# complete remote connection in child
remote.connect_remote(go_daemon='done')
local.connect()
- if ffd:
- os.close(ffd)
local.service_loop(*[r for r in [remote] if r])
+ logging.info("exiting.")
+
if __name__ == "__main__":
main()
diff --git a/xlators/features/marker/utils/syncdaemon/libcxattr.py b/xlators/features/marker/utils/syncdaemon/libcxattr.py
index f0a9d2292..907a16c78 100644
--- a/xlators/features/marker/utils/syncdaemon/libcxattr.py
+++ b/xlators/features/marker/utils/syncdaemon/libcxattr.py
@@ -3,15 +3,6 @@ from ctypes import *
from ctypes.util import find_library
class Xattr(object):
- """singleton that wraps the extended attribues system
- interface for python using ctypes
-
- Just implement it to the degree we need it, in particular
- - we need just the l*xattr variants, ie. we never want symlinks to be
- followed
- - don't need size discovery for getxattr, as we always know the exact
- sizes we expect
- """
libc = CDLL(find_library("libc"))
@@ -63,10 +54,10 @@ class Xattr(object):
@classmethod
def llistxattr_buf(cls, path):
- """listxattr variant with size discovery"""
size = cls.llistxattr(path)
- if size == -1:
- cls.raise_oserr()
- if size == 0:
- return []
+ if size == -1:
+ raise_oserr()
return cls.llistxattr(path, size)
+
+
+
diff --git a/xlators/features/marker/utils/syncdaemon/master.py b/xlators/features/marker/utils/syncdaemon/master.py
index 336f59207..76f924ed3 100644
--- a/xlators/features/marker/utils/syncdaemon/master.py
+++ b/xlators/features/marker/utils/syncdaemon/master.py
@@ -2,343 +2,29 @@ import os
import sys
import time
import stat
-import random
import signal
import logging
-import socket
import errno
-from errno import ENOENT, ENODATA, EPIPE
+from errno import ENOENT, ENODATA
from threading import currentThread, Condition, Lock
-from datetime import datetime
-try:
- from hashlib import md5 as md5
-except ImportError:
- # py 2.4
- from md5 import new as md5
from gconf import gconf
-from syncdutils import FreeObject, Thread, GsyncdError, boolify, \
- escape, unescape, select
+from syncdutils import FreeObject, Thread
URXTIME = (-1, 0)
-# Utility functions to help us to get to closer proximity
-# of the DRY principle (no, don't look for elevated or
-# perspectivistic things here)
-
-def _xtime_now():
- t = time.time()
- sec = int(t)
- nsec = int((t - sec) * 1000000)
- return (sec, nsec)
-
-def _volinfo_hook_relax_foreign(self):
- volinfo_sys = self.get_sys_volinfo()
- fgn_vi = volinfo_sys[self.KFGN]
- if fgn_vi:
- expiry = fgn_vi['timeout'] - int(time.time()) + 1
- logging.info('foreign volume info found, waiting %d sec for expiry' % \
- expiry)
- time.sleep(expiry)
- volinfo_sys = self.get_sys_volinfo()
- self.volinfo_state, state_change = self.volinfo_state_machine(self.volinfo_state,
- volinfo_sys)
- if self.inter_master:
- raise GsyncdError("cannot be intermediate master in special mode")
- return (volinfo_sys, state_change)
-
-
-# The API!
-
-def gmaster_builder():
- """produce the GMaster class variant corresponding
- to sync mode"""
- this = sys.modules[__name__]
- modemixin = gconf.special_sync_mode
- if not modemixin:
- modemixin = 'normal'
- logging.info('setting up master for %s sync mode' % modemixin)
- modemixin = getattr(this, modemixin.capitalize() + 'Mixin')
- sendmarkmixin = boolify(gconf.use_rsync_xattrs) and SendmarkRsyncMixin or SendmarkNormalMixin
- purgemixin = boolify(gconf.ignore_deletes) and PurgeNoopMixin or PurgeNormalMixin
- class _GMaster(GMasterBase, modemixin, sendmarkmixin, purgemixin):
- pass
- return _GMaster
-
-
-# Mixin classes that implement the data format
-# and logic particularities of the certain
-# sync modes
-
-class NormalMixin(object):
- """normal geo-rep behavior"""
-
- minus_infinity = URXTIME
-
- # following staticmethods ideally would be
- # methods of an xtime object (in particular,
- # implementing the hooks needed for comparison
- # operators), but at this point we don't yet
- # have a dedicated xtime class
-
- @staticmethod
- def serialize_xtime(xt):
- return "%d.%d" % tuple(xt)
-
- @staticmethod
- def deserialize_xtime(xt):
- return tuple(int(x) for x in xt.split("."))
-
- @staticmethod
- def native_xtime(xt):
- return xt
-
- @staticmethod
- def xtime_geq(xt0, xt1):
- return xt0 >= xt1
-
- def make_xtime_opts(self, is_master, opts):
- if not 'create' in opts:
- opts['create'] = is_master and not self.inter_master
- if not 'default_xtime' in opts:
- if is_master and self.inter_master:
- opts['default_xtime'] = ENODATA
- else:
- opts['default_xtime'] = URXTIME
-
- def xtime_low(self, server, path, **opts):
- xt = server.xtime(path, self.uuid)
- if isinstance(xt, int) and xt != ENODATA:
- return xt
- if xt == ENODATA or xt < self.volmark:
- if opts['create']:
- xt = _xtime_now()
- server.set_xtime(path, self.uuid, xt)
- else:
- xt = opts['default_xtime']
- return xt
-
- def keepalive_payload_hook(self, timo, gap):
- # first grab a reference as self.volinfo
- # can be changed in main thread
- vi = self.volinfo
- if vi:
- # then have a private copy which we can mod
- vi = vi.copy()
- vi['timeout'] = int(time.time()) + timo
- else:
- # send keep-alives more frequently to
- # avoid a delay in announcing our volume info
- # to slave if it becomes established in the
- # meantime
- gap = min(10, gap)
- return (vi, gap)
-
- def volinfo_hook(self):
- volinfo_sys = self.get_sys_volinfo()
- self.volinfo_state, state_change = self.volinfo_state_machine(self.volinfo_state,
- volinfo_sys)
- return (volinfo_sys, state_change)
-
- def xtime_reversion_hook(self, path, xtl, xtr):
- if xtr > xtl:
- raise GsyncdError("timestamp corruption for " + path)
-
- def need_sync(self, e, xte, xtrd):
- return xte > xtrd
-
- def set_slave_xtime(self, path, mark):
- self.slave.server.set_xtime(path, self.uuid, mark)
-
-class WrapupMixin(NormalMixin):
- """a variant that differs from normal in terms
- of ignoring non-indexed files"""
-
- @staticmethod
- def make_xtime_opts(is_master, opts):
- if not 'create' in opts:
- opts['create'] = False
- if not 'default_xtime' in opts:
- opts['default_xtime'] = URXTIME
-
- @staticmethod
- def keepalive_payload_hook(timo, gap):
- return (None, gap)
-
- def volinfo_hook(self):
- return _volinfo_hook_relax_foreign(self)
-
-class BlindMixin(object):
- """Geo-rep flavor using vectored xtime.
-
- Coordinates are the master, slave uuid pair;
- in master coordinate behavior is normal,
- in slave coordinate we force synchronization
- on any value difference (these are in disjunctive
- relation, ie. if either orders the entry to be
- synced, it shall be synced.
- """
-
- minus_infinity = (URXTIME, None)
-
- @staticmethod
- def serialize_xtime(xt):
- a = []
- for x in xt:
- if not x:
- x = ('None', '')
- a.extend(x)
- return '.'.join(str(n) for n in a)
-
- @staticmethod
- def deserialize_xtime(xt):
- a = xt.split(".")
- a = (tuple(a[0:2]), tuple(a[3:4]))
- b = []
- for p in a:
- if p[0] == 'None':
- p = None
- else:
- p = tuple(int(x) for x in p)
- b.append(p)
- return tuple(b)
-
- @staticmethod
- def native_xtime(xt):
- return xt[0]
-
- @staticmethod
- def xtime_geq(xt0, xt1):
- return (not xt1[0] or xt0[0] >= xt1[0]) and \
- (not xt1[1] or xt0[1] >= xt1[1])
-
- @property
- def ruuid(self):
- if self.volinfo_r:
- return self.volinfo_r['uuid']
-
- @staticmethod
- def make_xtime_opts(is_master, opts):
- if not 'create' in opts:
- opts['create'] = is_master
- if not 'default_xtime' in opts:
- opts['default_xtime'] = URXTIME
-
- def xtime_low(self, server, path, **opts):
- xtd = server.xtime_vec(path, self.uuid, self.ruuid)
- if isinstance(xtd, int):
- return xtd
- xt = (xtd[self.uuid], xtd[self.ruuid])
- if not xt[1] and (not xt[0] or xt[0] < self.volmark):
- if opts['create']:
- # not expected, but can happen if file originates
- # from interrupted gsyncd transfer
- logging.warn('have to fix up missing xtime on ' + path)
- xt0 = _xtime_now()
- server.set_xtime(path, self.uuid, xt0)
- else:
- xt0 = opts['default_xtime']
- xt = (xt0, xt[1])
- return xt
-
- @staticmethod
- def keepalive_payload_hook(timo, gap):
- return (None, gap)
-
- def volinfo_hook(self):
- res = _volinfo_hook_relax_foreign(self)
- volinfo_r_new = self.slave.server.native_volume_info()
- if volinfo_r_new['retval']:
- raise GsyncdError("slave is corrupt")
- if getattr(self, 'volinfo_r', None):
- if self.volinfo_r['uuid'] != volinfo_r_new['uuid']:
- raise GsyncdError("uuid mismatch on slave")
- self.volinfo_r = volinfo_r_new
- return res
-
- def xtime_reversion_hook(self, path, xtl, xtr):
- if not isinstance(xtr[0], int) and \
- (isinstance(xtl[0], int) or xtr[0] > xtl[0]):
- raise GsyncdError("timestamp corruption for " + path)
-
- def need_sync(self, e, xte, xtrd):
- if xte[0]:
- if not xtrd[0] or xte[0] > xtrd[0]:
- # there is outstanding diff at 0th pos,
- # we can short-cut to true
- return True
- # we arrived to this point by either of these
- # two possiblilites:
- # - no outstanding difference at 0th pos,
- # wanna see 1st pos if he raises veto
- # against "no need to sync" proposal
- # - no data at 0th pos, 1st pos will have
- # to decide (due to xtime assignment,
- # in this case 1st pos does carry data
- # -- iow, if 1st pos did not have data,
- # and 0th neither, 0th would have been
- # force-feeded)
- if not xte[1]:
- # no data, no veto
- return False
- # the hard work: for 1st pos,
- # the conduct is fetch corresponding
- # slave data and do a "blind" comparison
- # (ie. do not care who is newer, we trigger
- # sync on non-identical xitmes)
- xtr = self.xtime(e, self.slave)
- return isinstance(xtr, int) or xte[1] != xtr[1]
-
- def set_slave_xtime(self, path, mark):
- xtd = {}
- for (u, t) in zip((self.uuid, self.ruuid), mark):
- if t:
- xtd[u] = t
- self.slave.server.set_xtime_vec(path, xtd)
-
-
-# Further mixins for certain tunable behaviors
-
-class SendmarkNormalMixin(object):
-
- def sendmark_regular(self, *a, **kw):
- return self.sendmark(*a, **kw)
-
-class SendmarkRsyncMixin(object):
-
- def sendmark_regular(self, *a, **kw):
- pass
-
-
-class PurgeNormalMixin(object):
-
- def purge_missing(self, path, names):
- self.slave.server.purge(path, names)
-
-class PurgeNoopMixin(object):
-
- def purge_missing(self, path, names):
- pass
-
-
-
-class GMasterBase(object):
- """abstract class impementling master role"""
+class GMaster(object):
KFGN = 0
KNAT = 1
def get_sys_volinfo(self):
- """query volume marks on fs root
-
- err out on multiple foreign masters
- """
fgn_vis, nat_vi = self.master.server.foreign_volume_infos(), \
self.master.server.native_volume_info()
fgn_vi = None
if fgn_vis:
if len(fgn_vis) > 1:
- raise GsyncdError("cannot work with multiple foreign masters")
+ raise RuntimeError("cannot work with multiple foreign masters")
fgn_vi = fgn_vis[0]
return fgn_vi, nat_vi
@@ -354,208 +40,91 @@ class GMasterBase(object):
@property
def inter_master(self):
- """decide if we are an intermediate master
- in a cascading setup
- """
return self.volinfo_state[self.KFGN] and True or False
def xtime(self, path, *a, **opts):
- """get amended xtime
-
- as of amending, we can create missing xtime, or
- determine a valid value if what we get is expired
- (as of the volume mark expiry); way of amendig
- depends on @opts and on subject of query (master
- or slave).
- """
if a:
rsc = a[0]
else:
rsc = self.master
- self.make_xtime_opts(rsc == self.master, opts)
- return self.xtime_low(rsc.server, path, **opts)
+ if not 'create' in opts:
+ opts['create'] = (rsc == self.master and not self.inter_master)
+ if not 'default_xtime' in opts:
+ if rsc == self.master and self.inter_master:
+ opts['default_xtime'] = ENODATA
+ else:
+ opts['default_xtime'] = URXTIME
+ xt = rsc.server.xtime(path, self.uuid)
+ if isinstance(xt, int) and xt != ENODATA:
+ return xt
+ invalid_xtime = (xt == ENODATA or xt < self.volmark)
+ if invalid_xtime and opts['create']:
+ t = time.time()
+ sec = int(t)
+ nsec = int((t - sec) * 1000000)
+ xt = (sec, nsec)
+ rsc.server.set_xtime(path, self.uuid, xt)
+ if invalid_xtime:
+ xt = opts['default_xtime']
+ return xt
def __init__(self, master, slave):
self.master = master
self.slave = slave
self.jobtab = {}
self.syncer = Syncer(slave)
- # crawls vs. turns:
- # - self.crawls is simply the number of crawl() invocations on root
- # - one turn is a maximal consecutive sequence of crawls so that each
- # crawl in it detects a change to be synced
- # - self.turns is the number of turns since start
- # - self.total_turns is a limit so that if self.turns reaches it, then
- # we exit (for diagnostic purposes)
- # so, eg., if the master fs changes unceasingly, self.turns will remain 0.
- self.crawls = 0
- self.turns = 0
self.total_turns = int(gconf.turns)
- self.lastreport = {'crawls': 0, 'turns': 0}
+ self.turns = 0
self.start = None
self.change_seen = None
- # the authoritative (foreign, native) volinfo pair
+ # the authorative (foreign, native) volinfo pair
# which lets us deduce what to do when we refetch
# the volinfos from system
uuid_preset = getattr(gconf, 'volume_id', None)
self.volinfo_state = (uuid_preset and {'uuid': uuid_preset}, None)
# the actual volinfo we make use of
self.volinfo = None
- self.terminate = False
- self.checkpoint_thread = None
-
- @classmethod
- def _checkpt_param(cls, chkpt, prm, xtimish=True):
- """use config backend to lookup a parameter belonging to
- checkpoint @chkpt"""
- cprm = getattr(gconf, 'checkpoint_' + prm, None)
- if not cprm:
- return
- chkpt_mapped, val = cprm.split(':', 1)
- if unescape(chkpt_mapped) != chkpt:
- return
- if xtimish:
- val = cls.deserialize_xtime(val)
- return val
-
- @classmethod
- def _set_checkpt_param(cls, chkpt, prm, val, xtimish=True):
- """use config backend to store a parameter associated
- with checkpoint @chkpt"""
- if xtimish:
- val = cls.serialize_xtime(val)
- gconf.configinterface.set('checkpoint_' + prm, "%s:%s" % (escape(chkpt), val))
-
- @staticmethod
- def humantime(*tpair):
- """format xtime-like (sec, nsec) pair to human readable format"""
- ts = datetime.fromtimestamp(float('.'.join(str(n) for n in tpair))).\
- strftime("%Y-%m-%d %H:%M:%S")
- if len(tpair) > 1:
- ts += '.' + str(tpair[1])
- return ts
-
- def checkpt_service(self, chan, chkpt, tgt):
- """checkpoint service loop
-
- monitor and verify checkpoint status for @chkpt, and listen
- for incoming requests for whom we serve a pretty-formatted
- status report"""
- if not chkpt:
- # dummy loop for the case when there is no checkpt set
- while True:
- select([chan], [], [])
- conn, _ = chan.accept()
- conn.send('\0')
- conn.close()
- completed = self._checkpt_param(chkpt, 'completed', xtimish=False)
- if completed:
- completed = tuple(int(x) for x in completed.split('.'))
- while True:
- s,_,_ = select([chan], [], [], (not completed) and 5 or None)
- # either request made and we re-check to not
- # give back stale data, or we still hunting for completion
- if self.native_xtime(tgt) and self.native_xtime(tgt) < self.volmark:
- # indexing has been reset since setting the checkpoint
- status = "is invalid"
- else:
- xtr = self.xtime('.', self.slave)
- if isinstance(xtr, int):
- raise GsyncdError("slave root directory is unaccessible (%s)",
- os.strerror(xtr))
- ncompleted = self.xtime_geq(xtr, tgt)
- if completed and not ncompleted: # stale data
- logging.warn("completion time %s for checkpoint %s became stale" % \
- (self.humantime(*completed), chkpt))
- completed = None
- gconf.confdata.delete('checkpoint-completed')
- if ncompleted and not completed: # just reaching completion
- completed = "%.6f" % time.time()
- self._set_checkpt_param(chkpt, 'completed', completed, xtimish=False)
- completed = tuple(int(x) for x in completed.split('.'))
- logging.info("checkpoint %s completed" % chkpt)
- status = completed and \
- "completed at " + self.humantime(completed[0]) or \
- "not reached yet"
- if s:
- conn = None
- try:
- conn, _ = chan.accept()
- try:
- conn.send(" | checkpoint %s %s\0" % (chkpt, status))
- except:
- exc = sys.exc_info()[1]
- if (isinstance(exc, OSError) or isinstance(exc, IOError)) and \
- exc.errno == EPIPE:
- logging.debug('checkpoint client disconnected')
- else:
- raise
- finally:
- if conn:
- conn.close()
-
- def start_checkpoint_thread(self):
- """prepare and start checkpoint service"""
- if self.checkpoint_thread or not getattr(gconf, 'state_socket_unencoded', None):
- return
- chan = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- state_socket = "/tmp/%s.socket" % md5(gconf.state_socket_unencoded).hexdigest()
- try:
- os.unlink(state_socket)
- except:
- if sys.exc_info()[0] == OSError:
- pass
- chan.bind(state_socket)
- chan.listen(1)
- checkpt_tgt = None
- if gconf.checkpoint:
- checkpt_tgt = self._checkpt_param(gconf.checkpoint, 'target')
- if not checkpt_tgt:
- checkpt_tgt = self.xtime('.')
- if isinstance(checkpt_tgt, int):
- raise GsyncdError("master root directory is unaccessible (%s)",
- os.strerror(checkpt_tgt))
- self._set_checkpt_param(gconf.checkpoint, 'target', checkpt_tgt)
- logging.debug("checkpoint target %s has been determined for checkpoint %s" % \
- (repr(checkpt_tgt), gconf.checkpoint))
- t = Thread(target=self.checkpt_service, args=(chan, gconf.checkpoint, checkpt_tgt))
- t.start()
- self.checkpoint_thread = t
+ self.terminate = False
def crawl_loop(self):
- """start the keep-alive thread and iterate .crawl"""
+ ffd = getattr(gconf, 'feedback_fd', None)
+ if ffd:
+ os.close(int(ffd))
timo = int(gconf.timeout or 0)
if timo > 0:
def keep_alive():
while True:
- vi, gap = self.keepalive_payload_hook(timo, timo * 0.5)
+ gap = timo * 0.5
+ # first grab a reference as self.volinfo
+ # can be changed in main thread
+ vi = self.volinfo
+ if vi:
+ # then have a private copy which we can mod
+ vi = vi.copy()
+ vi['timeout'] = int(time.time()) + timo
+ else:
+ # send keep-alives more frequently to
+ # avoid a delay in announcing our volume info
+ # to slave if it becomes established in the
+ # meantime
+ gap = min(10, gap)
self.slave.server.keep_alive(vi)
time.sleep(gap)
t = Thread(target=keep_alive)
t.start()
- self.lastreport['time'] = time.time()
while not self.terminate:
self.crawl()
def add_job(self, path, label, job, *a, **kw):
- """insert @job function to job table at @path with @label"""
if self.jobtab.get(path) == None:
self.jobtab[path] = []
self.jobtab[path].append((label, a, lambda : job(*a, **kw)))
def add_failjob(self, path, label):
- """invoke .add_job with a job that does nothing just fails"""
logging.debug('salvaged: ' + label)
self.add_job(path, label, lambda: False)
def wait(self, path, *args):
- """perform jobs registered for @path
-
- Reset jobtab entry for @path,
- determine success as the conjuction of
- success of all the jobs. In case of
- success, call .sendmark on @path
- """
jobs = self.jobtab.pop(path, [])
succeed = True
for j in jobs:
@@ -567,29 +136,12 @@ class GMasterBase(object):
return succeed
def sendmark(self, path, mark, adct=None):
- """update slave side xtime for @path to master side xtime
-
- also can send a setattr payload (see Server.setattr).
- """
if adct:
self.slave.server.setattr(path, adct)
- self.set_slave_xtime(path, mark)
+ self.slave.server.set_xtime(path, self.uuid, mark)
@staticmethod
def volinfo_state_machine(volinfo_state, volinfo_sys):
- """compute new volinfo_state from old one and incoming
- as of current system state, also indicating if there was a
- change regarding which volume mark is the authoritative one
-
- @volinfo_state, @volinfo_sys are pairs of volume mark dicts
- (foreign, native).
-
- Note this method is marked as static, ie. the computation is
- pure, without reliance on any excess implicit state. State
- transitions which are deemed as ambiguous or banned will raise
- an exception.
-
- """
# store the value below "boxed" to emulate proper closures
# (variables of the enclosing scope are available inner functions
# provided they are no reassigned; mutation is OK).
@@ -605,7 +157,7 @@ class GMasterBase(object):
return vi
if vi0 and vi and vi0['uuid'] != vi['uuid'] and not param.relax_mismatch:
# uuid mismatch for master candidate, bail out
- raise GsyncdError("aborting on uuid change from %s to %s" % \
+ raise RuntimeError("aborting on uuid change from %s to %s" % \
(vi0['uuid'], vi['uuid']))
# fall back to old
return vi0
@@ -616,82 +168,33 @@ class GMasterBase(object):
return newstate, param.state_change
def crawl(self, path='.', xtl=None):
- """crawling...
-
- Standing around
- All the right people
- Crawling
- Tennis on Tuesday
- The ladder is long
- It is your nature
- You've gotta suntan
- Football on Sunday
- Society boy
-
- Recursively walk the master side tree and check if updates are
- needed due to xtime differences. One invocation of crawl checks
- children of @path and do a recursive enter only on
- those directory children where there is an update needed.
-
- Way of updates depend on file type:
- - for symlinks, sync them directy and synchronously
- - for regular children, register jobs for @path (cf. .add_job) to start
- and wait on their rsync
- - for directory children, register a job for @path which waits (.wait)
- on jobs for the given child
- (other kind of filesystem nodes are not considered)
-
- Those slave side children which do not exist on master are simply
- purged (see Server.purge).
-
- Behavior is fault tolerant, synchronization is adaptive: if some action fails,
- just go on relentlessly, adding a fail job (see .add_failjob) which will prevent
- the .sendmark on @path, so when the next crawl will arrive to @path it will not
- see it as up-to-date and will try to sync it again. While this semantics can be
- supported by funky design principles (http://c2.com/cgi/wiki?LazinessImpatienceHubris),
- the ultimate reason which excludes other possibilities is simply transience: we cannot
- assert that the file systems (master / slave) underneath do not change and actions
- taken upon some condition will not lose their context by the time they are performed.
- """
if path == '.':
if self.start:
- self.crawls += 1
- logging.debug("... crawl #%d done, took %.6f seconds" % \
- (self.crawls, time.time() - self.start))
+ logging.info("... done, took %.6f seconds" % (time.time() - self.start))
time.sleep(1)
self.start = time.time()
- should_display_info = self.start - self.lastreport['time'] >= 60
- if should_display_info:
- logging.info("completed %d crawls, %d turns",
- self.crawls - self.lastreport['crawls'],
- self.turns - self.lastreport['turns'])
- self.lastreport.update(crawls = self.crawls,
- turns = self.turns,
- time = self.start)
- volinfo_sys, state_change = self.volinfo_hook()
+ volinfo_sys = self.get_sys_volinfo()
+ self.volinfo_state, state_change = self.volinfo_state_machine(self.volinfo_state,
+ volinfo_sys)
if self.inter_master:
self.volinfo = volinfo_sys[self.KFGN]
else:
self.volinfo = volinfo_sys[self.KNAT]
if state_change == self.KFGN or (state_change == self.KNAT and not self.inter_master):
logging.info('new master is %s', self.uuid)
- if self.volinfo:
- logging.info("%s master with volume id %s ..." % \
- (self.inter_master and "intermediate" or "primary",
- self.uuid))
if state_change == self.KFGN:
gconf.configinterface.set('volume_id', self.uuid)
if self.volinfo:
if self.volinfo['retval']:
- raise GsyncdError ("master is corrupt")
- self.start_checkpoint_thread()
+ raise RuntimeError ("master is corrupt")
+ logging.info("%s master with volume id %s ..." % \
+ (self.inter_master and "intermediate" or "primary", self.uuid))
else:
- if should_display_info or self.crawls == 0:
- if self.inter_master:
- logging.info("waiting for being synced from %s ..." % \
- self.volinfo_state[self.KFGN]['uuid'])
- else:
- logging.info("waiting for volume info ...")
+ if self.inter_master:
+ logging.info("waiting for being synced from %s ..." % \
+ self.volinfo_state[self.KFGN]['uuid'])
+ else:
+ logging.info("waiting for volume info ...")
return
logging.debug("entering " + path)
if not xtl:
@@ -699,28 +202,28 @@ class GMasterBase(object):
if isinstance(xtl, int):
self.add_failjob(path, 'no-local-node')
return
- xtr = self.xtime(path, self.slave)
- if isinstance(xtr, int):
- if xtr != ENOENT:
+ xtr0 = self.xtime(path, self.slave)
+ if isinstance(xtr0, int):
+ if xtr0 != ENOENT:
self.slave.server.purge(path)
try:
self.slave.server.mkdir(path)
except OSError:
self.add_failjob(path, 'no-remote-node')
return
- xtr = self.minus_infinity
+ xtr = URXTIME
else:
- self.xtime_reversion_hook(path, xtl, xtr)
+ xtr = xtr0
+ if xtr > xtl:
+ raise RuntimeError("timestamp corruption for " + path)
if xtl == xtr:
- if path == '.' and self.change_seen:
+ if path == '.' and self.total_turns and self.change_seen:
self.turns += 1
self.change_seen = False
- if self.total_turns:
- logging.info("finished turn #%s/%s" % \
- (self.turns, self.total_turns))
- if self.turns == self.total_turns:
- logging.info("reached turn limit")
- self.terminate = True
+ logging.info("finished turn #%s/%s" % (self.turns, self.total_turns))
+ if self.turns == self.total_turns:
+ logging.info("reached turn limit")
+ self.terminate = True
return
if path == '.':
self.change_seen = True
@@ -729,7 +232,6 @@ class GMasterBase(object):
except OSError:
self.add_failjob(path, 'local-entries-fail')
return
- random.shuffle(dem)
try:
des = self.slave.server.entries(path)
except OSError:
@@ -742,14 +244,14 @@ class GMasterBase(object):
return
dd = set(des) - set(dem)
if dd:
- self.purge_missing(path, dd)
+ self.slave.server.purge(path, dd)
chld = []
for e in dem:
e = os.path.join(path, e)
xte = self.xtime(e)
if isinstance(xte, int):
logging.warn("irregular xtime for %s: %s" % (e, errno.errorcode[xte]))
- elif self.need_sync(e, xte, xtr):
+ elif xte > xtr:
chld.append((e, xte))
def indulgently(e, fnc, blame=None):
if not blame:
@@ -759,7 +261,7 @@ class GMasterBase(object):
except (IOError, OSError):
ex = sys.exc_info()[1]
if ex.errno == ENOENT:
- logging.warn("salvaged ENOENT for " + e)
+ logging.warn("salvaged ENOENT for" + e)
self.add_failjob(blame, 'by-indulgently')
return False
else:
@@ -780,10 +282,10 @@ class GMasterBase(object):
def regjob(e, xte, pb):
if pb.wait():
logging.debug("synced " + e)
- self.sendmark_regular(e, xte)
+ self.sendmark(e, xte)
return True
else:
- logging.warn("failed to sync " + e)
+ logging.error("failed to sync " + e)
self.add_job(path, 'reg', regjob, e, xte, pb)
elif stat.S_ISDIR(mo):
adct['mode'] = mo
@@ -801,18 +303,14 @@ class BoxClosedErr(Exception):
pass
class PostBox(list):
- """synchronized collection for storing things thought of as "requests" """
def __init__(self, *a):
list.__init__(self, *a)
- # too bad Python stdlib does not have read/write locks...
- # it would suffivce to grab the lock in .append as reader, in .close as writer
self.lever = Condition()
self.open = True
self.done = False
def wait(self):
- """wait on requests to be processed"""
self.lever.acquire()
if not self.done:
self.lever.wait()
@@ -820,7 +318,6 @@ class PostBox(list):
return self.result
def wakeup(self, data):
- """wake up requestors with the result"""
self.result = data
self.lever.acquire()
self.done = True
@@ -828,7 +325,6 @@ class PostBox(list):
self.lever.release()
def append(self, e):
- """post a request"""
self.lever.acquire()
if not self.open:
raise BoxClosedErr
@@ -836,43 +332,13 @@ class PostBox(list):
self.lever.release()
def close(self):
- """prohibit the posting of further requests"""
self.lever.acquire()
self.open = False
self.lever.release()
class Syncer(object):
- """a staged queue to relay rsync requests to rsync workers
-
- By "staged queue" its meant that when a consumer comes to the
- queue, it takes _all_ entries, leaving the queue empty.
- (I don't know if there is an official term for this pattern.)
-
- The queue uses a PostBox to accumulate incoming items.
- When a consumer (rsync worker) comes, a new PostBox is
- set up and the old one is passed on to the consumer.
-
- Instead of the simplistic scheme of having one big lock
- which synchronizes both the addition of new items and
- PostBox exchanges, use a separate lock to arbitrate consumers,
- and rely on PostBox's synchronization mechanisms take
- care about additions.
-
- There is a corner case racy situation, producers vs. consumers,
- which is not handled by this scheme: namely, when the PostBox
- exchange occurs in between being passed to the producer for posting
- and the post placement. But that's what Postbox.close is for:
- such a posting will find the PostBox closed, in which case
- the producer can re-try posting against the actual PostBox of
- the queue.
-
- To aid accumlation of items in the PostBoxen before grabbed
- by an rsync worker, the worker goes to sleep a bit after
- each completed syncjob.
- """
def __init__(self, slave):
- """spawn worker threads"""
self.slave = slave
self.lock = Lock()
self.pb = PostBox()
@@ -881,7 +347,6 @@ class Syncer(object):
t.start()
def syncjob(self):
- """the life of a worker"""
while True:
pb = None
while True:
@@ -893,21 +358,12 @@ class Syncer(object):
break
time.sleep(0.5)
pb.close()
- po = self.slave.rsync(pb)
- if po.returncode == 0:
- ret = True
- elif po.returncode in (23, 24):
- # partial transfer (cf. rsync(1)), that's normal
- ret = False
- else:
- po.errfail()
- pb.wakeup(ret)
+ pb.wakeup(self.slave.rsync(pb))
def add(self, e):
while True:
- pb = self.pb
try:
- pb.append(e)
- return pb
+ self.pb.append(e)
+ return self.pb
except BoxClosedErr:
pass
diff --git a/xlators/features/marker/utils/syncdaemon/monitor.py b/xlators/features/marker/utils/syncdaemon/monitor.py
index b8956dcc2..a86acdc75 100644
--- a/xlators/features/marker/utils/syncdaemon/monitor.py
+++ b/xlators/features/marker/utils/syncdaemon/monitor.py
@@ -1,20 +1,18 @@
import os
import sys
import time
-import signal
import logging
+import select
+from signal import SIGKILL
from gconf import gconf
-from syncdutils import update_file, select, waitpid, set_term_handler
+from syncdutils import update_file
class Monitor(object):
- """class which spawns and manages gsyncd workers"""
def __init__(self):
self.state = None
def set_state(self, state):
- """set the state that can be used by external agents
- like glusterd for status reporting"""
if state == self.state:
return
self.state = state
@@ -23,37 +21,6 @@ class Monitor(object):
update_file(gconf.state_file, lambda f: f.write(state + '\n'))
def monitor(self):
- """the monitor loop
-
- Basic logic is a blantantly simple blunt heuristics:
- if spawned client survives 60 secs, it's considered OK.
- This servers us pretty well as it's not vulneralbe to
- any kind of irregular behavior of the child...
-
- ... well, except for one: if children is hung up on
- waiting for some event, it can survive aeons, still
- will be defunct. So we tweak the above logic to
- expect the worker to send us a signal within 60 secs
- (in the form of closing its end of a pipe). The worker
- does this when it's done with the setup stage
- ready to enter the service loop (note it's the setup
- stage which is vulnerable to hangs -- the full
- blown worker blows up on EPIPE if the net goes down,
- due to the keep-alive thread)
- """
- def sigcont_handler(*a):
- """
- Re-init logging and send group kill signal
- """
- md = gconf.log_metadata
- logging.shutdown()
- lcls = logging.getLoggerClass()
- lcls.setup(label=md.get('saved_label'), **md)
- pid = os.getpid()
- os.kill(-pid, signal.SIGUSR1)
- signal.signal(signal.SIGUSR1, lambda *a: ())
- signal.signal(signal.SIGCONT, sigcont_handler)
-
argv = sys.argv[:]
for o in ('-N', '--no-daemon', '--monitor'):
while o in argv:
@@ -64,18 +31,13 @@ class Monitor(object):
self.set_state('starting...')
ret = 0
def nwait(p, o=0):
- p2, r = waitpid(p, o)
+ p2, r = os.waitpid(p, o)
if not p2:
return
- return r
- def exit_signalled(s):
- """ child teminated due to receipt of SIGUSR1 """
- return (os.WIFSIGNALED(s) and (os.WTERMSIG(s) == signal.SIGUSR1))
- def exit_status(s):
- if os.WIFEXITED(s):
- return os.WEXITSTATUS(s)
+ if os.WIFEXITED(r):
+ return os.WEXITSTATUS(r)
return 1
- conn_timeout = int(gconf.connection_timeout)
+ conn_timeout = 60
while ret in (0, 1):
logging.info('-' * conn_timeout)
logging.info('starting gsyncd worker')
@@ -86,44 +48,27 @@ class Monitor(object):
os.execv(sys.executable, argv + ['--feedback-fd', str(pw)])
os.close(pw)
t0 = time.time()
- so = select((pr,), (), (), conn_timeout)[0]
+ select.select((pr,), (), (), conn_timeout)
os.close(pr)
- if so:
+ et = time.time() - t0
+ if et < conn_timeout:
+ et2 = conn_timeout - et
+ logging.debug("worker got connected in %d sec, "
+ "waiting %d more to make sure it's fine" % (et, et2))
+ time.sleep(et2)
ret = nwait(cpid, os.WNOHANG)
- if ret != None:
- logging.debug("worker died before establishing connection")
- else:
- logging.debug("worker seems to be connected (?? racy check)")
- while time.time() < t0 + conn_timeout:
- ret = nwait(cpid, os.WNOHANG)
- if ret != None:
- logging.debug("worker died in startup phase")
- break
- time.sleep(1)
else:
- logging.debug("worker not confirmed in %d sec, aborting it" % \
- conn_timeout)
- # relax one SIGTERM by setting a handler that sets back
- # standard handler
- set_term_handler(lambda *a: set_term_handler())
- # give a chance to graceful exit
- os.kill(-os.getpid(), signal.SIGTERM)
- time.sleep(1)
- os.kill(cpid, signal.SIGKILL)
+ logging.debug("worker not confirmed in %d sec, aborting it" % et)
+ os.kill(cpid, SIGKILL)
ret = nwait(cpid)
if ret == None:
self.set_state('OK')
ret = nwait(cpid)
- if exit_signalled(ret):
- ret = 0
- else:
- ret = exit_status(ret)
- if ret in (0,1):
- self.set_state('faulty')
+ elif ret in (0, 1):
+ self.set_state('faulty')
time.sleep(10)
self.set_state('inconsistent')
return ret
def monitor():
- """oh yeah, actually Monitor is used as singleton, too"""
return Monitor().monitor()
diff --git a/xlators/features/marker/utils/syncdaemon/repce.py b/xlators/features/marker/utils/syncdaemon/repce.py
index 755fb61df..47691301e 100644
--- a/xlators/features/marker/utils/syncdaemon/repce.py
+++ b/xlators/features/marker/utils/syncdaemon/repce.py
@@ -1,5 +1,6 @@
import os
import sys
+import select
import time
import logging
from threading import Condition
@@ -19,7 +20,7 @@ except ImportError:
# py 3
import pickle
-from syncdutils import Thread, select
+from syncdutils import Thread
pickle_proto = -1
repce_version = 1.0
@@ -35,39 +36,21 @@ def ioparse(i, o):
return (i, o)
def send(out, *args):
- """pickle args and write out wholly in one syscall
-
- ie. not use the ability of pickle to dump directly to
- a stream, as that would potentially mess up messages
- by interleaving them
- """
os.write(out, pickle.dumps(args, pickle_proto))
def recv(inf):
- """load an object from input stream"""
return pickle.load(inf)
class RepceServer(object):
- """RePCe is Hungarian for canola, http://hu.wikipedia.org/wiki/Repce
-
- ... also our homebrewed RPC backend where the transport layer is
- reduced to a pair of filehandles.
-
- This is the server component.
- """
def __init__(self, obj, i, o, wnum=6):
- """register a backend object .obj to which incoming messages
- are dispatched, also incoming/outcoming streams
- """
self.obj = obj
self.inf, self.out = ioparse(i, o)
self.wnum = wnum
self.q = Queue()
def service_loop(self):
- """fire up worker threads, get messages and dispatch among them"""
for i in range(self.wnum):
t = Thread(target=self.worker)
t.start()
@@ -78,15 +61,6 @@ class RepceServer(object):
logging.info("terminating on reaching EOF.")
def worker(self):
- """life of a worker
-
- Get message, extract its id, method name and arguments
- (kwargs not supported), call method on .obj.
- Send back message id + return value.
- If method call throws an exception, rescue it, and send
- back the exception as result (with flag marking it as
- exception).
- """
while True:
in_data = self.q.get(True)
rid = in_data[0]
@@ -105,14 +79,8 @@ class RepceServer(object):
class RepceJob(object):
- """class representing message status we can use
- for waiting on reply"""
def __init__(self, cbk):
- """
- - .rid: (process-wise) unique id
- - .cbk: what we do upon receiving reply
- """
self.rid = (os.getpid(), thread.get_ident(), time.time())
self.cbk = cbk
self.lever = Condition()
@@ -137,13 +105,6 @@ class RepceJob(object):
class RepceClient(object):
- """RePCe is Hungarian for canola, http://hu.wikipedia.org/wiki/Repce
-
- ... also our homebrewed RPC backend where the transport layer is
- reduced to a pair of filehandles.
-
- This is the client component.
- """
def __init__(self, i, o):
self.inf, self.out = ioparse(i, o)
@@ -153,18 +114,13 @@ class RepceClient(object):
def listen(self):
while True:
- select((self.inf,), (), ())
+ select.select((self.inf,), (), ())
rid, exc, res = recv(self.inf)
rjob = self.jtab.pop(rid)
if rjob.cbk:
rjob.cbk(rjob, [exc, res])
def push(self, meth, *args, **kw):
- """wrap arguments in a RepceJob, send them to server
- and return the RepceJob
-
- @cbk to pass on RepceJob can be given as kwarg.
- """
cbk = kw.get('cbk')
if not cbk:
def cbk(rj, res):
@@ -177,11 +133,6 @@ class RepceClient(object):
return rjob
def __call__(self, meth, *args):
- """RePCe client is callabe, calling it implements a synchronous remote call
-
- We do a .push with a cbk which does a wakeup upon receiving anwser, then wait
- on the RepceJob.
- """
rjob = self.push(meth, *args, **{'cbk': lambda rj, res: rj.wakeup(res)})
exc, res = rjob.wait()
if exc:
@@ -191,11 +142,7 @@ class RepceClient(object):
return res
class mprx(object):
- """method proxy, standard trick to implement rubyesque method_missing
- in Python
- A class is a closure factory, you know what I mean, or go read some SICP.
- """
def __init__(self, ins, meth):
self.ins = ins
self.meth = meth
@@ -204,19 +151,9 @@ class RepceClient(object):
return self.ins(self.meth, *a)
def __getattr__(self, meth):
- """this implements transparent method dispatch to remote object,
- so that you don't need to call the RepceClient instance like
-
- rclient('how_old_are_you_if_born_in', 1979)
-
- but you can make it into an ordinary method call like
-
- rclient.how_old_are_you_if_born_in(1979)
- """
return self.mprx(self, meth)
def __version__(self):
- """used in handshake to verify compatibility"""
d = {'proto': self('__repce_version__')}
try:
d['object'] = self('version')
diff --git a/xlators/features/marker/utils/syncdaemon/resource.py b/xlators/features/marker/utils/syncdaemon/resource.py
index 47e4748df..800d297ba 100644
--- a/xlators/features/marker/utils/syncdaemon/resource.py
+++ b/xlators/features/marker/utils/syncdaemon/resource.py
@@ -1,44 +1,31 @@
import re
import os
import sys
+import pwd
import stat
import time
-import fcntl
import errno
import struct
+import select
import socket
import logging
import tempfile
-import threading
-import subprocess
from errno import EEXIST, ENOENT, ENODATA, ENOTDIR, ELOOP, EISDIR
-from select import error as selecterror
from gconf import gconf
import repce
from repce import RepceServer, RepceClient
-from master import gmaster_builder
+from master import GMaster
import syncdutils
-from syncdutils import GsyncdError, select, privileged, boolify
-UrlRX = re.compile('\A(\w+)://([^ *?[]*)\Z')
+UrlRX = re.compile('\A(\w+)://(.*)')
HostRX = re.compile('[a-z\d](?:[a-z\d.-]*[a-z\d])?', re.I)
UserRX = re.compile("[\w!\#$%&'*+-\/=?^_`{|}~]+")
def sup(x, *a, **kw):
- """a rubyesque "super" for python ;)
-
- invoke caller method in parent class with given args.
- """
return getattr(super(type(x), x), sys._getframe(1).f_code.co_name)(*a, **kw)
def desugar(ustr):
- """transform sugared url strings to standard <scheme>://<urlbody> form
-
- parsing logic enforces the constraint that sugared forms should contatin
- a ':' or a '/', which ensures that sugared urls do not conflict with
- gluster volume names.
- """
m = re.match('([^:]*):(.*)', ustr)
if m:
if not m.groups()[0]:
@@ -49,52 +36,29 @@ def desugar(ustr):
return "gluster://" + ustr
else:
if ustr[0] != '/':
- raise GsyncdError("cannot resolve sugared url '%s'" % ustr)
+ raise RuntimeError("cannot resolve sugared url '%s'" % ustr)
ap = os.path.normpath(ustr)
if ap.startswith('//'):
ap = ap[1:]
return "file://" + ap
-def gethostbyname(hnam):
- """gethostbyname wrapper"""
- try:
- return socket.gethostbyname(hnam)
- except socket.gaierror:
- ex = sys.exc_info()[1]
- raise GsyncdError("failed to resolve %s: %s" % \
- (hnam, ex.strerror))
-
def parse_url(ustr):
- """instantiate an url object by scheme-to-class dispatch
-
- The url classes taken into consideration are the ones in
- this module whose names are full-caps.
- """
m = UrlRX.match(ustr)
if not m:
ustr = desugar(ustr)
m = UrlRX.match(ustr)
if not m:
- raise GsyncdError("malformed url")
+ raise RuntimeError("malformed url")
sch, path = m.groups()
this = sys.modules[__name__]
if not hasattr(this, sch.upper()):
- raise GsyncdError("unknown url scheme " + sch)
+ raise RuntimeError("unknown url scheme " + sch)
return getattr(this, sch.upper())(path)
class _MetaXattr(object):
- """singleton class, a lazy wrapper around the
- libcxattr module
-
- libcxattr (a heavy import due to ctypes) is
- loaded only when when the single
- instance is tried to be used.
- This reduces runtime for those invocations
- which do not need filesystem manipulation
- (eg. for config, url parsing)
- """
+ # load Xattr stuff on-demand
def __getattr__(self, meth):
from libcxattr import Xattr as LXattr
@@ -108,194 +72,22 @@ class _MetaXattr(object):
Xattr = _MetaXattr()
-class Popen(subprocess.Popen):
- """customized subclass of subprocess.Popen with a ring
- buffer for children error output"""
-
- @classmethod
- def init_errhandler(cls):
- """start the thread which handles children's error output"""
- cls.errstore = {}
- def tailer():
- while True:
- errstore = cls.errstore.copy()
- try:
- poe, _ ,_ = select([po.stderr for po in errstore], [], [], 1)
- except ValueError, selecterror:
- continue
- for po in errstore:
- if po.stderr not in poe:
- continue
- po.lock.acquire()
- try:
- if po.on_death_row:
- continue
- la = errstore[po]
- try:
- fd = po.stderr.fileno()
- except ValueError: # file is already closed
- continue
- l = os.read(fd, 1024)
- if not l:
- continue
- tots = len(l)
- for lx in la:
- tots += len(lx)
- while tots > 1<<20 and la:
- tots -= len(la.pop(0))
- la.append(l)
- finally:
- po.lock.release()
- t = syncdutils.Thread(target = tailer)
- t.start()
- cls.errhandler = t
-
- @classmethod
- def fork(cls):
- """fork wrapper that restarts errhandler thread in child"""
- pid = os.fork()
- if not pid:
- cls.init_errhandler()
- return pid
-
- def __init__(self, args, *a, **kw):
- """customizations for subprocess.Popen instantiation
-
- - 'close_fds' is taken to be the default
- - if child's stderr is chosen to be managed,
- register it with the error handler thread
- """
- self.args = args
- if 'close_fds' not in kw:
- kw['close_fds'] = True
- self.lock = threading.Lock()
- self.on_death_row = False
- try:
- sup(self, args, *a, **kw)
- except:
- ex = sys.exc_info()[1]
- if not isinstance(ex, OSError):
- raise
- raise GsyncdError("""execution of "%s" failed with %s (%s)""" % \
- (args[0], errno.errorcode[ex.errno], os.strerror(ex.errno)))
- if kw.get('stderr') == subprocess.PIPE:
- assert(getattr(self, 'errhandler', None))
- self.errstore[self] = []
-
- def errlog(self):
- """make a log about child's failure event"""
- filling = ""
- if self.elines:
- filling = ", saying:"
- logging.error("""command "%s" returned with %s%s""" % \
- (" ".join(self.args), repr(self.returncode), filling))
- lp = ''
- def logerr(l):
- logging.error(self.args[0] + "> " + l)
- for l in self.elines:
- ls = l.split('\n')
- ls[0] = lp + ls[0]
- lp = ls.pop()
- for ll in ls:
- logerr(ll)
- if lp:
- logerr(lp)
-
- def errfail(self):
- """fail nicely if child did not terminate with success"""
- self.errlog()
- syncdutils.finalize(exval = 1)
-
- def terminate_geterr(self, fail_on_err = True):
- """kill child, finalize stderr harvesting (unregister
- from errhandler, set up .elines), fail on error if
- asked for
- """
- self.lock.acquire()
- try:
- self.on_death_row = True
- finally:
- self.lock.release()
- elines = self.errstore.pop(self)
- if self.poll() == None:
- self.terminate()
- if self.poll() == None:
- time.sleep(0.1)
- self.kill()
- self.wait()
- while True:
- if not select([self.stderr],[],[],0.1)[0]:
- break
- b = os.read(self.stderr.fileno(), 1024)
- if b:
- elines.append(b)
- else:
- break
- self.stderr.close()
- self.elines = elines
- if fail_on_err and self.returncode != 0:
- self.errfail()
-
-
class Server(object):
- """singleton implemening those filesystem access primitives
- which are needed for geo-replication functionality
- (Singleton in the sense it's a class which has only static
- and classmethods and is used directly, without instantiation.)
- """
-
- GX_NSPACE = (privileged() and "trusted" or "system") + ".glusterfs"
+ GX_NSPACE = "trusted.glusterfs"
NTV_FMTSTR = "!" + "B"*19 + "II"
FRGN_XTRA_FMT = "I"
FRGN_FMTSTR = NTV_FMTSTR + FRGN_XTRA_FMT
- def _pathguard(f):
- """decorator method that checks
- the path argument of the decorated
- functions to make sure it does not
- point out of the managed tree
- """
-
- fc = getattr(f, 'func_code', None)
- if not fc:
- # python 3
- fc = f.__code__
- pi = list(fc.co_varnames).index('path')
- def ff(*a):
- path = a[pi]
- ps = path.split('/')
- if path[0] == '/' or '..' in ps:
- raise ValueError('unsafe path')
- return f(*a)
- return ff
-
@staticmethod
- @_pathguard
def entries(path):
- """directory entries in an array"""
# prevent symlinks being followed
if not stat.S_ISDIR(os.lstat(path).st_mode):
raise OSError(ENOTDIR, os.strerror(ENOTDIR))
return os.listdir(path)
@classmethod
- @_pathguard
def purge(cls, path, entries=None):
- """force-delete subtrees
-
- If @entries is not specified, delete
- the whole subtree under @path (including
- @path).
-
- Otherwise, @entries should be a
- a sequence of children of @path, and
- the effect is identical with a joint
- @entries-less purge on them, ie.
-
- for e in entries:
- cls.purge(os.path.join(path, e))
- """
me_also = entries == None
if not entries:
try:
@@ -329,9 +121,7 @@ class Server(object):
os.rmdir(path)
@classmethod
- @_pathguard
def _create(cls, path, ctor):
- """path creation backend routine"""
try:
ctor(path)
except OSError:
@@ -342,25 +132,15 @@ class Server(object):
raise
@classmethod
- @_pathguard
def mkdir(cls, path):
cls._create(path, os.mkdir)
@classmethod
- @_pathguard
def symlink(cls, lnk, path):
cls._create(path, lambda p: os.symlink(lnk, p))
@classmethod
- @_pathguard
def xtime(cls, path, uuid):
- """query xtime extended attribute
-
- Return xtime of @path for @uuid as a pair of integers.
- "Normal" errors due to non-existent @path or extended attribute
- are tolerated and errno is returned in such a case.
- """
-
try:
return struct.unpack('!II', Xattr.lgetxattr(path, '.'.join([cls.GX_NSPACE, uuid, 'xtime']), 8))
except OSError:
@@ -371,46 +151,11 @@ class Server(object):
raise
@classmethod
- def xtime_vec(cls, path, *uuids):
- """vectored version of @xtime
-
- accepts a list of uuids and returns a dictionary
- with uuid as key(s) and xtime as value(s)
- """
- xt = {}
- for uuid in uuids:
- xtu = cls.xtime(path, uuid)
- if xtu == ENODATA:
- xtu = None
- if isinstance(xtu, int):
- return xtu
- xt[uuid] = xtu
- return xt
-
- @classmethod
- @_pathguard
def set_xtime(cls, path, uuid, mark):
- """set @mark as xtime for @uuid on @path"""
Xattr.lsetxattr(path, '.'.join([cls.GX_NSPACE, uuid, 'xtime']), struct.pack('!II', *mark))
- @classmethod
- def set_xtime_vec(cls, path, mark_dct):
- """vectored (or dictered) version of set_xtime
-
- ignore values that match @ignore
- """
- for u,t in mark_dct.items():
- cls.set_xtime(path, u, t)
-
@staticmethod
- @_pathguard
def setattr(path, adct):
- """set file attributes
-
- @adct is a dict, where 'own', 'mode' and 'times'
- keys are looked for and values used to perform
- chown, chmod or utimes on @path.
- """
own = adct.get('own')
if own:
os.lchown(path, *own)
@@ -428,14 +173,6 @@ class Server(object):
last_keep_alive = 0
@classmethod
def keep_alive(cls, dct):
- """process keepalive messages.
-
- Return keep-alive counter (number of received keep-alive
- messages).
-
- Now the "keep-alive" message can also have a payload which is
- used to set a foreign volume-mark on the underlying file system.
- """
if dct:
key = '.'.join([cls.GX_NSPACE, 'volume-mark', dct['uuid']])
val = struct.pack(cls.FRGN_FMTSTR,
@@ -448,37 +185,17 @@ class Server(object):
@staticmethod
def version():
- """version used in handshake"""
return 1.0
class SlaveLocal(object):
- """mix-in class to implement some factes of a slave server
-
- ("mix-in" is sort of like "abstract class", ie. it's not
- instantiated just included in the ancesty DAG. I use "mix-in"
- to indicate that it's not used as an abstract base class,
- rather just taken in to implement additional functionality
- on the basis of the assumed availability of certain interfaces.)
- """
def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
return not remote
def service_loop(self):
- """start a RePCe server serving self's server
-
- stop servicing if a timeout is configured and got no
- keep-alime in that inteval
- """
-
- if boolify(gconf.use_rsync_xattrs) and not privileged():
- raise GsyncdError("using rsync for extended attributes is not supported")
-
repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs))
- t = syncdutils.Thread(target=lambda: (repce.service_loop(),
- syncdutils.finalize()))
+ t = syncdutils.Thread(target=repce.service_loop)
t.start()
logging.info("slave listening")
if gconf.timeout and int(gconf.timeout) > 0:
@@ -489,37 +206,33 @@ class SlaveLocal(object):
logging.info("connection inactive for %d seconds, stopping" % int(gconf.timeout))
break
else:
- select((), (), ())
+ select.select((), (), ())
class SlaveRemote(object):
- """mix-in class to implement an interface to a remote slave"""
def connect_remote(self, rargs=[], **opts):
- """connects to a remote slave
-
- Invoke an auxiliary utility (slave gsyncd, possibly wrapped)
- which sets up the connection and set up a RePCe client to
- communicate throuh its stdio.
- """
slave = opts.get('slave', self.url)
- extra_opts = []
- so = getattr(gconf, 'session_owner', None)
- if so:
- extra_opts += ['--session-owner', so]
- if boolify(gconf.use_rsync_xattrs):
- extra_opts.append('--use-rsync-xattrs')
- po = Popen(rargs + gconf.remote_gsyncd.split() + extra_opts + \
- ['-N', '--listen', '--timeout', str(gconf.timeout), slave],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- gconf.transport = po
- return self.start_fd_client(po.stdout, po.stdin, **opts)
+ ix, ox = os.pipe()
+ iy, oy = os.pipe()
+ pid = os.fork()
+ if not pid:
+ os.close(ox)
+ os.dup2(ix, sys.stdin.fileno())
+ os.close(iy)
+ os.dup2(oy, sys.stdout.fileno())
+ so = getattr(gconf, 'session_owner', None)
+ if so:
+ so_args = ['--session-owner', so]
+ else:
+ so_args = []
+ argv = rargs + gconf.remote_gsyncd.split() + so_args + \
+ ['-N', '--listen', '--timeout', str(gconf.timeout), slave]
+ os.execvp(argv[0], argv)
+ os.close(ix)
+ os.close(oy)
+ return self.start_fd_client(iy, ox, **opts)
def start_fd_client(self, i, o, **opts):
- """set up RePCe client, handshake with server
-
- It's cut out as a separate method to let
- subclasses hook into client startup
- """
self.server = RepceClient(i, o)
rv = self.server.__version__()
exrv = {'proto': repce.repce_version, 'object': Server.version()}
@@ -529,29 +242,22 @@ class SlaveRemote(object):
for k, v in da0[i].iteritems():
da1[i][k] = int(v)
if da1[0] != da1[1]:
- raise GsyncdError("RePCe major version mismatch: local %s, remote %s" % (exrv, rv))
+ raise RuntimeError("RePCe major version mismatch: local %s, remote %s" % (exrv, rv))
def rsync(self, files, *args):
- """invoke rsync"""
if not files:
- raise GsyncdError("no files to sync")
+ raise RuntimeError("no files to sync")
logging.debug("files: " + ", ".join(files))
- argv = gconf.rsync_command.split() + ['-aR', '--super', '--numeric-ids', '--no-implied-dirs'] + \
- gconf.rsync_options.split() + (boolify(gconf.use_rsync_xattrs) and ['--xattrs'] or []) + \
- files + list(args)
- po = Popen(argv, stderr=subprocess.PIPE)
- po.wait()
- po.terminate_geterr(fail_on_err = False)
- return po
+ argv = gconf.rsync_command.split() + gconf.rsync_extra.split() + ['-aR'] + files + list(args)
+ return os.spawnvp(os.P_WAIT, argv[0], argv) == 0
class AbstractUrl(object):
- """abstract base class for url scheme classes"""
def __init__(self, path, pattern):
m = re.search(pattern, path)
if not m:
- raise GsyncdError("malformed path")
+ raise RuntimeError("malformed path")
self.path = path
return m.groups()
@@ -563,7 +269,6 @@ class AbstractUrl(object):
return self.path
def get_url(self, canonical=False, escaped=False):
- """format self's url in various styles"""
if canonical:
pa = self.canonical_path()
else:
@@ -582,15 +287,8 @@ class AbstractUrl(object):
class FILE(AbstractUrl, SlaveLocal, SlaveRemote):
- """scheme class for file:// urls
-
- can be used to represent a file slave server
- on slave side, or interface to a remote file
- file server on master side
- """
class FILEServer(Server):
- """included server flavor"""
pass
server = FILEServer
@@ -599,7 +297,6 @@ class FILE(AbstractUrl, SlaveLocal, SlaveRemote):
sup(self, path, '^/')
def connect(self):
- """inhibit the resource beyond"""
os.chdir(self.path)
def rsync(self, files):
@@ -607,21 +304,11 @@ class FILE(AbstractUrl, SlaveLocal, SlaveRemote):
class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
- """scheme class for gluster:// urls
-
- can be used to represent a gluster slave server
- on slave side, or interface to a remote gluster
- slave on master side, or to represent master
- (slave-ish features come from the mixins, master
- functionality is outsourced to GMaster from master)
- """
class GLUSTERServer(Server):
- "server enhancements for a glusterfs backend"""
@classmethod
def _attr_unpack_dict(cls, xattr, extra_fields = ''):
- """generic volume mark fetching/parsing backed"""
fmt_string = cls.NTV_FMTSTR + extra_fields
buf = Xattr.lgetxattr('.', xattr, struct.calcsize(fmt_string))
vm = struct.unpack(fmt_string, buf)
@@ -639,7 +326,6 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
@classmethod
def foreign_volume_infos(cls):
- """return list of valid (not expired) foreign volume marks"""
dict_list = []
xattr_list = Xattr.llistxattr_buf('.')
for ele in xattr_list:
@@ -649,7 +335,6 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
if x[0] > now:
logging.debug("volinfo[%s] expires: %d (%d sec later)" % \
(d['uuid'], x[0], x[0] - now))
- d['timeout'] = x[0]
dict_list.append(d)
else:
try:
@@ -660,7 +345,6 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
@classmethod
def native_volume_info(cls):
- """get the native volume mark of the underlying gluster volume"""
try:
return cls._attr_unpack_dict('.'.join([cls.GX_NSPACE, 'volume-mark']))
except OSError:
@@ -674,199 +358,47 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
self.host, self.volume = sup(self, path, '^(%s):(.+)' % HostRX.pattern)
def canonical_path(self):
- return ':'.join([gethostbyname(self.host), self.volume])
+ return ':'.join([socket.gethostbyname(self.host), self.volume])
def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
return True
- class Mounter(object):
- """Abstract base class for mounter backends"""
-
- def __init__(self, params):
- self.params = params
- self.mntpt = None
-
- @classmethod
- def get_glusterprog(cls):
- return os.path.join(gconf.gluster_command_dir, cls.glusterprog)
-
- def umount_l(self, d):
- """perform lazy umount"""
- po = Popen(self.make_umount_argv(d), stderr=subprocess.PIPE)
- po.wait()
- return po
-
- @classmethod
- def make_umount_argv(cls, d):
- raise NotImplementedError
-
- def make_mount_argv(self, *a):
- raise NotImplementedError
-
- def cleanup_mntpt(self, *a):
- pass
-
- def handle_mounter(self, po):
- po.wait()
-
- def inhibit(self, *a):
- """inhibit a gluster filesystem
-
- Mount glusterfs over a temporary mountpoint,
- change into the mount, and lazy unmount the
- filesystem.
- """
-
- mpi, mpo = os.pipe()
- mh = Popen.fork()
- if mh:
- os.close(mpi)
- fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
- d = None
- margv = self.make_mount_argv(*a)
- if self.mntpt:
- # mntpt is determined pre-mount
- d = self.mntpt
- os.write(mpo, d + '\0')
- po = Popen(margv, **self.mountkw)
- self.handle_mounter(po)
- po.terminate_geterr()
- logging.debug('auxiliary glusterfs mount in place')
- if not d:
- # mntpt is determined during mount
- d = self.mntpt
- os.write(mpo, d + '\0')
- os.write(mpo, 'M')
- t = syncdutils.Thread(target=lambda: os.chdir(d))
- t.start()
- tlim = gconf.starttime + int(gconf.connection_timeout)
- while True:
- if not t.isAlive():
- break
- if time.time() >= tlim:
- syncdutils.finalize(exval = 1)
- time.sleep(1)
- os.close(mpo)
- _, rv = syncdutils.waitpid(mh, 0)
- if rv:
- rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \
- (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0)
- logging.warn('stale mount possibly left behind on ' + d)
- raise GsyncdError("cleaning up temp mountpoint %s failed with status %d" % \
- (d, rv))
- else:
- rv = 0
- try:
- os.setsid()
- os.close(mpo)
- mntdata = ''
- while True:
- c = os.read(mpi, 1)
- if not c:
- break
- mntdata += c
- if mntdata:
- mounted = False
- if mntdata[-1] == 'M':
- mntdata = mntdata[:-1]
- assert(mntdata)
- mounted = True
- assert(mntdata[-1] == '\0')
- mntpt = mntdata[:-1]
- assert(mntpt)
- if mounted:
- po = self.umount_l(mntpt)
- po.terminate_geterr(fail_on_err = False)
- if po.returncode != 0:
- po.errlog()
- rv = po.returncode
- self.cleanup_mntpt(mntpt)
- except:
- logging.exception('mount cleanup failure:')
- rv = 200
- os._exit(rv)
- logging.debug('auxiliary glusterfs mount prepared')
-
- class DirectMounter(Mounter):
- """mounter backend which calls mount(8), umount(8) directly"""
-
- mountkw = {'stderr': subprocess.PIPE}
- glusterprog = 'glusterfs'
-
- @staticmethod
- def make_umount_argv(d):
- return ['umount', '-l', d]
-
- def make_mount_argv(self):
- self.mntpt = tempfile.mkdtemp(prefix = 'gsyncd-aux-mount-')
- return [self.get_glusterprog()] + ['--' + p for p in self.params] + [self.mntpt]
-
- def cleanup_mntpt(self, mntpt = None):
- if not mntpt:
- mntpt = self.mntpt
- os.rmdir(mntpt)
-
- class MountbrokerMounter(Mounter):
- """mounter backend using the mountbroker gluster service"""
-
- mountkw = {'stderr': subprocess.PIPE, 'stdout': subprocess.PIPE}
- glusterprog = 'gluster'
-
- @classmethod
- def make_cli_argv(cls):
- return [cls.get_glusterprog()] + gconf.gluster_cli_options.split() + ['system::']
-
- @classmethod
- def make_umount_argv(cls, d):
- return cls.make_cli_argv() + ['umount', d, 'lazy']
-
- def make_mount_argv(self, label):
- return self.make_cli_argv() + \
- ['mount', label, 'user-map-root=' + syncdutils.getusername()] + self.params
-
- def handle_mounter(self, po):
- self.mntpt = po.stdout.readline()[:-1]
- po.stdout.close()
- sup(self, po)
- if po.returncode != 0:
- # if cli terminated with error due to being
- # refused by glusterd, what it put
- # out on stdout is a diagnostic message
- logging.error('glusterd answered: %s' % self.mntpt)
-
def connect(self):
- """inhibit the resource beyond
-
- Choose mounting backend (direct or mountbroker),
- set up glusterfs parameters and perform the mount
- with given backend
- """
-
- label = getattr(gconf, 'mountbroker', None)
- if not label and not privileged():
- label = syncdutils.getusername()
- mounter = label and self.MountbrokerMounter or self.DirectMounter
- params = gconf.gluster_params.split() + \
- (gconf.gluster_log_level and ['log-level=' + gconf.gluster_log_level] or []) + \
- ['log-file=' + gconf.gluster_log_file, 'volfile-server=' + self.host,
- 'volfile-id=' + self.volume, 'client-pid=-1']
- mounter(params).inhibit(*[l for l in [label] if l])
+ def umount_l(d):
+ time.sleep(0.2) # XXX temporary workaround
+ argv = ['umount', '-l', d]
+ return os.spawnvp(os.P_WAIT, argv[0], argv)
+ d = tempfile.mkdtemp(prefix='gsyncd-aux-mount-')
+ mounted = False
+ try:
+ argv = gconf.gluster_command.split() + \
+ (gconf.gluster_log_level and ['-L', gconf.gluster_log_level] or []) + \
+ ['-l', gconf.gluster_log_file, '-s', self.host,
+ '--volfile-id', self.volume, '--client-pid=-1', d]
+ if os.spawnvp(os.P_WAIT, argv[0], argv):
+ raise RuntimeError("command failed: " + " ".join(argv))
+ mounted = True
+ logging.debug('auxiliary glusterfs mount in place')
+ os.chdir(d)
+ if umount_l(d) != 0:
+ raise RuntimeError("umounting %s failed" % d)
+ mounted = False
+ finally:
+ try:
+ if mounted:
+ umount_l(d)
+ os.rmdir(d)
+ except:
+ logging.warn('stale mount possibly left behind on ' + d)
+ logging.debug('auxiliary glusterfs mount prepared')
def connect_remote(self, *a, **kw):
sup(self, *a, **kw)
self.slavedir = "/proc/%d/cwd" % self.server.pid()
def service_loop(self, *args):
- """enter service loop
-
- - if slave given, instantiate GMaster and
- pass control to that instance, which implements
- master behavior
- - else do that's what's inherited
- """
if args:
- gmaster_builder()(self, args[0]).crawl_loop()
+ GMaster(self, args[0]).crawl_loop()
else:
sup(self, *args)
@@ -875,11 +407,6 @@ class GLUSTER(AbstractUrl, SlaveLocal, SlaveRemote):
class SSH(AbstractUrl, SlaveRemote):
- """scheme class for ssh:// urls
-
- interface to remote slave on master side
- implementing an ssh based proxy
- """
def __init__(self, path):
self.remote_addr, inner_url = sup(self, path,
@@ -891,21 +418,14 @@ class SSH(AbstractUrl, SlaveRemote):
if m:
u, h = m.groups()
else:
- u, h = syncdutils.getusername(), self.remote_addr
- remote_addr = '@'.join([u, gethostbyname(h)])
+ u, h = pwd.getpwuid(os.geteuid()).pw_name, self.remote_addr
+ remote_addr = '@'.join([u, socket.gethostbyname(h)])
return ':'.join([remote_addr, self.inner_rsc.get_url(canonical=True)])
def can_connect_to(self, remote):
- """determine our position in the connectibility matrix"""
return False
def start_fd_client(self, *a, **opts):
- """customizations for client startup
-
- - be a no-op if we are to daemonize (client startup is deferred
- to post-daemon stage)
- - determine target url for rsync after consulting server
- """
if opts.get('deferred'):
return a
sup(self, *a)
@@ -919,23 +439,6 @@ class SSH(AbstractUrl, SlaveRemote):
self.slaveurl = ':'.join([self.remote_addr, slavepath])
def connect_remote(self, go_daemon=None):
- """connect to inner slave url through outer ssh url
-
- Wrap the connecting utility in ssh.
-
- Much care is put into daemonizing: in that case
- ssh is started before daemonization, but
- RePCe client is to be created after that (as ssh
- interactive password auth would be defeated by
- a daemonized ssh, while client should be present
- only in the final process). In that case the action
- is taken apart to two parts, this method is ivoked
- once pre-daemon, once post-daemon. Use @go_daemon
- to deiced what part to perform.
-
- [NB. ATM gluster product does not makes use of interactive
- authentication.]
- """
if go_daemon == 'done':
return self.start_fd_client(*self.fd_pair)
gconf.setup_ssh_ctl(tempfile.mkdtemp(prefix='gsyncd-aux-ssh-'))
@@ -952,7 +455,7 @@ class SSH(AbstractUrl, SlaveRemote):
i, o = ret
inf = os.fdopen(i)
repce.send(o, None, '__repce_version__')
- select((inf,), (), ())
+ select.select((inf,), (), ())
repce.recv(inf)
# hack hack hack: store a global reference to the file
# to save it from getting GC'd which implies closing it
@@ -961,5 +464,4 @@ class SSH(AbstractUrl, SlaveRemote):
return 'should'
def rsync(self, files):
- return sup(self, files, '-e', " ".join(gconf.ssh_command.split() + gconf.ssh_ctl_args),
- *(gconf.rsync_ssh_options.split() + [self.slaveurl]))
+ return sup(self, files, '-ze', " ".join(gconf.ssh_command.split() + gconf.ssh_ctl_args), self.slaveurl)
diff --git a/xlators/features/marker/utils/syncdaemon/syncdutils.py b/xlators/features/marker/utils/syncdaemon/syncdutils.py
index 1d4eb2003..4bf51da74 100644
--- a/xlators/features/marker/utils/syncdaemon/syncdutils.py
+++ b/xlators/features/marker/utils/syncdaemon/syncdutils.py
@@ -1,21 +1,13 @@
import os
import sys
-import pwd
import time
import fcntl
import shutil
import logging
from threading import Lock, Thread as baseThread
-from errno import EACCES, EAGAIN, EPIPE, ENOTCONN, ECONNABORTED, EINTR, errorcode
-from signal import signal, SIGTERM, SIGKILL
+from errno import EACCES, EAGAIN
+from signal import SIGTERM, SIGKILL
from time import sleep
-import select as oselect
-from os import waitpid as owaitpid
-try:
- from cPickle import PickleError
-except ImportError:
- # py 3
- from pickle import PickleError
from gconf import gconf
@@ -26,12 +18,9 @@ except ImportError:
import urllib
def escape(s):
- """the chosen flavor of string escaping, used all over
- to turn whatever data to creatable representation"""
return urllib.quote_plus(s)
def unescape(s):
- """inverse of .escape"""
return urllib.unquote_plus(s)
def norm(s):
@@ -69,10 +58,6 @@ def update_file(path, updater, merger = lambda f: True):
fx.close()
def grabfile(fname, content=None):
- """open @fname + contest for its fcntl lock
-
- @content: if given, set the file content to it
- """
# damn those messy open() mode codes
fd = os.open(fname, os.O_CREAT|os.O_RDWR)
f = os.fdopen(fd, 'r+b', 0)
@@ -96,7 +81,6 @@ def grabfile(fname, content=None):
return f
def grabpidfile(fname=None, setpid=True):
- """.grabfile customization for pid files"""
if not fname:
fname = gconf.pid_file
content = None
@@ -107,10 +91,6 @@ def grabpidfile(fname=None, setpid=True):
final_lock = Lock()
def finalize(*a, **kw):
- """all those messy final steps we go trough upon termination
-
- Do away with pidfile, ssh control dir and logging.
- """
final_lock.acquire()
if getattr(gconf, 'pid_file', None):
rm_pidf = gconf.pid_file_owned
@@ -138,57 +118,18 @@ def finalize(*a, **kw):
raise
if gconf.ssh_ctl_dir and not gconf.cpid:
shutil.rmtree(gconf.ssh_ctl_dir)
- if getattr(gconf, 'state_socket', None):
- try:
- os.unlink(gconf.state_socket)
- except:
- if sys.exc_info()[0] == OSError:
- pass
- if gconf.log_exit:
- logging.info("exiting.")
sys.stdout.flush()
sys.stderr.flush()
os._exit(kw.get('exval', 0))
def log_raise_exception(excont):
- """top-level exception handler
-
- Try to some fancy things to cover up we face with an error.
- Translate some weird sounding but well understood exceptions
- into human-friendly lingo
- """
- is_filelog = False
- for h in logging.getLogger().handlers:
- fno = getattr(getattr(h, 'stream', None), 'fileno', None)
- if fno and not os.isatty(fno()):
- is_filelog = True
-
exc = sys.exc_info()[1]
if isinstance(exc, SystemExit):
excont.exval = exc.code or 0
raise
else:
- logtag = None
- if isinstance(exc, GsyncdError):
- if is_filelog:
- logging.error(exc.message)
- sys.stderr.write('failure: ' + exc.message + "\n")
- elif isinstance(exc, PickleError) or isinstance(exc, EOFError) or \
- ((isinstance(exc, OSError) or isinstance(exc, IOError)) and \
- exc.errno == EPIPE):
- logging.error('connection to peer is broken')
- if hasattr(gconf, 'transport'):
- gconf.transport.wait()
- gconf.transport.terminate_geterr()
- elif isinstance(exc, OSError) and exc.errno in (ENOTCONN, ECONNABORTED):
- logging.error('glusterfs session went down [%s]', errorcode[exc.errno])
- else:
- logtag = "FAIL"
- if not logtag and logging.getLogger().isEnabledFor(logging.DEBUG):
- logtag = "FULL EXCEPTION TRACE"
- if logtag:
- logging.exception(logtag + ": ")
- sys.stderr.write("failed with %s.\n" % type(exc).__name__)
+ logging.exception("FAIL: ")
+ sys.stderr.write("failed with %s.\n" % type(exc).__name__)
excont.exval = 1
sys.exit(excont.exval)
@@ -197,16 +138,11 @@ class FreeObject(object):
"""wildcard class for which any attribute can be set"""
def __init__(self, **kw):
- for k,v in kw.items():
+ for k,v in kw.iteritems():
setattr(self, k, v)
class Thread(baseThread):
- """thread class flavor for gsyncd
- - always a daemon thread
- - force exit for whole program if thread
- function coughs up an exception
- """
def __init__(self, *a, **kw):
tf = kw.get('target')
if tf:
@@ -222,61 +158,3 @@ class Thread(baseThread):
kw['target'] = twrap
baseThread.__init__(self, *a, **kw)
self.setDaemon(True)
-
-class GsyncdError(Exception):
- pass
-
-def getusername(uid = None):
- if uid == None:
- uid = os.geteuid()
- return pwd.getpwuid(uid).pw_name
-
-def privileged():
- return os.geteuid() == 0
-
-def boolify(s):
- """
- Generic string to boolean converter
-
- return
- - Quick return if string 's' is of type bool
- - True if it's in true_list
- - False if it's in false_list
- - Warn if it's not present in either and return False
- """
- true_list = ['true', 'yes', '1', 'on']
- false_list = ['false', 'no', '0', 'off']
-
- if isinstance(s, bool):
- return s
-
- rv = False
- lstr = s.lower()
- if lstr in true_list:
- rv = True
- elif not lstr in false_list:
- logging.warn("Unknown string (%s) in string to boolean conversion defaulting to False\n" % (s))
-
- return rv
-
-def eintr_wrap(func, exc, *a):
- """
- wrapper around syscalls resilient to interrupt caused
- by signals
- """
- while True:
- try:
- return func(*a)
- except exc:
- ex = sys.exc_info()[1]
- if not ex.args[0] == EINTR:
- raise
-
-def select(*a):
- return eintr_wrap(oselect.select, oselect.error, *a)
-
-def waitpid (*a):
- return eintr_wrap(owaitpid, OSError, *a)
-
-def set_term_handler(hook=lambda *a: finalize(*a, **{'exval': 1})):
- signal(SIGTERM, hook)
diff --git a/xlators/features/path-convertor/src/path-mem-types.h b/xlators/features/path-convertor/src/path-mem-types.h
index c071513b6..a0b4d90cc 100644
--- a/xlators/features/path-convertor/src/path-mem-types.h
+++ b/xlators/features/path-convertor/src/path-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/path-convertor/src/path.c b/xlators/features/path-convertor/src/path.c
index 22ec8fe1e..858c6b2d0 100644
--- a/xlators/features/path-convertor/src/path.c
+++ b/xlators/features/path-convertor/src/path.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -52,7 +52,7 @@ static char *
name_this_to_that (xlator_t *xl, const char *path, const char *name)
{
path_private_t *priv = xl->private;
- char priv_path[PATH_MAX] = {0,};
+ char priv_path[ZR_PATH_MAX] = {0,};
char *tmp_name = NULL;
int32_t path_len = strlen (path);
int32_t name_len = strlen (name) - ZR_FILE_CONTENT_STRLEN;
@@ -848,7 +848,8 @@ path_setxattr (call_frame_t *frame,
if (tmp_path != loc_path)
GF_FREE (tmp_path);
- GF_FREE (tmp_name);
+ if (tmp_name)
+ GF_FREE (tmp_name);
return 0;
}
diff --git a/xlators/features/quiesce/src/quiesce-mem-types.h b/xlators/features/quiesce/src/quiesce-mem-types.h
index 00f7aa4f1..f9154173a 100644
--- a/xlators/features/quiesce/src/quiesce-mem-types.h
+++ b/xlators/features/quiesce/src/quiesce-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/features/quiesce/src/quiesce.c b/xlators/features/quiesce/src/quiesce.c
index 423ec6ffb..c9828054c 100644
--- a/xlators/features/quiesce/src/quiesce.c
+++ b/xlators/features/quiesce/src/quiesce.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -34,22 +34,29 @@
void
gf_quiesce_local_wipe (xlator_t *this, quiesce_local_t *local)
{
+ quiesce_priv_t *priv = NULL;
+
if (!local || !this || !this->private)
return;
+ priv = this->private;
+
if (local->loc.inode)
loc_wipe (&local->loc);
if (local->fd)
fd_unref (local->fd);
- GF_FREE (local->name);
- GF_FREE (local->volname);
+ if (local->name)
+ GF_FREE (local->name);
+ if (local->volname)
+ GF_FREE (local->volname);
if (local->dict)
dict_unref (local->dict);
if (local->iobref)
iobref_unref (local->iobref);
- GF_FREE (local->vector);
+ if (local->vector)
+ GF_FREE (local->vector);
- mem_put (local);
+ mem_put (priv->local_pool, local);
}
call_stub_t *
@@ -101,6 +108,7 @@ gf_quiesce_timeout (void *data)
{
xlator_t *this = NULL;
quiesce_priv_t *priv = NULL;
+ int need_dequeue = 0;
this = data;
priv = this->private;
@@ -109,6 +117,7 @@ gf_quiesce_timeout (void *data)
LOCK (&priv->lock);
{
priv->pass_through = _gf_true;
+ need_dequeue = (priv->queue_size)? 1:0;
}
UNLOCK (&priv->lock);
@@ -159,9 +168,12 @@ quiesce_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
@@ -188,21 +200,23 @@ out:
int32_t
quiesce_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_stat_stub (frame, default_stat_resume,
- &local->loc, xdata);
+ &local->loc);
if (!stub) {
STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -210,7 +224,7 @@ quiesce_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
out:
gf_quiesce_local_wipe (this, local);
@@ -219,19 +233,22 @@ out:
int32_t
quiesce_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_access_stub (frame, default_access_resume,
- &local->loc, local->flag, xdata);
+ &local->loc, local->flag);
if (!stub) {
- STACK_UNWIND_STRICT (access, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (access, frame, -1, ENOMEM);
goto out;
}
@@ -239,7 +256,7 @@ quiesce_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -249,20 +266,23 @@ out:
int32_t
quiesce_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_readlink_stub (frame, default_readlink_resume,
- &local->loc, local->size, xdata);
+ &local->loc, local->size);
if (!stub) {
STACK_UNWIND_STRICT (readlink, frame, -1, ENOMEM,
- NULL, NULL, NULL);
+ NULL, NULL);
goto out;
}
@@ -270,7 +290,7 @@ quiesce_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf, xdata);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, buf);
out:
gf_quiesce_local_wipe (this, local);
@@ -279,21 +299,24 @@ out:
int32_t
quiesce_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_open_stub (frame, default_open_resume,
&local->loc, local->flag, local->fd,
- xdata);
+ local->wbflags);
if (!stub) {
STACK_UNWIND_STRICT (open, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -301,7 +324,7 @@ quiesce_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
out:
gf_quiesce_local_wipe (this, local);
@@ -311,21 +334,23 @@ out:
int32_t
quiesce_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_readv_stub (frame, default_readv_resume,
- local->fd, local->size, local->offset,
- local->io_flag, xdata);
+ local->fd, local->size, local->offset);
if (!stub) {
STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
- NULL, 0, NULL, NULL, NULL);
+ NULL, 0, NULL, NULL);
goto out;
}
@@ -334,7 +359,7 @@ quiesce_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
out:
gf_quiesce_local_wipe (this, local);
@@ -343,19 +368,22 @@ out:
int32_t
quiesce_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_flush_stub (frame, default_flush_resume,
- local->fd, xdata);
+ local->fd);
if (!stub) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
goto out;
}
@@ -363,7 +391,7 @@ quiesce_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -375,20 +403,23 @@ out:
int32_t
quiesce_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_fsync_stub (frame, default_fsync_resume,
- local->fd, local->flag, xdata);
+ local->fd, local->flag);
if (!stub) {
STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
- NULL, NULL, NULL);
+ NULL, NULL);
goto out;
}
@@ -396,7 +427,7 @@ quiesce_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
out:
gf_quiesce_local_wipe (this, local);
@@ -405,20 +436,23 @@ out:
int32_t
quiesce_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_fstat_stub (frame, default_fstat_resume,
- local->fd, xdata);
+ local->fd);
if (!stub) {
STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -426,7 +460,7 @@ quiesce_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
out:
gf_quiesce_local_wipe (this, local);
@@ -435,20 +469,23 @@ out:
int32_t
quiesce_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_opendir_stub (frame, default_opendir_resume,
- &local->loc, local->fd, xdata);
+ &local->loc, local->fd);
if (!stub) {
STACK_UNWIND_STRICT (opendir, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -456,7 +493,7 @@ quiesce_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
out:
gf_quiesce_local_wipe (this, local);
@@ -465,19 +502,22 @@ out:
int32_t
quiesce_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_fsyncdir_stub (frame, default_fsyncdir_resume,
- local->fd, local->flag, xdata);
+ local->fd, local->flag);
if (!stub) {
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM);
goto out;
}
@@ -485,7 +525,7 @@ quiesce_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -494,20 +534,23 @@ out:
int32_t
quiesce_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_statfs_stub (frame, default_statfs_resume,
- &local->loc, xdata);
+ &local->loc);
if (!stub) {
STACK_UNWIND_STRICT (statfs, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -515,7 +558,7 @@ quiesce_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
out:
gf_quiesce_local_wipe (this, local);
@@ -524,20 +567,23 @@ out:
int32_t
quiesce_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_fgetxattr_stub (frame, default_fgetxattr_resume,
- local->fd, local->name, xdata);
+ local->fd, local->name);
if (!stub) {
STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -545,7 +591,7 @@ quiesce_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
out:
gf_quiesce_local_wipe (this, local);
@@ -555,20 +601,23 @@ out:
int32_t
quiesce_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_getxattr_stub (frame, default_getxattr_resume,
- &local->loc, local->name, xdata);
+ &local->loc, local->name);
if (!stub) {
STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -576,7 +625,7 @@ quiesce_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
out:
gf_quiesce_local_wipe (this, local);
@@ -587,20 +636,23 @@ out:
int32_t
quiesce_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum, dict_t *xdata)
+ uint8_t *strong_checksum)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_rchecksum_stub (frame, default_rchecksum_resume,
- local->fd, local->offset, local->flag, xdata);
+ local->fd, local->offset, local->flag);
if (!stub) {
STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOMEM,
- 0, NULL, NULL);
+ 0, NULL);
goto out;
}
@@ -609,7 +661,7 @@ quiesce_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
+ strong_checksum);
out:
gf_quiesce_local_wipe (this, local);
@@ -619,20 +671,23 @@ out:
int32_t
quiesce_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_readdir_stub (frame, default_readdir_resume,
- local->fd, local->size, local->offset, xdata);
+ local->fd, local->size, local->offset);
if (!stub) {
STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -640,7 +695,7 @@ quiesce_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
out:
gf_quiesce_local_wipe (this, local);
@@ -650,21 +705,23 @@ out:
int32_t
quiesce_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
+ quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
quiesce_local_t *local = NULL;
+ priv = this->private;
+
local = frame->local;
frame->local = NULL;
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_readdirp_stub (frame, default_readdirp_resume,
- local->fd, local->size, local->offset,
- local->dict);
+ local->fd, local->size, local->offset);
if (!stub) {
STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -672,7 +729,7 @@ quiesce_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
out:
gf_quiesce_local_wipe (this, local);
@@ -685,7 +742,7 @@ out:
int32_t
quiesce_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -699,11 +756,10 @@ quiesce_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_writev_stub (frame, default_writev_resume,
local->fd, local->vector, local->flag,
- local->offset, local->io_flags,
- local->iobref, xdata);
+ local->offset, local->iobref);
if (!stub) {
STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM,
- NULL, NULL, NULL);
+ NULL, NULL);
goto out;
}
@@ -711,7 +767,7 @@ quiesce_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
out:
gf_quiesce_local_wipe (this, local);
@@ -720,7 +776,7 @@ out:
int32_t
quiesce_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -734,10 +790,10 @@ quiesce_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_xattrop_stub (frame, default_xattrop_resume,
&local->loc, local->xattrop_flags,
- local->dict, xdata);
+ local->dict);
if (!stub) {
STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -745,7 +801,7 @@ quiesce_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, dict);
out:
gf_quiesce_local_wipe (this, local);
@@ -754,7 +810,7 @@ out:
int32_t
quiesce_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -768,10 +824,10 @@ quiesce_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_fxattrop_stub (frame, default_fxattrop_resume,
local->fd, local->xattrop_flags,
- local->dict, xdata);
+ local->dict);
if (!stub) {
STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -779,7 +835,7 @@ quiesce_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, dict);
out:
gf_quiesce_local_wipe (this, local);
@@ -788,7 +844,7 @@ out:
int32_t
quiesce_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -801,10 +857,10 @@ quiesce_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_lk_stub (frame, default_lk_resume,
- local->fd, local->flag, &local->flock, xdata);
+ local->fd, local->flag, &local->flock);
if (!stub) {
STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM,
- NULL, NULL);
+ NULL);
goto out;
}
@@ -812,7 +868,7 @@ quiesce_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
out:
gf_quiesce_local_wipe (this, local);
@@ -821,7 +877,7 @@ out:
int32_t
quiesce_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -835,9 +891,9 @@ quiesce_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_inodelk_stub (frame, default_inodelk_resume,
local->volname, &local->loc,
- local->flag, &local->flock, xdata);
+ local->flag, &local->flock);
if (!stub) {
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM);
goto out;
}
@@ -845,7 +901,7 @@ quiesce_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -855,7 +911,7 @@ out:
int32_t
quiesce_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -869,9 +925,9 @@ quiesce_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_finodelk_stub (frame, default_finodelk_resume,
local->volname, local->fd,
- local->flag, &local->flock, xdata);
+ local->flag, &local->flock);
if (!stub) {
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM);
goto out;
}
@@ -879,7 +935,7 @@ quiesce_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -888,7 +944,7 @@ out:
int32_t
quiesce_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -902,9 +958,9 @@ quiesce_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_entrylk_stub (frame, default_entrylk_resume,
local->volname, &local->loc,
- local->name, local->cmd, local->type, xdata);
+ local->name, local->cmd, local->type);
if (!stub) {
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM);
goto out;
}
@@ -912,7 +968,7 @@ quiesce_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -921,7 +977,7 @@ out:
int32_t
quiesce_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -935,9 +991,9 @@ quiesce_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* Re-transmit (by putting in the queue) */
stub = fop_fentrylk_stub (frame, default_fentrylk_resume,
local->volname, local->fd,
- local->name, local->cmd, local->type, xdata);
+ local->name, local->cmd, local->type);
if (!stub) {
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM);
goto out;
}
@@ -945,7 +1001,7 @@ quiesce_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno);
out:
gf_quiesce_local_wipe (this, local);
@@ -955,7 +1011,7 @@ out:
int32_t
quiesce_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -968,10 +1024,10 @@ quiesce_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_setattr_stub (frame, default_setattr_resume,
- &local->loc, &local->stbuf, local->flag, xdata);
+ &local->loc, &local->stbuf, local->flag);
if (!stub) {
STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM,
- NULL, NULL, NULL);
+ NULL, NULL);
goto out;
}
@@ -980,7 +1036,7 @@ quiesce_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
out:
gf_quiesce_local_wipe (this, local);
@@ -990,7 +1046,7 @@ out:
int32_t
quiesce_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1004,10 +1060,10 @@ quiesce_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((op_ret == -1) && (op_errno == ENOTCONN)) {
/* Re-transmit (by putting in the queue) */
stub = fop_fsetattr_stub (frame, default_fsetattr_resume,
- local->fd, &local->stbuf, local->flag, xdata);
+ local->fd, &local->stbuf, local->flag);
if (!stub) {
STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM,
- NULL, NULL, NULL);
+ NULL, NULL);
goto out;
}
@@ -1016,7 +1072,7 @@ quiesce_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
out:
gf_quiesce_local_wipe (this, local);
@@ -1034,7 +1090,7 @@ int32_t
quiesce_removexattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1047,14 +1103,14 @@ quiesce_removexattr (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->removexattr,
loc,
- name, xdata);
- return 0;
+ name);
+ return 0;
}
stub = fop_removexattr_stub (frame, default_removexattr_resume,
- loc, name, xdata);
+ loc, name);
if (!stub) {
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (removexattr, frame, -1, ENOMEM);
return 0;
}
@@ -1067,7 +1123,7 @@ int32_t
quiesce_truncate (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1080,13 +1136,13 @@ quiesce_truncate (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
loc,
- offset, xdata);
- return 0;
+ offset);
+ return 0;
}
- stub = fop_truncate_stub (frame, default_truncate_resume, loc, offset, xdata);
+ stub = fop_truncate_stub (frame, default_truncate_resume, loc, offset);
if (!stub) {
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1100,7 +1156,7 @@ quiesce_fsetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1114,14 +1170,14 @@ quiesce_fsetxattr (call_frame_t *frame,
FIRST_CHILD(this)->fops->fsetxattr,
fd,
dict,
- flags, xdata);
- return 0;
+ flags);
+ return 0;
}
stub = fop_fsetxattr_stub (frame, default_fsetxattr_resume,
- fd, dict, flags, xdata);
+ fd, dict, flags);
if (!stub) {
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOMEM);
return 0;
}
@@ -1135,7 +1191,7 @@ quiesce_setxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1149,14 +1205,14 @@ quiesce_setxattr (call_frame_t *frame,
FIRST_CHILD(this)->fops->setxattr,
loc,
dict,
- flags, xdata);
- return 0;
+ flags);
+ return 0;
}
stub = fop_setxattr_stub (frame, default_setxattr_resume,
- loc, dict, flags, xdata);
+ loc, dict, flags);
if (!stub) {
- STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM);
return 0;
}
@@ -1168,7 +1224,7 @@ quiesce_setxattr (call_frame_t *frame,
int32_t
quiesce_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata)
+ fd_t *fd, dict_t *params)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1181,15 +1237,15 @@ quiesce_create (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, (flags & ~O_APPEND), mode, umask, fd, xdata);
- return 0;
+ loc, (flags & ~O_APPEND), mode, fd, params);
+ return 0;
}
stub = fop_create_stub (frame, default_create_resume,
- loc, (flags & ~O_APPEND), mode, umask, fd, xdata);
+ loc, (flags & ~O_APPEND), mode, fd, params);
if (!stub) {
STACK_UNWIND_STRICT (create, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -1202,7 +1258,7 @@ int32_t
quiesce_link (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1214,14 +1270,14 @@ quiesce_link (call_frame_t *frame,
default_link_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
+ oldloc, newloc);
+ return 0;
}
- stub = fop_link_stub (frame, default_link_resume, oldloc, newloc, xdata);
+ stub = fop_link_stub (frame, default_link_resume, oldloc, newloc);
if (!stub) {
STACK_UNWIND_STRICT (link, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -1234,7 +1290,7 @@ int32_t
quiesce_rename (call_frame_t *frame,
xlator_t *this,
loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1246,14 +1302,14 @@ quiesce_rename (call_frame_t *frame,
default_rename_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
+ oldloc, newloc);
+ return 0;
}
- stub = fop_rename_stub (frame, default_rename_resume, oldloc, newloc, xdata);
+ stub = fop_rename_stub (frame, default_rename_resume, oldloc, newloc);
if (!stub) {
STACK_UNWIND_STRICT (rename, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -1265,7 +1321,7 @@ quiesce_rename (call_frame_t *frame,
int
quiesce_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkpath, loc_t *loc, mode_t umask, dict_t *xdata)
+ const char *linkpath, loc_t *loc, dict_t *params)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1276,15 +1332,15 @@ quiesce_symlink (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- linkpath, loc, umask, xdata);
- return 0;
+ linkpath, loc, params);
+ return 0;
}
stub = fop_symlink_stub (frame, default_symlink_resume,
- linkpath, loc, umask, xdata);
+ linkpath, loc, params);
if (!stub) {
STACK_UNWIND_STRICT (symlink, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -1295,7 +1351,7 @@ quiesce_symlink (call_frame_t *frame, xlator_t *this,
int
-quiesce_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
+quiesce_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1306,13 +1362,13 @@ quiesce_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_
STACK_WIND (frame, default_rmdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rmdir,
- loc, flags, xdata);
- return 0;
+ loc, flags);
+ return 0;
}
- stub = fop_rmdir_stub (frame, default_rmdir_resume, loc, flags, xdata);
+ stub = fop_rmdir_stub (frame, default_rmdir_resume, loc, flags);
if (!stub) {
- STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (rmdir, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1324,7 +1380,7 @@ quiesce_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_
int32_t
quiesce_unlink (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
+ loc_t *loc)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1336,13 +1392,13 @@ quiesce_unlink (call_frame_t *frame,
default_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
+ loc);
+ return 0;
}
- stub = fop_unlink_stub (frame, default_unlink_resume, loc, xflag, xdata);
+ stub = fop_unlink_stub (frame, default_unlink_resume, loc);
if (!stub) {
- STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (unlink, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1353,7 +1409,7 @@ quiesce_unlink (call_frame_t *frame,
int
quiesce_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dict_t *params)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1364,15 +1420,15 @@ quiesce_mkdir (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_mkdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
+ loc, mode, params);
+ return 0;
}
stub = fop_mkdir_stub (frame, default_mkdir_resume,
- loc, mode, umask, xdata);
+ loc, mode, params);
if (!stub) {
STACK_UNWIND_STRICT (mkdir, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -1384,7 +1440,7 @@ quiesce_mkdir (call_frame_t *frame, xlator_t *this,
int
quiesce_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dev_t rdev, dict_t *parms)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1395,15 +1451,15 @@ quiesce_mknod (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_mknod_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
+ loc, mode, rdev, parms);
+ return 0;
}
stub = fop_mknod_stub (frame, default_mknod_resume,
- loc, mode, rdev, umask, xdata);
+ loc, mode, rdev, parms);
if (!stub) {
STACK_UNWIND_STRICT (mknod, frame, -1, ENOMEM,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -1416,7 +1472,7 @@ int32_t
quiesce_ftruncate (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1429,13 +1485,13 @@ quiesce_ftruncate (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
fd,
- offset, xdata);
- return 0;
+ offset);
+ return 0;
}
- stub = fop_ftruncate_stub (frame, default_ftruncate_resume, fd, offset, xdata);
+ stub = fop_ftruncate_stub (frame, default_ftruncate_resume, fd, offset);
if (!stub) {
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1450,7 +1506,7 @@ int32_t
quiesce_readlink (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- size_t size, dict_t *xdata)
+ size_t size)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1469,13 +1525,13 @@ quiesce_readlink (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
loc,
- size, xdata);
- return 0;
+ size);
+ return 0;
}
- stub = fop_readlink_stub (frame, default_readlink_resume, loc, size, xdata);
+ stub = fop_readlink_stub (frame, default_readlink_resume, loc, size);
if (!stub) {
- STACK_UNWIND_STRICT (readlink, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (readlink, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1489,7 +1545,7 @@ int32_t
quiesce_access (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- int32_t mask, dict_t *xdata)
+ int32_t mask)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1508,13 +1564,13 @@ quiesce_access (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->access,
loc,
- mask, xdata);
- return 0;
+ mask);
+ return 0;
}
- stub = fop_access_stub (frame, default_access_resume, loc, mask, xdata);
+ stub = fop_access_stub (frame, default_access_resume, loc, mask);
if (!stub) {
- STACK_UNWIND_STRICT (access, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (access, frame, -1, ENOMEM);
return 0;
}
@@ -1527,7 +1583,7 @@ int32_t
quiesce_fgetxattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1548,13 +1604,13 @@ quiesce_fgetxattr (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fgetxattr,
fd,
- name, xdata);
+ name);
return 0;
}
- stub = fop_fgetxattr_stub (frame, default_fgetxattr_resume, fd, name, xdata);
+ stub = fop_fgetxattr_stub (frame, default_fgetxattr_resume, fd, name);
if (!stub) {
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1566,7 +1622,7 @@ quiesce_fgetxattr (call_frame_t *frame,
int32_t
quiesce_statfs (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1583,13 +1639,13 @@ quiesce_statfs (call_frame_t *frame,
quiesce_statfs_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->statfs,
- loc, xdata);
- return 0;
+ loc);
+ return 0;
}
- stub = fop_statfs_stub (frame, default_statfs_resume, loc, xdata);
+ stub = fop_statfs_stub (frame, default_statfs_resume, loc);
if (!stub) {
- STACK_UNWIND_STRICT (statfs, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (statfs, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1602,7 +1658,7 @@ int32_t
quiesce_fsyncdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1621,13 +1677,13 @@ quiesce_fsyncdir (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsyncdir,
fd,
- flags, xdata);
- return 0;
+ flags);
+ return 0;
}
- stub = fop_fsyncdir_stub (frame, default_fsyncdir_resume, fd, flags, xdata);
+ stub = fop_fsyncdir_stub (frame, default_fsyncdir_resume, fd, flags);
if (!stub) {
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOMEM);
return 0;
}
@@ -1639,7 +1695,7 @@ quiesce_fsyncdir (call_frame_t *frame,
int32_t
quiesce_opendir (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+ loc_t *loc, fd_t *fd)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1657,13 +1713,13 @@ quiesce_opendir (call_frame_t *frame,
quiesce_opendir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->opendir,
- loc, fd, xdata);
- return 0;
+ loc, fd);
+ return 0;
}
- stub = fop_opendir_stub (frame, default_opendir_resume, loc, fd, xdata);
+ stub = fop_opendir_stub (frame, default_opendir_resume, loc, fd);
if (!stub) {
- STACK_UNWIND_STRICT (opendir, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (opendir, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1675,7 +1731,7 @@ quiesce_opendir (call_frame_t *frame,
int32_t
quiesce_fstat (call_frame_t *frame,
xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1692,13 +1748,13 @@ quiesce_fstat (call_frame_t *frame,
quiesce_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
- return 0;
+ fd);
+ return 0;
}
- stub = fop_fstat_stub (frame, default_fstat_resume, fd, xdata);
+ stub = fop_fstat_stub (frame, default_fstat_resume, fd);
if (!stub) {
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (fstat, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1711,7 +1767,7 @@ int32_t
quiesce_fsync (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1730,13 +1786,13 @@ quiesce_fsync (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsync,
fd,
- flags, xdata);
- return 0;
+ flags);
+ return 0;
}
- stub = fop_fsync_stub (frame, default_fsync_resume, fd, flags, xdata);
+ stub = fop_fsync_stub (frame, default_fsync_resume, fd, flags);
if (!stub) {
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1748,7 +1804,7 @@ quiesce_fsync (call_frame_t *frame,
int32_t
quiesce_flush (call_frame_t *frame,
xlator_t *this,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1765,13 +1821,13 @@ quiesce_flush (call_frame_t *frame,
quiesce_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
- return 0;
+ fd);
+ return 0;
}
- stub = fop_flush_stub (frame, default_flush_resume, fd, xdata);
+ stub = fop_flush_stub (frame, default_flush_resume, fd);
if (!stub) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
return 0;
}
@@ -1786,8 +1842,8 @@ quiesce_writev (call_frame_t *frame,
fd_t *fd,
struct iovec *vector,
int32_t count,
- off_t off, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
+ off_t off,
+ struct iobref *iobref)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1802,15 +1858,15 @@ quiesce_writev (call_frame_t *frame,
fd,
vector,
count,
- off, flags,
- iobref, xdata);
- return 0;
+ off,
+ iobref);
+ return 0;
}
stub = fop_writev_stub (frame, default_writev_resume,
- fd, vector, count, off, flags, iobref, xdata);
+ fd, vector, count, off, iobref);
if (!stub) {
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1824,7 +1880,7 @@ quiesce_readv (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1837,7 +1893,6 @@ quiesce_readv (call_frame_t *frame,
local->fd = fd_ref (fd);
local->size = size;
local->offset = offset;
- local->io_flag = flags;
frame->local = local;
STACK_WIND (frame,
@@ -1846,15 +1901,14 @@ quiesce_readv (call_frame_t *frame,
FIRST_CHILD(this)->fops->readv,
fd,
size,
- offset, flags, xdata);
- return 0;
+ offset);
+ return 0;
}
- stub = fop_readv_stub (frame, default_readv_resume, fd, size, offset,
- flags, xdata);
+ stub = fop_readv_stub (frame, default_readv_resume, fd, size, offset);
if (!stub) {
STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
- NULL, 0, NULL, NULL, NULL);
+ NULL, 0, NULL, NULL);
return 0;
}
@@ -1869,7 +1923,7 @@ quiesce_open (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
int32_t flags, fd_t *fd,
- dict_t *xdata)
+ int32_t wbflags)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1885,20 +1939,21 @@ quiesce_open (call_frame_t *frame,
/* Don't send O_APPEND below, as write() re-transmittions can
fail with O_APPEND */
local->flag = (flags & ~O_APPEND);
+ local->wbflags = wbflags;
frame->local = local;
STACK_WIND (frame,
quiesce_open_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- loc, (flags & ~O_APPEND), fd, xdata);
- return 0;
+ loc, (flags & ~O_APPEND), fd, wbflags);
+ return 0;
}
stub = fop_open_stub (frame, default_open_resume, loc,
- (flags & ~O_APPEND), fd, xdata);
+ (flags & ~O_APPEND), fd, wbflags);
if (!stub) {
- STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1911,7 +1966,7 @@ int32_t
quiesce_getxattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1932,13 +1987,13 @@ quiesce_getxattr (call_frame_t *frame,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr,
loc,
- name, xdata);
- return 0;
+ name);
+ return 0;
}
- stub = fop_getxattr_stub (frame, default_getxattr_resume, loc, name, xdata);
+ stub = fop_getxattr_stub (frame, default_getxattr_resume, loc, name);
if (!stub) {
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (getxattr, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1953,7 +2008,7 @@ quiesce_xattrop (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -1967,14 +2022,14 @@ quiesce_xattrop (call_frame_t *frame,
FIRST_CHILD(this)->fops->xattrop,
loc,
flags,
- dict, xdata);
- return 0;
+ dict);
+ return 0;
}
stub = fop_xattrop_stub (frame, default_xattrop_resume,
- loc, flags, dict, xdata);
+ loc, flags, dict);
if (!stub) {
- STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (xattrop, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -1988,7 +2043,7 @@ quiesce_fxattrop (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
gf_xattrop_flags_t flags,
- dict_t *dict, dict_t *xdata)
+ dict_t *dict)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2002,14 +2057,14 @@ quiesce_fxattrop (call_frame_t *frame,
FIRST_CHILD(this)->fops->fxattrop,
fd,
flags,
- dict, xdata);
- return 0;
+ dict);
+ return 0;
}
stub = fop_fxattrop_stub (frame, default_fxattrop_resume,
- fd, flags, dict, xdata);
+ fd, flags, dict);
if (!stub) {
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2023,7 +2078,7 @@ quiesce_lk (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2037,13 +2092,13 @@ quiesce_lk (call_frame_t *frame,
FIRST_CHILD(this)->fops->lk,
fd,
cmd,
- lock, xdata);
- return 0;
+ lock);
+ return 0;
}
- stub = fop_lk_stub (frame, default_lk_resume, fd, cmd, lock, xdata);
+ stub = fop_lk_stub (frame, default_lk_resume, fd, cmd, lock);
if (!stub) {
- STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (lk, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2056,7 +2111,7 @@ quiesce_lk (call_frame_t *frame,
int32_t
quiesce_inodelk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2068,14 +2123,14 @@ quiesce_inodelk (call_frame_t *frame, xlator_t *this,
default_inodelk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->inodelk,
- volume, loc, cmd, lock, xdata);
- return 0;
+ volume, loc, cmd, lock);
+ return 0;
}
stub = fop_inodelk_stub (frame, default_inodelk_resume,
- volume, loc, cmd, lock, xdata);
+ volume, loc, cmd, lock);
if (!stub) {
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (inodelk, frame, -1, ENOMEM);
return 0;
}
@@ -2086,7 +2141,7 @@ quiesce_inodelk (call_frame_t *frame, xlator_t *this,
int32_t
quiesce_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2098,14 +2153,14 @@ quiesce_finodelk (call_frame_t *frame, xlator_t *this,
default_finodelk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk,
- volume, fd, cmd, lock, xdata);
- return 0;
+ volume, fd, cmd, lock);
+ return 0;
}
stub = fop_finodelk_stub (frame, default_finodelk_resume,
- volume, fd, cmd, lock, xdata);
+ volume, fd, cmd, lock);
if (!stub) {
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (finodelk, frame, -1, ENOMEM);
return 0;
}
@@ -2117,7 +2172,7 @@ quiesce_finodelk (call_frame_t *frame, xlator_t *this,
int32_t
quiesce_entrylk (call_frame_t *frame, xlator_t *this,
const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2128,14 +2183,14 @@ quiesce_entrylk (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_entrylk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
- return 0;
+ volume, loc, basename, cmd, type);
+ return 0;
}
stub = fop_entrylk_stub (frame, default_entrylk_resume,
- volume, loc, basename, cmd, type, xdata);
+ volume, loc, basename, cmd, type);
if (!stub) {
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (entrylk, frame, -1, ENOMEM);
return 0;
}
@@ -2147,7 +2202,7 @@ quiesce_entrylk (call_frame_t *frame, xlator_t *this,
int32_t
quiesce_fentrylk (call_frame_t *frame, xlator_t *this,
const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
+ entrylk_cmd cmd, entrylk_type type)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2158,14 +2213,14 @@ quiesce_fentrylk (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, default_fentrylk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
- return 0;
+ volume, fd, basename, cmd, type);
+ return 0;
}
stub = fop_fentrylk_stub (frame, default_fentrylk_resume,
- volume, fd, basename, cmd, type, xdata);
+ volume, fd, basename, cmd, type);
if (!stub) {
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOMEM);
return 0;
}
@@ -2178,7 +2233,7 @@ int32_t
quiesce_rchecksum (call_frame_t *frame,
xlator_t *this,
fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
+ int32_t len)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2197,14 +2252,14 @@ quiesce_rchecksum (call_frame_t *frame,
quiesce_rchecksum_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->rchecksum,
- fd, offset, len, xdata);
- return 0;
+ fd, offset, len);
+ return 0;
}
stub = fop_rchecksum_stub (frame, default_rchecksum_resume,
- fd, offset, len, xdata);
+ fd, offset, len);
if (!stub) {
- STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOMEM, 0, NULL, NULL);
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOMEM, 0, NULL);
return 0;
}
@@ -2219,7 +2274,7 @@ quiesce_readdir (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t off, dict_t *xdata)
+ off_t off)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2238,13 +2293,13 @@ quiesce_readdir (call_frame_t *frame,
quiesce_readdir_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdir,
- fd, size, off, xdata);
- return 0;
+ fd, size, off);
+ return 0;
}
- stub = fop_readdir_stub (frame, default_readdir_resume, fd, size, off, xdata);
+ stub = fop_readdir_stub (frame, default_readdir_resume, fd, size, off);
if (!stub) {
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (readdir, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2259,7 +2314,7 @@ quiesce_readdirp (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
size_t size,
- off_t off, dict_t *dict)
+ off_t off)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2272,21 +2327,19 @@ quiesce_readdirp (call_frame_t *frame,
local->fd = fd_ref (fd);
local->size = size;
local->offset = off;
- local->dict = dict_ref (dict);
frame->local = local;
STACK_WIND (frame,
quiesce_readdirp_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readdirp,
- fd, size, off, dict);
- return 0;
+ fd, size, off);
+ return 0;
}
- stub = fop_readdirp_stub (frame, default_readdirp_resume, fd, size,
- off, dict);
+ stub = fop_readdirp_stub (frame, default_readdirp_resume, fd, size, off);
if (!stub) {
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (readdirp, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2300,7 +2353,7 @@ quiesce_setattr (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+ int32_t valid)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2312,14 +2365,14 @@ quiesce_setattr (call_frame_t *frame,
default_setattr_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
+ loc, stbuf, valid);
+ return 0;
}
stub = fop_setattr_stub (frame, default_setattr_resume,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
if (!stub) {
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (setattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2332,7 +2385,7 @@ quiesce_setattr (call_frame_t *frame,
int32_t
quiesce_stat (call_frame_t *frame,
xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2349,13 +2402,13 @@ quiesce_stat (call_frame_t *frame,
quiesce_stat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->stat,
- loc, xdata);
- return 0;
+ loc);
+ return 0;
}
- stub = fop_stat_stub (frame, default_stat_resume, loc, xdata);
+ stub = fop_stat_stub (frame, default_stat_resume, loc);
if (!stub) {
- STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2386,8 +2439,9 @@ quiesce_lookup (call_frame_t *frame,
quiesce_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xattr_req);
- return 0;
+ loc,
+ xattr_req);
+ return 0;
}
stub = fop_lookup_stub (frame, default_lookup_resume, loc, xattr_req);
@@ -2407,7 +2461,7 @@ quiesce_fsetattr (call_frame_t *frame,
xlator_t *this,
fd_t *fd,
struct iatt *stbuf,
- int32_t valid, dict_t *xdata)
+ int32_t valid)
{
quiesce_priv_t *priv = NULL;
call_stub_t *stub = NULL;
@@ -2419,14 +2473,14 @@ quiesce_fsetattr (call_frame_t *frame,
default_fsetattr_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
+ fd, stbuf, valid);
+ return 0;
}
stub = fop_fsetattr_stub (frame, default_fsetattr_resume,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
if (!stub) {
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
diff --git a/xlators/features/quiesce/src/quiesce.h b/xlators/features/quiesce/src/quiesce.h
index 08f87e2ae..45eea34a2 100644
--- a/xlators/features/quiesce/src/quiesce.h
+++ b/xlators/features/quiesce/src/quiesce.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -25,7 +25,7 @@
#include "xlator.h"
#include "timer.h"
-#define GF_FOPS_EXPECTED_IN_PARALLEL 512
+#define GF_FOPS_EXPECTED_IN_PARALLEL 4096
typedef struct {
gf_timer_t *timer;
@@ -55,7 +55,6 @@ typedef struct {
entrylk_type type;
gf_xattrop_flags_t xattrop_flags;
int32_t wbflags;
- uint32_t io_flag;
} quiesce_local_t;
#endif
diff --git a/xlators/features/quota/src/quota-mem-types.h b/xlators/features/quota/src/quota-mem-types.h
index ed70c2928..ff5777f97 100644
--- a/xlators/features/quota/src/quota-mem-types.h
+++ b/xlators/features/quota/src/quota-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,7 +23,8 @@
#include "mem-types.h"
enum gf_quota_mem_types_ {
- gf_quota_mt_quota_priv_t = gf_common_mt_end + 1,
+ gf_quota_mt_quota_local_t = gf_common_mt_end + 1,
+ gf_quota_mt_quota_priv_t,
gf_quota_mt_quota_inode_ctx_t,
gf_quota_mt_loc_t,
gf_quota_mt_char,
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index 55dd3d59d..5d1f304f4 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -1,32 +1,28 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
-#include <fnmatch.h>
-
#include "quota.h"
#include "common-utils.h"
-#include "defaults.h"
int32_t
quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
- char *name, uuid_t par);
-struct volume_options options[];
+ char *name, ino_t par);
int
quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
@@ -39,6 +35,7 @@ quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
if (inode) {
loc->inode = inode_ref (inode);
+ loc->ino = inode->ino;
}
if (parent) {
@@ -82,15 +79,16 @@ quota_inode_loc_fill (inode_t *inode, loc_t *loc)
this = THIS;
- if ((inode) && __is_root_gfid (inode->gfid)) {
+ if ((inode) && (inode->ino == 1)) {
loc->parent = NULL;
goto ignore_parent;
}
parent = inode_parent (inode, 0, NULL);
if (!parent) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot find parent for inode (gfid:%s)",
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot find parent for inode (ino:%"PRId64", "
+ "gfid:%s)", inode->ino,
uuid_utoa (inode->gfid));
goto err;
}
@@ -98,8 +96,9 @@ quota_inode_loc_fill (inode_t *inode, loc_t *loc)
ignore_parent:
ret = inode_path (inode, NULL, &resolvedpath);
if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot construct path for inode (gfid:%s)",
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot construct path for inode (ino:%"PRId64", "
+ "gfid:%s)", inode->ino,
uuid_utoa (inode->gfid));
goto err;
}
@@ -141,22 +140,23 @@ out:
}
-static inline quota_local_t *
+quota_local_t *
quota_local_new ()
{
- quota_local_t *local = NULL;
- local = mem_get0 (THIS->local_pool);
- if (local)
- LOCK_INIT (&local->lock);
+ quota_local_t *local = NULL;
+ int32_t ret = 0;
+
+ QUOTA_LOCAL_ALLOC_OR_GOTO (local, quota_local_t, err);
+err:
return local;
}
quota_dentry_t *
-__quota_dentry_new (quota_inode_ctx_t *ctx, char *name, uuid_t par)
+__quota_dentry_new (quota_inode_ctx_t *ctx, char *name, ino_t par)
{
- quota_dentry_t *dentry = NULL;
- GF_UNUSED int32_t ret = 0;
+ quota_dentry_t *dentry = NULL;
+ int32_t ret = 0;
QUOTA_ALLOC_OR_GOTO (dentry, quota_dentry_t, err);
@@ -168,7 +168,7 @@ __quota_dentry_new (quota_inode_ctx_t *ctx, char *name, uuid_t par)
goto err;
}
- uuid_copy (dentry->par, par);
+ dentry->par = par;
list_add_tail (&dentry->next, &ctx->parents);
err:
@@ -194,13 +194,13 @@ out:
int32_t
quota_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
quota_local_t *local = NULL;
uint32_t validate_count = 0, link_count = 0;
int32_t ret = 0;
quota_inode_ctx_t *ctx = NULL;
+ quota_priv_t *priv = NULL;
int64_t *size = 0;
uint64_t value = 0;
call_stub_t *stub = NULL;
@@ -212,6 +212,9 @@ quota_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
GF_ASSERT (local);
+
+ priv = this->private;
+
GF_ASSERT (frame);
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quota", this, unwind, op_errno,
EINVAL);
@@ -223,7 +226,8 @@ quota_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ctx = (quota_inode_ctx_t *)(unsigned long)value;
if ((ret == -1) || (ctx == NULL)) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context is not present in inode (gfid:%s)",
+ "quota context is not present in inode (ino:%"PRId64", "
+ "gfid:%s)", local->validate_loc.inode->ino,
uuid_utoa (local->validate_loc.inode->gfid));
op_errno = EINVAL;
goto unwind;
@@ -248,7 +252,7 @@ quota_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
UNLOCK (&ctx->lock);
- quota_check_limit (frame, local->validate_loc.inode, this, NULL, NULL);
+ quota_check_limit (frame, local->validate_loc.inode, this, NULL, 0);
return 0;
unwind:
@@ -300,7 +304,7 @@ quota_timeout (struct timeval *tv, int32_t timeout)
int32_t
quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
- char *name, uuid_t par)
+ char *name, ino_t par)
{
int32_t ret = -1;
inode_t *_inode = NULL, *parent = NULL;
@@ -313,7 +317,6 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
int32_t validate_count = 0, link_count = 0;
uint64_t value = 0;
char just_validated = 0;
- uuid_t trav_uuid = {0,};
GF_VALIDATE_OR_GOTO ("quota", this, out);
GF_VALIDATE_OR_GOTO (this->name, frame, out);
@@ -333,20 +336,8 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
_inode = inode_ref (inode);
- LOCK (&local->lock);
- {
- just_validated = local->just_validated;
- local->just_validated = 0;
-
- if (just_validated) {
- local->validate_count--;
- }
- }
- UNLOCK (&local->lock);
-
- if ( par != NULL ) {
- uuid_copy (trav_uuid, par);
- }
+ just_validated = local->just_validated;
+ local->just_validated = 0;
do {
if (ctx != NULL) {
@@ -376,27 +367,27 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
}
}
- if (__is_root_gfid (_inode->gfid)) {
+ if (_inode->ino == 1) {
break;
}
- parent = inode_parent (_inode, trav_uuid, name);
+ parent = inode_parent (_inode, par, name);
if (name != NULL) {
name = NULL;
- uuid_clear (trav_uuid);
+ par = 0;
}
if (parent == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot find parent for inode (gfid:%s), hence "
- "aborting enforcing quota-limits and continuing"
- " with the fop", uuid_utoa (_inode->gfid));
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot find parent for inode (ino:%"PRId64", "
+ "gfid:%s), hence aborting enforcing "
+ "quota-limits and continuing with the fop",
+ _inode->ino, uuid_utoa (_inode->gfid));
}
inode_unref (_inode);
_inode = parent;
- just_validated = 0;
if (_inode == NULL) {
break;
@@ -415,6 +406,10 @@ quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this,
LOCK (&local->lock);
{
+ if (just_validated) {
+ local->validate_count--;
+ }
+
validate_count = local->validate_count;
link_count = local->link_count;
if ((validate_count == 0) && (link_count == 0)) {
@@ -444,8 +439,9 @@ validate:
ret = quota_inode_loc_fill (_inode, &local->validate_loc);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot fill loc for inode (gfid:%s), hence "
- "aborting quota-checks and continuing with fop",
+ "cannot fill loc for inode (ino:%"PRId64", "
+ "gfid:%s), hence aborting quota-checks and "
+ "continuing with the fop", _inode->ino,
uuid_utoa (_inode->gfid));
local->validate_count--;
}
@@ -458,7 +454,7 @@ validate:
STACK_WIND (frame, quota_validate_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr, &local->validate_loc,
- QUOTA_SIZE_KEY, NULL);
+ QUOTA_SIZE_KEY);
loc_fill_failed:
inode_unref (_inode);
@@ -497,8 +493,6 @@ quota_get_limit_value (inode_t *inode, xlator_t *this, int64_t *n)
}
out:
- GF_FREE (path);
-
return ret;
}
@@ -511,11 +505,14 @@ __quota_init_inode_ctx (inode_t *inode, int64_t limit, xlator_t *this,
int32_t ret = -1;
int64_t *size = 0;
quota_inode_ctx_t *ctx = NULL;
+ quota_priv_t *priv = NULL;
if (inode == NULL) {
goto out;
}
+ priv = this->private;
+
QUOTA_ALLOC_OR_GOTO (ctx, quota_inode_ctx_t, out);
ctx->limit = limit;
@@ -541,8 +538,8 @@ __quota_init_inode_ctx (inode_t *inode, int64_t limit, xlator_t *this,
ret = __inode_ctx_put (inode, this, (uint64_t )(long)ctx);
if (ret == -1) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot set quota context in inode (gfid:%s)",
- uuid_utoa (inode->gfid));
+ "cannot set quota context in inode (ino:%"PRId64", "
+ "gfid:%s)", inode->ino, uuid_utoa (inode->gfid));
}
out:
return ret;
@@ -579,47 +576,30 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
- int32_t ret = -1;
- char found = 0;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL;
- int64_t *size = 0;
- uint64_t value = 0;
- limits_t *limit_node = NULL;
- quota_priv_t *priv = NULL;
+ int32_t ret = -1;
+ char found = 0;
+ quota_local_t *local = NULL;
+ quota_inode_ctx_t *ctx = NULL;
+ quota_dentry_t *dentry = NULL;
+ quota_priv_t *priv = NULL;
+ int64_t *size = 0;
local = frame->local;
- priv = this->private;
-
- inode_ctx_get (inode, this, &value);
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
-
if ((op_ret < 0) || (local == NULL)
- || (((ctx == NULL) || (ctx->limit == local->limit))
- && (local->limit < 0) && !((IA_ISREG (buf->ia_type))
- || (IA_ISLNK (buf->ia_type))))) {
+ || ((local->limit < 0) && !((IA_ISREG (buf->ia_type))
+ || (IA_ISLNK (buf->ia_type))))) {
goto unwind;
}
- LOCK (&priv->lock);
- {
- list_for_each_entry (limit_node, &priv->limit_head,
- limit_list) {
- if (strcmp (local->loc.path, limit_node->path) == 0) {
- uuid_copy (limit_node->gfid, buf->ia_gfid);
- break;
- }
- }
- }
- UNLOCK (&priv->lock);
+ priv = this->private;
ret = quota_inode_ctx_get (local->loc.inode, local->limit, this, dict,
buf, &ctx, 1);
if ((ret == -1) || (ctx == NULL)) {
gf_log (this->name, GF_LOG_WARNING, "cannot create quota "
- "context in inode(gfid:%s)",
+ "context in inode(ino:%"PRId64", gfid:%s)",
+ local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
@@ -648,13 +628,9 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
- if (local->loc.name == NULL)
- goto unlock;
-
list_for_each_entry (dentry, &ctx->parents, next) {
- if ((strcmp (dentry->name, local->loc.name) == 0) &&
- (uuid_compare (local->loc.parent->gfid,
- dentry->par) == 0)) {
+ if ((strcmp (dentry->name, local->loc.name) == 0)
+ && (local->loc.parent->ino == dentry->par)) {
found = 1;
break;
}
@@ -663,13 +639,15 @@ quota_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!found) {
dentry = __quota_dentry_new (ctx,
(char *)local->loc.name,
- local->loc.parent->gfid);
+ local->loc.parent->ino);
if (dentry == NULL) {
/*
gf_log (this->name, GF_LOG_WARNING,
"cannot create a new dentry (par:%"
PRId64", name:%s) for inode(ino:%"
PRId64", gfid:%s)",
+ local->loc.parent->ino,
+ local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
*/
op_ret = -1;
@@ -756,14 +734,12 @@ err:
void
-quota_update_size (xlator_t *this, inode_t *inode, char *name, uuid_t par,
+quota_update_size (xlator_t *this, inode_t *inode, char *name, ino_t par,
int64_t delta)
{
- inode_t *_inode = NULL;
- inode_t *parent = NULL;
- uint64_t value = 0;
- quota_inode_ctx_t *ctx = NULL;
- uuid_t trav_uuid = {0,};
+ inode_t *_inode = NULL, *parent = NULL;
+ uint64_t value = 0;
+ quota_inode_ctx_t *ctx = NULL;
GF_VALIDATE_OR_GOTO ("quota", this, out);
GF_VALIDATE_OR_GOTO (this->name, inode, out);
@@ -773,10 +749,6 @@ quota_update_size (xlator_t *this, inode_t *inode, char *name, uuid_t par,
_inode = inode_ref (inode);
- if ( par != NULL ) {
- uuid_copy (trav_uuid, par);
- }
-
do {
if ((ctx != NULL) && (ctx->limit >= 0)) {
LOCK (&ctx->lock);
@@ -786,21 +758,22 @@ quota_update_size (xlator_t *this, inode_t *inode, char *name, uuid_t par,
UNLOCK (&ctx->lock);
}
- if (__is_root_gfid (_inode->gfid)) {
+ if (_inode->ino == 1) {
break;
}
- parent = inode_parent (_inode, trav_uuid, name);
+ parent = inode_parent (_inode, par, name);
if (parent == NULL) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot find parent for inode (gfid:%s), hence "
- "aborting size updation of parents",
- uuid_utoa (_inode->gfid));
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot find parent for inode (ino:%"PRId64", "
+ "gfid:%s), hence aborting size updation of "
+ "parents",
+ _inode->ino, uuid_utoa (_inode->gfid));
}
if (name != NULL) {
name = NULL;
- uuid_clear (trav_uuid);
+ par = 0;
}
inode_unref (_inode);
@@ -822,7 +795,7 @@ out:
int32_t
quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
int32_t ret = 0;
uint64_t ctx_int = 0;
@@ -838,18 +811,14 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
ret = inode_ctx_get (local->loc.inode, this, &ctx_int);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to get the context", local->loc.path);
- goto out;
- }
ctx = (quota_inode_ctx_t *)(unsigned long) ctx_int;
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in %s (gfid:%s)",
- local->loc.path, uuid_utoa (local->loc.inode->gfid));
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
+ uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -866,8 +835,7 @@ quota_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
out:
- QUOTA_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ QUOTA_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -876,7 +844,7 @@ out:
int32_t
quota_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t off,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -894,11 +862,11 @@ quota_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, quota_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
- flags, iobref, xdata);
+ iobref);
return 0;
unwind:
- QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -906,7 +874,7 @@ unwind:
int32_t
quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t off,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
int32_t ret = -1, op_errno = EINVAL;
int32_t parents = 0;
@@ -932,13 +900,14 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = quota_inode_ctx_get (fd->inode, -1, this, NULL, NULL, &ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64", "
+ "gfid:%s)", fd->inode->ino,
uuid_utoa (fd->inode->gfid));
goto unwind;
}
stub = fop_writev_stub (frame, quota_writev_helper, fd, vector, count,
- off, flags, iobref, xdata);
+ off, iobref);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -987,7 +956,7 @@ quota_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
unwind:
- QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -996,17 +965,17 @@ int32_t
quota_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
QUOTA_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
+ buf, preparent, postparent);
return 0;
}
int32_t
quota_mkdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, mode_t umask, dict_t *xdata)
+ mode_t mode, dict_t *params)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -1024,19 +993,19 @@ quota_mkdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
STACK_WIND (frame, quota_mkdir_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mkdir, loc, mode, umask, xdata);
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
return 0;
unwind:
QUOTA_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
int32_t
quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
int32_t ret = 0, op_errno = 0;
quota_local_t *local = NULL;
@@ -1059,8 +1028,7 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto err;
}
- stub = fop_mkdir_stub (frame, quota_mkdir_helper, loc, mode, umask,
- xdata);
+ stub = fop_mkdir_stub (frame, quota_mkdir_helper, loc, mode, params);
if (stub == NULL) {
op_errno = ENOMEM;
goto err;
@@ -1069,7 +1037,7 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
local->stub = stub;
local->delta = 0;
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
+ quota_check_limit (frame, loc->parent, this, NULL, 0);
stub = NULL;
@@ -1091,7 +1059,7 @@ quota_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
return 0;
err:
QUOTA_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
return 0;
}
@@ -1101,7 +1069,7 @@ int32_t
quota_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t ret = -1;
quota_local_t *local = NULL;
@@ -1116,8 +1084,8 @@ quota_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ret = quota_inode_ctx_get (inode, -1, this, NULL, buf, &ctx, 1);
if ((ret == -1) || (ctx == NULL)) {
gf_log (this->name, GF_LOG_WARNING, "cannot create quota "
- "context in inode(gfid:%s)",
- uuid_utoa (inode->gfid));
+ "context in inode(ino:%"PRId64", gfid:%s)",
+ inode->ino, uuid_utoa (inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
goto unwind;
@@ -1128,11 +1096,13 @@ quota_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ctx->buf = *buf;
dentry = __quota_dentry_new (ctx, (char *)local->loc.name,
- local->loc.parent->gfid);
+ local->loc.parent->ino);
if (dentry == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) for "
- "inode(gfid:%s)", local->loc.name,
+ "cannot create a new dentry (par:%"
+ PRId64", name:%s) for inode(ino:%"
+ PRId64", gfid:%s)", local->loc.parent->ino,
+ local->loc.name, local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
@@ -1144,15 +1114,14 @@ unlock:
unwind:
QUOTA_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int32_t
quota_create_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
- dict_t *xdata)
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -1169,20 +1138,20 @@ quota_create_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
STACK_WIND (frame, quota_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode, umask,
- fd, xdata);
+ FIRST_CHILD(this)->fops->create, loc, flags, mode, fd,
+ params);
return 0;
unwind:
QUOTA_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
int32_t
quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
int32_t ret = -1;
quota_local_t *local = NULL;
@@ -1202,7 +1171,7 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
}
stub = fop_create_stub (frame, quota_create_helper, loc, flags, mode,
- umask, fd, xdata);
+ fd, params);
if (stub == NULL) {
goto err;
}
@@ -1211,7 +1180,7 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
local->stub = stub;
local->delta = 0;
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
+ quota_check_limit (frame, loc->parent, this, NULL, 0);
stub = NULL;
@@ -1232,7 +1201,7 @@ quota_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
return 0;
err:
QUOTA_STACK_UNWIND (create, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
return 0;
}
@@ -1241,7 +1210,7 @@ err:
int32_t
quota_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -1258,25 +1227,25 @@ quota_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
quota_update_size (this, local->loc.inode, (char *)local->loc.name,
- local->loc.parent->gfid,
+ local->loc.parent->ino,
(-(ctx->buf.ia_blocks * 512)));
out:
QUOTA_STACK_UNWIND (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
return 0;
}
int32_t
-quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
+quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int32_t ret = 0;
quota_local_t *local = NULL;
@@ -1295,13 +1264,13 @@ quota_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
}
STACK_WIND (frame, quota_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
+ FIRST_CHILD(this)->fops->unlink, loc);
ret = 0;
err:
if (ret == -1) {
- QUOTA_STACK_UNWIND (unlink, frame, -1, 0, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (unlink, frame, -1, 0, NULL, NULL);
}
return 0;
@@ -1312,7 +1281,7 @@ int32_t
quota_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int32_t ret = -1;
quota_local_t *local = NULL;
@@ -1326,14 +1295,14 @@ quota_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = (quota_local_t *) frame->local;
- quota_update_size (this, local->loc.parent, NULL, NULL,
+ quota_update_size (this, local->loc.parent, NULL, 0,
(buf->ia_blocks * 512));
ret = quota_inode_ctx_get (inode, -1, this, NULL, NULL, &ctx, 0);
if ((ret == -1) || (ctx == NULL)) {
gf_log (this->name, GF_LOG_WARNING, "cannot find quota "
- "context in %s (gfid:%s)", local->loc.path,
- uuid_utoa (inode->gfid));
+ "context in inode(ino:%"PRId64", gfid:%s)",
+ inode->ino, uuid_utoa (inode->gfid));
op_ret = -1;
op_errno = EINVAL;
goto out;
@@ -1342,14 +1311,15 @@ quota_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
LOCK (&ctx->lock);
{
list_for_each_entry (dentry, &ctx->parents, next) {
- if ((strcmp (dentry->name, local->loc.name) == 0) &&
- (uuid_compare (local->loc.parent->gfid,
- dentry->par) == 0)) {
+ if ((strcmp (dentry->name, local->loc.name) == 0)
+ && (local->loc.parent->ino == dentry->par)) {
found = 1;
gf_log (this->name, GF_LOG_WARNING,
- "new entry being linked (name:%s) for "
- "inode (gfid:%s) is already present "
- "in inode-dentry-list", dentry->name,
+ "new entry being linked (par:%"
+ PRId64", name:%s) for inode (ino:%"
+ PRId64", gfid:%s) is already present "
+ "in inode-dentry-list", dentry->par,
+ dentry->name, local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
break;
}
@@ -1358,11 +1328,15 @@ quota_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (!found) {
dentry = __quota_dentry_new (ctx,
(char *)local->loc.name,
- local->loc.parent->gfid);
+ local->loc.parent->ino);
if (dentry == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) "
- "for inode(gfid:%s)", local->loc.name,
+ "cannot create a new dentry (par:%"
+ PRId64", name:%s) for inode(ino:%"
+ PRId64", gfid:%s)",
+ local->loc.parent->ino,
+ local->loc.name,
+ local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
@@ -1377,7 +1351,7 @@ unlock:
out:
QUOTA_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1385,7 +1359,7 @@ out:
int32_t
quota_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -1403,19 +1377,18 @@ quota_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
}
STACK_WIND (frame, quota_link_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->link, oldloc, newloc, xdata);
+ FIRST_CHILD(this)->fops->link, oldloc, newloc);
return 0;
unwind:
QUOTA_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
int32_t
-quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
int32_t ret = -1, op_errno = ENOMEM;
quota_local_t *local = NULL;
@@ -1435,7 +1408,7 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
goto err;
}
- stub = fop_link_stub (frame, quota_link_helper, oldloc, newloc, xdata);
+ stub = fop_link_stub (frame, quota_link_helper, oldloc, newloc);
if (stub == NULL) {
goto err;
}
@@ -1447,15 +1420,16 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
- oldloc->inode ? uuid_utoa (oldloc->inode->gfid) : "0");
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", oldloc->inode?oldloc->inode->ino:0,
+ oldloc->inode?uuid_utoa (oldloc->inode->gfid):"0");
op_errno = EINVAL;
goto err;
}
local->delta = ctx->buf.ia_blocks * 512;
- quota_check_limit (frame, newloc->parent, this, NULL, NULL);
+ quota_check_limit (frame, newloc->parent, this, NULL, 0);
stub = NULL;
@@ -1478,7 +1452,7 @@ quota_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
err:
if (ret < 0) {
QUOTA_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
}
return 0;
@@ -1489,8 +1463,7 @@ int32_t
quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
int32_t ret = -1;
quota_local_t *local = NULL;
@@ -1517,8 +1490,8 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (local->oldloc.parent != local->newloc.parent) {
- quota_update_size (this, local->oldloc.parent, NULL, NULL, (-size));
- quota_update_size (this, local->newloc.parent, NULL, NULL, size);
+ quota_update_size (this, local->oldloc.parent, NULL, 0, (-size));
+ quota_update_size (this, local->newloc.parent, NULL, 0, size);
}
if (!(IA_ISREG (local->oldloc.inode->ia_type)
@@ -1530,7 +1503,8 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if ((ret == -1) || (ctx == NULL)) {
gf_log (this->name, GF_LOG_WARNING, "quota context not"
- "set in inode(gfid:%s)",
+ "set in inode(ino:%"PRId64", gfid:%s)",
+ local->oldloc.inode->ino,
uuid_utoa (local->oldloc.inode->gfid));
op_ret = -1;
op_errno = EINVAL;
@@ -1546,19 +1520,19 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
* should be changed to set a new context in newloc->inode.
*/
list_for_each_entry (dentry, &ctx->parents, next) {
- if ((strcmp (dentry->name, local->oldloc.name) == 0) &&
- (uuid_compare (local->oldloc.parent->gfid,
- dentry->par) == 0)) {
+ if ((strcmp (dentry->name, local->oldloc.name) == 0)
+ && (local->oldloc.parent->ino == dentry->par)) {
old_dentry = dentry;
- } else if ((strcmp (dentry->name,
- local->newloc.name) == 0) &&
- (uuid_compare (local->oldloc.parent->gfid,
- dentry->par) == 0)) {
+ } else if ((strcmp (dentry->name, local->newloc.name)
+ == 0) && (local->oldloc.parent->ino
+ == dentry->par)) {
new_dentry_found = 1;
gf_log (this->name, GF_LOG_WARNING,
- "new entry being linked (name:%s) for "
- "inode (gfid:%s) is already present "
- "in inode-dentry-list", dentry->name,
+ "new entry being linked (par:%"
+ PRId64", name:%s) for inode (ino:%"
+ PRId64", gfid:%s) is already present "
+ "in inode-dentry-list", dentry->par,
+ dentry->name, local->newloc.inode->ino,
uuid_utoa (local->newloc.inode->gfid));
break;
}
@@ -1569,17 +1543,22 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
} else {
gf_log (this->name, GF_LOG_WARNING,
"dentry corresponding to the path just renamed "
- "(name:%s) is not present", local->oldloc.name);
+ "(par:%"PRId64", name:%s) is not present",
+ local->oldloc.inode->ino, local->oldloc.name);
}
if (!new_dentry_found) {
dentry = __quota_dentry_new (ctx,
(char *)local->newloc.name,
- local->newloc.parent->gfid);
+ local->newloc.parent->ino);
if (dentry == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) "
- "for inode(gfid:%s)", local->newloc.name,
+ "cannot create a new dentry (par:%"
+ PRId64", name:%s) for inode(ino:%"
+ PRId64", gfid:%s)",
+ local->newloc.parent->ino,
+ local->newloc.name,
+ local->newloc.inode->ino,
uuid_utoa (local->newloc.inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
@@ -1594,7 +1573,7 @@ unlock:
out:
QUOTA_STACK_UNWIND (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
+ postoldparent, prenewparent, postnewparent);
return 0;
}
@@ -1602,7 +1581,7 @@ out:
int32_t
quota_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -1620,19 +1599,19 @@ quota_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
}
STACK_WIND (frame, quota_rename_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rename, oldloc, newloc, xdata);
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc);
return 0;
unwind:
QUOTA_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
int32_t
quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
int32_t ret = -1, op_errno = ENOMEM;
quota_local_t *local = NULL;
@@ -1658,8 +1637,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
goto err;
}
- stub = fop_rename_stub (frame, quota_rename_helper, oldloc, newloc,
- xdata);
+ stub = fop_rename_stub (frame, quota_rename_helper, oldloc, newloc);
if (stub == NULL) {
goto err;
}
@@ -1673,9 +1651,11 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)",
+ oldloc->inode ? oldloc->inode->ino:0,
oldloc->inode ? uuid_utoa (oldloc->inode->gfid)
- : "0");
+ :"0");
op_errno = EINVAL;
goto err;
}
@@ -1684,7 +1664,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
local->delta = 0;
}
- quota_check_limit (frame, newloc->parent, this, NULL, NULL);
+ quota_check_limit (frame, newloc->parent, this, NULL, 0);
stub = NULL;
@@ -1707,7 +1687,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
err:
if (ret == -1) {
QUOTA_STACK_UNWIND (rename, frame, -1, op_errno, NULL,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
}
return 0;
@@ -1718,7 +1698,7 @@ int32_t
quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
int64_t size = 0;
quota_local_t *local = NULL;
@@ -1732,13 +1712,14 @@ quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
size = buf->ia_blocks * 512;
- quota_update_size (this, local->loc.parent, NULL, NULL, size);
+ quota_update_size (this, local->loc.parent, NULL, 0, size);
quota_inode_ctx_get (local->loc.inode, -1, this, NULL, NULL,
&ctx, 1);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -1748,11 +1729,13 @@ quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ctx->buf = *buf;
dentry = __quota_dentry_new (ctx, (char *)local->loc.name,
- local->loc.parent->gfid);
+ local->loc.parent->ino);
if (dentry == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) for "
- "inode(gfid:%s)", local->loc.name,
+ "cannot create a new dentry (par:%"
+ PRId64", name:%s) for inode(ino:%"
+ PRId64", gfid:%s)", local->loc.parent->ino,
+ local->loc.name, local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
op_ret = -1;
op_errno = ENOMEM;
@@ -1762,7 +1745,7 @@ quota_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -1770,7 +1753,7 @@ out:
int
quota_symlink_helper (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
quota_local_t *local = NULL;
int32_t op_errno = EINVAL;
@@ -1787,20 +1770,19 @@ quota_symlink_helper (call_frame_t *frame, xlator_t *this, const char *linkpath,
}
STACK_WIND (frame, quota_symlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->symlink, linkpath, loc, umask,
- xdata);
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc, params);
return 0;
unwind:
QUOTA_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
int
quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
int32_t ret = -1;
int32_t op_errno = ENOMEM;
@@ -1823,7 +1805,7 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
local->link_count = 1;
stub = fop_symlink_stub (frame, quota_symlink_helper, linkpath, loc,
- umask, xdata);
+ params);
if (stub == NULL) {
goto err;
}
@@ -1831,7 +1813,7 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
local->stub = stub;
local->delta = strlen (linkpath);
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
+ quota_check_limit (frame, loc->parent, this, NULL, 0);
stub = NULL;
@@ -1854,7 +1836,7 @@ quota_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
err:
QUOTA_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
return 0;
}
@@ -1863,7 +1845,7 @@ err:
int32_t
quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
quota_local_t *local = NULL;
int64_t delta = 0;
@@ -1881,13 +1863,14 @@ quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512;
- quota_update_size (this, local->loc.inode, NULL, NULL, delta);
+ quota_update_size (this, local->loc.inode, NULL, 0, delta);
quota_inode_ctx_get (local->loc.inode, -1, this, NULL, NULL,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -1900,14 +1883,13 @@ quota_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int32_t
-quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
int32_t ret = -1;
quota_local_t *local = NULL;
@@ -1926,11 +1908,11 @@ quota_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
}
STACK_WIND (frame, quota_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
return 0;
err:
- QUOTA_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -1939,7 +1921,7 @@ err:
int32_t
quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
quota_local_t *local = NULL;
int64_t delta = 0;
@@ -1957,13 +1939,14 @@ quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
delta = (postbuf->ia_blocks - prebuf->ia_blocks) * 512;
- quota_update_size (this, local->loc.inode, NULL, NULL, delta);
+ quota_update_size (this, local->loc.inode, NULL, 0, delta);
quota_inode_ctx_get (local->loc.inode, -1, this, NULL, NULL,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -1976,14 +1959,13 @@ quota_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int32_t
-quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
quota_local_t *local = NULL;
@@ -1996,11 +1978,11 @@ quota_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
local->loc.inode = inode_ref (fd->inode);
STACK_WIND (frame, quota_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
return 0;
err:
- QUOTA_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2035,7 +2017,7 @@ quota_send_dir_limit_to_cli (call_frame_t *frame, xlator_t *this,
gf_log (this->name, GF_LOG_INFO, "str = %s", dir_limit);
- QUOTA_STACK_UNWIND (getxattr, frame, 0, 0, dict, NULL);
+ QUOTA_STACK_UNWIND (getxattr, frame, 0, 0, dict);
ret = 0;
@@ -2046,11 +2028,11 @@ out:
int32_t
quota_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
int32_t ret = 0;
- if (name && strcasecmp (name, "trusted.limit.list") == 0) {
+ if (strcasecmp (name, "trusted.limit.list") == 0) {
ret = quota_send_dir_limit_to_cli (frame, this, fd->inode,
name);
if (ret == 0) {
@@ -2059,14 +2041,14 @@ quota_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
STACK_WIND (frame, default_fgetxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fgetxattr, fd, name, xdata);
+ FIRST_CHILD(this)->fops->fgetxattr, fd, name);
return 0;
}
int32_t
quota_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int32_t ret = 0;
@@ -2078,14 +2060,14 @@ quota_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
+ FIRST_CHILD(this)->fops->getxattr, loc, name);
return 0;
}
int32_t
quota_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2104,7 +2086,8 @@ quota_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_DEBUG,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2117,13 +2100,13 @@ quota_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&ctx->lock);
out:
- QUOTA_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
+ QUOTA_STACK_UNWIND (stat, frame, op_ret, op_errno, buf);
return 0;
}
int32_t
-quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
quota_local_t *local = NULL;
int32_t ret = -1;
@@ -2141,19 +2124,18 @@ quota_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
}
STACK_WIND (frame, quota_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
+ FIRST_CHILD(this)->fops->stat, loc);
return 0;
unwind:
- QUOTA_STACK_UNWIND (stat, frame, -1, ENOMEM, NULL, NULL);
+ QUOTA_STACK_UNWIND (stat, frame, -1, ENOMEM, NULL);
return 0;
}
int32_t
quota_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2172,7 +2154,8 @@ quota_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2185,13 +2168,13 @@ quota_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&ctx->lock);
out:
- QUOTA_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
+ QUOTA_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int32_t
-quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
quota_local_t *local = NULL;
@@ -2205,11 +2188,11 @@ quota_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
local->loc.inode = inode_ref (fd->inode);
STACK_WIND (frame, quota_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ FIRST_CHILD(this)->fops->fstat, fd);
return 0;
unwind:
- QUOTA_STACK_UNWIND (fstat, frame, -1, ENOMEM, NULL, NULL);
+ QUOTA_STACK_UNWIND (fstat, frame, -1, ENOMEM, NULL);
return 0;
}
@@ -2217,7 +2200,7 @@ unwind:
int32_t
quota_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2236,7 +2219,8 @@ quota_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2248,14 +2232,13 @@ quota_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&ctx->lock);
out:
- QUOTA_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, buf, xdata);
+ QUOTA_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, buf);
return 0;
}
int32_t
-quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
- dict_t *xdata)
+quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
{
quota_local_t *local = NULL;
int32_t ret = -1;
@@ -2274,11 +2257,11 @@ quota_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size,
}
STACK_WIND (frame, quota_readlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readlink, loc, size, xdata);
+ FIRST_CHILD(this)->fops->readlink, loc, size);
return 0;
unwind:
- QUOTA_STACK_UNWIND (readlink, frame, -1, ENOMEM, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (readlink, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2286,8 +2269,7 @@ unwind:
int32_t
quota_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *buf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *buf, struct iobref *iobref)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2306,7 +2288,8 @@ quota_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2319,14 +2302,14 @@ quota_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
- buf, iobref, xdata);
+ buf, iobref);
return 0;
}
int32_t
quota_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
quota_local_t *local = NULL;
@@ -2340,12 +2323,11 @@ quota_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
local->loc.inode = inode_ref (fd->inode);
STACK_WIND (frame, quota_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
- xdata);
+ FIRST_CHILD(this)->fops->readv, fd, size, offset);
return 0;
unwind:
- QUOTA_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (readv, frame, -1, ENOMEM, NULL, -1, NULL, NULL);
return 0;
}
@@ -2353,7 +2335,7 @@ unwind:
int32_t
quota_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2372,7 +2354,8 @@ quota_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2384,15 +2367,13 @@ quota_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
UNLOCK (&ctx->lock);
out:
- QUOTA_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ QUOTA_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int32_t
-quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
+quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
quota_local_t *local = NULL;
@@ -2406,11 +2387,11 @@ quota_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
frame->local = local;
STACK_WIND (frame, quota_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
+ FIRST_CHILD(this)->fops->fsync, fd, flags);
return 0;
unwind:
- QUOTA_STACK_UNWIND (fsync, frame, -1, ENOMEM, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (fsync, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2419,7 +2400,7 @@ unwind:
int32_t
quota_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2438,7 +2419,8 @@ quota_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_DEBUG,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2452,14 +2434,14 @@ quota_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
return 0;
}
int32_t
quota_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
quota_local_t *local = NULL;
int32_t ret = -1;
@@ -2478,11 +2460,11 @@ quota_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
STACK_WIND (frame, quota_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
return 0;
unwind:
- QUOTA_STACK_UNWIND (setattr, frame, -1, ENOMEM, NULL, NULL, NULL);
+ QUOTA_STACK_UNWIND (setattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -2490,7 +2472,7 @@ unwind:
int32_t
quota_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
quota_local_t *local = NULL;
quota_inode_ctx_t *ctx = NULL;
@@ -2509,7 +2491,8 @@ quota_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
&ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
- "quota context not set in inode (gfid:%s)",
+ "quota context not set in inode (ino:%"PRId64
+ ", gfid:%s)", local->loc.inode->ino,
uuid_utoa (local->loc.inode->gfid));
goto out;
}
@@ -2522,14 +2505,14 @@ quota_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QUOTA_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
return 0;
}
int32_t
quota_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
quota_local_t *local = NULL;
@@ -2543,433 +2526,11 @@ quota_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
local->loc.inode = inode_ref (fd->inode);
STACK_WIND (frame, quota_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid, xdata);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
return 0;
unwind:
- QUOTA_STACK_UNWIND (fsetattr, frame, -1, ENOMEM, NULL, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-quota_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- int32_t ret = -1;
- quota_local_t *local = NULL;
- quota_inode_ctx_t *ctx = NULL;
- quota_dentry_t *dentry = NULL;
-
- local = frame->local;
- if (op_ret < 0) {
- goto unwind;
- }
-
- ret = quota_inode_ctx_get (inode, -1, this, NULL, buf, &ctx, 1);
- if ((ret == -1) || (ctx == NULL)) {
- gf_log (this->name, GF_LOG_WARNING, "cannot create quota "
- "context in inode (gfid:%s)", uuid_utoa (inode->gfid));
- op_ret = -1;
- op_errno = ENOMEM;
- goto unwind;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->buf = *buf;
-
- dentry = __quota_dentry_new (ctx, (char *)local->loc.name,
- local->loc.parent->gfid);
- if (dentry == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot create a new dentry (name:%s) for "
- "inode(gfid:%s)", local->loc.name,
- uuid_utoa (local->loc.inode->gfid));
- op_ret = -1;
- op_errno = ENOMEM;
- goto unlock;
- }
- }
-unlock:
- UNLOCK (&ctx->lock);
-
-unwind:
- QUOTA_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode,
- buf, preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-quota_mknod_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
-{
- quota_local_t *local = NULL;
- int32_t op_errno = EINVAL;
-
- local = frame->local;
- if (local == NULL) {
- gf_log (this->name, GF_LOG_WARNING, "local is NULL");
- goto unwind;
- }
-
- if (local->op_ret == -1) {
- op_errno = local->op_errno;
- goto unwind;
- }
-
- STACK_WIND (frame, quota_mknod_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod, loc, mode, rdev, umask,
- xdata);
-
- return 0;
-
-unwind:
- QUOTA_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
- return 0;
-}
-
-
-int
-quota_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
-{
- int32_t ret = -1;
- quota_local_t *local = NULL;
- call_stub_t *stub = NULL;
-
- local = quota_local_new ();
- if (local == NULL) {
- goto err;
- }
-
- frame->local = local;
-
- ret = loc_copy (&local->loc, loc);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "loc_copy failed");
- goto err;
- }
-
- stub = fop_mknod_stub (frame, quota_mknod_helper, loc, mode, rdev,
- umask, xdata);
- if (stub == NULL) {
- goto err;
- }
-
- local->link_count = 1;
- local->stub = stub;
- local->delta = 0;
-
- quota_check_limit (frame, loc->parent, this, NULL, NULL);
-
- stub = NULL;
-
- LOCK (&local->lock);
- {
- local->link_count = 0;
- if (local->validate_count == 0) {
- stub = local->stub;
- local->stub = NULL;
- }
- }
- UNLOCK (&local->lock);
-
- if (stub != NULL) {
- call_resume (stub);
- }
-
- return 0;
-err:
- QUOTA_STACK_UNWIND (mknod, frame, -1, ENOMEM, NULL, NULL, NULL, NULL,
- NULL);
-
- return 0;
-}
-
-int
-quota_setxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno, dict_t *xdata)
-{
- QUOTA_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-quota_setxattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
-{
- data_pair_t *trav = NULL;
- int op_errno = EINVAL;
- int op_ret = -1;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (loc, err);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict,
- trav, op_errno, err);
-
- STACK_WIND (frame, quota_setxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr,
- loc, dict, flags, xdata);
- return 0;
-err:
- QUOTA_STACK_UNWIND (setxattr, frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-int
-quota_fsetxattr_cbk (call_frame_t *frame, void *cookie,
- xlator_t *this, int op_ret, int op_errno, dict_t *xdata)
-{
- QUOTA_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-quota_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int flags, dict_t *xdata)
-{
- data_pair_t *trav = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict,
- trav, op_errno, err);
-
- STACK_WIND (frame, quota_fsetxattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsetxattr,
- fd, dict, flags, xdata);
- return 0;
- err:
- QUOTA_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-
-int
-quota_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- QUOTA_STACK_UNWIND (removexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-quota_removexattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, const char *name, dict_t *xdata)
-{
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (this, err);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.quota*",
- name, op_errno, err);
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (loc, err);
-
- STACK_WIND (frame, quota_removexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr,
- loc, name, xdata);
- return 0;
-err:
- QUOTA_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- return 0;
-}
-
-
-int
-quota_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- QUOTA_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-int
-quota_fremovexattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, const char *name, dict_t *xdata)
-{
- int32_t op_ret = -1;
- int32_t op_errno = EINVAL;
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- GF_IF_NATIVE_XATTR_GOTO ("trusted.quota*",
- name, op_errno, err);
-
- STACK_WIND (frame, quota_fremovexattr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fremovexattr,
- fd, name, xdata);
- return 0;
- err:
- QUOTA_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, NULL);
- return 0;
-}
-
-
-int32_t
-quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
-{
- inode_t *root_inode = NULL;
- quota_priv_t *priv = NULL;
- uint64_t value = 0;
- quota_inode_ctx_t *ctx = NULL;
- limits_t *limit_node = NULL;
- int64_t usage = -1;
- int64_t avail = -1;
- int64_t blocks = 0;
-
- root_inode = cookie;
-
- /* This fop will fail mostly in case of client disconnect's,
- * which is already logged. Hence, not logging here */
- if (op_ret == -1)
- goto unwind;
- /*
- * We should never get here unless quota_statfs (below) sent us a
- * cookie, and it would only do so if the value was non-NULL. This
- * check is therefore just routine defensive coding.
- */
- if (!root_inode) {
- gf_log(this->name,GF_LOG_WARNING,
- "null inode, cannot adjust for quota");
- goto unwind;
- }
- if (!root_inode->table || (root_inode != root_inode->table->root)) {
- gf_log(this->name,GF_LOG_WARNING,
- "non-root inode, cannot adjust for quota");
- goto unwind;
- }
-
- inode_ctx_get (root_inode, this, &value);
- if (!value) {
- goto unwind;
- }
- ctx = (quota_inode_ctx_t *)(unsigned long)value;
- usage = (ctx->size) / buf->f_bsize;
- priv = this->private;
-
- list_for_each_entry (limit_node, &priv->limit_head, limit_list) {
- /* Notice that this only works for volume-level quota. */
- if (strcmp (limit_node->path, "/") == 0) {
- blocks = limit_node->value / buf->f_bsize;
- if (usage > blocks) {
- break;
- }
-
- buf->f_blocks = blocks;
- avail = buf->f_blocks - usage;
- if (buf->f_bfree > avail) {
- buf->f_bfree = avail;
- }
- /*
- * We have to assume that the total assigned quota
- * won't cause us to dip into the reserved space,
- * because dealing with the overcommitted cases is
- * just too hairy (especially when different bricks
- * might be using different reserved percentages and
- * such).
- */
- buf->f_bavail = buf->f_bfree;
- break;
- }
- }
-
-unwind:
- if (root_inode) {
- inode_unref(root_inode);
- }
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
- return 0;
-}
-
-
-int32_t
-quota_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- inode_t *root_inode = NULL;
-
- if (loc->inode) {
- root_inode = loc->inode->table->root;
- inode_ref(root_inode);
- STACK_WIND_COOKIE (frame, quota_statfs_cbk, root_inode,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc, xdata);
- }
- else {
- /*
- * We have to make sure that we never get to quota_statfs_cbk
- * with a cookie that points to something other than an inode,
- * which is exactly what would happen with STACK_UNWIND using
- * that as a callback. Therefore, use default_statfs_cbk in
- * this case instead.
- */
- gf_log(this->name,GF_LOG_WARNING,
- "missing inode, cannot adjust for quota");
- STACK_WIND (frame, default_statfs_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->statfs, loc, xdata);
- }
- return 0;
-}
-
-
-int
-quota_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries,
- dict_t *xdata)
-{
- gf_dirent_t *entry = NULL;
-
- if (op_ret <= 0)
- goto unwind;
-
- list_for_each_entry (entry, &entries->list, list) {
- /* TODO: fill things */
- }
-
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
-
- return 0;
-}
-int
-quota_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
-{
- int ret = 0;
-
- if (dict) {
- ret = dict_set_uint64 (dict, QUOTA_SIZE_KEY, 0);
- if (ret < 0) {
- goto err;
- }
- }
-
- STACK_WIND (frame, quota_readdirp_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
- return 0;
-err:
- STACK_UNWIND_STRICT (readdirp, frame, -1, EINVAL, NULL, NULL);
+ QUOTA_STACK_UNWIND (fsetattr, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
@@ -3025,25 +2586,52 @@ quota_forget (xlator_t *this, inode_t *inode)
return 0;
}
-
int
-quota_parse_limits (quota_priv_t *priv, xlator_t *this, dict_t *xl_options,
- struct list_head *old_list)
+validate_options (xlator_t *this, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
+
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
+
+out:
+
+ return ret;
+}
+
+int32_t
+quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *options)
{
int32_t ret = -1;
char *str = NULL;
char *str_val = NULL;
- char *path = NULL, *saveptr = NULL;
+ char *path = NULL;
uint64_t value = 0;
- limits_t *quota_lim = NULL, *old = NULL;
+ limits_t *quota_lim = NULL;
- ret = dict_get_str (xl_options, "limit-set", &str);
+ ret = dict_get_str (options, "limit-set", &str);
if (str) {
- path = strtok_r (str, ":", &saveptr);
+ path = strtok (str, ":");
while (path) {
- str_val = strtok_r (NULL, ",", &saveptr);
+ str_val = strtok (NULL, ",");
ret = gf_string2bytesize (str_val, &value);
if (ret != 0)
@@ -3058,40 +2646,40 @@ quota_parse_limits (quota_priv_t *priv, xlator_t *this, dict_t *xl_options,
gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64,
quota_lim->path, quota_lim->value);
- if (old_list != NULL) {
- list_for_each_entry (old, old_list,
- limit_list) {
- if (strcmp (old->path, quota_lim->path)
- == 0) {
- uuid_copy (quota_lim->gfid,
- old->gfid);
- break;
- }
- }
- }
+ list_add_tail (&quota_lim->limit_list,
+ &priv->limit_head);
- LOCK (&priv->lock);
- {
- list_add_tail (&quota_lim->limit_list,
- &priv->limit_head);
- }
- UNLOCK (&priv->lock);
-
- path = strtok_r (NULL, ":", &saveptr);
+ path = strtok (NULL, ":");
}
} else {
gf_log (this->name, GF_LOG_INFO,
"no \"limit-set\" option provided");
}
- LOCK (&priv->lock);
- {
- list_for_each_entry (quota_lim, &priv->limit_head, limit_list) {
- gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64,
- quota_lim->path, quota_lim->value);
+ ret = dict_get_str (options, "timeout", &str);
+ if (str) {
+ ret = gf_string2bytesize (str, &value);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "Invalid quota timout value.");
+ ret = -1;
+ goto err;
+ } else {
+ priv->timeout = (int64_t) value;
+ gf_log (this->name, GF_LOG_INFO,
+ "quota timeout value = %"PRId64,
+ priv->timeout);
}
+ } else {
+ gf_log (this->name, GF_LOG_INFO, "timeout option not provided, "
+ "taking default as 0");
+ priv->timeout = 0;
+ }
+
+ list_for_each_entry (quota_lim, &priv->limit_head, limit_list) {
+ gf_log (this->name, GF_LOG_INFO, "%s:%"PRId64, quota_lim->path,
+ quota_lim->value);
}
- UNLOCK (&priv->lock);
ret = 0;
err:
@@ -3122,148 +2710,41 @@ init (xlator_t *this)
INIT_LIST_HEAD (&priv->limit_head);
- LOCK_INIT (&priv->lock);
-
this->private = priv;
- ret = quota_parse_limits (priv, this, this->options, NULL);
+ ret = quota_parse_options (priv, this, this->options);
if (ret) {
goto err;
}
- GF_OPTION_INIT ("timeout", priv->timeout, int64, err);
-
- this->local_pool = mem_pool_new (quota_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto err;
- }
-
ret = 0;
err:
return ret;
}
-void
-__quota_reconfigure_inode_ctx (xlator_t *this, inode_t *inode, limits_t *limit)
-{
- int ret = -1;
- quota_inode_ctx_t *ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("quota", this, out);
- GF_VALIDATE_OR_GOTO (this->name, inode, out);
- GF_VALIDATE_OR_GOTO (this->name, limit, out);
-
- ret = quota_inode_ctx_get (inode, limit->value, this, NULL, NULL, &ctx,
- 1);
- if ((ret == -1) || (ctx == NULL)) {
- gf_log (this->name, GF_LOG_WARNING, "cannot create quota "
- "context in inode(gfid:%s)",
- uuid_utoa (inode->gfid));
- goto out;
- }
-
- LOCK (&ctx->lock);
- {
- ctx->limit = limit->value;
- }
- UNLOCK (&ctx->lock);
-
-out:
- return;
-}
-
-
-void
-__quota_reconfigure (xlator_t *this, inode_table_t *itable, limits_t *limit)
-{
- inode_t *inode = NULL;
-
- if ((this == NULL) || (itable == NULL) || (limit == NULL)) {
- goto out;
- }
-
- if (!uuid_is_null (limit->gfid)) {
- inode = inode_find (itable, limit->gfid);
- } else {
- inode = inode_resolve (itable, limit->path);
- }
-
- if (inode != NULL) {
- __quota_reconfigure_inode_ctx (this, inode, limit);
- }
-
-out:
- return;
-}
-
-
int
reconfigure (xlator_t *this, dict_t *options)
{
- int32_t ret = -1;
- quota_priv_t *priv = NULL;
- limits_t *limit = NULL, *next = NULL, *new = NULL;
- struct list_head head = {0, };
- xlator_t *top = NULL;
- char found = 0;
+ int32_t ret = -1;
+ quota_priv_t *priv = NULL;
+ limits_t *limit = NULL;
+ limits_t *next = NULL;
priv = this->private;
- INIT_LIST_HEAD (&head);
+ list_for_each_entry_safe (limit, next, &priv->limit_head, limit_list) {
+ list_del (&limit->limit_list);
- LOCK (&priv->lock);
- {
- list_splice_init (&priv->limit_head, &head);
+ GF_FREE (limit);
}
- UNLOCK (&priv->lock);
- ret = quota_parse_limits (priv, this, options, &head);
- if (ret == -1) {
- gf_log ("quota", GF_LOG_WARNING,
- "quota reconfigure failed, "
- "new changes will not take effect");
- goto out;
- }
+ ret = quota_parse_options (priv, this, options);
- LOCK (&priv->lock);
- {
- top = ((glusterfs_ctx_t *)this->ctx)->active->top;
- GF_ASSERT (top);
+ if (ret == -1)
+ GF_ASSERT (0);
- list_for_each_entry (limit, &priv->limit_head, limit_list) {
- __quota_reconfigure (this, top->itable, limit);
- }
-
- list_for_each_entry_safe (limit, next, &head, limit_list) {
- found = 0;
- list_for_each_entry (new, &priv->limit_head,
- limit_list) {
- if (strcmp (new->path, limit->path) == 0) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- limit->value = -1;
- __quota_reconfigure (this, top->itable, limit);
- }
-
- list_del_init (&limit->limit_list);
- GF_FREE (limit);
- }
- }
- UNLOCK (&priv->lock);
-
- GF_OPTION_RECONF ("timeout", priv->timeout, options, int64, out);
-
- ret = 0;
-out:
return ret;
}
@@ -3276,32 +2757,25 @@ fini (xlator_t *this)
struct xlator_fops fops = {
- .statfs = quota_statfs,
- .lookup = quota_lookup,
- .writev = quota_writev,
- .create = quota_create,
- .mkdir = quota_mkdir,
- .truncate = quota_truncate,
- .ftruncate = quota_ftruncate,
- .unlink = quota_unlink,
- .symlink = quota_symlink,
- .link = quota_link,
- .rename = quota_rename,
- .getxattr = quota_getxattr,
- .fgetxattr = quota_fgetxattr,
- .stat = quota_stat,
- .fstat = quota_fstat,
- .readlink = quota_readlink,
- .readv = quota_readv,
- .fsync = quota_fsync,
- .setattr = quota_setattr,
- .fsetattr = quota_fsetattr,
- .mknod = quota_mknod,
- .setxattr = quota_setxattr,
- .fsetxattr = quota_fsetxattr,
- .removexattr = quota_removexattr,
- .fremovexattr = quota_fremovexattr,
- .readdirp = quota_readdirp,
+ .lookup = quota_lookup,
+ .writev = quota_writev,
+ .create = quota_create,
+ .mkdir = quota_mkdir,
+ .truncate = quota_truncate,
+ .ftruncate = quota_ftruncate,
+ .unlink = quota_unlink,
+ .symlink = quota_symlink,
+ .link = quota_link,
+ .rename = quota_rename,
+ .getxattr = quota_getxattr,
+ .fgetxattr = quota_fgetxattr,
+ .stat = quota_stat,
+ .fstat = quota_fstat,
+ .readlink = quota_readlink,
+ .readv = quota_readv,
+ .fsync = quota_fsync,
+ .setattr = quota_setattr,
+ .fsetattr = quota_fsetattr,
};
struct xlator_cbks cbks = {
@@ -3310,13 +2784,7 @@ struct xlator_cbks cbks = {
struct volume_options options[] = {
{.key = {"limit-set"}},
- {.key = {"timeout"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 0,
- .max = 60,
- .default_value = "0",
- .description = "quota caches the directory sizes on client. Timeout "
- "indicates the timeout for the cache to be revalidated."
+ {.key = {"timeout"}
},
{.key = {NULL}}
};
diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h
index cf9c4f9b7..7250a5dc9 100644
--- a/xlators/features/quota/src/quota.h
+++ b/xlators/features/quota/src/quota.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -60,6 +60,12 @@
UNLOCK (lock); \
} while (0)
+#define QUOTA_LOCAL_ALLOC_OR_GOTO(local, type, label) \
+ do { \
+ QUOTA_ALLOC_OR_GOTO (local, type, label); \
+ LOCK_INIT (&local->lock); \
+ } while (0)
+
#define QUOTA_ALLOC_OR_GOTO(var, type, label) \
do { \
var = GF_CALLOC (sizeof (type), 1, \
@@ -83,7 +89,7 @@
} \
STACK_UNWIND_STRICT (fop, frame, params); \
quota_local_cleanup (_this, _local); \
- mem_put (_local); \
+ GF_FREE (_local); \
} while (0)
#define QUOTA_FREE_CONTRIBUTION_NODE(_contribution) \
@@ -119,7 +125,7 @@
struct quota_dentry {
char *name;
- uuid_t par;
+ ino_t par;
struct list_head next;
};
typedef struct quota_dentry quota_dentry_t;
@@ -154,18 +160,16 @@ struct quota_local {
typedef struct quota_local quota_local_t;
struct quota_priv {
- int64_t timeout;
- struct list_head limit_head;
- gf_lock_t lock;
+ int64_t timeout;
+ struct list_head limit_head;
};
typedef struct quota_priv quota_priv_t;
struct limits {
struct list_head limit_list;
char *path;
- int64_t value;
- uuid_t gfid;
+ int64_t value;
};
-typedef struct limits limits_t;
+typedef struct limits limits_t;
uint64_t cn = 1;
diff --git a/xlators/features/read-only/src/Makefile.am b/xlators/features/read-only/src/Makefile.am
index 31ae4f340..15f49966f 100644
--- a/xlators/features/read-only/src/Makefile.am
+++ b/xlators/features/read-only/src/Makefile.am
@@ -1,19 +1,11 @@
-xlator_LTLIBRARIES = read-only.la worm.la
-
+xlator_LTLIBRARIES = read-only.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features
-noinst_HEADERS = read-only-common.h
-
read_only_la_LDFLAGS = -module -avoidversion
-read_only_la_SOURCES = read-only.c read-only-common.c
+read_only_la_SOURCES = read-only.c
read_only_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-worm_la_LDFLAGS = -module -avoidversion
-
-worm_la_SOURCES = read-only-common.c worm.c
-worm_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
diff --git a/xlators/features/read-only/src/read-only-common.c b/xlators/features/read-only/src/read-only-common.c
deleted file mode 100644
index dbb529ce5..000000000
--- a/xlators/features/read-only/src/read-only-common.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "defaults.h"
-
-int32_t
-ro_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (xattrop, frame, -1, EROFS, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_fxattrop (call_frame_t *frame, xlator_t *this,
- fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fxattrop, frame, -1, EROFS, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (entrylk, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (inodelk, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (finodelk, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
- struct gf_flock *flock, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (lk, frame, -1, EROFS, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetattr, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-
-int32_t
-ro_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (truncate, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (ftruncate, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-int
-ro_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (mknod, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
- return 0;
-}
-
-
-int
-ro_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (mkdir, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (unlink, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-
-int
-ro_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rmdir, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-
-int
-ro_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (symlink, frame, -1, EROFS, NULL, NULL, NULL,
- NULL, xdata);
- return 0;
-}
-
-
-
-int32_t
-ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (rename, frame, -1, EROFS, NULL, NULL, NULL, NULL,
- NULL, xdata);
- return 0;
-}
-
-
-int32_t
-ro_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (link, frame, -1, EROFS, NULL, NULL, NULL, NULL, xdata);
- return 0;
-}
-
-int32_t
-ro_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (create, frame, -1, EROFS, NULL, NULL, NULL,
- NULL, NULL, xdata);
- return 0;
-}
-
-
-static int32_t
-ro_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-ro_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- if (((flags & O_ACCMODE) == O_WRONLY) ||
- ((flags & O_ACCMODE) == O_RDWR)) {
- STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, xdata);
- return 0;
- }
-
- STACK_WIND (frame, ro_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
- return 0;
-}
-
-int32_t
-ro_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (writev, frame, -1, EROFS, NULL, NULL, xdata);
- return 0;
-}
-
-
-int32_t
-ro_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (setxattr, frame, -1, EROFS, xdata);
- return 0;
-}
-
-int32_t
-ro_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (removexattr, frame, -1, EROFS, xdata);
- return 0;
-}
diff --git a/xlators/features/read-only/src/read-only-common.h b/xlators/features/read-only/src/read-only-common.h
deleted file mode 100644
index 0a3f7dceb..000000000
--- a/xlators/features/read-only/src/read-only-common.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "defaults.h"
-
-int32_t
-ro_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
-
-int32_t
-ro_fxattrop (call_frame_t *frame, xlator_t *this,
- fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata);
-
-int32_t
-ro_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata);
-
-int32_t
-ro_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type
- type, dict_t *xdata);
-
-int32_t
-ro_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata);
-
-int32_t
-ro_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata);
-
-int32_t
-ro_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
- struct gf_flock *flock, dict_t *xdata);
-
-int32_t
-ro_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-
-int32_t
-ro_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata);
-
-
-int32_t
-ro_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, dict_t *xdata);
-
-int32_t
-ro_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, dict_t *xdata);
-
-int
-ro_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata);
-
-int
-ro_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata);
-
-int32_t
-ro_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata);
-
-int
-ro_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata);
-
-
-int
-ro_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata);
-
-int32_t
-ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata);
-
-int32_t
-ro_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc, dict_t *xdata);
-
-int32_t
-ro_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata);
-
-int32_t
-ro_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata);
-
-int32_t
-ro_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata);
-
-int32_t
-ro_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata);
-
-int32_t
-ro_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t off, uint32_t flags, struct iobref *iobref, dict_t *xdata);
-
-int32_t
-ro_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata);
-
-int32_t
-ro_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata);
diff --git a/xlators/features/read-only/src/read-only.c b/xlators/features/read-only/src/read-only.c
index b11e84f24..a4d7aa8dc 100644
--- a/xlators/features/read-only/src/read-only.c
+++ b/xlators/features/read-only/src/read-only.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -24,7 +24,226 @@
#include "xlator.h"
#include "defaults.h"
-#include "read-only-common.h"
+
+int32_t
+ro_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ STACK_UNWIND_STRICT (xattrop, frame, -1, EROFS, NULL);
+ return 0;
+}
+
+int32_t
+ro_fxattrop (call_frame_t *frame, xlator_t *this,
+ fd_t *fd, gf_xattrop_flags_t flags, dict_t *dict)
+{
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, EROFS, NULL);
+ return 0;
+}
+
+int32_t
+ro_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, const char *basename, entrylk_cmd cmd,
+ entrylk_type type)
+{
+ STACK_UNWIND_STRICT (entrylk, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type)
+{
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock)
+{
+ STACK_UNWIND_STRICT (inodelk, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct gf_flock *lock)
+{
+ STACK_UNWIND_STRICT (finodelk, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int cmd,
+ struct gf_flock *flock)
+{
+ STACK_UNWIND_STRICT (lk, frame, -1, EROFS, NULL);
+ return 0;
+}
+
+int32_t
+ro_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid)
+{
+ STACK_UNWIND_STRICT (setattr, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ro_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid)
+{
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+ro_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ STACK_UNWIND_STRICT (truncate, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ro_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+{
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+int
+ro_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, dict_t *params)
+{
+ STACK_UNWIND_STRICT (mknod, frame, -1, EROFS, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int
+ro_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *params)
+{
+ STACK_UNWIND_STRICT (mkdir, frame, -1, EROFS, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ro_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ STACK_UNWIND_STRICT (unlink, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+
+int
+ro_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+{
+ STACK_UNWIND_STRICT (rmdir, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+
+int
+ro_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, dict_t *params)
+{
+ STACK_UNWIND_STRICT (symlink, frame, -1, EROFS, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+ro_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ STACK_UNWIND_STRICT (rename, frame, -1, EROFS, NULL, NULL, NULL, NULL,
+ NULL);
+ return 0;
+}
+
+
+int32_t
+ro_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ STACK_UNWIND_STRICT (link, frame, -1, EROFS, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+int32_t
+ro_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd, dict_t *params)
+{
+ STACK_UNWIND_STRICT (create, frame, -1, EROFS, NULL, NULL, NULL,
+ NULL, NULL);
+ return 0;
+}
+
+
+static int32_t
+ro_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, fd_t *fd)
+{
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
+ return 0;
+}
+
+int32_t
+ro_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
+{
+ if (((flags & O_ACCMODE) == O_WRONLY) ||
+ ((flags & O_ACCMODE) == O_RDWR)) {
+ STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL);
+ return 0;
+ }
+
+ STACK_WIND (frame, ro_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+ return 0;
+}
+
+int32_t
+ro_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags)
+{
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, struct iobref *iobref)
+{
+ STACK_UNWIND_STRICT (writev, frame, -1, EROFS, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+ro_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags)
+{
+ STACK_UNWIND_STRICT (setxattr, frame, -1, EROFS);
+ return 0;
+}
+
+int32_t
+ro_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ STACK_UNWIND_STRICT (removexattr, frame, -1, EROFS);
+ return 0;
+}
int32_t
init (xlator_t *this)
diff --git a/xlators/features/read-only/src/worm.c b/xlators/features/read-only/src/worm.c
deleted file mode 100644
index d6c1e1b7d..000000000
--- a/xlators/features/read-only/src/worm.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "defaults.h"
-#include "read-only-common.h"
-
-static int32_t
-worm_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
- return 0;
-}
-
-int32_t
-worm_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
-{
- if ((((flags & O_ACCMODE) == O_WRONLY) ||
- ((flags & O_ACCMODE) == O_RDWR)) &&
- !(flags & O_APPEND)) {
- STACK_UNWIND_STRICT (open, frame, -1, EROFS, NULL, NULL);
- return 0;
- }
-
- STACK_WIND (frame, worm_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
- return 0;
-}
-
-int32_t
-init (xlator_t *this)
-{
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "translator not configured with exactly one child");
- return -1;
- }
-
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
-
- return 0;
-}
-
-
-void
-fini (xlator_t *this)
-{
- return;
-}
-
-struct xlator_fops fops = {
- .open = worm_open,
-
- .unlink = ro_unlink,
- .rmdir = ro_rmdir,
- .rename = ro_rename,
- .truncate = ro_truncate,
- .removexattr = ro_removexattr,
- .fsyncdir = ro_fsyncdir,
- .xattrop = ro_xattrop,
- .inodelk = ro_inodelk,
- .finodelk = ro_finodelk,
- .entrylk = ro_entrylk,
- .fentrylk = ro_fentrylk,
- .lk = ro_lk,
-};
-
-struct xlator_cbks cbks = {
-};
-
-struct volume_options options[] = {
- { .key = {NULL} },
-};
-
diff --git a/xlators/features/trash/src/trash-mem-types.h b/xlators/features/trash/src/trash-mem-types.h
index bb2cd33cf..888c86925 100644
--- a/xlators/features/trash/src/trash-mem-types.h
+++ b/xlators/features/trash/src/trash-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,7 +23,8 @@
#include "mem-types.h"
enum gf_trash_mem_types_ {
- gf_trash_mt_trash_private_t = gf_common_mt_end + 1,
+ gf_trash_mt_trash_local_t = gf_common_mt_end + 1,
+ gf_trash_mt_trash_private_t,
gf_trash_mt_char,
gf_trash_mt_trash_elim_pattern_t,
gf_trash_mt_end
diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c
index ded650271..c34593c71 100644
--- a/xlators/features/trash/src/trash.c
+++ b/xlators/features/trash/src/trash.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -63,7 +63,7 @@ trash_local_wipe (trash_local_t *local)
if (local->newfd)
fd_unref (local->newfd);
- mem_put (local);
+ GF_FREE (local);
out:
return;
}
@@ -170,7 +170,8 @@ trash_unlink_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
GF_FREE (cookie);
- GF_FREE (tmp_str);
+ if (tmp_str)
+ GF_FREE (tmp_str);
return 0;
}
@@ -441,7 +442,8 @@ trash_rename_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
GF_FREE (cookie); /* strdup (dir_name) was sent here :) */
- GF_FREE (tmp_str);
+ if (tmp_str)
+ GF_FREE (tmp_str);
return 0;
}
@@ -502,7 +504,9 @@ trash_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
trash_elim_pattern_t *trav = NULL;
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
- char timestr[64] = {0,};
+ struct tm *tm = NULL;
+ char timestr[256] = {0,};
+ time_t utime = 0;
int32_t match = 0;
priv = this->private;
@@ -529,7 +533,8 @@ trash_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (trash_local_t),
+ gf_trash_mt_trash_local_t);
if (!local) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
TRASH_STACK_UNWIND (rename, frame, -1, ENOMEM,
@@ -549,8 +554,9 @@ trash_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
{
/* append timestamp to file name */
/* TODO: can we make it optional? */
- gf_time_ftm (timestr, sizeof timestr, time (NULL),
- gf_timefmt_F_HMS);
+ utime = time (NULL);
+ tm = localtime (&utime);
+ strftime (timestr, 256, ".%Y-%m-%d-%H%M%S", tm);
strcat (local->newpath, timestr);
}
@@ -569,7 +575,9 @@ trash_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
trash_elim_pattern_t *trav = NULL;
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
- char timestr[64] = {0,};
+ struct tm *tm = NULL;
+ char timestr[256] = {0,};
+ time_t utime = 0;
int32_t match = 0;
priv = this->private;
@@ -602,7 +610,8 @@ trash_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (trash_local_t),
+ gf_trash_mt_trash_local_t);
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
TRASH_STACK_UNWIND (unlink, frame, -1, ENOMEM, NULL, NULL);
@@ -618,8 +627,9 @@ trash_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
/* append timestamp to file name */
/* TODO: can we make it optional? */
- gf_time_fmt (timestr, sizeof timestr, time (NULL),
- gf_timefmt_F_HMS);
+ utime = time (NULL);
+ tm = localtime (&utime);
+ strftime (timestr, 256, ".%Y-%m-%d-%H%M%S", tm);
strcat (local->newpath, timestr);
}
@@ -680,7 +690,7 @@ trash_truncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->fsize = stbuf->ia_size;
STACK_WIND (frame, trash_truncate_writev_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- local->newfd, vector, count, local->cur_offset, 0, iobuf);
+ local->newfd, vector, count, local->cur_offset, iobuf);
out:
return 0;
@@ -713,7 +723,7 @@ trash_truncate_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_truncate_readv_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
local->fd, (size_t)GF_BLOCK_READV_SIZE,
- local->cur_offset, 0);
+ local->cur_offset);
goto out;
}
@@ -753,7 +763,7 @@ trash_truncate_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_truncate_readv_cbk,
FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,
- local->fd, (size_t)GF_BLOCK_READV_SIZE, local->cur_offset, 0);
+ local->fd, (size_t)GF_BLOCK_READV_SIZE, local->cur_offset);
out:
return 0;
@@ -922,7 +932,8 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
GF_FREE (cookie); /* strdup (dir_name) was sent here :) */
- GF_FREE (tmp_str);
+ if (tmp_str)
+ GF_FREE (tmp_str);
return 0;
}
@@ -934,8 +945,10 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
{
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
- char timestr[64] = {0,};
+ struct tm *tm = NULL;
+ char timestr[256] = {0,};
char loc_newname[PATH_MAX] = {0,};
+ time_t utime = 0;
int32_t flags = 0;
priv = this->private;
@@ -967,8 +980,9 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
strcat (local->newpath, local->loc.path);
{
- gf_time_fmt (timestr, sizeof timestr, time (NULL),
- gf_timefmt_F_HMS);
+ utime = time (NULL);
+ tm = localtime (&utime);
+ strftime (timestr, 256, ".%Y-%m-%d-%H%M%S", tm);
strcat (local->newpath, timestr);
}
strcpy (loc_newname,local->loc.name);
@@ -977,6 +991,7 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->newloc.name = gf_strdup (loc_newname);
local->newloc.path = gf_strdup (local->newpath);
local->newloc.inode = inode_new (local->loc.inode->table);
+ local->newloc.ino = local->newloc.inode->ino;
local->newfd = fd_create (local->newloc.inode, frame->root->pid);
flags = O_CREAT|O_EXCL|O_WRONLY;
@@ -1030,7 +1045,8 @@ trash_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
LOCK_INIT (&frame->lock);
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (trash_local_t),
+ gf_trash_mt_trash_local_t);
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
TRASH_STACK_UNWIND (truncate, frame, -1, ENOMEM, NULL, NULL);
@@ -1095,7 +1111,7 @@ trash_ftruncate_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_ftruncate_readv_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
local->fd, (size_t)GF_BLOCK_READV_SIZE,
- local->cur_offset, 0);
+ local->cur_offset);
return 0;
}
@@ -1127,7 +1143,7 @@ trash_ftruncate_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_ftruncate_writev_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
- local->newfd, vector, count, local->cur_offset, 0, NULL);
+ local->newfd, vector, count, local->cur_offset, NULL);
return 0;
}
@@ -1179,7 +1195,7 @@ trash_ftruncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, trash_ftruncate_readv_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv, local->fd,
- (size_t)GF_BLOCK_READV_SIZE, local->cur_offset, 0);
+ (size_t)GF_BLOCK_READV_SIZE, local->cur_offset);
return 0;
}
@@ -1284,7 +1300,8 @@ trash_ftruncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
GF_FREE (cookie); /* strdup (dir_name) was sent here :) */
- GF_FREE (tmp_str);
+ if (tmp_str)
+ GF_FREE (tmp_str);
return 0;
}
@@ -1333,9 +1350,11 @@ trash_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
trash_private_t *priv = NULL;
trash_local_t *local = NULL;
dentry_t *dir_entry = NULL;
+ struct tm *tm = NULL;
char *pathbuf = NULL;
inode_t *newinode = NULL;
- char timestr[64];
+ time_t utime = 0;
+ char timestr[256];
int32_t retval = 0;
int32_t match = 0;
@@ -1367,14 +1386,18 @@ trash_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
return 0;
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (trash_local_t),
+ gf_trash_mt_trash_local_t);
if (!local) {
gf_log (this->name, GF_LOG_DEBUG, "out of memory");
TRASH_STACK_UNWIND (ftruncate, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
- gf_time_fmt (timestr, sizeof timestr, time (NULL), gf_timefmt_F_HMS);
+ utime = time (NULL);
+ tm = localtime (&utime);
+ strftime (timestr, 256, ".%Y-%m-%d-%H%M%S", tm);
+
strcpy (local->newpath, priv->trash_dir);
strcat (local->newpath, pathbuf);
strcat (local->newpath, timestr);
@@ -1388,6 +1411,7 @@ trash_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
local->newloc.path = local->newpath;
local->loc.inode = inode_ref (fd->inode);
+ local->loc.ino = fd->inode->ino;
local->loc.path = pathbuf;
local->fop_offset = offset;
@@ -1500,14 +1524,6 @@ init (xlator_t *this)
_priv->max_trash_file_size);
}
- this->local_pool = mem_pool_new (trash_local_t, 64);
- if (!this->local_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- return -1;
- }
-
-
this->private = (void *)_priv;
return 0;
}
@@ -1518,7 +1534,8 @@ fini (xlator_t *this)
trash_private_t *priv = NULL;
priv = this->private;
- GF_FREE (priv);
+ if (priv)
+ GF_FREE (priv);
return;
}
diff --git a/xlators/features/trash/src/trash.h b/xlators/features/trash/src/trash.h
index d385ee346..e8655322f 100644
--- a/xlators/features/trash/src/trash.h
+++ b/xlators/features/trash/src/trash.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/lib/src/libxlator.c b/xlators/lib/src/libxlator.c
index afa1d2ca3..3991d80ff 100644
--- a/xlators/lib/src/libxlator.c
+++ b/xlators/lib/src/libxlator.c
@@ -1,21 +1,3 @@
-/*Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
#include "mem-types.h"
#include "libxlator.h"
@@ -53,75 +35,91 @@ match_uuid_local (const char *name, char *uuid)
return 0;
}
-static void
-marker_local_incr_errcount (xl_marker_local_t *local, int op_errno)
-{
- if (!local)
- return;
- switch (op_errno) {
- case ENODATA:
- local->enodata_count++;
- break;
- case ENOENT:
- local->enoent_count++;
- break;
- case ENOTCONN:
- local->enotconn_count++;
- break;
- default:
- break;
- }
-}
+
/* Aggregate all the <volid>.xtime attrs of the cluster and send the max*/
int32_t
cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *dict)
{
- int32_t callcnt = 0;
- int ret = -1;
- uint32_t *net_timebuf = NULL;
- uint32_t host_timebuf[2] = {0,};
- char *marker_xattr = NULL;
- xl_marker_local_t *local = NULL;
- char *vol_uuid = NULL;
- char need_unwind = 0;
+ int32_t callcnt = 0;
+ int ret = -1;
+ uint32_t *net_timebuf = NULL;
+ uint32_t host_timebuf[2] = {0,};
+ char *marker_xattr = NULL;
+ struct marker_str *local = NULL;
+ char *vol_uuid = NULL;
if (!this || !frame || !frame->local || !cookie) {
- gf_log ("", GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
+ gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
goto out;
}
local = frame->local;
if (!local || !local->vol_uuid) {
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
goto out;
}
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
+ if (local->esomerr) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ }
+ goto done;
+ }
+
+ vol_uuid = local->vol_uuid;
+
+ if (op_ret && op_errno == ENODATA) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ local->enodata_count++;
+ }
+ goto done;
+ }
- if (local->esomerr)
- goto unlock;
+ if (op_ret && op_errno == ENOENT) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ local->enoent_count++;
+ }
+ goto done;
+ }
- vol_uuid = local->vol_uuid;
+ if (op_ret && op_errno == ENOTCONN) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ local->enotconn_count++;
+ }
+ goto done;
+ }
- if (op_ret) {
- marker_local_incr_errcount (local, op_errno);
+ if (op_ret) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
local->esomerr = op_errno;
- goto unlock;
}
+ goto done;
+ }
- if (!gf_asprintf (&marker_xattr, "%s.%s.%s",
+
+
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --local->call_count;
+ if (!gf_asprintf (& marker_xattr, "%s.%s.%s",
MARKER_XATTR_PREFIX, vol_uuid, XTIME)) {
op_errno = ENOMEM;
- goto unlock;
+ goto done;
}
@@ -129,37 +127,47 @@ cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log (this->name, GF_LOG_WARNING,
"Unable to get <uuid>.xtime attr");
local->noxtime_count++;
- goto unlock;
+ goto done;
}
if (local->has_xtime) {
+
get_hosttime (net_timebuf, host_timebuf);
if ( (host_timebuf[0]>local->host_timebuf[0]) ||
(host_timebuf[0] == local->host_timebuf[0] &&
host_timebuf[1] >= local->host_timebuf[1])) {
+
update_timebuf (net_timebuf, local->net_timebuf);
update_timebuf (host_timebuf, local->host_timebuf);
+
}
- } else {
+ }
+ else {
get_hosttime (net_timebuf, local->host_timebuf);
update_timebuf (net_timebuf, local->net_timebuf);
local->has_xtime = _gf_true;
}
+
+
}
-unlock:
+done:
UNLOCK (&frame->lock);
if (!callcnt) {
+
op_ret = 0;
op_errno = 0;
- need_unwind = 1;
-
if (local->has_xtime) {
- if (!dict)
+ if (!dict) {
dict = dict_new();
-
+ if (ret) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
ret = dict_set_static_bin (dict, marker_xattr,
(void *)local->net_timebuf, 8);
if (ret) {
@@ -167,141 +175,178 @@ unlock:
op_errno = ENOMEM;
goto out;
}
+ goto out;
}
if (local->noxtime_count)
goto out;
- if (local->enodata_count || local->enotconn_count ||
- local->enoent_count) {
+ if (local->enodata_count) {
+ op_ret = -1;
+ op_errno = ENODATA;
+ goto out;
+ }
+ if (local->enotconn_count) {
op_ret = -1;
- op_errno = local->enodata_count? ENODATA:
- local->enotconn_count? ENOTCONN:
- local->enoent_count? ENOENT:
- local->esomerr;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ if (local->enoent_count) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ }
+ else {
+ op_errno = local->esomerr;
+ goto out;
}
- }
-
out:
- if (need_unwind && local && local->xl_specf_unwind) {
- frame->local = local->xl_local;
- local->xl_specf_unwind (frame, op_ret,
- op_errno, dict, xdata);
- } else if (need_unwind) {
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno,
- dict, xdata);
+ if (local->xl_specf_unwind) {
+ frame->local = local->xl_local;
+ local->xl_specf_unwind (frame, op_ret,
+ op_errno, dict);
+ return 0;
+ }
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+
}
- GF_FREE (marker_xattr);
return 0;
}
int32_t
cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
+ int op_ret, int op_errno, dict_t *dict)
{
- int32_t callcnt = 0;
- struct volume_mark *volmark = NULL;
- xl_marker_local_t *local = NULL;
- int32_t ret = -1;
- char need_unwind = 0;
- char *vol_uuid = NULL;
+ int32_t callcnt = 0;
+ data_t *data = NULL;
+ struct volume_mark *volmark = NULL;
+ struct marker_str *marker = NULL;
+ char *vol_uuid;
if (!this || !frame || !cookie) {
- gf_log ("", GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
+ gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
goto out;
}
- local = frame->local;
+ marker = frame->local;
- if (!local) {
+ if (!marker) {
gf_log (this->name, GF_LOG_DEBUG, "possible NULL deref");
- need_unwind = 1;
goto out;
}
- LOCK (&frame->lock);
- {
- callcnt = --local->call_count;
- vol_uuid = local->vol_uuid;
+ vol_uuid = marker->vol_uuid;
+
+ if (op_ret && (ENOENT == op_errno)) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --marker->call_count;
+ marker->enoent_count++;
+ }
+ goto done;
+ }
- if (op_ret) {
- marker_local_incr_errcount (local, op_errno);
- goto unlock;
+ if (op_ret && (ENOTCONN == op_errno)) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --marker->call_count;
+ marker->enotconn_count++;
}
+ goto done;
+ }
+
+ if (!(data = dict_get (dict, GF_XATTR_MARKER_KEY))) {
+ LOCK (&frame->lock);
+ {
+ callcnt = --marker->call_count;
+ }
+ goto done;
+ }
+
+ volmark = (struct volume_mark *)data->data;
+
+ LOCK (&frame->lock);
+ {
+ callcnt = --marker->call_count;
- ret = dict_get_bin (dict, GF_XATTR_MARKER_KEY,
- (void *)&volmark);
- if (ret)
- goto unlock;
+ if (marker_has_volinfo (marker)) {
- if (marker_has_volinfo (local)) {
- if ((local->volmark->major != volmark->major) ||
- (local->volmark->minor != volmark->minor)) {
+ if ((marker->volmark->major != volmark->major) ||
+ (marker->volmark->minor != volmark->minor)) {
op_ret = -1;
op_errno = EINVAL;
- goto unlock;
+ goto done;
}
-
- if (local->retval)
- goto unlock;
else if (volmark->retval) {
- GF_FREE (local->volmark);
- local->volmark =
- memdup (volmark, sizeof (*volmark));
- local->retval = volmark->retval;
- } else if ((volmark->sec > local->volmark->sec) ||
- ((volmark->sec == local->volmark->sec) &&
- (volmark->usec >= local->volmark->usec))) {
- GF_FREE (local->volmark);
- local->volmark =
- memdup (volmark, sizeof (*volmark));
+ data_unref ((data_t *) marker->volmark);
+ marker->volmark = volmark;
+ callcnt = 0;
+ }
+ else if ( (volmark->sec > marker->volmark->sec) ||
+ ((volmark->sec == marker->volmark->sec)
+ && (volmark->usec >= marker->volmark->usec))) {
+
+ GF_FREE (marker->volmark);
+ marker->volmark = memdup (volmark, sizeof (struct volume_mark));
+ VALIDATE_OR_GOTO (marker->volmark, done);
}
} else {
- local->volmark = memdup (volmark, sizeof (*volmark));
- VALIDATE_OR_GOTO (local->volmark, unlock);
+ marker->volmark = memdup (volmark, sizeof (struct volume_mark));
+ VALIDATE_OR_GOTO (marker->volmark, done);
+
uuid_unparse (volmark->uuid, vol_uuid);
if (volmark->retval)
- local->retval = volmark->retval;
+ callcnt = 0;
}
}
-unlock:
+done:
UNLOCK (&frame->lock);
if (!callcnt) {
op_ret = 0;
op_errno = 0;
- need_unwind = 1;
-
- if (marker_has_volinfo (local)) {
- if (!dict)
+ if (marker_has_volinfo (marker)) {
+ if (!dict) {
dict = dict_new();
-
+ if (!dict) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
if (dict_set_bin (dict, GF_XATTR_MARKER_KEY,
- local->volmark,
+ marker->volmark,
sizeof (struct volume_mark))) {
op_ret = -1;
op_errno = ENOMEM;
}
- } else {
+ goto out;
+ }
+ if (marker->enotconn_count) {
op_ret = -1;
- op_errno = local->enotconn_count? ENOTCONN:
- local->enoent_count? ENOENT:EINVAL;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ if (marker->enoent_count) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ }
+ else {
+ op_ret = -1;
+ op_errno = EINVAL;
}
- }
out:
- if (need_unwind && local && local->xl_specf_unwind) {
- frame->local = local->xl_local;
- local->xl_specf_unwind (frame, op_ret,
- op_errno, dict, xdata);
- return 0;
- } else if (need_unwind){
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno,
- dict, xdata);
+ if (marker->xl_specf_unwind) {
+ frame->local = marker->xl_local;
+ marker->xl_specf_unwind (frame, op_ret,
+ op_errno, dict);
+ return 0;
+ }
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
}
return 0;
}
@@ -314,8 +359,8 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
xlator_t **sub_volumes, int count, int type,
char *vol_uuid)
{
- int i = 0;
- xl_marker_local_t *local = NULL;
+ int i;
+ struct marker_str *local;
VALIDATE_OR_GOTO (frame, err);
VALIDATE_OR_GOTO (this, err);
@@ -328,35 +373,33 @@ cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
local = GF_CALLOC (sizeof (struct marker_str), 1,
gf_common_mt_libxl_marker_local);
- if (!local)
- goto err;
-
local->xl_local = xl_local;
+ frame->local = local;
+
local->call_count = count;
+
local->xl_specf_unwind = xl_specf_getxattr_unwind;
- local->vol_uuid = vol_uuid;
- frame->local = local;
+ local->vol_uuid = vol_uuid;
for (i=0; i < count; i++) {
if (MARKER_UUID_TYPE == type)
STACK_WIND (frame, cluster_markeruuid_cbk,
*(sub_volumes + i),
(*(sub_volumes + i))->fops->getxattr,
- loc, name, NULL);
+ loc, name);
else if (MARKER_XTIME_TYPE == type)
STACK_WIND (frame, cluster_markerxtime_cbk,
*(sub_volumes + i),
(*(sub_volumes + i))->fops->getxattr,
- loc, name, NULL);
+ loc, name);
else {
gf_log (this->name, GF_LOG_WARNING,
- "Unrecognized type (%d) of marker attr "
- "received", type);
+ "Unrecognized type of marker attr recived");
STACK_WIND (frame, default_getxattr_cbk,
*(sub_volumes + i),
(*(sub_volumes + i))->fops->getxattr,
- loc, name, NULL);
+ loc, name);
break;
}
}
diff --git a/xlators/lib/src/libxlator.h b/xlators/lib/src/libxlator.h
index 560e388c7..af7eb434a 100644
--- a/xlators/lib/src/libxlator.h
+++ b/xlators/lib/src/libxlator.h
@@ -1,21 +1,3 @@
-/*Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
#ifndef _LIBXLATOR_H
#define _LIBXLATOR_H
@@ -44,8 +26,7 @@
typedef int32_t (*xlator_specf_unwind_t) (call_frame_t *frame,
- int op_ret, int op_errno,
- dict_t *dict, dict_t *xdata);
+ int op_ret, int op_errno, dict_t *dict);
struct volume_mark {
@@ -75,13 +56,10 @@ struct marker_str {
xlator_specf_unwind_t xl_specf_unwind;
void *xl_local;
char *vol_uuid;
- uint8_t retval;
};
-typedef struct marker_str xl_marker_local_t;
-
static inline gf_boolean_t
-marker_has_volinfo (xl_marker_local_t *marker)
+marker_has_volinfo (struct marker_str *marker)
{
if (marker->volmark)
return _gf_true;
@@ -91,11 +69,11 @@ marker_has_volinfo (xl_marker_local_t *marker)
int32_t
cluster_markerxtime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata);
+ int op_ret, int op_errno, dict_t *dict);
int32_t
cluster_markeruuid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, dict_t *dict, dict_t *xdata);
+ int op_ret, int op_errno, dict_t *dict);
int32_t
cluster_getmarkerattr (call_frame_t *frame,xlator_t *this, loc_t *loc,
diff --git a/xlators/meta/src/meta-mem-types.h b/xlators/meta/src/meta-mem-types.h
index 9585b7838..15bb77ba5 100644
--- a/xlators/meta/src/meta-mem-types.h
+++ b/xlators/meta/src/meta-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/meta.c b/xlators/meta/src/meta.c
index 412b4a2b5..2f3231be5 100644
--- a/xlators/meta/src/meta.c
+++ b/xlators/meta/src/meta.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/meta.h b/xlators/meta/src/meta.h
index 5636487c9..681fe2ac0 100644
--- a/xlators/meta/src/meta.h
+++ b/xlators/meta/src/meta.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/misc.c b/xlators/meta/src/misc.c
index bea07e70c..cf59ffe97 100644
--- a/xlators/meta/src/misc.c
+++ b/xlators/meta/src/misc.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/misc.h b/xlators/meta/src/misc.h
index f934a6d8d..49e6ea157 100644
--- a/xlators/meta/src/misc.h
+++ b/xlators/meta/src/misc.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/tree.c b/xlators/meta/src/tree.c
index 2ea99fa5b..79cf2f77f 100644
--- a/xlators/meta/src/tree.c
+++ b/xlators/meta/src/tree.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -123,7 +123,7 @@ lookup_meta_entry (meta_dirent_t *root, const char *path,
gf_asprintf (remain, "/%s/%s", *remain, piece);
else
gf_asprintf (remain, "/%s", piece);
- GF_FREE (tmp);
+ if (tmp) GF_FREE (tmp);
piece = strtok (NULL, "/");
}
}
diff --git a/xlators/meta/src/tree.h b/xlators/meta/src/tree.h
index 8157148db..f52441146 100644
--- a/xlators/meta/src/tree.h
+++ b/xlators/meta/src/tree.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/view.c b/xlators/meta/src/view.c
index ba3c30e0b..3b9d4c058 100644
--- a/xlators/meta/src/view.c
+++ b/xlators/meta/src/view.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/meta/src/view.h b/xlators/meta/src/view.h
index 440c0d34d..62cd88571 100644
--- a/xlators/meta/src/view.h
+++ b/xlators/meta/src/view.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
index 485350b3d..1c89dba97 100644
--- a/xlators/mgmt/glusterd/src/Makefile.am
+++ b/xlators/mgmt/glusterd/src/Makefile.am
@@ -1,40 +1,23 @@
xlator_LTLIBRARIES = glusterd.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt
-glusterd_la_CPPFLAGS = "-DFILTERDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/filter\""
-glusterd_la_LDFLAGS = -module -avoidversion $(LIBXML2_LIBS) -lcrypto
-glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
- glusterd-op-sm.c glusterd-utils.c glusterd-rpc-ops.c \
- glusterd-store.c glusterd-handshake.c glusterd-pmap.c \
- glusterd-volgen.c glusterd-rebalance.c glusterd-quota.c \
- glusterd-geo-rep.c glusterd-replace-brick.c glusterd-log-ops.c \
- glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \
- glusterd-syncop.c glusterd-hooks.c
+glusterd_la_LDFLAGS = -module -avoidversion
+glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c glusterd-op-sm.c \
+ glusterd-utils.c glusterd-rpc-ops.c glusterd-store.c glusterd-handshake.c \
+ glusterd-pmap.c glusterd-volgen.c glusterd-rebalance.c
-glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
- $(top_builddir)/rpc/xdr/src/libgfxdr.la \
+glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la\
+ $(top_builddir)/rpc/xdr/src/libgfxdr.la\
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la
-noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h \
- glusterd-sm.h glusterd-store.h glusterd-mem-types.h \
- glusterd-pmap.h glusterd-volgen.h glusterd-mountbroker.h \
- glusterd-syncop.h glusterd-hooks.h
+noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h glusterd-sm.h \
+ glusterd-store.h glusterd-mem-types.h glusterd-pmap.h glusterd-volgen.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\
- -I$(rpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree \
- -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src \
- -I$(CONTRIBDIR)/uuid \
- -DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \
- -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
- -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(LIBXML2_CFLAGS)
+ -I$(rpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree -I$(top_srcdir)/rpc/xdr/src\
+ -I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/uuid -I$(top_srcdir)/contrib/md5 -DGFS_PREFIX=\"$(prefix)\" \
+ -DDATADIR=\"$(localstatedir)\" -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\
+ -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE)
CLEANFILES =
-
-install-data-hook:
-
-if GF_INSTALL_VAR_LIB_GLUSTERD
- $(mkdir_p) /var/lib/
- (stat /etc/glusterd && mv /etc/glusterd /var/lib/) || true;
- (ln -sf /var/lib/glusterd /etc/glusterd) || true;
-endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
deleted file mode 100644
index ce81c0c79..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
+++ /dev/null
@@ -1,1616 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-#include "run.h"
-#include <sys/signal.h>
-
-/* misc */
-
-/* In this function, we decide, based on the 'count' of the brick,
- where to add it in the current volume. 'count' tells us already
- how many of the given bricks are added. other argument are self-
- descriptive. */
-int
-add_brick_at_right_order (glusterd_brickinfo_t *brickinfo,
- glusterd_volinfo_t *volinfo, int count,
- int32_t stripe_cnt, int32_t replica_cnt)
-{
- int idx = 0;
- int i = 0;
- int sub_cnt = 0;
- glusterd_brickinfo_t *brick = NULL;
-
- /* The complexity of the function is in deciding at which index
- to add new brick. Even though it can be defined with a complex
- single formula for all volume, it is seperated out to make it
- more readable */
- if (stripe_cnt) {
- /* common formula when 'stripe_count' is set */
- /* idx = ((count / ((stripe_cnt * volinfo->replica_count) -
- volinfo->dist_leaf_count)) * volinfo->dist_leaf_count) +
- (count + volinfo->dist_leaf_count);
- */
-
- sub_cnt = volinfo->dist_leaf_count;
-
- idx = ((count / ((stripe_cnt * volinfo->replica_count) -
- sub_cnt)) * sub_cnt) +
- (count + sub_cnt);
-
- goto insert_brick;
- }
-
- /* replica count is set */
- /* common formula when 'replica_count' is set */
- /* idx = ((count / (replica_cnt - existing_replica_count)) *
- existing_replica_count) +
- (count + existing_replica_count);
- */
-
- sub_cnt = volinfo->replica_count;
- idx = (count / (replica_cnt - sub_cnt) * sub_cnt) +
- (count + sub_cnt);
-
-insert_brick:
- i = 0;
- list_for_each_entry (brick, &volinfo->bricks, brick_list) {
- i++;
- if (i < idx)
- continue;
- gf_log (THIS->name, GF_LOG_DEBUG, "brick:%s index=%d, count=%d",
- brick->path, idx, count);
-
- list_add (&brickinfo->brick_list, &brick->brick_list);
- break;
- }
-
- return 0;
-}
-
-
-static int
-gd_addbr_validate_stripe_count (glusterd_volinfo_t *volinfo, int stripe_count,
- int total_bricks, int *type, char *err_str,
- size_t err_len)
-{
- int ret = -1;
-
- switch (volinfo->type) {
- case GF_CLUSTER_TYPE_NONE:
- if ((volinfo->brick_count * stripe_count) == total_bricks) {
- /* Change the volume type */
- *type = GF_CLUSTER_TYPE_STRIPE;
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the type of volume %s from "
- "'distribute' to 'stripe'", volinfo->volname);
- ret = 0;
- goto out;
- } else {
- snprintf (err_str, err_len, "Incorrect number of "
- "bricks (%d) supplied for stripe count (%d).",
- (total_bricks - volinfo->brick_count),
- stripe_count);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- break;
- case GF_CLUSTER_TYPE_REPLICATE:
- if (!(total_bricks % (volinfo->replica_count * stripe_count))) {
- /* Change the volume type */
- *type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the type of volume %s from "
- "'replicate' to 'replicate-stripe'",
- volinfo->volname);
- ret = 0;
- goto out;
- } else {
- snprintf (err_str, err_len, "Incorrect number of "
- "bricks (%d) supplied for changing volume's "
- "stripe count to %d, need at least %d bricks",
- (total_bricks - volinfo->brick_count),
- stripe_count,
- (volinfo->replica_count * stripe_count));
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- break;
- case GF_CLUSTER_TYPE_STRIPE:
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- if (stripe_count < volinfo->stripe_count) {
- snprintf (err_str, err_len,
- "Incorrect stripe count (%d) supplied. "
- "Volume already has stripe count (%d)",
- stripe_count, volinfo->stripe_count);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- if (stripe_count == volinfo->stripe_count) {
- if (!(total_bricks % volinfo->dist_leaf_count)) {
- /* its same as the one which exists */
- ret = 1;
- goto out;
- }
- }
- if (stripe_count > volinfo->stripe_count) {
- /* We have to make sure before and after 'add-brick',
- the number or subvolumes for distribute will remain
- same, when stripe count is given */
- if ((volinfo->brick_count * (stripe_count *
- volinfo->replica_count)) ==
- (total_bricks * volinfo->dist_leaf_count)) {
- /* Change the dist_leaf_count */
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the stripe count of "
- "volume %s from %d to %d",
- volinfo->volname,
- volinfo->stripe_count, stripe_count);
- ret = 0;
- goto out;
- }
- }
- break;
- }
-
-out:
- return ret;
-}
-
-static int
-gd_addbr_validate_replica_count (glusterd_volinfo_t *volinfo, int replica_count,
- int total_bricks, int *type, char *err_str,
- int err_len)
-{
- int ret = -1;
-
- /* replica count is set */
- switch (volinfo->type) {
- case GF_CLUSTER_TYPE_NONE:
- if ((volinfo->brick_count * replica_count) == total_bricks) {
- /* Change the volume type */
- *type = GF_CLUSTER_TYPE_REPLICATE;
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the type of volume %s from "
- "'distribute' to 'replica'", volinfo->volname);
- ret = 0;
- goto out;
-
- } else {
- snprintf (err_str, err_len, "Incorrect number of "
- "bricks (%d) supplied for replica count (%d).",
- (total_bricks - volinfo->brick_count),
- replica_count);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- break;
- case GF_CLUSTER_TYPE_STRIPE:
- if (!(total_bricks % (volinfo->dist_leaf_count * replica_count))) {
- /* Change the volume type */
- *type = GF_CLUSTER_TYPE_STRIPE_REPLICATE;
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the type of volume %s from "
- "'stripe' to 'replicate-stripe'",
- volinfo->volname);
- ret = 0;
- goto out;
- } else {
- snprintf (err_str, err_len, "Incorrect number of "
- "bricks (%d) supplied for changing volume's "
- "replica count to %d, need at least %d "
- "bricks",
- (total_bricks - volinfo->brick_count),
- replica_count, (volinfo->dist_leaf_count *
- replica_count));
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- break;
- case GF_CLUSTER_TYPE_REPLICATE:
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- if (replica_count < volinfo->replica_count) {
- snprintf (err_str, err_len,
- "Incorrect replica count (%d) supplied. "
- "Volume already has (%d)",
- replica_count, volinfo->replica_count);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- if (replica_count == volinfo->replica_count) {
- if (!(total_bricks % volinfo->dist_leaf_count)) {
- ret = 1;
- goto out;
- }
- }
- if (replica_count > volinfo->replica_count) {
- /* We have to make sure before and after 'add-brick',
- the number or subvolumes for distribute will remain
- same, when replica count is given */
- if ((total_bricks * volinfo->dist_leaf_count) ==
- (volinfo->brick_count * (replica_count *
- volinfo->stripe_count))) {
- /* Change the dist_leaf_count */
- gf_log (THIS->name, GF_LOG_INFO,
- "Changing the replica count of "
- "volume %s from %d to %d",
- volinfo->volname, volinfo->replica_count,
- replica_count);
- ret = 0;
- goto out;
- }
- }
- break;
- }
-out:
- return ret;
-}
-
-static int
-gd_rmbr_validate_replica_count (glusterd_volinfo_t *volinfo,
- int32_t replica_count,
- int32_t brick_count, char *err_str,
- size_t err_len)
-{
- int ret = -1;
- int replica_nodes = 0;
-
- switch (volinfo->type) {
- case GF_CLUSTER_TYPE_NONE:
- case GF_CLUSTER_TYPE_STRIPE:
- snprintf (err_str, err_len,
- "replica count (%d) option given for non replicate "
- "volume %s", replica_count, volinfo->volname);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", err_str);
- goto out;
-
- case GF_CLUSTER_TYPE_REPLICATE:
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- /* in remove brick, you can only reduce the replica count */
- if (replica_count > volinfo->replica_count) {
- snprintf (err_str, err_len,
- "given replica count (%d) option is more "
- "than volume %s's replica count (%d)",
- replica_count, volinfo->volname,
- volinfo->replica_count);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", err_str);
- goto out;
- }
- if (replica_count == volinfo->replica_count) {
- /* This means the 'replica N' option on CLI was
- redundant. Check if the total number of bricks given
- for removal is same as 'dist_leaf_count' */
- if (brick_count % volinfo->dist_leaf_count) {
- snprintf (err_str, err_len,
- "number of bricks provided (%d) is "
- "not valid. need at least %d "
- "(or %dxN)", brick_count,
- volinfo->dist_leaf_count,
- volinfo->dist_leaf_count);
- gf_log (THIS->name, GF_LOG_WARNING, "%s",
- err_str);
- goto out;
- }
- ret = 1;
- goto out;
- }
-
- replica_nodes = ((volinfo->brick_count /
- volinfo->replica_count) *
- (volinfo->replica_count - replica_count));
-
- if (brick_count % replica_nodes) {
- snprintf (err_str, err_len,
- "need %d(xN) bricks for reducing replica "
- "count of the volume from %d to %d",
- replica_nodes, volinfo->replica_count,
- replica_count);
- goto out;
- }
- break;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-/* Handler functions */
-int
-glusterd_handle_add_brick (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- char *bricks = NULL;
- char *volname = NULL;
- int brick_count = 0;
- char *brick_list = NULL;
- void *cli_rsp = NULL;
- char err_str[2048] = {0,};
- gf_cli_rsp rsp = {0,};
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- int total_bricks = 0;
- int32_t replica_count = 0;
- int32_t stripe_count = 0;
- int type = 0;
-
- this = THIS;
- GF_ASSERT(this);
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- snprintf (err_str, sizeof (err_str), "Garbage args received");
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received add brick req");
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the buffer");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- gf_cmd_log ("Volume add-brick", "on volname: %s attempted",
- volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- goto out;
- }
-
- if (!(ret = glusterd_check_volume_exists (volname))) {
- ret = -1;
- snprintf(err_str, 2048, "Volume %s does not exist", volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "brick count");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (!ret) {
- gf_log (THIS->name, GF_LOG_INFO, "replica-count is %d",
- replica_count);
- }
-
- ret = dict_get_int32 (dict, "stripe-count", &stripe_count);
- if (!ret) {
- gf_log (THIS->name, GF_LOG_INFO, "stripe-count is %d",
- stripe_count);
- }
-
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volinfo "
- "for volume name %s", volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
-
- }
-
- total_bricks = volinfo->brick_count + brick_count;
-
- if (!stripe_count && !replica_count) {
- if (volinfo->type == GF_CLUSTER_TYPE_NONE)
- goto brick_val;
-
- if ((volinfo->brick_count < volinfo->dist_leaf_count) &&
- (total_bricks <= volinfo->dist_leaf_count))
- goto brick_val;
-
- if ((brick_count % volinfo->dist_leaf_count) != 0) {
- snprintf(err_str, 2048, "Incorrect number of bricks"
- " supplied %d with count %d",
- brick_count, volinfo->dist_leaf_count);
- gf_log("glusterd", GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
- goto brick_val;
- /* done with validation.. below section is if stripe|replica
- count is given */
- }
-
- /* These bricks needs to be added one per a replica or stripe volume */
- if (stripe_count) {
- ret = gd_addbr_validate_stripe_count (volinfo, stripe_count,
- total_bricks, &type,
- err_str,
- sizeof (err_str));
- if (ret == -1) {
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- /* if stripe count is same as earlier, set it back to 0 */
- if (ret == 1)
- stripe_count = 0;
-
- ret = dict_set_int32 (dict, "stripe-count", stripe_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set the stripe-count in dict");
- goto out;
- }
- goto brick_val;
- }
-
- ret = gd_addbr_validate_replica_count (volinfo, replica_count,
- total_bricks,
- &type, err_str,
- sizeof (err_str));
- if (ret == -1) {
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- /* if replica count is same as earlier, set it back to 0 */
- if (ret == 1)
- replica_count = 0;
-
- ret = dict_set_int32 (dict, "replica-count", replica_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set the replica-count in dict");
- goto out;
- }
-
-brick_val:
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "bricks");
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- gf_cmd_log ("Volume add-brick", "volname: %s type %d count:%d bricks:%s"
- ,volname, volinfo->type, brick_count, brick_list);
-
- if (type != volinfo->type) {
- ret = dict_set_int32 (dict, "type", type);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set the new type in dict");
- }
-
- ret = glusterd_op_begin (req, GD_OP_ADD_BRICK, dict);
-
-out:
- gf_cmd_log ("Volume add-brick","on volname: %s %s", volname,
- (ret != 0)? "FAILED" : "SUCCESS");
- if (ret) {
- if (dict)
- dict_unref (dict);
- rsp.op_ret = -1;
- rsp.op_errno = 0;
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str), "Operation failed");
- rsp.op_errstr = err_str;
- cli_rsp = &rsp;
- glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
- ret = 0; //sent error to cli, prevent second reply
- }
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- return ret;
-}
-
-
-int
-glusterd_handle_remove_brick (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- int32_t count = 0;
- char *brick = NULL;
- char key[256] = {0,};
- char *brick_list = NULL;
- int i = 1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t pos = 0;
- int32_t sub_volume = 0;
- int32_t sub_volume_start = 0;
- int32_t sub_volume_end = 0;
- glusterd_brickinfo_t *tmp = NULL;
- char err_str[2048] = {0};
- gf_cli_rsp rsp = {0,};
- void *cli_rsp = NULL;
- char vol_type[256] = {0,};
- int32_t replica_count = 0;
- int32_t brick_index = 0;
- int32_t tmp_brick_idx = 0;
- int found = 0;
- int diff_count = 0;
- char *volname = 0;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
-
- gf_log ("glusterd", GF_LOG_INFO, "Received rem brick req");
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to get volname");
- goto out;
- }
-
- gf_cmd_log ("Volume remove-brick","on volname: %s attempted", volname);
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (err_str, 2048, "Volume %s does not exist",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (!ret) {
- gf_log (THIS->name, GF_LOG_INFO,
- "request to change replica-count to %d", replica_count);
- ret = gd_rmbr_validate_replica_count (volinfo, replica_count,
- count, err_str,
- sizeof (err_str));
- if (ret < 0) {
- /* logging and error msg are done in above function
- itself */
- goto out;
- }
- dict_del (dict, "replica-count");
- if (ret) {
- replica_count = 0;
- } else {
- ret = dict_set_int32 (dict, "replica-count",
- replica_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to set the replica_count "
- "in dict");
- goto out;
- }
- }
- }
-
- /* 'vol_type' is used for giving the meaning full error msg for user */
- if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
- strcpy (vol_type, "replica");
- } else if (volinfo->type == GF_CLUSTER_TYPE_STRIPE) {
- strcpy (vol_type, "stripe");
- } else if (volinfo->type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) {
- strcpy (vol_type, "stripe-replicate");
- } else {
- strcpy (vol_type, "distribute");
- }
-
- /* Do not allow remove-brick if the volume is plain stripe */
- if ((volinfo->type == GF_CLUSTER_TYPE_STRIPE) &&
- (volinfo->brick_count == volinfo->stripe_count)) {
- snprintf (err_str, 2048,
- "Removing brick from a plain stripe is not allowed");
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- if (!replica_count &&
- (volinfo->type == GF_CLUSTER_TYPE_STRIPE_REPLICATE) &&
- (volinfo->brick_count == volinfo->dist_leaf_count)) {
- snprintf (err_str, 2048,
- "Removing bricks from stripe-replicate"
- " configuration is not allowed without reducing "
- "replica or stripe count explicitly.");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- if (!replica_count &&
- (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) &&
- (volinfo->brick_count == volinfo->dist_leaf_count)) {
- snprintf (err_str, 2048,
- "Removing bricks from replicate configuration "
- "is not allowed without reducing replica count "
- "explicitly.");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
-
- /* Do not allow remove-brick if the bricks given is less than
- the replica count or stripe count */
- if (!replica_count && (volinfo->type != GF_CLUSTER_TYPE_NONE)) {
- if (volinfo->dist_leaf_count &&
- (count % volinfo->dist_leaf_count)) {
- snprintf (err_str, 2048, "Remove brick incorrect"
- " brick count of %d for %s %d",
- count, vol_type, volinfo->dist_leaf_count);
- gf_log ("", GF_LOG_ERROR, "%s", err_str);
- ret = -1;
- goto out;
- }
- }
-
- brick_list = GF_MALLOC (120000 * sizeof(*brick_list),gf_common_mt_char);
-
- if (!brick_list) {
- ret = -1;
- goto out;
- }
-
- strcpy (brick_list, " ");
- while ( i <= count) {
- snprintf (key, 256, "brick%d", i);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get %s", key);
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG, "Remove brick count %d brick: %s",
- i, brick);
-
- ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo,
- &brickinfo);
- if (ret) {
- snprintf(err_str, 2048,"Incorrect brick %s for volume"
- " %s", brick, volname);
- gf_log ("", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
- strcat(brick_list, brick);
- strcat(brick_list, " ");
-
- i++;
- if ((volinfo->type == GF_CLUSTER_TYPE_NONE) ||
- (volinfo->brick_count <= volinfo->dist_leaf_count))
- continue;
-
- if (replica_count) {
- /* do the validation of bricks here */
- /* -2 because i++ is already done, and i starts with 1,
- instead of 0 */
- diff_count = (volinfo->replica_count - replica_count);
- brick_index = (((i -2) / diff_count) * volinfo->replica_count);
- tmp_brick_idx = 0;
- found = 0;
- list_for_each_entry (tmp, &volinfo->bricks, brick_list) {
- tmp_brick_idx++;
- gf_log (THIS->name, GF_LOG_TRACE,
- "validate brick %s:%s (%d %d %d)",
- tmp->hostname, tmp->path, tmp_brick_idx,
- brick_index, volinfo->replica_count);
- if (tmp_brick_idx <= brick_index)
- continue;
- if (tmp_brick_idx >
- (brick_index + volinfo->replica_count))
- break;
- if ((!strcmp (tmp->hostname,brickinfo->hostname)) &&
- !strcmp (tmp->path, brickinfo->path)) {
- found = 1;
- break;
- }
- }
- if (found)
- continue;
-
- snprintf(err_str, 2048,"Bricks are from same subvol");
- gf_log (THIS->name, GF_LOG_INFO,
- "failed to validate brick %s:%s (%d %d %d)",
- tmp->hostname, tmp->path, tmp_brick_idx,
- brick_index, volinfo->replica_count);
- ret = -1;
- /* brick order is not valid */
- goto out;
- }
-
- pos = 0;
- list_for_each_entry (tmp, &volinfo->bricks, brick_list) {
-
- if (strcmp (tmp->hostname,brickinfo->hostname) ||
- strcmp (tmp->path, brickinfo->path)) {
- pos++;
- continue;
- }
-
- gf_log ("", GF_LOG_INFO, "Found brick");
- if (!sub_volume && (volinfo->dist_leaf_count > 1)) {
- sub_volume = (pos / volinfo->dist_leaf_count) + 1;
- sub_volume_start = (volinfo->dist_leaf_count *
- (sub_volume - 1));
- sub_volume_end = (volinfo->dist_leaf_count *
- sub_volume) - 1;
- } else {
- if (pos < sub_volume_start ||
- pos >sub_volume_end) {
- ret = -1;
- snprintf(err_str, 2048,"Bricks not from"
- " same subvol for %s",
- vol_type);
- gf_log ("", GF_LOG_ERROR,
- "%s", err_str);
- goto out;
- }
- }
- break;
- }
- }
- gf_cmd_log ("Volume remove-brick","volname: %s count:%d bricks:%s",
- volname, count, brick_list);
-
- ret = glusterd_op_begin (req, GD_OP_REMOVE_BRICK, dict);
- gf_cmd_log ("Volume remove-brick","on volname: %s %s", volname,
- (ret) ? "FAILED" : "SUCCESS");
-
-out:
- if (ret) {
- if (dict)
- dict_unref (dict);
- rsp.op_ret = -1;
- rsp.op_errno = 0;
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str), "Operation failed");
- gf_log ("", GF_LOG_ERROR, "%s", err_str);
- rsp.op_errstr = err_str;
- cli_rsp = &rsp;
- glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
-
- ret = 0; //sent error to cli, prevent second reply
-
- }
- GF_FREE (brick_list);
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-
-/* op-sm */
-
-int
-glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count,
- char *bricks, dict_t *dict)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- char *brick = NULL;
- int32_t i = 1;
- char *brick_list = NULL;
- char *free_ptr1 = NULL;
- char *free_ptr2 = NULL;
- char *saveptr = NULL;
- int32_t ret = -1;
- int32_t stripe_count = 0;
- int32_t replica_count = 0;
- int32_t type = 0;
-
- GF_ASSERT (volinfo);
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- free_ptr1 = brick_list;
- }
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
-
- if (dict) {
- ret = dict_get_int32 (dict, "stripe-count", &stripe_count);
- if (!ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "stripe-count is set %d", stripe_count);
-
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (!ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "replica-count is set %d", replica_count);
- ret = dict_get_int32 (dict, "type", &type);
- if (!ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "type is set %d, need to change it", type);
- }
-
- while ( i <= count) {
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (brickinfo);
- if (ret)
- goto out;
- if (stripe_count || replica_count) {
- add_brick_at_right_order (brickinfo, volinfo, (i - 1),
- stripe_count, replica_count);
- } else {
- list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
- }
- brick = strtok_r (NULL, " \n", &saveptr);
- i++;
- volinfo->brick_count++;
-
- }
-
-
- /* Gets changed only if the options are given in add-brick cli */
- if (type)
- volinfo->type = type;
- if (replica_count) {
- volinfo->replica_count = replica_count;
- }
- if (stripe_count) {
- volinfo->stripe_count = stripe_count;
- }
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
-
- /* backward compatibility */
- volinfo->sub_count = ((volinfo->dist_leaf_count == 1) ? 0:
- volinfo->dist_leaf_count);
-
- brick_list = gf_strdup (bricks);
- free_ptr2 = brick_list;
- i = 1;
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret)
- goto out;
-
- while (i <= count) {
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_brick_start (volinfo, brickinfo);
- if (ret)
- goto out;
- }
- i++;
- brick = strtok_r (NULL, " \n", &saveptr);
- }
-
-out:
- GF_FREE (free_ptr1);
- GF_FREE (free_ptr2);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-int
-glusterd_op_perform_remove_brick (glusterd_volinfo_t *volinfo, char *brick,
- int force, int *need_migrate)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t ret = -1;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brick);
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- &brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (brickinfo);
- if (ret)
- goto out;
-
- glusterd_volinfo_reset_defrag_stats (volinfo);
-
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- /* Only if the brick is in this glusterd, do the rebalance */
- if (need_migrate)
- *need_migrate = 1;
- }
-
- if (force) {
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_brick_stop (volinfo, brickinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to stop "
- "glusterfs, ret: %d", ret);
- goto out;
- }
- }
- glusterd_delete_brick (volinfo, brickinfo);
- goto out;
- }
-
- brickinfo->decommissioned = 1;
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- int count = 0;
- int i = 0;
- char *bricks = NULL;
- char *brick_list = NULL;
- char *saveptr = NULL;
- char *free_ptr = NULL;
- char *brick = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- char msg[2048] = {0,};
- gf_boolean_t brick_alloc = _gf_false;
- char *all_bricks = NULL;
- char *str_ret = NULL;
-
- priv = THIS->private;
- if (!priv)
- goto out;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to find volume: %s", volname);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- if (glusterd_is_rb_ongoing (volinfo)) {
- snprintf (msg, sizeof (msg), "Replace brick is in progress on "
- "volume %s. Please retry after replace-brick "
- "operation is committed or aborted", volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (glusterd_is_defrag_on(volinfo)) {
- snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
- "progress. Please retry after completion", volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
-
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to get bricks");
- goto out;
- }
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- all_bricks = gf_strdup (bricks);
- free_ptr = brick_list;
- }
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
-
-
- while ( i < count) {
- if (!glusterd_store_is_valid_brickpath (volname, brick) ||
- !glusterd_is_valid_volfpath (volname, brick)) {
- snprintf (msg, sizeof (msg), "brick path %s is "
- "too long", brick);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
-
- ret = -1;
- goto out;
-
- }
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Add-brick: Unable"
- " to get brickinfo");
- goto out;
- }
- brick_alloc = _gf_true;
-
- ret = glusterd_new_brick_validate (brick, brickinfo, msg,
- sizeof (msg));
- if (ret) {
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (!uuid_compare (brickinfo->uuid, MY_UUID)) {
- ret = glusterd_brick_create_path (brickinfo->hostname,
- brickinfo->path,
- volinfo->volume_id,
- op_errstr);
- if (ret)
- goto out;
- }
-
- glusterd_brickinfo_delete (brickinfo);
- brick_alloc = _gf_false;
- brickinfo = NULL;
- brick = strtok_r (NULL, " \n", &saveptr);
- i++;
- }
-
-out:
- GF_FREE (free_ptr);
- if (brick_alloc && brickinfo)
- glusterd_brickinfo_delete (brickinfo);
- GF_FREE (str_ret);
- GF_FREE (all_bricks);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *errstr = NULL;
- int32_t brick_count = 0;
- char msg[2048] = {0,};
- int32_t flag = 0;
- gf1_op_commands cmd = GF_OP_CMD_NONE;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Volume %s does not exist", volname);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- if (glusterd_is_rb_ongoing (volinfo)) {
- snprintf (msg, sizeof (msg), "Replace brick is in progress on "
- "volume %s. Please retry after replace-brick "
- "operation is committed or aborted", volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_int32 (dict, "command", &flag);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get brick count");
- goto out;
- }
- cmd = flag;
-
- ret = -1;
- switch (cmd) {
- case GF_OP_CMD_NONE:
- errstr = gf_strdup ("no remove-brick command issued");
- goto out;
-
- case GF_OP_CMD_STATUS:
- ret = 0;
- goto out;
-
- case GF_OP_CMD_START:
- {
- if (GLUSTERD_STATUS_STARTED != volinfo->status) {
- snprintf (msg, sizeof (msg), "Volume %s needs to be started "
- "before remove-brick (you can use 'force' or "
- "'commit' to override this behavior)",
- volinfo->volname);
- errstr = gf_strdup (msg);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- if (glusterd_is_defrag_on(volinfo)) {
- errstr = gf_strdup("Rebalance is in progress. Please retry"
- " after completion");
- gf_log ("glusterd", GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
- break;
- }
-
- case GF_OP_CMD_STOP:
- ret = 0;
- break;
-
- case GF_OP_CMD_COMMIT:
- if (volinfo->decommission_in_progress) {
- errstr = gf_strdup ("use 'force' option as migration "
- "is in progress");
- goto out;
- }
- break;
-
- case GF_OP_CMD_COMMIT_FORCE:
- break;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get brick count");
- goto out;
- }
-
- ret = 0;
- if (volinfo->brick_count == brick_count) {
- errstr = gf_strdup ("Deleting all the bricks of the "
- "volume is not allowed");
- ret = -1;
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- if (ret && errstr) {
- if (op_errstr)
- *op_errstr = errstr;
- }
-
- return ret;
-}
-
-int
-glusterd_remove_brick_migrate_cbk (glusterd_volinfo_t *volinfo,
- gf_defrag_status_t status)
-{
- int ret = 0;
-
-#if 0 /* TODO: enable this behavior once cluster-wide awareness comes for
- defrag cbk function */
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *tmp = NULL;
-
- switch (status) {
- case GF_DEFRAG_STATUS_PAUSED:
- case GF_DEFRAG_STATUS_FAILED:
- /* No changes required in the volume file.
- everything should remain as is */
- break;
- case GF_DEFRAG_STATUS_STOPPED:
- /* Fall back to the old volume file */
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, brick_list) {
- if (!brickinfo->decommissioned)
- continue;
- brickinfo->decommissioned = 0;
- }
- break;
-
- case GF_DEFRAG_STATUS_COMPLETE:
- /* Done with the task, you can remove the brick from the
- volume file */
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks, brick_list) {
- if (!brickinfo->decommissioned)
- continue;
- gf_log (THIS->name, GF_LOG_INFO, "removing the brick %s",
- brickinfo->path);
- brickinfo->decommissioned = 0;
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_brick_stop (volinfo, brickinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to stop glusterfs (%d)", ret);
- }
- }
- glusterd_delete_brick (volinfo, brickinfo);
- }
- break;
-
- default:
- GF_ASSERT (!"cbk function called with wrong status");
- break;
- }
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to write volume files (%d)", ret);
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to store volume info (%d)", ret);
-
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_check_generate_start_nfs ();
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to start nfs process (%d)", ret);
- }
-
-#endif
-
- volinfo->decommission_in_progress = 0;
- return ret;
-}
-
-
-int
-glusterd_op_add_brick (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- char *bricks = NULL;
- int32_t count = 0;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
-
-
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
- goto out;
- }
-
- ret = glusterd_op_perform_add_bricks (volinfo, count, bricks, dict);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to add bricks");
- goto out;
- }
-
- /* Need to reset the defrag/rebalance status accordingly */
- switch (volinfo->defrag_status) {
- case GF_DEFRAG_STATUS_FAILED:
- case GF_DEFRAG_STATUS_COMPLETE:
- volinfo->defrag_status = 0;
- default:
- break;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status)
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
-
-out:
- return ret;
-}
-
-int
-glusterd_op_remove_brick (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char *brick = NULL;
- int32_t count = 0;
- int32_t i = 1;
- char key[256] = {0,};
- int32_t flag = 0;
- char err_str[4096] = {0,};
- int need_rebalance = 0;
- int force = 0;
- gf1_op_commands cmd = 0;
- int32_t replica_count = 0;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *tmp = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "command", &flag);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get brick count");
- goto out;
- }
- cmd = flag;
-
- ret = -1;
- switch (cmd) {
- case GF_OP_CMD_NONE:
- goto out;
-
- case GF_OP_CMD_STATUS:
- ret = 0;
- goto out;
-
- case GF_OP_CMD_STOP:
- {
- /* Fall back to the old volume file */
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
- brick_list) {
- if (!brickinfo->decommissioned)
- continue;
- brickinfo->decommissioned = 0;
- }
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to create volfiles");
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to store volinfo");
- goto out;
- }
-
- ret = 0;
- goto out;
- }
-
- case GF_OP_CMD_START:
- force = 0;
- break;
-
- case GF_OP_CMD_COMMIT:
- force = 1;
- break;
-
- case GF_OP_CMD_COMMIT_FORCE:
-
- if (volinfo->decommission_in_progress) {
- if (volinfo->defrag) {
- LOCK (&volinfo->defrag->lock);
- /* Fake 'rebalance-complete' so the graph change
- happens right away */
- volinfo->defrag_status = GF_DEFRAG_STATUS_COMPLETE;
-
- UNLOCK (&volinfo->defrag->lock);
- }
- /* Graph change happens in rebalance _cbk function,
- no need to do anything here */
- /* TODO: '_cbk' function is not doing anything for now */
- }
-
- ret = 0;
- force = 1;
- break;
- }
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
-
-
- while ( i <= count) {
- snprintf (key, 256, "brick%d", i);
- ret = dict_get_str (dict, key, &brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get %s", key);
- goto out;
- }
-
- ret = glusterd_op_perform_remove_brick (volinfo, brick, force,
- &need_rebalance);
- if (ret)
- goto out;
- i++;
- }
- ret = dict_get_int32 (dict, "replica-count", &replica_count);
- if (!ret) {
- gf_log (THIS->name, GF_LOG_INFO,
- "changing replica count %d to %d on volume %s",
- volinfo->replica_count, replica_count,
- volinfo->volname);
- volinfo->replica_count = replica_count;
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- replica_count);
- if (replica_count == 1) {
- if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {
- volinfo->type = GF_CLUSTER_TYPE_NONE;
- /* backward compatibility */
- volinfo->sub_count = 0;
- } else {
- volinfo->type = GF_CLUSTER_TYPE_STRIPE;
- /* backward compatibility */
- volinfo->sub_count = volinfo->dist_leaf_count;
- }
- }
- }
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING, "failed to create volfiles");
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING, "failed to store volinfo");
- goto out;
- }
-
- /* Need to reset the defrag/rebalance status accordingly */
- switch (volinfo->defrag_status) {
- case GF_DEFRAG_STATUS_FAILED:
- case GF_DEFRAG_STATUS_COMPLETE:
- volinfo->defrag_status = 0;
- default:
- break;
- }
- if (!force && need_rebalance) {
- /* perform the rebalance operations */
- ret = glusterd_handle_defrag_start (volinfo, err_str, 4096,
- GF_DEFRAG_CMD_START_FORCE,
- glusterd_remove_brick_migrate_cbk);
- if (!ret)
- volinfo->decommission_in_progress = 1;
-
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to start the rebalance");
- }
- } else {
- if (GLUSTERD_STATUS_STARTED == volinfo->status)
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
- }
-
-out:
- if (ret && err_str[0] && op_errstr)
- *op_errstr = gf_strdup (err_str);
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
deleted file mode 100644
index 901e5e1e6..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c
+++ /dev/null
@@ -1,2222 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-#include "run.h"
-#include "syscall.h"
-
-#include <signal.h>
-
-static char *gsync_reserved_opts[] = {
- "gluster-command-dir",
- "pid-file",
- "state-file",
- "session-owner",
- NULL
-};
-
-int
-glusterd_handle_gsync_set (rpcsvc_request_t *req)
-{
- int32_t ret = 0;
- dict_t *dict = NULL;
- gf_cli_req cli_req = {{0},};
- glusterd_op_t cli_op = GD_OP_GSYNC_SET;
- char *master = NULL;
- char *slave = NULL;
- char operation[256] = {0,};
- int type = 0;
- glusterd_conf_t *priv = NULL;
- char *host_uuid = NULL;
-
- GF_ASSERT (req);
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- dict = dict_new ();
- if (!dict)
- goto out;
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
-
- host_uuid = gf_strdup (uuid_utoa(MY_UUID));
- if (host_uuid == NULL) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to get"
- "the uuid of the host machine");
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dict, "host-uuid", host_uuid);
- if (ret)
- goto out;
-
- }
-
- ret = dict_get_str (dict, "master", &master);
- if (ret < 0) {
- gf_log ("", GF_LOG_INFO, "master not found, while handling"
- GEOREP" options");
- master = "(No Master)";
- }
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0) {
- gf_log ("", GF_LOG_INFO, "slave not not found, while"
- "handling "GEOREP" options");
- slave = "(No Slave)";
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "command type not found, while"
- "handling "GEOREP" options");
- goto out;
- }
-
- switch (type) {
-
- case GF_GSYNC_OPTION_TYPE_START:
- strncpy (operation, "start", sizeof (operation));
- break;
-
- case GF_GSYNC_OPTION_TYPE_STOP:
- strncpy (operation, "stop", sizeof (operation));
- break;
-
- case GF_GSYNC_OPTION_TYPE_CONFIG:
- strncpy (operation, "config", sizeof (operation));
- break;
-
- case GF_GSYNC_OPTION_TYPE_STATUS:
- strncpy (operation, "status", sizeof (operation));
- break;
- case GF_GSYNC_OPTION_TYPE_ROTATE:
- strncpy (operation, "rotate", sizeof(operation));
- break;
- }
-
- gf_cmd_log ("volume "GEOREP, " %s command on %s,%s", operation, master,
- slave);
- ret = glusterd_op_begin (req, GD_OP_GSYNC_SET, dict);
- gf_cmd_log ("volume "GEOREP, " %s command on %s,%s %s ", operation,
- master, slave, (ret != 0)? "FAILED" : "SUCCEEDED");
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (dict)
- dict_unref (dict);
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- }
- return ret;
-}
-
-
-/*****
- *
- * glusterd_urltransform* internal API
- *
- *****/
-
-static void
-glusterd_urltransform_init (runner_t *runner, const char *transname)
-{
- runinit (runner);
- runner_add_arg (runner, GSYNCD_PREFIX"/gsyncd");
- runner_argprintf (runner, "--%s-url", transname);
-}
-
-static void
-glusterd_urltransform_add (runner_t *runner, const char *url)
-{
- runner_add_arg (runner, url);
-}
-
-static void
-_glusterd_urltransform_add_iter (dict_t *dict, char *key, data_t *value, void *data)
-{
- runner_t *runner = (runner_t *)data;
- char *slave = NULL;
-
- slave = strchr (value->data, ':');
- GF_ASSERT (slave);
- slave++;
- runner_add_arg (runner, slave);
-}
-
-static void
-glusterd_urltransform_free (char **linearr, unsigned n)
-{
- int i = 0;
-
- for (; i < n; i++)
- GF_FREE (linearr[i]);
-
- GF_FREE (linearr);
-}
-
-static int
-glusterd_urltransform (runner_t *runner, char ***linearrp)
-{
- char **linearr = NULL;
- char *line = NULL;
- unsigned arr_len = 32;
- unsigned arr_idx = 0;
- gf_boolean_t error = _gf_false;
-
- linearr = GF_CALLOC (arr_len, sizeof (char *), gf_gld_mt_linearr);
- if (!linearr) {
- error = _gf_true;
- goto out;
- }
-
- runner_redir (runner, STDOUT_FILENO, RUN_PIPE);
- if (runner_start (runner) != 0) {
- gf_log ("", GF_LOG_ERROR, "spawning child failed");
-
- error = _gf_true;
- goto out;
- }
-
- arr_idx = 0;
- for (;;) {
- size_t len;
- line = GF_MALLOC (1024, gf_gld_mt_linebuf);
- if (!line) {
- error = _gf_true;
- goto out;
- }
-
- if (fgets (line, 1024, runner_chio (runner, STDOUT_FILENO)) ==
- NULL)
- break;
-
- len = strlen (line);
- if (len == 0 || line[len - 1] != '\n') {
- GF_FREE (line);
- error = _gf_true;
- goto out;
- }
- line[len - 1] = '\0';
-
- if (arr_idx == arr_len) {
- arr_len <<= 1;
- linearr = GF_REALLOC (linearr, arr_len);
- if (!linearr) {
- GF_FREE (line);
- error = _gf_true;
- goto out;
- }
- }
- linearr[arr_idx] = line;
-
- arr_idx++;
- }
-
- out:
-
- /* XXX chpid field is not exported by run API
- * but runner_end() does not abort the invoked
- * process (ie. it might block in waitpid(2))
- * so we resort to a manual kill a the private field
- */
- if (error && runner->chpid > 0)
- kill (runner->chpid, SIGKILL);
-
- if (runner_end (runner) != 0)
- error = _gf_true;
-
- if (error) {
- gf_log ("", GF_LOG_ERROR, "reading data from child failed");
- glusterd_urltransform_free (linearr, arr_idx);
- return -1;
- }
-
- *linearrp = linearr;
- return arr_idx;
-}
-
-static int
-glusterd_urltransform_single (const char *url, const char *transname,
- char ***linearrp)
-{
- runner_t runner = {0,};
-
- glusterd_urltransform_init (&runner, transname);
- glusterd_urltransform_add (&runner, url);
- return glusterd_urltransform (&runner, linearrp);
-}
-
-
-struct dictidxmark {
- unsigned isrch;
- unsigned ithis;
- char *ikey;
-};
-
-static void
-_dict_mark_atindex (dict_t *dict, char *key, data_t *value, void *data)
-{
- struct dictidxmark *dim = data;
-
- if (dim->isrch == dim->ithis)
- dim->ikey = key;
-
- dim->ithis++;
-}
-
-static char *
-dict_get_by_index (dict_t *dict, unsigned i)
-{
- struct dictidxmark dim = {0,};
-
- dim.isrch = i;
- dict_foreach (dict, _dict_mark_atindex, &dim);
-
- return dim.ikey;
-}
-
-static int
-glusterd_get_slave (glusterd_volinfo_t *vol, const char *slaveurl, char **slavekey)
-{
- runner_t runner = {0,};
- int n = 0;
- int i = 0;
- char **linearr = NULL;
-
- glusterd_urltransform_init (&runner, "canonicalize");
- dict_foreach (vol->gsync_slaves, _glusterd_urltransform_add_iter, &runner);
- glusterd_urltransform_add (&runner, slaveurl);
-
- n = glusterd_urltransform (&runner, &linearr);
- if (n == -1)
- return -2;
-
- for (i = 0; i < n - 1; i++) {
- if (strcmp (linearr[i], linearr[n - 1]) == 0)
- break;
- }
- glusterd_urltransform_free (linearr, i);
-
- if (i < n - 1)
- *slavekey = dict_get_by_index (vol->gsync_slaves, i);
- else
- i = -1;
-
- return i;
-}
-
-
-static int
-glusterd_query_extutil_generic (char *resbuf, size_t blen, runner_t *runner, void *data,
- int (*fcbk)(char *resbuf, size_t blen, FILE *fp, void *data))
-{
- int ret = 0;
-
- runner_redir (runner, STDOUT_FILENO, RUN_PIPE);
- if (runner_start (runner) != 0) {
- gf_log ("", GF_LOG_ERROR, "spawning child failed");
-
- return -1;
- }
-
- ret = fcbk (resbuf, blen, runner_chio (runner, STDOUT_FILENO), data);
-
- ret |= runner_end (runner);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "reading data from child failed");
-
- return ret ? -1 : 0;
-}
-
-static int
-_fcbk_singleline(char *resbuf, size_t blen, FILE *fp, void *data)
-{
- char *ptr = NULL;
-
- errno = 0;
- ptr = fgets (resbuf, blen, fp);
- if (ptr) {
- size_t len = strlen(resbuf);
- if (len && resbuf[len-1] == '\n')
- resbuf[len-1] = '\0'; //strip off \n
- }
-
- return errno ? -1 : 0;
-}
-
-static int
-glusterd_query_extutil (char *resbuf, runner_t *runner)
-{
- return glusterd_query_extutil_generic (resbuf, PATH_MAX, runner, NULL,
- _fcbk_singleline);
-}
-
-static int
-_fcbk_conftodict (char *resbuf, size_t blen, FILE *fp, void *data)
-{
- char *ptr = NULL;
- dict_t *dict = data;
- char *v = NULL;
-
- for (;;) {
- errno = 0;
- ptr = fgets (resbuf, blen, fp);
- if (!ptr)
- break;
- v = resbuf + strlen(resbuf) - 1;
- while (isspace (*v))
- /* strip trailing space */
- *v-- = '\0';
- if (v == resbuf)
- /* skip empty line */
- continue;
- v = strchr (resbuf, ':');
- if (!v)
- return -1;
- *v++ = '\0';
- while (isspace (*v))
- v++;
- v = gf_strdup (v);
- if (!v)
- return -1;
- if (dict_set_dynstr (dict, resbuf, v) != 0) {
- GF_FREE (v);
- return -1;
- }
- }
-
- return errno ? -1 : 0;
-}
-
-static int
-glusterd_gsync_get_config (char *master, char *slave, char *gl_workdir, dict_t *dict)
-{
- /* key + value, where value must be able to accommodate a path */
- char resbuf[256 + PATH_MAX] = {0,};
- runner_t runner = {0,};
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir);
- runner_argprintf (&runner, ":%s", master);
- runner_add_args (&runner, slave, "--config-get-all", NULL);
-
- return glusterd_query_extutil_generic (resbuf, sizeof (resbuf),
- &runner, dict, _fcbk_conftodict);
-}
-
-static int
-glusterd_gsync_get_param_file (char *prmfile, const char *param, char *master,
- char *slave, char *gl_workdir)
-{
- runner_t runner = {0,};
-
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir);
- runner_argprintf (&runner, ":%s", master);
- runner_add_args (&runner, slave, "--config-get", NULL);
- runner_argprintf (&runner, "%s-file", param);
-
- return glusterd_query_extutil (prmfile, &runner);
-}
-
-static int
-glusterd_gsync_get_session_owner (char *master, char *slave, char *session_owner,
- char *gl_workdir)
-{
- runner_t runner = {0,};
-
- runinit(&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir);
- runner_argprintf (&runner, ":%s", master);
- runner_add_args (&runner, slave, "--config-get", "session-owner",
- NULL);
-
- return glusterd_query_extutil (session_owner, &runner);
-}
-
-/* check whether @slave is local or remote. normalized
- * urls starting with ssh are considered to be remote
- * @returns
- * 1 if slave is remote
- * 0 is slave is local
- */
-static int
-glusterd_gsync_slave_is_remote (char *slave)
-{
- int ret = 0;
- char *ssh_pos = NULL;
-
- ssh_pos = strstr(slave, "ssh://");
- if ( ssh_pos && ((ssh_pos - slave) == 0) )
- ret = 1;
-
- return ret;
-}
-
-static int
-glusterd_gsync_get_slave_log_file (char *master, char *slave, char *log_file)
-{
- int ret = -1;
- runner_t runner = {0,};
- char uuid_str[64] = {0,};
- glusterd_conf_t *priv = NULL;
- char *gl_workdir = NULL;
-
- GF_ASSERT(THIS);
- GF_ASSERT(THIS->private);
-
- priv = THIS->private;
-
- GF_VALIDATE_OR_GOTO("gsyncd", master, out);
- GF_VALIDATE_OR_GOTO("gsyncd", slave, out);
-
- gl_workdir = priv->workdir;
-
- /* get the session owner for the master-slave session */
- ret = glusterd_gsync_get_session_owner (master, slave, uuid_str,
- gl_workdir);
- if (ret)
- goto out;
-
- /* get the log file for the slave */
- runinit(&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, gl_workdir);
- runner_argprintf (&runner, "--session-owner=%s", uuid_str);
- runner_add_args (&runner, slave, "--config-get", "log-file", NULL);
-
- ret = glusterd_query_extutil (log_file, &runner);
-
- out:
- return ret;
-}
-
-static int
-gsyncd_getpidfile (char *master, char *slave, char *pidfile)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- GF_VALIDATE_OR_GOTO ("gsync", master, out);
- GF_VALIDATE_OR_GOTO ("gsync", slave, out);
-
- ret = glusterd_gsync_get_param_file (pidfile, "pid", master,
- slave, priv->workdir);
- if (ret == -1) {
- ret = -2;
- gf_log ("", GF_LOG_WARNING, "failed to create the pidfile string");
- goto out;
- }
-
- ret = open (pidfile, O_RDWR);
-
- out:
- return ret;
-}
-
-static int
-glusterd_gsyncd_getlogfile (char *master, char *slave, char *log_file)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- GF_VALIDATE_OR_GOTO ("gsync", master, out);
- GF_VALIDATE_OR_GOTO ("gsync", slave, out);
-
- ret = glusterd_gsync_get_param_file (log_file, "log", master,
- slave, priv->workdir);
- if (ret == -1) {
- ret = -2;
- gf_log ("", GF_LOG_WARNING, "failed to gsyncd logfile");
- goto out;
- }
-
- out:
- return ret;
-}
-
-static int
-gsync_status_byfd (int fd)
-{
- GF_ASSERT (fd >= -1);
-
- if (lockf (fd, F_TEST, 0) == -1 &&
- (errno == EAGAIN || errno == EACCES))
- /* gsyncd keeps the pidfile locked */
- return 0;
-
- return -1;
-}
-
-/* status: return 0 when gsync is running
- * return -1 when not running
- */
-int
-gsync_status (char *master, char *slave, int *status)
-{
- char pidfile[PATH_MAX] = {0,};
- int fd = -1;
-
- fd = gsyncd_getpidfile (master, slave, pidfile);
- if (fd == -2)
- return -1;
-
- *status = gsync_status_byfd (fd);
-
- sys_close (fd);
-
- return 0;
-}
-
-
-static int32_t
-glusterd_gsync_volinfo_dict_set (glusterd_volinfo_t *volinfo,
- char *key, char *value)
-{
- int32_t ret = -1;
- char *gsync_status = NULL;
-
- gsync_status = gf_strdup (value);
- if (!gsync_status) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = dict_set_dynstr (volinfo->dict, key, gsync_status);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set dict");
- goto out;
- }
-
- ret = 0;
-out:
- return 0;
-}
-
-static int
-gsync_verify_config_options (dict_t *dict, char **op_errstr)
-{
- char **resopt = NULL;
- int i = 0;
- char *subop = NULL;
- char *slave = NULL;
- char *op_name = NULL;
- char *op_value = NULL;
- char *t = NULL;
- gf_boolean_t banned = _gf_true;
-
- if (dict_get_str (dict, "subop", &subop) != 0) {
- gf_log ("", GF_LOG_WARNING, "missing subop");
- *op_errstr = gf_strdup ("Invalid config request");
- return -1;
- }
-
- if (dict_get_str (dict, "slave", &slave) != 0) {
- gf_log ("", GF_LOG_WARNING, GEOREP" CONFIG: no slave given");
- *op_errstr = gf_strdup ("Slave required");
- return -1;
- }
-
- if (strcmp (subop, "get-all") == 0)
- return 0;
-
- if (dict_get_str (dict, "op_name", &op_name) != 0) {
- gf_log ("", GF_LOG_WARNING, "option name missing");
- *op_errstr = gf_strdup ("Option name missing");
- return -1;
- }
-
- if (runcmd (GSYNCD_PREFIX"/gsyncd", "--config-check", op_name, NULL)) {
- gf_log ("", GF_LOG_WARNING, "Invalid option %s", op_name);
- *op_errstr = gf_strdup ("Invalid option");
-
- return -1;
- }
-
- if (strcmp (subop, "get") == 0)
- return 0;
-
- t = strtail (subop, "set");
- if (!t)
- t = strtail (subop, "del");
- if (!t || (t[0] && strcmp (t, "-glob") != 0)) {
- gf_log ("", GF_LOG_WARNING, "unknown subop %s", subop);
- *op_errstr = gf_strdup ("Invalid config request");
- return -1;
- }
-
- if (strtail (subop, "set") &&
- dict_get_str (dict, "op_value", &op_value) != 0) {
- gf_log ("", GF_LOG_WARNING, "missing value for set");
- *op_errstr = gf_strdup ("missing value");
- }
-
- /* match option name against reserved options, modulo -/_
- * difference
- */
- for (resopt = gsync_reserved_opts; *resopt; resopt++) {
- banned = _gf_true;
- for (i = 0; (*resopt)[i] && op_name[i]; i++) {
- if ((*resopt)[i] == op_name[i] ||
- ((*resopt)[i] == '-' && op_name[i] == '_'))
- continue;
- banned = _gf_false;
- }
- if (banned) {
- gf_log ("", GF_LOG_WARNING, "Reserved option %s", op_name);
- *op_errstr = gf_strdup ("Reserved option");
-
- return -1;
- break;
- }
- }
-
- return 0;
-}
-
-static int
-glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,
- char *slave, dict_t *rsp_dict);
-
-static void
-_get_status_mst_slv (dict_t *this, char *key, data_t *value, void *data)
-{
- glusterd_gsync_status_temp_t *param = NULL;
- char *slave = NULL;
- int ret = 0;
-
- param = (glusterd_gsync_status_temp_t *)data;
-
- GF_ASSERT (param);
- GF_ASSERT (param->volinfo);
-
- slave = strchr(value->data, ':');
- if (slave)
- slave ++;
- else
- return;
-
- ret = glusterd_get_gsync_status_mst_slv(param->volinfo,
- slave, param->rsp_dict);
-
-}
-
-
-static void
-_get_max_gsync_slave_num (dict_t *this, char *key, data_t *value, void *data)
-{
- int tmp_slvnum = 0;
- int *slvnum = (int *)data;
-
- sscanf (key, "slave%d", &tmp_slvnum);
- if (tmp_slvnum > *slvnum)
- *slvnum = tmp_slvnum;
-}
-
-static int
-glusterd_remove_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,
- char **op_errstr)
-{
- int ret = 0;
- char *slavekey = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
-
- ret = glusterd_get_slave (volinfo, slave, &slavekey);
- if (ret < 0) {
- ret++;
- goto out;
- }
-
- dict_del (volinfo->gsync_slaves, slavekey);
-
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- *op_errstr = gf_strdup ("Failed to store the Volume"
- "information");
- goto out;
- }
- out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-
-}
-
-static int
-glusterd_gsync_get_uuid (char *slave, glusterd_volinfo_t *vol,
- uuid_t uuid)
-{
- int ret = 0;
- char *slavekey = NULL;
- char *slaveentry = NULL;
- char *t = NULL;
-
- GF_ASSERT (vol);
- GF_ASSERT (slave);
-
- ret = glusterd_get_slave (vol, slave, &slavekey);
- if (ret < 0) {
- /* XXX colliding cases of failure and non-extant
- * slave... now just doing this as callers of this
- * function can make sense only of -1 and 0 as retvals;
- * getting at the proper semanticals will involve
- * fixing callers as well.
- */
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (vol->gsync_slaves, slavekey, &slaveentry);
- GF_ASSERT (ret == 0);
-
- t = strchr (slaveentry, ':');
- GF_ASSERT (t);
- *t = '\0';
- ret = uuid_parse (slaveentry, uuid);
- *t = ':';
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_check_gsync_running_local (char *master, char *slave,
- gf_boolean_t *is_run)
-{
- int ret = -1;
- int ret_status = 0;
-
- GF_ASSERT (master);
- GF_ASSERT (slave);
- GF_ASSERT (is_run);
-
- *is_run = _gf_false;
- ret = gsync_status (master, slave, &ret_status);
- if (ret == 0 && ret_status == 0) {
- *is_run = _gf_true;
- } else if (ret == -1) {
- gf_log ("", GF_LOG_WARNING, GEOREP" validation "
- " failed");
- goto out;
- }
- ret = 0;
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-static int
-glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,
- char *host_uuid, char **op_errstr)
-{
- int ret = 0;
- int maxslv = 0;
- char **linearr = NULL;
- char *value = NULL;
- char *slavekey = NULL;
- char *slaveentry = NULL;
- char key[512] = {0, };
- char *t = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (host_uuid);
-
- ret = glusterd_get_slave (volinfo, slave, &slavekey);
- switch (ret) {
- case -2:
- ret = -1;
- goto out;
- case -1:
- break;
- default:
- GF_ASSERT (ret > 0);
- ret = dict_get_str (volinfo->gsync_slaves, slavekey, &slaveentry);
- GF_ASSERT (ret == 0);
-
- /* same-name + same-uuid slave entries should have been filtered
- * out in glusterd_op_verify_gsync_start_options(), so we can
- * assert an uuid mismatch
- */
- t = strtail (slaveentry, host_uuid);
- GF_ASSERT (!t || *t != ':');
-
- gf_log ("", GF_LOG_ERROR, GEOREP" has already been invoked for "
- "the %s (master) and %s (slave) "
- "from a different machine",
- volinfo->volname, slave);
- *op_errstr = gf_strdup (GEOREP" already running in an an"
- "another machine");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_urltransform_single (slave, "normalize", &linearr);
- if (ret == -1)
- goto out;
-
- ret = gf_asprintf (&value, "%s:%s", host_uuid, linearr[0]);
- glusterd_urltransform_free (linearr, 1);
- if (ret == -1)
- goto out;
-
- dict_foreach (volinfo->gsync_slaves, _get_max_gsync_slave_num, &maxslv);
- snprintf (key, 512, "slave%d", maxslv + 1);
- ret = dict_set_dynstr (volinfo->gsync_slaves, key, value);
- if (ret)
- goto out;
-
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- *op_errstr = gf_strdup ("Failed to store the Volume "
- "information");
- goto out;
- }
- ret = 0;
- out:
- return ret;
-}
-
-
-static int
-glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo,
- char *slave, char **op_errstr)
-{
- int ret = -1;
- gf_boolean_t is_running = _gf_false;
- char msg[2048] = {0};
- uuid_t uuid = {0};
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (op_errstr);
- GF_ASSERT (this && this->private);
-
- priv = this->private;
-
- if (GLUSTERD_STATUS_STARTED != volinfo->status) {
- snprintf (msg, sizeof (msg), "Volume %s needs to be started "
- "before "GEOREP" start", volinfo->volname);
- goto out;
- }
- /*Check if the gsync is already started in cmd. inited host
- * If so initiate add it into the glusterd's priv*/
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if ((ret == 0) && (uuid_compare (MY_UUID, uuid) == 0)) {
- ret = glusterd_check_gsync_running_local (volinfo->volname,
- slave, &is_running);
- if (ret) {
- snprintf (msg, sizeof (msg), GEOREP" start option "
- "validation failed ");
- goto out;
- }
- if (_gf_true == is_running) {
- snprintf (msg, sizeof (msg), GEOREP " session between"
- " %s & %s already started", volinfo->volname,
- slave);
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-out:
- if (ret && (msg[0] != '\0')) {
- *op_errstr = gf_strdup (msg);
- }
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag)
-{
-
- GF_ASSERT (volinfo);
- GF_ASSERT (flag);
-
- if (volinfo->gsync_slaves->count)
- *flag = _gf_true;
- else
- *flag = _gf_false;
-
- return 0;
-}
-
-static int
-glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo,
- char *slave, char **op_errstr)
-{
- int ret = -1;
- char msg[2048] = {0};
- uuid_t uuid = {0};
-
- GF_ASSERT (THIS && THIS->private);
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (op_errstr);
-
- if (GLUSTERD_STATUS_STARTED != volinfo->status) {
- snprintf (msg, sizeof (msg), "Volume %s needs to be started "
- "before "GEOREP" start", volinfo->volname);
-
- goto out;
- }
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if (ret == -1) {
- snprintf (msg, sizeof (msg), GEOREP" session between %s & %s"
- " not active", volinfo->volname, slave);
- goto out;
- }
-
- ret = 0;
-out:
- if (ret && (msg[0] != '\0')) {
- *op_errstr = gf_strdup (msg);
- }
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr)
-{
- char *slave = NULL;
- char *volname = NULL;
- char errmsg[PATH_MAX] = {0, };
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
-
- ret = dict_get_str (dict, "master", &volname);
- if (ret < 0) {
- ret = 0;
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((ret) || (!exists)) {
- gf_log ("", GF_LOG_WARNING, "volume name does not exist");
- snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
- " exist", volname);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0) {
- ret = 0;
- goto out;
- }
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-
-int
-glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,
- char **master, char **slave)
-{
-
- int ret = -1;
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- if (master) {
- ret = dict_get_str (dict, "master", master);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "master not found");
- *op_errstr = gf_strdup ("master not found");
- goto out;
- }
- }
-
- if (slave) {
- ret = dict_get_str (dict, "slave", slave);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "slave not found");
- *op_errstr = gf_strdup ("slave not found");
- goto out;
- }
- }
-
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- int type = 0;
- char *volname = NULL;
- char *slave = NULL;
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char errmsg[PATH_MAX] = {0,};
- dict_t *ctx = NULL;
-
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "command type not found");
- *op_errstr = gf_strdup ("command unsuccessful");
- goto out;
- }
-
- switch (type) {
- case GF_GSYNC_OPTION_TYPE_STATUS:
- ret = glusterd_verify_gsync_status_opts (dict, op_errstr);
-
- goto out;
- case GF_GSYNC_OPTION_TYPE_CONFIG:
- ret = gsync_verify_config_options (dict, op_errstr);
-
- goto out;
-
- case GF_GSYNC_OPTION_TYPE_ROTATE:
- /* checks same as status mode */
- ret = glusterd_verify_gsync_status_opts(dict, op_errstr);
- goto out;
- }
-
- ret = glusterd_op_gsync_args_get (dict, op_errstr, &volname, &slave);
- if (ret)
- goto out;
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((ret) || (!exists)) {
- gf_log ("", GF_LOG_WARNING, "volume name does not exist");
- snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
- " exist", volname);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- switch (type) {
- case GF_GSYNC_OPTION_TYPE_START:
- ret = glusterd_op_verify_gsync_start_options (volinfo, slave,
- op_errstr);
- if (ret)
- goto out;
- ctx = glusterd_op_get_ctx();
- if (ctx) {
- /*gsyncd does a fuse mount to start the geo-rep session*/
- if (!glusterd_is_fuse_available ()) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to open"
- " /dev/fuse (%s), geo-replication start"
- " failed", strerror (errno));
- snprintf (errmsg, sizeof(errmsg),
- "fuse unvailable");
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
- }
- break;
-
- case GF_GSYNC_OPTION_TYPE_STOP:
- ret = glusterd_op_verify_gsync_running (volinfo, slave,
- op_errstr);
- break;
- }
-
-out:
- return ret;
-}
-
-static int
-stop_gsync (char *master, char *slave, char **msg)
-{
- int32_t ret = 0;
- int pfd = -1;
- pid_t pid = 0;
- char pidfile[PATH_MAX] = {0,};
- char buf [1024] = {0,};
- int i = 0;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- pfd = gsyncd_getpidfile (master, slave, pidfile);
- if (pfd == -2) {
- gf_log ("", GF_LOG_ERROR, GEOREP" stop validation "
- " failed for %s & %s", master, slave);
- ret = -1;
- goto out;
- }
- if (gsync_status_byfd (pfd) == -1) {
- gf_log ("", GF_LOG_ERROR, "gsyncd b/w %s & %s is not"
- " running", master, slave);
- if (msg)
- *msg = gf_strdup ("Warning: "GEOREP" session was "
- "defunct at stop time");
- /* monitor gsyncd already dead */
- goto out;
- }
-
- if (pfd < 0)
- goto out;
-
- ret = read (pfd, buf, 1024);
- if (ret > 0) {
- pid = strtol (buf, NULL, 10);
- ret = kill (-pid, SIGTERM);
- if (ret) {
- gf_log ("", GF_LOG_WARNING,
- "failed to kill gsyncd");
- goto out;
- }
- for (i = 0; i < 20; i++) {
- if (gsync_status_byfd (pfd) == -1) {
- /* monitor gsyncd is dead but worker may
- * still be alive, give some more time
- * before SIGKILL (hack)
- */
- usleep (50000);
- break;
- }
- usleep (50000);
- }
- kill (-pid, SIGKILL);
- unlink (pidfile);
- }
- ret = 0;
-
-out:
- sys_close (pfd);
- return ret;
-}
-
-static int
-glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,
- dict_t *resp_dict);
-
-static int
-glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,
- dict_t *dict, dict_t *resp_dict, char **op_errstr)
-{
- int32_t ret = -1;
- char *op_name = NULL;
- char *op_value = NULL;
- runner_t runner = {0,};
- glusterd_conf_t *priv = NULL;
- char *subop = NULL;
- char *master = NULL;
-
- GF_ASSERT (slave);
- GF_ASSERT (op_errstr);
- GF_ASSERT (dict);
- GF_ASSERT (resp_dict);
-
- ret = dict_get_str (dict, "subop", &subop);
- if (ret != 0)
- goto out;
-
- if (strcmp (subop, "get") == 0 || strcmp (subop, "get-all") == 0) {
- /* deferred to cli */
- gf_log ("", GF_LOG_DEBUG, "Returning 0");
- return 0;
- }
-
- ret = dict_get_str (dict, "op_name", &op_name);
- if (ret != 0)
- goto out;
-
- if (strtail (subop, "set")) {
- ret = dict_get_str (dict, "op_value", &op_value);
- if (ret != 0)
- goto out;
- }
-
- if (THIS)
- priv = THIS->private;
- if (priv == NULL) {
- gf_log ("", GF_LOG_ERROR, "priv of glusterd not present");
- *op_errstr = gf_strdup ("glusterd defunct");
- goto out;
- }
-
- master = "";
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir);
- if (volinfo) {
- master = volinfo->volname;
- runner_argprintf (&runner, ":%s", master);
- }
- runner_add_arg (&runner, slave);
- runner_argprintf (&runner, "--config-%s", subop);
- runner_add_arg (&runner, op_name);
- if (op_value)
- runner_add_arg (&runner, op_value);
- ret = runner_run (&runner);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "gsyncd failed to "
- "%s %s option for %s %s peers",
- subop, op_name, master, slave);
-
- gf_asprintf (op_errstr, GEOREP" config-%s failed for %s %s",
- subop, master, slave);
-
- goto out;
- }
- ret = 0;
- gf_asprintf (op_errstr, "config-%s successful", subop);
-
-out:
- if (!ret && volinfo) {
- ret = glusterd_check_restart_gsync_session (volinfo, slave,
- resp_dict);
- if (ret)
- *op_errstr = gf_strdup ("internal error");
- }
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)
-{
- int ret = 0;
- int status_fd = -1;
-
- GF_ASSERT (path);
- GF_ASSERT (buf);
- status_fd = open (path, O_RDONLY);
- if (status_fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to read gsyncd status"
- " file");
- return -1;
- }
- ret = read (status_fd, buf, blen - 1);
- if (ret > 0) {
- size_t len = strnlen (buf, ret);
- /* Ensure there is a NUL byte and that it's not the first. */
- if (len == 0 || len == blen - 1) {
- ret = -1;
- } else {
- char *p = buf + len - 1;
- while (isspace (*p))
- *p-- = '\0';
- ret = 0;
- }
- } else if (ret < 0)
- gf_log ("", GF_LOG_ERROR, "Status file of gsyncd is corrupt");
-
- close (status_fd);
- return ret;
-}
-
-static int
-glusterd_gsync_fetch_status_extra (char *path, char *buf, size_t blen)
-{
- char sockpath[PATH_MAX] = {0,};
- struct sockaddr_un sa = {0,};
- size_t l = 0;
- int s = -1;
- struct pollfd pfd = {0,};
- int ret = 0;
-
- l = strlen (buf);
- /* seek to end of data in buf */
- buf += l;
- blen -= l;
-
- glusterd_set_socket_filepath (path, sockpath, sizeof (sockpath));
-
- strncpy(sa.sun_path, sockpath, sizeof(sa.sun_path));
- if (sa.sun_path[sizeof (sa.sun_path) - 1])
- return -1;
- sa.sun_family = AF_UNIX;
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if (s == -1)
- return -1;
-
- ret = connect (s, (struct sockaddr *)&sa, sizeof (sa));
- if (ret == -1)
- goto out;
- pfd.fd = s;
- pfd.events = POLLIN;
- /* we don't want to hang on gsyncd */
- if (poll (&pfd, 1, 5000) < 1 ||
- !(pfd.revents & POLLIN)) {
- ret = -1;
- goto out;
- }
- ret = read(s, buf, blen);
- /* we expect a terminating 0 byte */
- if (ret == 0 || (ret > 0 && buf[ret - 1]))
- ret = -1;
- if (ret > 0)
- ret = 0;
-
- out:
- close (s);
- return ret;
-}
-
-static int
-dict_get_param (dict_t *dict, char *key, char **param)
-{
- char *dk = NULL;
- char *s = NULL;
- char x = '\0';
- int ret = 0;
-
- if (dict_get_str (dict, key, param) == 0)
- return 0;
-
- dk = gf_strdup (key);
- if (!key)
- return -1;
-
- s = strpbrk (dk, "-_");
- if (!s)
- return -1;
- x = (*s == '-') ? '_' : '-';
- *s++ = x;
- while ((s = strpbrk (s, "-_")))
- *s++ = x;
-
- ret = dict_get_str (dict, dk, param);
-
- GF_FREE (dk);
- return ret;
-}
-
-static int
-glusterd_read_status_file (char *master, char *slave,
- dict_t *dict)
-{
- glusterd_conf_t *priv = NULL;
- int ret = 0;
- char *statefile = NULL;
- char buf[1024] = {0, };
- char mst[1024] = {0, };
- char slv[1024] = {0, };
- char sts[1024] = {0, };
- char *bufp = NULL;
- dict_t *confd = NULL;
- int gsync_count = 0;
- int status = 0;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- confd = dict_new ();
- if (!dict)
- return -1;
-
- priv = THIS->private;
- ret = glusterd_gsync_get_config (master, slave, priv->workdir,
- confd);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get configuration data"
- "for %s(master), %s(slave)", master, slave);
- goto out;
-
- }
-
- ret = gsync_status (master, slave, &status);
- if (ret == 0 && status == -1) {
- strncpy (buf, "defunct", sizeof (buf));
- goto done;
- } else if (ret == -1)
- goto out;
-
- ret = dict_get_param (confd, "state_file", &statefile);
- if (ret)
- goto out;
- ret = glusterd_gsync_read_frm_status (statefile, buf, sizeof (buf));
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to read the status"
- "file for %s(master), %s(slave)", master, slave);
- strncpy (buf, "defunct", sizeof (buf));
- goto done;
- }
- if (strcmp (buf, "OK") != 0)
- goto done;
-
- ret = dict_get_param (confd, "state_socket_unencoded", &statefile);
- if (ret)
- goto out;
- ret = glusterd_gsync_fetch_status_extra (statefile, buf, sizeof (buf));
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch extra status"
- "for %s(master), %s(slave)", master, slave);
- /* there is a slight chance that this occurs due to race
- * -- in that case, the following options all seem bad:
- *
- * - suppress irregurlar behavior by just leaving status
- * on "OK"
- * - freak out users with a misleading "defunct"
- * - overload the meaning of the regular error signal
- * mechanism of gsyncd, that is, when status is "faulty"
- *
- * -- so we just come up with something new...
- */
- strncpy (buf, "N/A", sizeof (buf));
- goto done;
- }
-
- done:
- ret = dict_get_int32 (dict, "gsync-count", &gsync_count);
-
- if (ret)
- gsync_count = 1;
- else
- gsync_count++;
-
- snprintf (mst, sizeof (mst), "master%d", gsync_count);
- master = gf_strdup (master);
- if (!master)
- goto out;
- ret = dict_set_dynstr (dict, mst, master);
- if (ret) {
- GF_FREE (master);
- goto out;
- }
-
- snprintf (slv, sizeof (slv), "slave%d", gsync_count);
- slave = gf_strdup (slave);
- if (!slave)
- goto out;
- ret = dict_set_dynstr (dict, slv, slave);
- if (ret) {
- GF_FREE (slave);
- goto out;
- }
-
- snprintf (sts, sizeof (slv), "status%d", gsync_count);
- bufp = gf_strdup (buf);
- if (!bufp)
- goto out;
- ret = dict_set_dynstr (dict, sts, bufp);
- if (ret) {
- GF_FREE (bufp);
- goto out;
- }
- ret = dict_set_int32 (dict, "gsync-count", gsync_count);
- if (ret)
- goto out;
-
- ret = 0;
- out:
- dict_destroy (confd);
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret);
- return ret;
-}
-
-static int
-glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave,
- dict_t *resp_dict)
-{
-
- int ret = 0;
- uuid_t uuid = {0, };
- glusterd_conf_t *priv = NULL;
- char *status_msg = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- if (glusterd_gsync_get_uuid (slave, volinfo, uuid))
- /* session does not exist, nothing to do */
- goto out;
- if (uuid_compare (MY_UUID, uuid) == 0) {
- ret = stop_gsync (volinfo->volname, slave, &status_msg);
- if (ret == 0 && status_msg)
- ret = dict_set_str (resp_dict, "gsync-status",
- status_msg);
- if (ret == 0)
- ret = glusterd_start_gsync (volinfo, slave,
- uuid_utoa(MY_UUID), NULL);
- }
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int32_t
-glusterd_marker_create_volfile (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = 0;
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create volfile"
- " for setting of marker while '"GEOREP" start'");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status)
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
- ret = 0;
-out:
- return ret;
-}
-
-static int
-glusterd_set_marker_gsync (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- int marker_set = _gf_false;
- char *gsync_status = NULL;
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- marker_set = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME);
- if (marker_set == -1) {
- gf_log ("", GF_LOG_ERROR, "failed to get the marker status");
- ret = -1;
- goto out;
- }
-
- if (marker_set == _gf_false) {
- gsync_status = gf_strdup ("on");
- if (gsync_status == NULL) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_gsync_volinfo_dict_set (volinfo,
- VKEY_MARKER_XTIME, gsync_status);
- if (ret < 0)
- goto out;
-
- ret = glusterd_marker_create_volfile (volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Setting dict failed");
- goto out;
- }
- }
- ret = 0;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-
-
-static int
-glusterd_get_gsync_status_mst_slv (glusterd_volinfo_t *volinfo,
- char *slave, dict_t *rsp_dict)
-{
- uuid_t uuid = {0, };
- glusterd_conf_t *priv = NULL;
- int ret = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if ((ret == 0) && (uuid_compare (MY_UUID, uuid) != 0))
- goto out;
-
- if (ret) {
- ret = 0;
- gf_log ("", GF_LOG_INFO, "geo-replication status %s %s :"
- "session is not active", volinfo->volname, slave);
- goto out;
- }
-
- ret = glusterd_read_status_file (volinfo->volname, slave, rsp_dict);
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static int
-glusterd_get_gsync_status_mst (glusterd_volinfo_t *volinfo, dict_t *rsp_dict)
-{
- glusterd_gsync_status_temp_t param = {0, };
-
- GF_ASSERT (volinfo);
-
- param.rsp_dict = rsp_dict;
- param.volinfo = volinfo;
- dict_foreach (volinfo->gsync_slaves, _get_status_mst_slv, &param);
-
- return 0;
-}
-
-static int
-glusterd_get_gsync_status_all ( dict_t *rsp_dict)
-{
-
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (THIS);
- priv = THIS->private;
-
- GF_ASSERT (priv);
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict);
- if (ret)
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-
-}
-
-static int
-glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- char *slave = NULL;
- char *volname = NULL;
- char errmsg[PATH_MAX] = {0, };
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
-
-
- ret = dict_get_str (dict, "master", &volname);
- if (ret < 0){
- ret = glusterd_get_gsync_status_all (rsp_dict);
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((ret) || (!exists)) {
- gf_log ("", GF_LOG_WARNING, "volume name does not exist");
- snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
- " exist", volname);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0) {
- ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict);
- goto out;
- }
-
- ret = glusterd_get_gsync_status_mst_slv (volinfo, slave, rsp_dict);
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-static int
-glusterd_send_sigstop (pid_t pid)
-{
- int ret = 0;
- ret = kill (pid, SIGSTOP);
- if (ret)
- gf_log ("", GF_LOG_ERROR, GEOREP"failed to send SIGSTOP signal");
- return ret;
-}
-
-static int
-glusterd_send_sigcont (pid_t pid)
-{
- int ret = 0;
- ret = kill (pid, SIGCONT);
- if (ret)
- gf_log ("", GF_LOG_ERROR, GEOREP"failed to send SIGCONT signal");
- return ret;
-}
-
-/*
- * Log rotations flow is something like this:
- * - Send SIGSTOP to process group (this will stop monitor/worker process
- * and also the slave if it's local)
- * - Rotate log file for monitor/worker
- * - Rotate log file for slave if it's local
- * - Send SIGCONT to the process group. Monitor wakes up, kills the worker
- * (this is done in the SIGCONT handler), which results in the termination
- * of the slave (local/remote). After returning from signal handler,
- * monitor detects absence of worker and starts it again, which in-turn
- * starts the slave.
- */
-static int
-glusterd_send_log_rotate_signal (pid_t pid, char *logfile1, char *logfile2)
-{
- int ret = 0;
- char rlogfile[PATH_MAX] = {0,};
- time_t rottime = 0;
-
- ret = glusterd_send_sigstop (-pid);
- rottime = time (NULL);
-
- snprintf (rlogfile, sizeof (rlogfile), "%s.%"PRIu64, logfile1,
- (uint64_t) rottime);
- ret = rename (logfile1, rlogfile);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "rename failed for geo-rep log file");
-
- if (!*logfile2) {
- gf_log ("", GF_LOG_DEBUG, "Slave is not local,"
- " skipping rotation");
- ret = 0;
- goto out;
- }
-
- (void) snprintf (rlogfile, sizeof (rlogfile), "%s.%"PRIu64, logfile2,
- (uint64_t) rottime);
- ret = rename (logfile2, rlogfile);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "rename failed for geo-rep slave"
- " log file");
-
- out:
- ret = glusterd_send_sigcont (-pid);
-
- return ret;
-}
-
-static int
-glusterd_get_pid_from_file (char *master, char *slave, pid_t *pid)
-{
- int ret = -1;
- int pfd = 0;
- char pidfile[PATH_MAX] = {0,};
- char buff[1024] = {0,};
-
- pfd = gsyncd_getpidfile (master, slave, pidfile);
- if (pfd == -2) {
- gf_log ("", GF_LOG_ERROR, GEOREP" log-rotate validation "
- " failed for %s & %s", master, slave);
- goto out;
- }
- if (gsync_status_byfd (pfd) == -1) {
- gf_log ("", GF_LOG_ERROR, "gsyncd b/w %s & %s is not"
- " running", master, slave);
- goto out;
- }
-
- if (pfd < 0)
- goto out;
-
- ret = read (pfd, buff, 1024);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, GEOREP" cannot read pid from pid-file");
- goto out;
- }
-
-
- *pid = strtol (buff, NULL, 10);
- ret = 0;
-
-out:
- sys_close(pfd);
- return ret;
-}
-
-static int
-glusterd_do_gsync_log_rotate (char *master, char *slave, uuid_t *uuid, char **op_errstr)
-{
- int ret = 0;
- glusterd_conf_t *priv = NULL;
- pid_t pid = 0;
- char log_file1[PATH_MAX] = {0,};
- char log_file2[PATH_MAX] = {0,};
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
-
- priv = THIS->private;
-
- ret = glusterd_get_pid_from_file (master, slave, &pid);
- if (ret)
- goto out;
-
- /* log file */
- ret = glusterd_gsyncd_getlogfile (master, slave, log_file1);
- if (ret)
- goto out;
-
- /* check if slave is local or remote */
- ret = glusterd_gsync_slave_is_remote (slave);
- if (ret)
- goto do_rotate;
-
- /* slave log file - slave is local and it's log can be rotated */
- ret = glusterd_gsync_get_slave_log_file (master, slave, log_file2);
- if (ret)
- goto out;
-
- do_rotate:
- ret = glusterd_send_log_rotate_signal (pid, log_file1, log_file2);
-
- out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup("Error rotating log file");
- return ret;
-}
-
-static int
-glusterd_do_gsync_log_rotation_mst_slv (glusterd_volinfo_t *volinfo, char *slave,
- char **op_errstr)
-{
- uuid_t uuid = {0, };
- glusterd_conf_t *priv = NULL;
- int ret = 0;
- char errmsg[1024] = {0,};
- xlator_t *this = NULL;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (slave);
- GF_ASSERT (THIS);
- this = THIS;
- GF_ASSERT (this->private);
- priv = this->private;
-
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if ((ret == 0) && (uuid_compare (MY_UUID, uuid) != 0))
- goto out;
-
- if (ret) {
- snprintf(errmsg, sizeof(errmsg), "geo-replication session b/w %s %s not active",
- volinfo->volname, slave);
- gf_log (this->name, GF_LOG_WARNING, "%s", errmsg);
- if (op_errstr)
- *op_errstr = gf_strdup(errmsg);
- goto out;
- }
-
- ret = glusterd_do_gsync_log_rotate (volinfo->volname, slave, &uuid, op_errstr);
-
- out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static void
-_iterate_log_rotate_mst_slv (dict_t *this, char *key, data_t *value, void *data)
-{
- glusterd_gsync_status_temp_t *param = NULL;
- char *slave = NULL;
-
- param = (glusterd_gsync_status_temp_t *) data;
-
- GF_ASSERT (param);
- GF_ASSERT (param->volinfo);
-
- slave = strchr (value->data, ':');
- if (slave)
- slave++;
- else {
- gf_log ("", GF_LOG_ERROR, "geo-replication log-rotate: slave (%s) "
- "not conforming to format", slave);
- return;
- }
-
- (void) glusterd_do_gsync_log_rotation_mst_slv (param->volinfo, slave, NULL);
-}
-
-static int
-glusterd_do_gsync_log_rotation_mst (glusterd_volinfo_t *volinfo)
-{
- glusterd_gsync_status_temp_t param = {0, };
-
- GF_ASSERT (volinfo);
-
- param.volinfo = volinfo;
- dict_foreach (volinfo->gsync_slaves, _iterate_log_rotate_mst_slv, &param);
- return 0;
-}
-
-static int
-glusterd_rotate_gsync_all ()
-{
- int32_t ret = 0;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (THIS);
- priv = THIS->private;
-
- GF_ASSERT (priv);
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- ret = glusterd_do_gsync_log_rotation_mst (volinfo);
- if (ret)
- goto out;
- }
-
- out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
-
-static int
-glusterd_rotate_gsync_logs (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- char *slave = NULL;
- char *volname = NULL;
- char errmsg[1024] = {0,};
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char **linearr = NULL;
- int ret = 0;
-
- ret = dict_get_str (dict, "master", &volname);
- if (ret < 0) {
- ret = glusterd_rotate_gsync_all ();
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if ((ret) || (!exists)) {
- snprintf (errmsg, sizeof(errmsg), "Volume %s does not"
- " exist", volname);
- gf_log ("", GF_LOG_WARNING, "%s", errmsg);
- *op_errstr = gf_strdup (errmsg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0) {
- ret = glusterd_do_gsync_log_rotation_mst (volinfo);
- goto out;
- }
-
- /* for the given slave use the normalized url */
- ret = glusterd_urltransform_single (slave, "normalize", &linearr);
- if (ret == -1)
- goto out;
-
- ret = glusterd_do_gsync_log_rotation_mst_slv (volinfo, linearr[0],
- op_errstr);
- if (ret)
- gf_log ("gsyncd", GF_LOG_ERROR, "gsyncd log-rotate failed for"
- " %s & %s", volname, slave);
-
- glusterd_urltransform_free (linearr, 1);
- out:
- return ret;
-}
-
-
-int
-glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
-{
- int32_t ret = -1;
- int32_t type = -1;
- dict_t *ctx = NULL;
- dict_t *resp_dict = NULL;
- char *host_uuid = NULL;
- char *slave = NULL;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- char *status_msg = NULL;
- uuid_t uuid = {0, };
-
- GF_ASSERT (THIS);
- GF_ASSERT (THIS->private);
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- priv = THIS->private;
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret < 0)
- goto out;
-
- ret = dict_get_str (dict, "host-uuid", &host_uuid);
- if (ret < 0)
- goto out;
-
- ctx = glusterd_op_get_ctx ();
- resp_dict = ctx ? ctx : rsp_dict;
- GF_ASSERT (resp_dict);
-
- if (type == GF_GSYNC_OPTION_TYPE_STATUS) {
- ret = glusterd_get_gsync_status (dict, op_errstr, resp_dict);
- goto out;
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_ROTATE) {
- ret = glusterd_rotate_gsync_logs (dict, op_errstr, resp_dict);
- goto out;
-
- }
-
- ret = dict_get_str (dict, "slave", &slave);
- if (ret < 0)
- goto out;
-
- if (dict_get_str (dict, "master", &volname) == 0) {
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Volinfo for %s (master) not found",
- volname);
- goto out;
- }
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_CONFIG) {
- ret = glusterd_gsync_configure (volinfo, slave, dict, resp_dict,
- op_errstr);
- goto out;
- }
-
- if (!volinfo) {
- ret = -1;
- goto out;
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_START) {
-
- ret = glusterd_set_marker_gsync (volinfo);
- if (ret != 0) {
- gf_log ("", GF_LOG_WARNING, "marker start failed");
- *op_errstr = gf_strdup ("failed to initialize indexing");
- ret = -1;
- goto out;
- }
- ret = glusterd_store_slave_in_info(volinfo, slave,
- host_uuid, op_errstr);
- if (ret)
- goto out;
-
- ret = glusterd_start_gsync (volinfo, slave, host_uuid,
- op_errstr);
- }
-
- if (type == GF_GSYNC_OPTION_TYPE_STOP) {
-
- ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, GEOREP" is not set up for"
- "%s(master) and %s(slave)", volname, slave);
- *op_errstr = strdup (GEOREP" is not set up");
- goto out;
- }
-
- ret = glusterd_remove_slave_in_info(volinfo, slave, op_errstr);
- if (ret)
- goto out;
-
- if (uuid_compare (MY_UUID, uuid) != 0) {
- goto out;
- }
-
- ret = stop_gsync (volname, slave, &status_msg);
- if (ret == 0 && status_msg)
- ret = dict_set_str (resp_dict, "gsync-status",
- status_msg);
- if (ret != 0)
- *op_errstr = gf_strdup ("internal error");
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG,"Returning %d", ret);
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index ccec91f80..bf601efcd 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -36,7 +36,6 @@
#include "compat.h"
#include "compat-errno.h"
#include "statedump.h"
-#include "run.h"
#include "glusterd-mem-types.h"
#include "glusterd.h"
#include "glusterd-sm.h"
@@ -44,12 +43,11 @@
#include "glusterd-utils.h"
#include "glusterd-store.h"
-#include "glusterd1-xdr.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
+#include "glusterd1.h"
+#include "cli1.h"
#include "rpc-clnt.h"
+#include "glusterd1-xdr.h"
#include "glusterd-volgen.h"
-#include "glusterd-mountbroker.h"
#include <sys/resource.h>
#include <inttypes.h>
@@ -57,9 +55,6 @@
#include "defaults.c"
#include "common-utils.h"
-#include "globals.h"
-#include "glusterd-syncop.h"
-
static int
glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
char *hostname, int port,
@@ -83,10 +78,8 @@ glusterd_handle_friend_req (rpcsvc_request_t *req, uuid_t uuid,
if (ret) {
ret = glusterd_xfer_friend_add_resp (req, rhost, port, -1,
GF_PROBE_UNKNOWN_PEER);
- if (friend_req->vols.vols_val) {
+ if (friend_req->vols.vols_val)
free (friend_req->vols.vols_val);
- friend_req->vols.vols_val = NULL;
- }
goto out;
}
@@ -144,16 +137,19 @@ out:
if (0 != ret) {
if (ctx && ctx->hostname)
GF_FREE (ctx->hostname);
- GF_FREE (ctx);
+ if (ctx)
+ GF_FREE (ctx);
if (dict) {
if ((!dict->extra_stdfree) &&
friend_req->vols.vols_val)
free (friend_req->vols.vols_val);
dict_unref (dict);
} else {
- free (friend_req->vols.vols_val);
+ if (friend_req->vols.vols_val)
+ free (friend_req->vols.vols_val);
}
- GF_FREE (event);
+ if (event)
+ GF_FREE (event);
} else {
if (peerinfo && (0 == peerinfo->connected))
ret = GLUSTERD_CONNECTION_AWAITED;
@@ -223,7 +219,8 @@ out:
if (0 != ret) {
if (ctx && ctx->hostname)
GF_FREE (ctx->hostname);
- GF_FREE (ctx);
+ if (ctx)
+ GF_FREE (ctx);
}
return ret;
@@ -285,9 +282,9 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
data_pair_t *pairs = NULL;
char reconfig_key[256] = {0, };
dict_t *dict = NULL;
+ data_t *value = NULL;
int opt_count = 0;
glusterd_conf_t *priv = NULL;
- char *volume_id_str = NULL;
GF_ASSERT (volinfo);
@@ -317,18 +314,8 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
- snprintf (key, 256, "volume%d.dist_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->dist_leaf_count);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.stripe_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->stripe_count);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.replica_count", count);
- ret = dict_set_int32 (volumes, key, volinfo->replica_count);
+ snprintf (key, 256, "volume%d.sub_count", count);
+ ret = dict_set_int32 (volumes, key, volinfo->sub_count);
if (ret)
goto out;
@@ -337,20 +324,6 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
- volume_id_str = gf_strdup (uuid_utoa (volinfo->volume_id));
- if (!volume_id_str)
- goto out;
-
- snprintf (key, sizeof (key), "volume%d.volume_id", count);
- ret = dict_set_dynstr (volumes, key, volume_id_str);
- if (ret)
- goto out;
-
- snprintf (key, 256, "volume%d.rebalance", count);
- ret = dict_set_int32 (volumes, key, volinfo->defrag_cmd);
- if (ret)
- goto out;
-
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
char brick[1024] = {0,};
snprintf (key, 256, "volume%d.brick%d", count, i);
@@ -369,13 +342,21 @@ glusterd_add_volume_detail_to_dict (glusterd_volinfo_t *volinfo,
goto out;
}
- for (pairs = dict->members_list; pairs != NULL; pairs = pairs->next) {
- snprintf (reconfig_key, 256, "volume%d.option.%s", count,
- pairs->key);
- ret = dict_set_str (volumes, reconfig_key, pairs->value->data);
- if (0 == ret)
- opt_count++;
+ pairs = dict->members_list;
+
+ while (pairs) {
+ if (1 == glusterd_check_option_exists (pairs->key, NULL)) {
+ value = pairs->value;
+ if (!value)
+ continue;
+ snprintf (reconfig_key, 256, "volume%d.option.%s", count,
+ pairs->key);
+ ret = dict_set_str (volumes, reconfig_key, value->data);
+ if (!ret)
+ opt_count++;
+ }
+ pairs = pairs->next;
}
snprintf (key, 256, "volume%d.opt_count", count);
@@ -418,49 +399,33 @@ out:
}
int32_t
-glusterd_op_txn_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx)
+glusterd_op_txn_begin ()
{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- int32_t locked = 0;
-
- GF_ASSERT (req);
- GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX));
- GF_ASSERT (NULL != ctx);
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+ int32_t locked = 0;
- this = THIS;
- priv = this->private;
+ priv = THIS->private;
GF_ASSERT (priv);
- ret = glusterd_lock (MY_UUID);
+ ret = glusterd_lock (priv->uuid);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log ("glusterd", GF_LOG_ERROR,
"Unable to acquire local lock, ret: %d", ret);
goto out;
}
locked = 1;
- gf_log (this->name, GF_LOG_INFO, "Acquired local lock");
+ gf_log ("glusterd", GF_LOG_INFO, "Acquired local lock");
ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_LOCK, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to acquire cluster"
- " lock.");
- goto out;
- }
-
- glusterd_op_set_op (op);
- glusterd_op_set_ctx (ctx);
- glusterd_op_set_req (req);
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
out:
if (locked && ret)
- glusterd_unlock (MY_UUID);
-
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+ glusterd_unlock (priv->uuid);
return ret;
}
@@ -470,11 +435,10 @@ glusterd_handle_cluster_lock (rpcsvc_request_t *req)
gd1_mgmt_cluster_lock_req lock_req = {{0},};
int32_t ret = -1;
glusterd_op_lock_ctx_t *ctx = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req)) {
+ if (!gd_xdr_to_mgmt_cluster_lock_req (req->msg[0], &lock_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -483,13 +447,6 @@ glusterd_handle_cluster_lock (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_INFO,
"Received LOCK from uuid: %s", uuid_utoa (lock_req.uuid));
- if (glusterd_friend_find_by_uuid (lock_req.uuid, &peerinfo)) {
- gf_log (THIS->name, GF_LOG_WARNING, "%s doesn't "
- "belong to the cluster. Ignoring request.",
- uuid_utoa (lock_req.uuid));
- ret = -1;
- goto out;
- }
ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t);
@@ -519,10 +476,12 @@ glusterd_req_ctx_create (rpcsvc_request_t *rpc_req,
gf_gld_mem_types_t mem_type,
glusterd_req_ctx_t **req_ctx_out)
{
- int ret = -1;
- char str[50] = {0,};
- glusterd_req_ctx_t *req_ctx = NULL;
- dict_t *dict = NULL;
+ int ret = -1;
+ glusterd_req_ctx_t *req_ctx = NULL;
+ char str[50] = {0,};
+ dict_t *dict = NULL;
+ char volname[GLUSTERD_MAX_VOLUME_NAME] = {0};
+ char *dup_volname = NULL;
uuid_unparse (uuid, str);
gf_log ("glusterd", GF_LOG_INFO,
@@ -531,30 +490,48 @@ glusterd_req_ctx_create (rpcsvc_request_t *rpc_req,
dict = dict_new ();
if (!dict)
goto out;
-
req_ctx = GF_CALLOC (1, sizeof (*req_ctx), mem_type);
+
if (!req_ctx) {
goto out;
}
uuid_copy (req_ctx->uuid, uuid);
req_ctx->op = op;
- ret = dict_unserialize (buf_val, buf_len, &dict);
- if (ret) {
- gf_log ("", GF_LOG_WARNING,
- "failed to unserialize the dictionary");
- goto out;
+ if (GD_OP_DELETE_VOLUME == op) {
+ strncpy (volname, buf_val, buf_len);
+ dup_volname = gf_strdup (volname);
+ if (dup_volname) {
+ ret = dict_set_dynstr (dict, "volname", dup_volname);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to set volume name from payload");
+ goto out;
+ }
+ } else {
+ ret = -1;
+ goto out;
+ }
+ } else {
+ ret = dict_unserialize (buf_val, buf_len, &dict);
+
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to unserialize the dictionary");
+ goto out;
+ }
}
req_ctx->dict = dict;
- req_ctx->req = rpc_req;
+ req_ctx->req = rpc_req;
*req_ctx_out = req_ctx;
ret = 0;
out:
if (ret) {
if (dict)
dict_unref (dict);
- GF_FREE (req_ctx);
+ if (req_ctx)
+ GF_FREE (req_ctx);
}
return ret;
}
@@ -565,23 +542,14 @@ glusterd_handle_stage_op (rpcsvc_request_t *req)
int32_t ret = -1;
glusterd_req_ctx_t *req_ctx = NULL;
gd1_mgmt_stage_op_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_stage_op_req)) {
+ if (!gd_xdr_to_mgmt_stage_op_req (req->msg[0], &op_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- if (glusterd_friend_find_by_uuid (op_req.uuid, &peerinfo)) {
- gf_log (THIS->name, GF_LOG_WARNING, "%s doesn't "
- "belong to the cluster. Ignoring request.",
- uuid_utoa (op_req.uuid));
- ret = -1;
- goto out;
- }
-
ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid,
op_req.buf.buf_val, op_req.buf.buf_len,
gf_gld_mt_op_stage_ctx_t, &req_ctx);
@@ -591,7 +559,8 @@ glusterd_handle_stage_op (rpcsvc_request_t *req)
ret = glusterd_op_sm_inject_event (GD_OP_EVENT_STAGE_OP, req_ctx);
out:
- free (op_req.buf.buf_val);//malloced by xdr
+ if (op_req.buf.buf_val)
+ free (op_req.buf.buf_val);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
return ret;
@@ -603,24 +572,15 @@ glusterd_handle_commit_op (rpcsvc_request_t *req)
int32_t ret = -1;
glusterd_req_ctx_t *req_ctx = NULL;
gd1_mgmt_commit_op_req op_req = {{0},};
- glusterd_peerinfo_t *peerinfo = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &op_req, (xdrproc_t)xdr_gd1_mgmt_commit_op_req)) {
+ if (!gd_xdr_to_mgmt_commit_op_req (req->msg[0], &op_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- if (glusterd_friend_find_by_uuid (op_req.uuid, &peerinfo)) {
- gf_log (THIS->name, GF_LOG_WARNING, "%s doesn't "
- "belong to the cluster. Ignoring request.",
- uuid_utoa (op_req.uuid));
- ret = -1;
- goto out;
- }
-
//the structures should always be equal
GF_ASSERT (sizeof (gd1_mgmt_commit_op_req) == sizeof (gd1_mgmt_stage_op_req));
ret = glusterd_req_ctx_create (req, op_req.op, op_req.uuid,
@@ -635,12 +595,12 @@ glusterd_handle_commit_op (rpcsvc_request_t *req)
ret = glusterd_op_init_ctx (op_req.op);
out:
- free (op_req.buf.buf_val);//malloced by xdr
+ if (op_req.buf.buf_val)
+ free (op_req.buf.buf_val);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
return ret;
}
-
int
glusterd_handle_cli_probe (rpcsvc_request_t *req)
{
@@ -650,7 +610,7 @@ glusterd_handle_cli_probe (rpcsvc_request_t *req)
gf_boolean_t run_fsm = _gf_true;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf1_cli_probe_req)) {
+ if (!gf_xdr_to_cli_probe_req (req->msg[0], &cli_req)) {
//failed to decode msg;
gf_log ("", GF_LOG_ERROR, "xdr decoding error");
req->rpc_err = GARBAGE_ARGS;
@@ -663,7 +623,7 @@ glusterd_handle_cli_probe (rpcsvc_request_t *req)
cli_req.hostname, cli_req.port);
if (!(ret = glusterd_is_local_addr(cli_req.hostname))) {
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_LOCALHOST, NULL,
+ glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_LOCALHOST,
cli_req.hostname, cli_req.port);
goto out;
}
@@ -675,8 +635,7 @@ glusterd_handle_cli_probe (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_DEBUG, "Probe host %s port %d"
" already a peer", cli_req.hostname, cli_req.port);
glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND,
- NULL, cli_req.hostname,
- cli_req.port);
+ cli_req.hostname, cli_req.port);
goto out;
}
}
@@ -691,7 +650,8 @@ glusterd_handle_cli_probe (rpcsvc_request_t *req)
ret = 0;
}
out:
- free (cli_req.hostname);//its malloced by xdr
+ if (cli_req.hostname)
+ free (cli_req.hostname);//its malloced by xdr
if (run_fsm) {
glusterd_friend_sm ();
@@ -705,7 +665,7 @@ int
glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
{
int32_t ret = -1;
- gf1_cli_deprobe_req cli_req = {0,};
+ gf1_cli_probe_req cli_req = {0,};
uuid_t uuid = {0};
int op_errno = 0;
xlator_t *this = NULL;
@@ -717,8 +677,7 @@ glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
GF_ASSERT (priv);
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf1_cli_deprobe_req)) {
+ if (!gf_xdr_to_cli_probe_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -732,19 +691,13 @@ glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
goto out;
}
- if (!uuid_compare (uuid, MY_UUID)) {
+ if (!uuid_compare (uuid, priv->uuid)) {
op_errno = GF_DEPROBE_LOCALHOST;
ret = -1;
goto out;
}
- if (!uuid_is_null (uuid) && !(cli_req.flags & GF_CLI_FLAG_OP_FORCE)) {
- /* Check if peers are connected, except peer being detached*/
- if (!glusterd_chk_peers_connected_befriended (uuid)) {
- ret = -1;
- op_errno = GF_DEPROBE_FRIEND_DOWN;
- goto out;
- }
+ if (!uuid_is_null (uuid)) {
ret = glusterd_all_volume_cond_check (
glusterd_friend_brick_belongs,
-1, &uuid);
@@ -766,11 +719,12 @@ glusterd_handle_cli_deprobe (rpcsvc_request_t *req)
cli_req.port, (ret) ? "FAILED" : "SUCCESS");
out:
if (ret) {
- ret = glusterd_xfer_cli_deprobe_resp (req, ret, op_errno, NULL,
+ ret = glusterd_xfer_cli_deprobe_resp (req, ret, op_errno,
cli_req.hostname);
}
- free (cli_req.hostname);//malloced by xdr
+ if (cli_req.hostname)
+ free (cli_req.hostname);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -787,7 +741,7 @@ glusterd_handle_cli_list_friends (rpcsvc_request_t *req)
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf1_cli_peer_list_req)) {
+ if (!gf_xdr_to_cli_peer_list_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -828,13 +782,12 @@ int
glusterd_handle_cli_get_volume (rpcsvc_request_t *req)
{
int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
+ gf1_cli_get_vol_req cli_req = {0,};
dict_t *dict = NULL;
- int32_t flags = 0;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req)) {
+ if (!gf_xdr_to_cli_get_vol_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -859,17 +812,235 @@ glusterd_handle_cli_get_volume (rpcsvc_request_t *req)
}
}
- ret = dict_get_int32 (dict, "flags", &flags);
+ ret = glusterd_get_volumes (req, dict, cli_req.flags);
+
+out:
+ if (dict)
+ dict_unref (dict);
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ return ret;
+}
+
+int32_t
+glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,
+ gf_boolean_t is_ctx_free)
+{
+ int ret = -1;
+ GF_ASSERT (req);
+ GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX));
+ GF_ASSERT ((NULL != ctx) || (_gf_false == is_ctx_free));
+
+ glusterd_op_set_op (op);
+ glusterd_op_set_ctx (op, ctx);
+ glusterd_op_set_ctx_free (op, is_ctx_free);
+ glusterd_op_set_req (req);
+
+ ret = glusterd_op_txn_begin ();
+
+ return ret;
+}
+
+int
+glusterd_handle_create_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_create_vol_req cli_req = {0,};
+ dict_t *dict = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char *brick = NULL;
+ char *bricks = NULL;
+ char *volname = NULL;
+ int brick_count = 0;
+ char *tmpptr = NULL;
+ int i = 0;
+ char *brick_list = NULL;
+ void *cli_rsp = NULL;
+ char err_str[2048] = {0,};
+ gf1_cli_create_vol_rsp rsp = {0,};
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char *free_ptr = NULL;
+ char *trans_type = NULL;
+ uuid_t volume_id = {0,};
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+ glusterd_volinfo_t tmpvolinfo = {{0},};
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_CREATE_VOLUME;
+
+ GF_ASSERT (req);
+
+ INIT_LIST_HEAD (&tmpvolinfo.bricks);
+
+ ret = glusterd_op_set_cli_op (cli_op);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get flags");
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ snprintf (err_str, sizeof (err_str), "Another operation is in "
+ "progress, please retry after some time");
goto out;
}
- ret = glusterd_get_volumes (req, dict, flags);
+ this = THIS;
+ GF_ASSERT(this);
+
+ priv = this->private;
+
+ ret = -1;
+ if (!gf_xdr_to_cli_create_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ snprintf (err_str, sizeof (err_str), "Garbage args received");
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received create volume req");
+
+ if (cli_req.bricks.bricks_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (cli_req.bricks.bricks_val,
+ cli_req.bricks.bricks_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ snprintf (err_str, sizeof (err_str), "Unable to decode "
+ "the buffer");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.bricks.bricks_val;
+ }
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "name");
+ goto out;
+ }
+ gf_cmd_log ("Volume create", "on volname: %s attempted", volname);
+
+ if ((ret = glusterd_check_volume_exists (volname))) {
+ snprintf(err_str, 2048, "Volume %s already exists", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "brick count");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "transport", &trans_type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get transport-type");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "transport-type");
+ goto out;
+ }
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "bricks");
+ goto out;
+ }
+
+ uuid_generate (volume_id);
+ free_ptr = gf_strdup (uuid_utoa (volume_id));
+ ret = dict_set_dynstr (dict, "volume-id", free_ptr);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "unable to set volume-id");
+ snprintf (err_str, sizeof (err_str), "Unable to set volume "
+ "id");
+ goto out;
+ }
+ free_ptr = NULL;
+
+ if (bricks) {
+ brick_list = gf_strdup (bricks);
+ free_ptr = brick_list;
+ }
+
+ gf_cmd_log ("Volume create", "on volname: %s type:%s count:%d bricks:%s",
+ cli_req.volname, ((cli_req.type == 0)? "DEFAULT":
+ ((cli_req.type == 1)? "STRIPE":"REPLICATE")), cli_req.count,
+ bricks);
+
+
+ while ( i < brick_count) {
+ i++;
+ brick= strtok_r (brick_list, " \n", &tmpptr);
+ brick_list = tmpptr;
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret) {
+ snprintf (err_str, sizeof (err_str), "Unable to get "
+ "brick info from brick %s", brick);
+ goto out;
+ }
+
+ ret = glusterd_new_brick_validate (brick, brickinfo, err_str,
+ sizeof (err_str));
+ if (ret)
+ goto out;
+ ret = glusterd_volume_brickinfo_get (brickinfo->uuid,
+ brickinfo->hostname,
+ brickinfo->path,
+ &tmpvolinfo, &tmpbrkinfo);
+ if (!ret) {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Brick: %s:%s, %s"
+ " in the arguments mean the same",
+ tmpbrkinfo->hostname, tmpbrkinfo->path,
+ brick);
+ goto out;
+ }
+ list_add_tail (&brickinfo->brick_list, &tmpvolinfo.bricks);
+ brickinfo = NULL;
+ }
+
+ ret = glusterd_op_begin (req, GD_OP_CREATE_VOLUME, dict, _gf_true);
+ gf_cmd_log ("Volume create", "on volname: %s %s", volname,
+ (ret != 0) ? "FAILED": "SUCCESS");
out:
- if (dict)
- dict_unref (dict);
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ rsp.op_ret = -1;
+ rsp.op_errno = 0;
+ rsp.volname = "";
+ if (err_str[0] == '\0')
+ snprintf (err_str, sizeof (err_str), "Operation failed");
+ rsp.op_errstr = err_str;
+ cli_rsp = &rsp;
+ glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_create_vol_rsp);
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ ret = 0; //Client response sent, prevent second response
+ }
+
+ if (free_ptr)
+ GF_FREE(free_ptr);
+
+ glusterd_volume_brickinfos_delete (&tmpvolinfo);
+ if (brickinfo)
+ glusterd_brickinfo_delete (brickinfo);
+ if (cli_req.volname)
+ free (cli_req.volname); // its a malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -878,86 +1049,762 @@ out:
}
int
-glusterd_handle_cli_list_volume (rpcsvc_request_t *req)
+glusterd_handle_cli_start_volume (rpcsvc_request_t *req)
{
- int ret = -1;
- dict_t *dict = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int count = 0;
- char key[1024] = {0,};
- gf_cli_rsp rsp = {0,};
+ int32_t ret = -1;
+ gf1_cli_start_vol_req cli_req = {0,};
+ int lock_fail = 0;
+ char *dup_volname = NULL;
+ dict_t *dict = NULL;
+ glusterd_op_t cli_op = GD_OP_START_VOLUME;
GF_ASSERT (req);
- priv = THIS->private;
- GF_ASSERT (priv);
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d", ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_start_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received start vol req"
+ "for volume %s", cli_req.volname);
dict = dict_new ();
+
if (!dict)
goto out;
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d", count);
- ret = dict_set_str (dict, key, volinfo->volname);
- if (ret)
- goto out;
- count++;
- }
+ dup_volname = gf_strdup (cli_req.volname);
+ if (!dup_volname)
+ goto out;
- ret = dict_set_int32 (dict, "count", count);
+ ret = dict_set_dynstr (dict, "volname", dup_volname);
if (ret)
goto out;
- ret = dict_allocate_and_serialize (dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
+ ret = dict_set_int32 (dict, "flags", cli_req.flags);
if (ret)
goto out;
+ ret = glusterd_op_begin (req, GD_OP_START_VOLUME, dict, _gf_true);
- ret = 0;
+ gf_cmd_log ("volume start","on volname: %s %s", cli_req.volname,
+ ((ret == 0) ? "SUCCESS": "FAILED"));
out:
- rsp.op_ret = ret;
+ if (ret && dict)
+ dict_unref (dict);
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ }
+
+ return ret;
+}
+
+
+int
+glusterd_handle_cli_stop_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_stop_vol_req cli_req = {0,};
+ int lock_fail = 0;
+ char *dup_volname = NULL;
+ dict_t *dict = NULL;
+ glusterd_op_t cli_op = GD_OP_STOP_VOLUME;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_stop_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received stop vol req"
+ "for volume %s", cli_req.volname);
+
+ dict = dict_new ();
+
+ if (!dict)
+ goto out;
+
+ dup_volname = gf_strdup (cli_req.volname);
+ if (!dup_volname)
+ goto out;
+
+ ret = dict_set_dynstr (dict, "volname", dup_volname);
if (ret)
- rsp.op_errstr = "Error listing volumes";
- else
- rsp.op_errstr = "";
+ goto out;
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
+ ret = dict_set_int32 (dict, "flags", cli_req.flags);
+ if (ret)
+ goto out;
- if (dict)
- dict_unref (dict);
+ ret = glusterd_op_begin (req, GD_OP_STOP_VOLUME, dict, _gf_true);
+ gf_cmd_log ("Volume stop","on volname: %s %s", cli_req.volname,
+ ((ret)?"FAILED":"SUCCESS"));
+
+out:
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+ }
+
return ret;
}
-int32_t
-glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx)
+int
+glusterd_handle_cli_delete_volume (rpcsvc_request_t *req)
{
- int ret = -1;
+ int lock_fail = 0;
+ int32_t ret = -1;
+ gf1_cli_delete_vol_req cli_req = {0,};
+ glusterd_op_delete_volume_ctx_t *ctx = NULL;
+ glusterd_op_t cli_op = GD_OP_DELETE_VOLUME;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_delete_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+ gf_cmd_log ("Volume delete","on volname: %s attempted", cli_req.volname);
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received delete vol req"
+ "for volume %s", cli_req.volname);
- ret = glusterd_op_txn_begin (req, op, ctx);
+
+ ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_delete_volume_ctx_t);
+ if (!ctx)
+ goto out;
+
+ strncpy (ctx->volume_name, cli_req.volname, GD_VOLUME_NAME_MAX);
+
+ ret = glusterd_op_begin (req, GD_OP_DELETE_VOLUME, ctx, _gf_true);
+ gf_cmd_log ("Volume delete", "on volname: %s %s", cli_req.volname,
+ ((ret) ? "FAILED" : "SUCCESS"));
+
+out:
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+ }
return ret;
}
int
+glusterd_handle_add_brick (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_add_brick_req cli_req = {0,};
+ dict_t *dict = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char *brick = NULL;
+ char *bricks = NULL;
+ char *volname = NULL;
+ int brick_count = 0;
+ char *tmpptr = NULL;
+ int i = 0;
+ char *brick_list = NULL;
+ void *cli_rsp = NULL;
+ char err_str[2048] = {0,};
+ gf1_cli_add_brick_rsp rsp = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char *free_ptr = NULL;
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+ glusterd_volinfo_t tmpvolinfo = {{0},};
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_ADD_BRICK;
+
+ this = THIS;
+ GF_ASSERT(this);
+
+ priv = this->private;
+
+ GF_ASSERT (req);
+
+ INIT_LIST_HEAD (&tmpvolinfo.bricks);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ snprintf (err_str, sizeof (err_str), "Another operation is in "
+ "progress, please retry after some time");
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_add_brick_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ snprintf (err_str, sizeof (err_str), "Garbage args received");
+ goto out;
+ }
+
+ gf_cmd_log ("Volume add-brick", "on volname: %s attempted",
+ cli_req.volname);
+ gf_log ("glusterd", GF_LOG_INFO, "Received add brick req");
+
+ if (cli_req.bricks.bricks_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (cli_req.bricks.bricks_val,
+ cli_req.bricks.bricks_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ snprintf (err_str, sizeof (err_str), "Unable to decode "
+ "the buffer");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.bricks.bricks_val;
+ }
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "name");
+ goto out;
+ }
+
+ if (!(ret = glusterd_check_volume_exists (volname))) {
+ ret = -1;
+ snprintf(err_str, 2048, "Volume %s does not exist", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "brick count");
+ goto out;
+ }
+
+ if (!(ret = glusterd_volinfo_find (volname, &volinfo))) {
+ if (volinfo->type == GF_CLUSTER_TYPE_NONE)
+ goto brick_val;
+ if (!brick_count || !volinfo->sub_count)
+ goto brick_val;
+
+ /* If the brick count is less than sub_count then, allow add-brick only for
+ plain replicate volume since in plain stripe brick_count becoming less than
+ the sub_count is not allowed */
+ if (volinfo->brick_count < volinfo->sub_count && (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) ) {
+ if ((volinfo->sub_count - volinfo->brick_count) == brick_count)
+ goto brick_val;
+ }
+
+ if ((brick_count % volinfo->sub_count) != 0) {
+ snprintf(err_str, 2048, "Incorrect number of bricks"
+ " supplied %d for type %s with count %d",
+ brick_count, (volinfo->type == 1)? "STRIPE":
+ "REPLICATE", volinfo->sub_count);
+ gf_log("glusterd", GF_LOG_ERROR, "%s", err_str);
+ ret = -1;
+ goto out;
+ }
+ } else {
+ snprintf (err_str, sizeof (err_str), "Unable to get volinfo "
+ "for volume name %s", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+brick_val:
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ snprintf (err_str, sizeof (err_str), "Unable to get volume "
+ "bricks");
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ if (bricks)
+ brick_list = gf_strdup (bricks);
+ if (!brick_list) {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Out of memory");
+ goto out;
+ } else {
+ free_ptr = brick_list;
+ }
+
+ gf_cmd_log ("Volume add-brick", "volname: %s type %s count:%d bricks:%s"
+ ,volname, ((volinfo->type == 0)? "DEFAULT" : ((volinfo->type
+ == 1)? "STRIPE": "REPLICATE")), brick_count, brick_list);
+
+
+ while ( i < brick_count) {
+ i++;
+ brick= strtok_r (brick_list, " \n", &tmpptr);
+ brick_list = tmpptr;
+ brickinfo = NULL;
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret) {
+ snprintf (err_str, sizeof (err_str), "Unable to get "
+ "brick info from brick %s", brick);
+ goto out;
+ }
+ ret = glusterd_new_brick_validate (brick, brickinfo, err_str,
+ sizeof (err_str));
+ if (ret)
+ goto out;
+ ret = glusterd_volume_brickinfo_get (brickinfo->uuid,
+ brickinfo->hostname,
+ brickinfo->path,
+ &tmpvolinfo, &tmpbrkinfo);
+ if (!ret) {
+ ret = -1;
+ snprintf (err_str, sizeof (err_str), "Brick: %s:%s, %s"
+ " in the arguments mean the same",
+ tmpbrkinfo->hostname, tmpbrkinfo->path,
+ brick);
+ goto out;
+ }
+ list_add_tail (&brickinfo->brick_list, &tmpvolinfo.bricks);
+ brickinfo = NULL;
+ }
+
+ ret = glusterd_op_begin (req, GD_OP_ADD_BRICK, dict, _gf_true);
+ gf_cmd_log ("Volume add-brick","on volname: %s %s", volname,
+ (ret != 0)? "FAILED" : "SUCCESS");
+
+out:
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ rsp.op_ret = -1;
+ rsp.op_errno = 0;
+ rsp.volname = "";
+ if (err_str[0] == '\0')
+ snprintf (err_str, sizeof (err_str), "Operation failed");
+ rsp.op_errstr = err_str;
+ cli_rsp = &rsp;
+ glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_add_brick_rsp);
+ if (!lock_fail)
+ glusterd_opinfo_unlock();
+ ret = 0; //sent error to cli, prevent second reply
+ }
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (free_ptr)
+ GF_FREE (free_ptr);
+ glusterd_volume_brickinfos_delete (&tmpvolinfo);
+ if (brickinfo)
+ glusterd_brickinfo_delete (brickinfo);
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
+
+ return ret;
+}
+
+int
+glusterd_handle_replace_brick (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_replace_brick_req cli_req = {0,};
+ dict_t *dict = NULL;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ int32_t op = 0;
+ char operation[256];
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_REPLACE_BRICK;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_replace_brick_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received replace brick req");
+
+ if (cli_req.bricks.bricks_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (cli_req.bricks.bricks_val,
+ cli_req.bricks.bricks_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.bricks.bricks_val;
+ }
+ }
+
+ ret = dict_get_int32 (dict, "operation", &op);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "dict_get on operation failed");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "src-brick", &src_brick);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
+ goto out;
+ }
+ gf_log ("", GF_LOG_DEBUG,
+ "src brick=%s", src_brick);
+
+ ret = dict_get_str (dict, "dst-brick", &dst_brick);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get dest brick");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "dst brick=%s", dst_brick);
+
+ switch (op) {
+ case GF_REPLACE_OP_START: strcpy (operation, "start");
+ break;
+ case GF_REPLACE_OP_COMMIT: strcpy (operation, "commit");
+ break;
+ case GF_REPLACE_OP_PAUSE: strcpy (operation, "pause");
+ break;
+ case GF_REPLACE_OP_ABORT: strcpy (operation, "abort");
+ break;
+ case GF_REPLACE_OP_STATUS: strcpy (operation, "status");
+ break;
+ case GF_REPLACE_OP_COMMIT_FORCE: strcpy (operation, "commit-force");
+ break;
+ default:strcpy (operation, "unknown");
+ break;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received replace brick %s request", operation);
+ gf_cmd_log ("Volume replace-brick","volname: %s src_brick:%s"
+ " dst_brick:%s op:%s",cli_req.volname, src_brick, dst_brick
+ ,operation);
+
+ ret = glusterd_op_begin (req, GD_OP_REPLACE_BRICK, dict, _gf_true);
+ gf_cmd_log ("Volume replace-brick","on volname: %s %s", cli_req.volname,
+ (ret) ? "FAILED" : "SUCCESS");
+
+out:
+ if (ret && dict)
+ dict_unref (dict);
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ }
+
+ return ret;
+}
+
+
+
+
+int
glusterd_handle_reset_volume (rpcsvc_request_t *req)
{
int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
+ gf1_cli_reset_vol_req cli_req = {0,};
dict_t *dict = NULL;
+ int lock_fail = 0;
glusterd_op_t cli_op = GD_OP_RESET_VOLUME;
- char *volname = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req)) {
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_set_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ if (cli_req.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ ret = dict_unserialize (cli_req.dict.dict_val,
+ cli_req.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR, "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.dict.dict_val;
+ }
+ }
+
+ gf_cmd_log ("Volume reset", "volume : %s", cli_req.volname);
+ ret = glusterd_op_begin (req, GD_OP_RESET_VOLUME, dict, _gf_true);
+ gf_cmd_log ("Volume reset", " on volume %s %s ", cli_req.volname,
+ ((ret == 0)? " SUCCEDED":" FAILED"));
+
+out:
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+ }
+
+ return ret;
+}
+
+int
+glusterd_handle_gsync_set (rpcsvc_request_t *req)
+{
+ int32_t ret = 0;
+ dict_t *dict = NULL;
+ gf1_cli_gsync_set_req cli_req = {{0},};
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_GSYNC_SET;
+ char *master = NULL;
+ char *slave = NULL;
+ char operation[256] = {0,};
+ int type = 0;
+ glusterd_conf_t *priv = NULL;
+ char *host_uuid = NULL;
+
+ GF_ASSERT (req);
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_gsync_set_req (req->msg[0], &cli_req)) {
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ if (cli_req.dict.dict_len) {
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_unserialize (cli_req.dict.dict_val,
+ cli_req.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log ("glusterd", GF_LOG_ERROR, "failed to "
+ "unserialize req-buffer to dictionary");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.dict.dict_val;
+ }
+
+ host_uuid = gf_strdup (uuid_utoa(priv->uuid));
+ if (host_uuid == NULL) {
+ gf_log ("glusterd", GF_LOG_ERROR, "failed to get"
+ "the uuid of the host machine");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_dynstr (dict, "host-uuid", host_uuid);
+ if (ret)
+ goto out;
+
+ }
+
+ ret = dict_get_str (dict, "master", &master);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_INFO, "master not found, while handling"
+ GEOREP" options");
+ master = "(No Master)";
+ }
+
+ ret = dict_get_str (dict, "slave", &slave);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_INFO, "slave not not found, while"
+ "handling "GEOREP" options");
+ slave = "(No Slave)";
+ }
+
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "command type not found, while"
+ "handling "GEOREP" options");
+ goto out;
+ }
+
+ switch (type) {
+
+ case GF_GSYNC_OPTION_TYPE_START:
+ strncpy (operation, "start", sizeof (operation));
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_STOP:
+ strncpy (operation, "stop", sizeof (operation));
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_CONFIG:
+ strncpy (operation, "config", sizeof (operation));
+ break;
+
+ case GF_GSYNC_OPTION_TYPE_STATUS:
+ strncpy (operation, "status", sizeof (operation));
+ break;
+ }
+
+ gf_cmd_log ("volume "GEOREP, " %s command on %s,%s", operation, master,
+ slave);
+ ret = glusterd_op_begin (req, GD_OP_GSYNC_SET, dict, _gf_true);
+ gf_cmd_log ("volume "GEOREP, " %s command on %s,%s %s ", operation,
+ master, slave, (ret != 0)? "FAILED" : "SUCCEEDED");
+
+out:
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+ }
+ return ret;
+}
+
+int
+glusterd_handle_quota (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_quota_req cli_req = {0,};
+ dict_t *dict = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_QUOTA;
+ char operation[256] = {0, };
+ char *volname = NULL;
+ int32_t type = 0;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ if (!gf_xdr_to_cli_quota_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -981,35 +1828,65 @@ glusterd_handle_reset_volume (rpcsvc_request_t *req)
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
+ gf_log ("", GF_LOG_WARNING, "Unable to get volume name, while"
+ "handling quota command");
goto out;
}
- gf_cmd_log ("Volume reset", "volume : %s", volname);
- ret = glusterd_op_begin (req, GD_OP_RESET_VOLUME, dict);
- gf_cmd_log ("Volume reset", " on volume %s %s ", volname,
- ((ret == 0)? " SUCCEDED":" FAILED"));
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "Unable to get type of cmd. , while"
+ "handling quota command");
+ goto out;
+ }
+
+ switch (type) {
+ case GF_QUOTA_OPTION_TYPE_ENABLE:
+ strncpy (operation, "enable", sizeof (operation));
+ break;
+
+ case GF_QUOTA_OPTION_TYPE_DISABLE:
+ strncpy (operation, "disable", sizeof (operation));
+ break;
+
+ case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
+ strncpy (operation, "limit-usage", sizeof (operation));
+ break;
+
+ case GF_QUOTA_OPTION_TYPE_REMOVE:
+ strncpy (operation, "remove", sizeof (operation));
+ break;
+ }
+ gf_cmd_log ("volume quota", " %s command on %s", operation, volname);
+ ret = glusterd_op_begin (req, GD_OP_QUOTA, dict, _gf_true);
+ gf_cmd_log ("volume quota", " %s command on %s %s", operation,volname,
+ (ret != 0)? "FAILED" : "SUCCEEDED");
out:
glusterd_friend_sm ();
glusterd_op_sm ();
+
if (ret) {
if (dict)
dict_unref (dict);
ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
}
+ if (cli_req.volname)
+ free (cli_req.volname); //malloced by xdr
return ret;
}
-
int
glusterd_handle_set_volume (rpcsvc_request_t *req)
{
int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
+ gf1_cli_set_vol_req cli_req = {0,};
dict_t *dict = NULL;
+ int lock_fail = 0;
glusterd_op_t cli_op = GD_OP_SET_VOLUME;
char *key = NULL;
char *value = NULL;
@@ -1017,7 +1894,16 @@ glusterd_handle_set_volume (rpcsvc_request_t *req)
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req)) {
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_set_vol_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -1049,29 +1935,26 @@ glusterd_handle_set_volume (rpcsvc_request_t *req)
ret = dict_get_str (dict, "key1", &key);
if (ret) {
- if (strcmp (volname, "help-xml") && strcmp (volname, "help")) {
- gf_log ("", GF_LOG_WARNING, "Unable to get key, while "
- "handling volume set for %s",volname);
- goto out;
- }
+ gf_log ("", GF_LOG_WARNING, "Unable to get key, while"
+ "handling volume set for %s",volname);
+ goto out;
}
ret = dict_get_str (dict, "value1", &value);
if (ret) {
- if (strcmp (volname, "help-xml") && strcmp (volname, "help")) {
- gf_log ("", GF_LOG_WARNING, "Unable to get value, while"
- "handling volume set for %s",volname);
- goto out;
- }
+ gf_log ("", GF_LOG_WARNING, "Unable to get value, while"
+ "handling volume set for %s",volname);
+ goto out;
}
-
gf_cmd_log ("volume set", "volume-name:%s: key:%s, value:%s",volname,
key, value);
- ret = glusterd_op_begin (req, GD_OP_SET_VOLUME, dict);
+ ret = glusterd_op_begin (req, GD_OP_SET_VOLUME, dict, _gf_true);
gf_cmd_log ("volume set", "volume-name:%s: key:%s, value:%s %s",
volname, key, value, (ret == 0)? "SUCCEDED" : "FAILED" );
out:
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -1081,37 +1964,63 @@ out:
dict_unref (dict);
ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
}
return ret;
}
int
-glusterd_handle_sync_volume (rpcsvc_request_t *req)
+glusterd_handle_remove_brick (rpcsvc_request_t *req)
{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- gf_cli_rsp cli_rsp = {0.};
- char msg[2048] = {0,};
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- gf1_cli_sync_volume flags = 0;
- char *hostname = NULL;
+ int32_t ret = -1;
+ gf1_cli_remove_brick_req cli_req = {0,};
+ dict_t *dict = NULL;
+ int32_t count = 0;
+ char *brick = NULL;
+ char key[256] = {0,};
+ char *brick_list = NULL;
+ int i = 1;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t pos = 0;
+ int32_t sub_volume = 0;
+ int32_t sub_volume_start = 0;
+ int32_t sub_volume_end = 0;
+ glusterd_brickinfo_t *tmp = NULL;
+ char err_str[2048] = {0};
+ gf1_cli_remove_brick_rsp rsp = {0,};
+ void *cli_rsp = NULL;
+ char vol_type[256] = {0,};
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_REMOVE_BRICK;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req)) {
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_remove_brick_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- if (cli_req.dict.dict_len) {
+ gf_cmd_log ("Volume remove-brick","on volname: %s attempted",cli_req.volname);
+ gf_log ("glusterd", GF_LOG_INFO, "Received rem brick req");
+
+ if (cli_req.bricks.bricks_len) {
/* Unserialize the dictionary */
dict = dict_new ();
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
+ ret = dict_unserialize (cli_req.bricks.bricks_val,
+ cli_req.bricks.bricks_len,
&dict);
if (ret < 0) {
gf_log ("glusterd", GF_LOG_ERROR,
@@ -1119,53 +2028,481 @@ glusterd_handle_sync_volume (rpcsvc_request_t *req)
"unserialize req-buffer to dictionary");
goto out;
} else {
- dict->extra_stdfree = cli_req.dict.dict_val;
+ dict->extra_stdfree = cli_req.bricks.bricks_val;
}
}
- ret = dict_get_str (dict, "hostname", &hostname);
+ ret = dict_get_int32 (dict, "count", &count);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get hostname");
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
goto out;
}
- ret = dict_get_str (dict, "volname", &volname);
+ ret = glusterd_volinfo_find (cli_req.volname, &volinfo);
+ if (ret) {
+ snprintf (err_str, 2048, "Volume %s does not exist",
+ cli_req.volname);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+
+ if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE)
+ strcpy (vol_type, "replica");
+ else if (volinfo->type == GF_CLUSTER_TYPE_STRIPE)
+ strcpy (vol_type, "stripe");
+ else
+ strcpy (vol_type, "distribute");
+
+ /* Do not allow remove-brick if the volume is plain stripe */
+ if ((volinfo->type == GF_CLUSTER_TYPE_STRIPE) && (volinfo->brick_count == volinfo->sub_count)) {
+ snprintf (err_str, 2048, "Removing brick from a plain stripe is not allowed");
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
+ ret = -1;
+ goto out;
+ }
+
+ /* Do not allow remove-brick if the bricks given is less than the replica count
+ or stripe count */
+ if (((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) || (volinfo->type == GF_CLUSTER_TYPE_STRIPE))
+ && !(volinfo->brick_count <= volinfo->sub_count)) {
+ if (volinfo->sub_count && (count % volinfo->sub_count != 0)) {
+ snprintf (err_str, 2048, "Remove brick incorrect"
+ " brick count of %d for %s %d",
+ count, vol_type, volinfo->sub_count);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ brick_list = GF_MALLOC (120000 * sizeof(*brick_list),gf_common_mt_char);
+
+ if (!brick_list) {
+ ret = -1;
+ goto out;
+ }
+
+ strcpy (brick_list, " ");
+ while ( i <= count) {
+ snprintf (key, 256, "brick%d", i);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get %s", key);
+ goto out;
+ }
+ gf_log ("", GF_LOG_DEBUG, "Remove brick count %d brick: %s",
+ i, brick);
+
+ ret = glusterd_volume_brickinfo_get_by_brick(brick, volinfo, &brickinfo);
+ if (ret) {
+ snprintf(err_str, 2048,"Incorrect brick %s for volume"
+ " %s", brick, cli_req.volname);
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ goto out;
+ }
+ strcat(brick_list, brick);
+ strcat(brick_list, " ");
+
+ i++;
+ if ((volinfo->type == GF_CLUSTER_TYPE_NONE) ||
+ (volinfo->brick_count <= volinfo->sub_count))
+ continue;
+
+ pos = 0;
+ list_for_each_entry (tmp, &volinfo->bricks, brick_list) {
+
+ if ((!strcmp (tmp->hostname,brickinfo->hostname)) &&
+ !strcmp (tmp->path, brickinfo->path)) {
+ gf_log ("", GF_LOG_INFO, "Found brick");
+ if (!sub_volume && volinfo->sub_count) {
+ sub_volume = (pos / volinfo->
+ sub_count) + 1;
+ sub_volume_start = volinfo->sub_count *
+ (sub_volume - 1);
+ sub_volume_end = (volinfo->sub_count *
+ sub_volume) -1 ;
+ } else {
+ if (pos < sub_volume_start ||
+ pos >sub_volume_end) {
+ ret = -1;
+ snprintf(err_str, 2048,"Bricks"
+ " not from same subvol"
+ " for %s", vol_type);
+ gf_log ("",GF_LOG_ERROR,
+ "%s", err_str);
+ goto out;
+ }
+ }
+ break;
+ }
+ pos++;
+ }
+ }
+ gf_cmd_log ("Volume remove-brick","volname: %s count:%d bricks:%s",
+ cli_req.volname, count, brick_list);
+
+ ret = glusterd_op_begin (req, GD_OP_REMOVE_BRICK, dict, _gf_true);
+ gf_cmd_log ("Volume remove-brick","on volname: %s %s",cli_req.volname,
+ (ret) ? "FAILED" : "SUCCESS");
+
+out:
+ if (ret) {
+ if (dict)
+ dict_unref (dict);
+ rsp.op_ret = -1;
+ rsp.op_errno = 0;
+ rsp.volname = "";
+ if (err_str[0] == '\0')
+ snprintf (err_str, sizeof (err_str), "Operation failed");
+ gf_log ("", GF_LOG_ERROR, "%s", err_str);
+ rsp.op_errstr = err_str;
+ cli_rsp = &rsp;
+ glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_remove_brick_rsp);
+ if (!lock_fail)
+ glusterd_opinfo_unlock();
+
+ ret = 0; //sent error to cli, prevent second reply
+
+ }
+ if (brick_list)
+ GF_FREE (brick_list);
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ return ret;
+}
+
+int
+glusterd_handle_log_filename (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_log_filename_req cli_req = {0,};
+ dict_t *dict = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_LOG_FILENAME;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_log_filename_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received log filename req "
+ "for volume %s", cli_req.volname);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
+ if (ret)
+ goto out;
+ ret = dict_set_dynmstr (dict, "brick", cli_req.brick);
+ if (ret)
+ goto out;
+ ret = dict_set_dynmstr (dict, "path", cli_req.path);
+ if (ret)
+ goto out;
+
+ ret = glusterd_op_begin (req, GD_OP_LOG_FILENAME, dict, _gf_true);
+
+out:
+ if (ret && dict)
+ dict_unref (dict);
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ }
+
+ return ret;
+}
+
+int
+glusterd_handle_log_locate (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_log_locate_req cli_req = {0,};
+ gf1_cli_log_locate_rsp rsp = {0,};
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char tmp_str[PATH_MAX] = {0,};
+ char *tmp_brick = NULL;
+ uint32_t found = 0;
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_LOG_LOCATE;
+
+ GF_ASSERT (req);
+
+ priv = THIS->private;
+
+ ret = glusterd_op_set_cli_op (cli_op);
if (ret) {
- ret = dict_get_int32 (dict, "flags", (int32_t*)&flags);
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_log_locate_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received log locate req "
+ "for volume %s", cli_req.volname);
+
+ if (strchr (cli_req.brick, ':')) {
+ /* TODO: need to get info of only that brick and then
+ tell what is the exact location */
+ tmp_brick = gf_strdup (cli_req.brick);
+ if (!tmp_brick)
+ goto out;
+
+ gf_log ("", GF_LOG_DEBUG, "brick : %s", cli_req.brick);
+ ret = glusterd_brickinfo_from_brick (tmp_brick, &tmpbrkinfo);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to get volume"
- "name, or flags");
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Cannot get brickinfo from the brick");
goto out;
}
}
+ ret = glusterd_volinfo_find (cli_req.volname, &volinfo);
+ if (ret) {
+ rsp.path = "request sent on non-existent volume";
+ goto out;
+ }
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (tmpbrkinfo) {
+ ret = glusterd_resolve_brick (tmpbrkinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "cannot resolve the brick");
+ goto out;
+ }
+ if (uuid_compare (tmpbrkinfo->uuid, brickinfo->uuid) || strcmp (brickinfo->path, tmpbrkinfo->path))
+ continue;
+ }
+
+ if (brickinfo->logfile) {
+ strcpy (tmp_str, brickinfo->logfile);
+ rsp.path = dirname (tmp_str);
+ found = 1;
+ } else {
+ snprintf (tmp_str, PATH_MAX, "%s/bricks/",
+ DEFAULT_LOG_FILE_DIRECTORY);
+ rsp.path = tmp_str;
+ found = 1;
+ }
+ break;
+ }
+
+ if (!found) {
+ snprintf (tmp_str, PATH_MAX, "brick %s:%s does not exitst in the volume %s",
+ tmpbrkinfo->hostname, tmpbrkinfo->path, cli_req.volname);
+ rsp.path = tmp_str;
+ }
+
+ ret = 0;
+out:
+ if (tmp_brick)
+ GF_FREE (tmp_brick);
+ if (tmpbrkinfo)
+ glusterd_brickinfo_delete (tmpbrkinfo);
+ rsp.op_ret = ret;
+ if (!rsp.path)
+ rsp.path = "Operation failed";
+
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_log_locate_rsp);
+
+ if (cli_req.brick)
+ free (cli_req.brick); //its malloced by xdr
+ if (cli_req.volname)
+ free (cli_req.volname); //its malloced by xdr
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+
+ return ret;
+}
+
+int
+glusterd_handle_log_rotate (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_log_rotate_req cli_req = {0,};
+ dict_t *dict = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_LOG_ROTATE;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_log_rotate_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received log rotate req "
+ "for volume %s", cli_req.volname);
+
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
+ if (ret)
+ goto out;
+
+ ret = dict_set_dynmstr (dict, "brick", cli_req.brick);
+ if (ret)
+ goto out;
+
+ ret = dict_set_uint64 (dict, "rotate-key", (uint64_t)time (NULL));
+ if (ret)
+ goto out;
+
+ ret = glusterd_op_begin (req, GD_OP_LOG_ROTATE, dict, _gf_true);
+
+out:
+ if (ret && dict)
+ dict_unref (dict);
+
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
+ if (ret) {
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
+ }
+
+ return ret;
+}
+
+int
+glusterd_handle_sync_volume (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf1_cli_sync_volume_req cli_req = {0,};
+ dict_t *dict = NULL;
+ gf1_cli_sync_volume_rsp cli_rsp = {0.};
+ char msg[2048] = {0,};
+ gf_boolean_t free_hostname = _gf_true;
+ gf_boolean_t free_volname = _gf_true;
+ glusterd_volinfo_t *volinfo = NULL;
+ int lock_fail = 0;
+ glusterd_op_t cli_op = GD_OP_SYNC_VOLUME;
+
+ GF_ASSERT (req);
+
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_sync_volume_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
gf_log ("glusterd", GF_LOG_INFO, "Received volume sync req "
"for volume %s",
- (flags & GF_CLI_SYNC_ALL) ? "all" : volname);
+ (cli_req.flags & GF_CLI_SYNC_ALL) ? "all" : cli_req.volname);
- if (!glusterd_is_local_addr (hostname)) {
+ dict = dict_new ();
+ if (!dict) {
+ gf_log ("", GF_LOG_ERROR, "Can't allocate sync vol dict");
+ goto out;
+ }
+
+ if (!glusterd_is_local_addr (cli_req.hostname)) {
ret = -1;
snprintf (msg, sizeof (msg), "sync from localhost"
" not allowed");
goto out;
}
- if (!flags) {
- ret = glusterd_volinfo_find (volname, &volinfo);
+ ret = dict_set_dynmstr (dict, "hostname", cli_req.hostname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "hostname set failed");
+ snprintf (msg, sizeof (msg), "hostname set failed");
+ goto out;
+ } else {
+ free_hostname = _gf_false;
+ }
+
+ ret = dict_set_int32 (dict, "flags", cli_req.flags);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "volume flags set failed");
+ snprintf (msg, sizeof (msg), "volume flags set failed");
+ goto out;
+ }
+
+ if (!cli_req.flags) {
+ ret = glusterd_volinfo_find (cli_req.volname, &volinfo);
if (!ret) {
snprintf (msg, sizeof (msg), "please delete the "
- "volume: %s before sync", volname);
+ "volume: %s before sync", cli_req.volname);
ret = -1;
goto out;
}
- ret = dict_set_dynmstr (dict, "volname", volname);
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
if (ret) {
gf_log ("", GF_LOG_ERROR, "volume name set failed");
snprintf (msg, sizeof (msg), "volume name set failed");
goto out;
+ } else {
+ free_volname = _gf_false;
}
} else {
+ free_volname = _gf_false;
if (glusterd_volume_count_get ()) {
snprintf (msg, sizeof (msg), "please delete all the "
"volumes before full sync");
@@ -1174,7 +2511,7 @@ glusterd_handle_sync_volume (rpcsvc_request_t *req)
}
}
- ret = glusterd_op_begin (req, GD_OP_SYNC_VOLUME, dict);
+ ret = glusterd_op_begin (req, GD_OP_SYNC_VOLUME, dict, _gf_true);
out:
if (ret) {
@@ -1183,10 +2520,16 @@ out:
if (msg[0] == '\0')
snprintf (msg, sizeof (msg), "Operation failed");
glusterd_submit_reply(req, &cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
+ gf_xdr_from_cli_sync_volume_rsp);
+ if (free_hostname && cli_req.hostname)
+ free (cli_req.hostname);
+ if (free_volname && cli_req.volname)
+ free (cli_req.volname);
if (dict)
dict_unref (dict);
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
ret = 0; //sent error to cli, prevent second reply
}
@@ -1212,11 +2555,12 @@ glusterd_fsm_log_send_resp (rpcsvc_request_t *req, int op_ret,
rsp.op_errstr = op_errstr;
if (rsp.op_ret == 0)
ret = dict_allocate_and_serialize (dict, &rsp.fsm_log.fsm_log_val,
- &rsp.fsm_log.fsm_log_len);
+ (size_t *)&rsp.fsm_log.fsm_log_len);
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_fsm_log_rsp);
- GF_FREE (rsp.fsm_log.fsm_log_val);
+ gf_xdr_from_cli_fsm_log_rsp);
+ if (rsp.fsm_log.fsm_log_val)
+ GF_FREE (rsp.fsm_log.fsm_log_val);
gf_log ("glusterd", GF_LOG_DEBUG, "Responded, ret: %d", ret);
@@ -1237,7 +2581,7 @@ glusterd_handle_fsm_log (rpcsvc_request_t *req)
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf1_cli_fsm_log_req)) {
+ if (!gf_xdr_to_cli_fsm_log_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
snprintf (msg, sizeof (msg), "Garbage request");
@@ -1268,7 +2612,8 @@ glusterd_handle_fsm_log (rpcsvc_request_t *req)
ret = glusterd_sm_tr_log_add_to_dict (dict, log);
out:
(void)glusterd_fsm_log_send_resp (req, ret, msg, dict);
- free (cli_req.name);//malloced by xdr
+ if (cli_req.name)
+ free (cli_req.name);//malloced by xdr
if (dict)
dict_unref (dict);
@@ -1290,7 +2635,7 @@ glusterd_op_lock_send_resp (rpcsvc_request_t *req, int32_t status)
rsp.op_ret = status;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
+ gd_xdr_serialize_mgmt_cluster_lock_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded, ret: %d", ret);
@@ -1310,7 +2655,7 @@ glusterd_op_unlock_send_resp (rpcsvc_request_t *req, int32_t status)
glusterd_get_uuid (&rsp.uuid);
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
+ gd_xdr_serialize_mgmt_cluster_unlock_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded to unlock, ret: %d", ret);
@@ -1324,12 +2669,10 @@ glusterd_handle_cluster_unlock (rpcsvc_request_t *req)
gd1_mgmt_cluster_unlock_req unlock_req = {{0}, };
int32_t ret = -1;
glusterd_op_lock_ctx_t *ctx = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &unlock_req,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req)) {
+ if (!gd_xdr_to_mgmt_cluster_unlock_req (req->msg[0], &unlock_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -1339,14 +2682,6 @@ glusterd_handle_cluster_unlock (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_INFO,
"Received UNLOCK from uuid: %s", uuid_utoa (unlock_req.uuid));
- if (glusterd_friend_find_by_uuid (unlock_req.uuid, &peerinfo)) {
- gf_log (THIS->name, GF_LOG_WARNING, "%s doesn't "
- "belong to the cluster. Ignoring request.",
- uuid_utoa (unlock_req.uuid));
- ret = -1;
- goto out;
- }
-
ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t);
if (!ctx) {
@@ -1382,8 +2717,9 @@ glusterd_op_stage_send_resp (rpcsvc_request_t *req,
else
rsp.op_errstr = "";
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
+ ret = dict_allocate_and_serialize (rsp_dict,
+ &rsp.dict.dict_val,
+ (size_t *)&rsp.dict.dict_len);
if (ret < 0) {
gf_log ("", GF_LOG_DEBUG,
"failed to get serialized length of dict");
@@ -1391,11 +2727,12 @@ glusterd_op_stage_send_resp (rpcsvc_request_t *req,
}
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
+ gd_xdr_serialize_mgmt_stage_op_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded to stage, ret: %d", ret);
- GF_FREE (rsp.dict.dict_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return ret;
}
@@ -1419,8 +2756,9 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,
rsp.op_errstr = "";
if (rsp_dict) {
- ret = dict_allocate_and_serialize (rsp_dict, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
+ ret = dict_allocate_and_serialize (rsp_dict,
+ &rsp.dict.dict_val,
+ (size_t *)&rsp.dict.dict_len);
if (ret < 0) {
gf_log ("", GF_LOG_DEBUG,
"failed to get serialized length of dict");
@@ -1430,13 +2768,14 @@ glusterd_op_commit_send_resp (rpcsvc_request_t *req,
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
+ gd_xdr_serialize_mgmt_commit_op_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded to commit, ret: %d", ret);
out:
- GF_FREE (rsp.dict.dict_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return ret;
}
@@ -1448,7 +2787,7 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
gf_boolean_t run_fsm = _gf_true;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &friend_req, (xdrproc_t)xdr_gd1_mgmt_friend_req)) {
+ if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &friend_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -1467,7 +2806,8 @@ glusterd_handle_incoming_friend_req (rpcsvc_request_t *req)
}
out:
- free (friend_req.hostname);//malloced by xdr
+ if (friend_req.hostname)
+ free (friend_req.hostname);//malloced by xdr
if (run_fsm) {
glusterd_friend_sm ();
@@ -1485,7 +2825,7 @@ glusterd_handle_incoming_unfriend_req (rpcsvc_request_t *req)
char remote_hostname[UNIX_PATH_MAX + 1] = {0,};
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &friend_req, (xdrproc_t)xdr_gd1_mgmt_friend_req)) {
+ if (!gd_xdr_to_mgmt_friend_req (req->msg[0], &friend_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -1504,8 +2844,10 @@ glusterd_handle_incoming_unfriend_req (rpcsvc_request_t *req)
remote_hostname, friend_req.port);
out:
- free (friend_req.hostname);//malloced by xdr
- free (friend_req.vols.vols_val);//malloced by xdr
+ if (friend_req.hostname)
+ free (friend_req.hostname);//malloced by xdr
+ if (friend_req.vols.vols_val)
+ free (friend_req.vols.vols_val);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -1513,6 +2855,7 @@ out:
return ret;
}
+
int
glusterd_handle_friend_update_delete (dict_t *dict)
{
@@ -1585,7 +2928,7 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
priv = this->private;
GF_ASSERT (priv);
- if (!xdr_to_generic (req->msg[0], &friend_req, (xdrproc_t)xdr_gd1_mgmt_friend_update)) {
+ if (!gd_xdr_to_mgmt_friend_update (req->msg[0], &friend_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -1645,13 +2988,7 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
gf_log ("", GF_LOG_INFO, "Received uuid: %s, hostname:%s",
uuid_buf, hostname);
- if (uuid_is_null (uuid)) {
- gf_log (this->name, GF_LOG_WARNING, "Updates mustn't "
- "contain peer with 'null' uuid");
- continue;
- }
-
- if (!uuid_compare (uuid, MY_UUID)) {
+ if (!uuid_compare (uuid, priv->uuid)) {
gf_log ("", GF_LOG_INFO, "Received my uuid as Friend");
i++;
continue;
@@ -1670,21 +3007,22 @@ glusterd_handle_friend_update (rpcsvc_request_t *req)
ret = glusterd_friend_add (hostname, friend_req.port,
GD_FRIEND_STATE_BEFRIENDED,
- &uuid, &peerinfo, 0, &args);
+ &uuid, NULL, &peerinfo, 0, &args);
i++;
}
out:
- uuid_copy (rsp.uuid, MY_UUID);
+ uuid_copy (rsp.uuid, priv->uuid);
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
+ gd_xdr_serialize_mgmt_friend_update_rsp);
if (dict) {
if (!dict->extra_stdfree && friend_req.friends.friends_val)
free (friend_req.friends.friends_val);//malloced by xdr
dict_unref (dict);
} else {
- free (friend_req.friends.friends_val);//malloced by xdr
+ if (friend_req.friends.friends_val)
+ free (friend_req.friends.friends_val);//malloced by xdr
}
glusterd_friend_sm ();
@@ -1708,12 +3046,13 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &probe_req, (xdrproc_t)xdr_gd1_mgmt_probe_req)) {
+ if (!gd_xdr_to_mgmt_probe_req (req->msg[0], &probe_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
+
this = THIS;
conf = this->private;
@@ -1725,20 +3064,6 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
gf_log ("glusterd", GF_LOG_INFO,
"Received probe from uuid: %s", uuid_utoa (probe_req.uuid));
- /* Check for uuid collision and handle it in a user friendly way by
- * sending the error.
- */
- if (!uuid_compare (probe_req.uuid, MY_UUID)) {
- gf_log (THIS->name, GF_LOG_ERROR, "Peer uuid %s is same as "
- "local uuid. Please check the uuid of both the peers "
- "from %s/%s", uuid_utoa (probe_req.uuid),
- GLUSTERD_DEFAULT_WORKDIR, GLUSTERD_INFO_FILE);
- rsp.op_ret = -1;
- rsp.op_errno = GF_PROBE_SAME_UUID;
- rsp.port = port;
- goto respond;
- }
-
ret = glusterd_remote_hostname_get (req, remote_hostname,
sizeof (remote_hostname));
if (ret) {
@@ -1755,7 +3080,7 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
args.mode = GD_MODE_ON;
ret = glusterd_friend_add (remote_hostname, port,
GD_FRIEND_STATE_PROBE_RCVD,
- NULL, &peerinfo, 0, &args);
+ NULL, NULL, &peerinfo, 0, &args);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Failed to add peer %s",
remote_hostname);
@@ -1763,20 +3088,20 @@ glusterd_handle_probe_query (rpcsvc_request_t *req)
}
}
-respond:
uuid_copy (rsp.uuid, conf->uuid);
rsp.hostname = probe_req.hostname;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
+ gd_xdr_serialize_mgmt_probe_rsp);
gf_log ("glusterd", GF_LOG_INFO, "Responded to %s, op_ret: %d, "
- "op_errno: %d, ret: %d", remote_hostname,
+ "op_errno: %d, ret: %d", probe_req.hostname,
rsp.op_ret, rsp.op_errno, ret);
out:
- free (probe_req.hostname);//malloced by xdr
+ if (probe_req.hostname)
+ free (probe_req.hostname);//malloced by xdr
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -1788,60 +3113,91 @@ int
glusterd_handle_cli_profile_volume (rpcsvc_request_t *req)
{
int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
+ gf1_cli_stats_volume_req cli_req = {0,};
dict_t *dict = NULL;
+ char msg[2048] = {0,};
+ gf_boolean_t free_volname = _gf_true;
+ int lock_fail = 0;
glusterd_op_t cli_op = GD_OP_PROFILE_VOLUME;
- char *volname = NULL;
- int32_t op = 0;
+ dict_t *tmp_dict = NULL;
GF_ASSERT (req);
- if (!xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req)) {
+ ret = glusterd_op_set_cli_op (cli_op);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set cli op: %d",
+ ret);
+ lock_fail = 1;
+ goto out;
+ }
+
+ ret = -1;
+ if (!gf_xdr_to_cli_stats_volume_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- if (cli_req.dict.dict_len > 0) {
- dict = dict_new();
- if (!dict)
- goto out;
- dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len, &dict);
- }
+ gf_log ("glusterd", GF_LOG_INFO, "Received volume profile req "
+ "for volume %s", cli_req.volname);
- ret = dict_get_str (dict, "volname", &volname);
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+ ret = dict_set_dynmstr (dict, "volname", cli_req.volname);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
+ gf_log ("", GF_LOG_ERROR, "volume name set failed");
+ snprintf (msg, sizeof (msg), "volume name set failed");
goto out;
+ } else {
+ free_volname = _gf_false;
}
- gf_log (THIS->name, GF_LOG_INFO, "Received volume profile req "
- "for volume %s", volname);
- ret = dict_get_int32 (dict, "op", &op);
+ ret = dict_set_int32 (dict, "op", cli_req.op);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get op");
+ gf_log ("", GF_LOG_ERROR, "op set failed");
goto out;
}
- gf_cmd_log ("Volume stats", "volume : %s, op: %d", volname, op);
- ret = glusterd_op_begin (req, cli_op, dict);
+ if (cli_req.dict_req.dict_req_len > 0) {
+ tmp_dict = dict_new();
+ if (!tmp_dict)
+ goto out;
+ dict_unserialize (cli_req.dict_req.dict_req_val,
+ cli_req.dict_req.dict_req_len, &tmp_dict);
+
+ dict_copy (tmp_dict, dict);
+ }
+
+ gf_cmd_log ("Volume stats", "volume : %s, op: %d", cli_req.volname,
+ cli_req.op);
+ ret = glusterd_op_begin (req, cli_op, dict, _gf_true);
gf_cmd_log ("Volume stats", " on volume %s, op: %d %s ",
- volname, op,
+ cli_req.volname, cli_req.op,
((ret == 0)? " SUCCEDED":" FAILED"));
out:
glusterd_friend_sm ();
glusterd_op_sm ();
+ if (tmp_dict)
+ dict_unref (tmp_dict);
+
if (ret && dict)
dict_unref (dict);
- free (cli_req.dict.dict_val);
- if (ret)
+ if (cli_req.dict_req.dict_req_val)
+ free (cli_req.dict_req.dict_req_val);
+ if (free_volname)
+ free (cli_req.volname); // malloced by xdr
+ if (ret) {
ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
NULL, "operation failed");
+ if (!lock_fail)
+ (void) glusterd_opinfo_unlock ();
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ }
+
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -1862,7 +3218,7 @@ glusterd_handle_getwd (rpcsvc_request_t *req)
rsp.wd = priv->workdir;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_getwd_rsp);
+ gf_xdr_from_cli_getwd_rsp);
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -1872,150 +3228,6 @@ glusterd_handle_getwd (rpcsvc_request_t *req)
int
-glusterd_handle_mount (rpcsvc_request_t *req)
-{
- gf1_cli_mount_req mnt_req = {0,};
- gf1_cli_mount_rsp rsp = {0,};
- dict_t *dict = NULL;
- int ret = 0;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &mnt_req, (xdrproc_t)xdr_gf1_cli_mount_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received mount req");
-
- if (mnt_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (mnt_req.dict.dict_val,
- mnt_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- rsp.op_ret = -1;
- rsp.op_errno = -EINVAL;
- goto out;
- } else {
- dict->extra_stdfree = mnt_req.dict.dict_val;
- }
- }
-
- rsp.op_ret = glusterd_do_mount (mnt_req.label, dict,
- &rsp.path, &rsp.op_errno);
-
- out:
- if (!rsp.path)
- rsp.path = "";
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_mount_rsp);
-
- if (dict)
- dict_unref (dict);
- if (*rsp.path)
- GF_FREE (rsp.path);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_umount (rpcsvc_request_t *req)
-{
- gf1_cli_umount_req umnt_req = {0,};
- gf1_cli_umount_rsp rsp = {0,};
- char *mountbroker_root = NULL;
- char mntp[PATH_MAX] = {0,};
- char *path = NULL;
- runner_t runner = {0,};
- int ret = 0;
- xlator_t *this = THIS;
- gf_boolean_t dir_ok = _gf_false;
- char *pdir = NULL;
- char *t = NULL;
-
- GF_ASSERT (req);
- GF_ASSERT (this);
-
- if (!xdr_to_generic (req->msg[0], &umnt_req, (xdrproc_t)xdr_gf1_cli_umount_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- rsp.op_ret = -1;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received umount req");
-
- if (dict_get_str (this->options, "mountbroker-root",
- &mountbroker_root) != 0) {
- rsp.op_errno = ENOENT;
- goto out;
- }
-
- /* check if it is allowed to umount path */
- path = gf_strdup (umnt_req.path);
- if (!path) {
- rsp.op_errno = ENOMEM;
- goto out;
- }
- dir_ok = _gf_false;
- pdir = dirname (path);
- t = strtail (pdir, mountbroker_root);
- if (t && *t == '/') {
- t = strtail(++t, MB_HIVE);
- if (t && !*t)
- dir_ok = _gf_true;
- }
- GF_FREE (path);
- if (!dir_ok) {
- rsp.op_errno = EACCES;
- goto out;
- }
-
- runinit (&runner);
- runner_add_args (&runner, "umount", umnt_req.path, NULL);
- if (umnt_req.lazy)
- runner_add_arg (&runner, "-l");
- rsp.op_ret = runner_run (&runner);
- if (rsp.op_ret == 0) {
- if (realpath (umnt_req.path, mntp))
- rmdir (mntp);
- else {
- rsp.op_ret = -1;
- rsp.op_errno = errno;
- }
- if (unlink (umnt_req.path) != 0) {
- rsp.op_ret = -1;
- rsp.op_errno = errno;
- }
- }
-
- out:
- if (rsp.op_errno)
- rsp.op_ret = -1;
-
- ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_umount_rsp);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
glusterd_friend_remove (uuid_t uuid, char *hostname)
{
int ret = 0;
@@ -2025,9 +3237,6 @@ glusterd_friend_remove (uuid_t uuid, char *hostname)
if (ret)
goto out;
- ret = glusterd_friend_remove_cleanup_vols (peerinfo->uuid);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "Volumes cleanup failed");
ret = glusterd_friend_cleanup (peerinfo);
out:
gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
@@ -2048,9 +3257,8 @@ glusterd_rpc_create (struct rpc_clnt **rpc,
GF_ASSERT (this);
GF_ASSERT (options);
+ new_rpc = rpc_clnt_new (options, this->ctx, this->name);
- /* TODO: is 32 enough? or more ? */
- new_rpc = rpc_clnt_new (options, this->ctx, this->name, 16);
if (!new_rpc)
goto out;
@@ -2120,20 +3328,20 @@ int
glusterd_friend_add (const char *hoststr, int port,
glusterd_friend_sm_state_t state,
uuid_t *uuid,
+ struct rpc_clnt *rpc,
glusterd_peerinfo_t **friend,
gf_boolean_t restore,
glusterd_peerctx_args_t *args)
{
- int ret = 0;
- xlator_t *this = NULL;
+ int ret = 0;
glusterd_conf_t *conf = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
glusterd_peerctx_t *peerctx = NULL;
+ gf_boolean_t is_allocated = _gf_false;
dict_t *options = NULL;
- gf_boolean_t handover = _gf_false;
- this = THIS;
- conf = this->private;
- GF_ASSERT (conf);
+ conf = THIS->private;
+ GF_ASSERT (conf)
GF_ASSERT (hoststr);
peerctx = GF_CALLOC (1, sizeof (*peerctx), gf_gld_mt_peerctx_t);
@@ -2145,44 +3353,50 @@ glusterd_friend_add (const char *hoststr, int port,
if (args)
peerctx->args = *args;
- ret = glusterd_peerinfo_new (friend, state, uuid, hoststr);
+ ret = glusterd_peerinfo_new (&peerinfo, state, uuid, hoststr);
if (ret)
goto out;
+ peerctx->peerinfo = peerinfo;
+ if (friend)
+ *friend = peerinfo;
- peerctx->peerinfo = *friend;
-
- ret = glusterd_transport_inet_keepalive_options_build (&options,
- hoststr, port);
- if (ret)
- goto out;
-
- if (!restore) {
- ret = glusterd_store_peerinfo (*friend);
+ if (!rpc) {
+ ret = glusterd_transport_inet_keepalive_options_build (&options,
+ hoststr, port);
+ if (ret)
+ goto out;
+ ret = glusterd_rpc_create (&rpc, options,
+ glusterd_peer_rpc_notify,
+ peerctx);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to store "
- "peerinfo");
-
+ gf_log ("glusterd", GF_LOG_ERROR, "failed to create rpc for"
+ " peer %s", (char*)hoststr);
goto out;
}
+ is_allocated = _gf_true;
}
- list_add_tail (&(*friend)->uuid_list, &conf->peers);
- ret = glusterd_rpc_create (&(*friend)->rpc, options,
- glusterd_peer_rpc_notify,
- peerctx);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to create rpc for"
- " peer %s", (char*)hoststr);
- goto out;
- }
- handover = _gf_true;
+
+ peerinfo->rpc = rpc;
+
+ if (!restore)
+ ret = glusterd_store_peerinfo (peerinfo);
+
+ list_add_tail (&peerinfo->uuid_list, &conf->peers);
out:
- if (ret && !handover) {
- (void) glusterd_friend_cleanup (*friend);
- *friend = NULL;
+ if (ret) {
+ if (peerctx)
+ GF_FREE (peerctx);
+ if (is_allocated && rpc) {
+ (void) rpc_clnt_unref (rpc);
+ }
+ if (peerinfo) {
+ peerinfo->rpc = NULL;
+ (void) glusterd_friend_cleanup (peerinfo);
+ }
}
- gf_log (this->name, GF_LOG_INFO, "connect returned %d", ret);
+ gf_log ("glusterd", GF_LOG_INFO, "connect returned %d", ret);
return ret;
}
@@ -2205,7 +3419,7 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port)
args.req = req;
ret = glusterd_friend_add ((char *)hoststr, port,
GD_FRIEND_STATE_DEFAULT,
- NULL, &peerinfo, 0, &args);
+ NULL, NULL, &peerinfo, 0, &args);
if ((!ret) && (!peerinfo->connected)) {
ret = GLUSTERD_CONNECTION_AWAITED;
}
@@ -2223,11 +3437,10 @@ glusterd_probe_begin (rpcsvc_request_t *req, const char *hoststr, int port)
event->peerinfo = peerinfo;
ret = glusterd_friend_sm_inject_event (event);
glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_SUCCESS,
- NULL, (char*)hoststr,
- port);
+ (char*)hoststr, port);
}
} else {
- glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND, NULL,
+ glusterd_xfer_cli_probe_resp (req, 0, GF_PROBE_FRIEND,
(char*)hoststr, port);
}
@@ -2317,7 +3530,7 @@ glusterd_xfer_friend_remove_resp (rpcsvc_request_t *req, char *hostname, int por
rsp.hostname = hostname;
rsp.port = port;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
+ gd_xdr_serialize_mgmt_friend_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded to %s (%d), ret: %d", hostname, port, ret);
@@ -2348,18 +3561,18 @@ glusterd_xfer_friend_add_resp (rpcsvc_request_t *req, char *hostname, int port,
rsp.port = port;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
+ gd_xdr_serialize_mgmt_friend_rsp);
gf_log ("glusterd", GF_LOG_INFO,
"Responded to %s (%d), ret: %d", hostname, port, ret);
- GF_FREE (rsp.hostname);
+ if (rsp.hostname)
+ GF_FREE (rsp.hostname)
return ret;
}
int
glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
- int32_t op_errno, char *op_errstr, char *hostname,
- int port)
+ int32_t op_errno, char *hostname, int port)
{
gf1_cli_probe_rsp rsp = {0, };
int32_t ret = -1;
@@ -2368,12 +3581,11 @@ glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
rsp.op_ret = op_ret;
rsp.op_errno = op_errno;
- rsp.op_errstr = op_errstr ? op_errstr : "";
rsp.hostname = hostname;
rsp.port = port;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_probe_rsp);
+ gf_xdr_serialize_cli_probe_rsp);
gf_log ("glusterd", GF_LOG_INFO, "Responded to CLI, ret: %d",ret);
@@ -2382,8 +3594,7 @@ glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
int
glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
- int32_t op_errno, char *op_errstr,
- char *hostname)
+ int32_t op_errno, char *hostname)
{
gf1_cli_deprobe_rsp rsp = {0, };
int32_t ret = -1;
@@ -2392,11 +3603,10 @@ glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
rsp.op_ret = op_ret;
rsp.op_errno = op_errno;
- rsp.op_errstr = op_errstr ? op_errstr : "";
rsp.hostname = hostname;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_deprobe_rsp);
+ gf_xdr_serialize_cli_deprobe_rsp);
gf_log ("glusterd", GF_LOG_INFO, "Responded to CLI, ret: %d",ret);
@@ -2444,7 +3654,7 @@ glusterd_list_friends (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
}
ret = dict_allocate_and_serialize (friends, &rsp.friends.friends_val,
- &rsp.friends.friends_len);
+ (size_t *)&rsp.friends.friends_len);
if (ret)
goto out;
@@ -2458,8 +3668,9 @@ out:
rsp.op_ret = ret;
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf1_cli_peer_list_rsp);
- GF_FREE (rsp.friends.friends_val);
+ gf_xdr_serialize_cli_peer_list_rsp);
+ if (rsp.friends.friends_val)
+ GF_FREE (rsp.friends.friends_val);
return ret;
}
@@ -2472,7 +3683,7 @@ glusterd_get_volumes (rpcsvc_request_t *req, dict_t *dict, int32_t flags)
glusterd_volinfo_t *entry = NULL;
int32_t count = 0;
dict_t *volumes = NULL;
- gf_cli_rsp rsp = {0,};
+ gf1_cli_get_vol_rsp rsp = {0,};
char *volname = NULL;
priv = THIS->private;
@@ -2549,8 +3760,8 @@ respond:
ret = dict_set_int32 (volumes, "count", count);
if (ret)
goto out;
- ret = dict_allocate_and_serialize (volumes, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
+ ret = dict_allocate_and_serialize (volumes, &rsp.volumes.volumes_val,
+ (size_t *)&rsp.volumes.volumes_len);
if (ret)
goto out;
@@ -2559,147 +3770,14 @@ respond:
out:
rsp.op_ret = ret;
- rsp.op_errstr = "";
ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
+ gf_xdr_serialize_cli_peer_list_rsp);
if (volumes)
dict_unref (volumes);
- GF_FREE (rsp.dict.dict_val);
- return ret;
-}
-
-int
-glusterd_handle_status_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- uint32_t cmd = 0;
- dict_t *dict = NULL;
- char *volname = 0;
- gf_cli_req cli_req = {{0,}};
- glusterd_op_t cli_op = GD_OP_STATUS_VOLUME;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len > 0) {
- dict = dict_new();
- if (!dict)
- goto out;
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len, &dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to "
- "unserialize buffer");
- goto out;
- }
-
- }
-
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- goto out;
-
- if (!(cmd & GF_CLI_STATUS_ALL)) {
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to get volname");
- goto out;
- }
- gf_log (THIS->name, GF_LOG_INFO,
- "Received status volume req "
- "for volume %s", volname);
-
- }
-
- ret = glusterd_op_begin (req, GD_OP_STATUS_VOLUME, dict);
-
-out:
- if (ret && dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- free (cli_req.dict.dict_val);
-
- return ret;
-}
-
-int
-glusterd_handle_cli_clearlocks_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- glusterd_op_t cli_op = GD_OP_CLEARLOCKS_VOLUME;
- char *volname = NULL;
- dict_t *dict = NULL;
-
- GF_ASSERT (req);
-
- ret = -1;
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to unserialize req-buffer to"
- " dictionary");
- goto out;
- }
-
- } else {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR, "Empty cli request.");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
- goto out;
- }
-
- gf_log (THIS->name, GF_LOG_INFO, "Received clear-locks volume req "
- "for volume %s", volname);
-
- ret = glusterd_op_begin (req, cli_op, dict);
-
- gf_cmd_log ("clear-locks", "on volume %s %s", volname,
- ((0 == ret) ? "SUCCEEDED" : "FAILED"));
-
-out:
- if (ret && dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- free (cli_req.dict.dict_val);
-
+ if (rsp.volumes.volumes_val)
+ GF_FREE (rsp.volumes.volumes_val);
return ret;
}
@@ -2733,6 +3811,8 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
case RPC_CLNT_DISCONNECT:
gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT");
glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED);
+ if (brickinfo->timer && brickinfo->timer->callbk)
+ brickinfo->timer->callbk (brickinfo->timer->data);
break;
default:
@@ -2745,100 +3825,15 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
}
int
-glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event,
- void *data)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char *server = NULL;
- int ret = 0;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- server = mydata;
- if (!server)
- return 0;
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_CONNECT");
- (void) glusterd_nodesvc_set_running (server, _gf_true);
- ret = default_notify (this, GF_EVENT_CHILD_UP, NULL);
-
- break;
-
- case RPC_CLNT_DISCONNECT:
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT");
- (void) glusterd_nodesvc_set_running (server, _gf_false);
- break;
-
- default:
- gf_log (this->name, GF_LOG_TRACE,
- "got some other RPC event %d", event);
- break;
- }
-
- return ret;
-}
-
-int
-glusterd_friend_remove_notify (glusterd_peerctx_t *peerctx)
-{
- int ret = -1;
- glusterd_friend_sm_event_t *new_event = NULL;
- glusterd_peerinfo_t *peerinfo = peerctx->peerinfo;
- rpcsvc_request_t *req = peerctx->args.req;
- char *errstr = peerctx->errstr;
-
- GF_ASSERT (peerctx);
-
- peerinfo = peerctx->peerinfo;
- req = peerctx->args.req;
- errstr = peerctx->errstr;
-
- ret = glusterd_friend_sm_new_event (GD_FRIEND_EVENT_REMOVE_FRIEND,
- &new_event);
- if (!ret) {
- if (!req) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "Unable to find the request for responding "
- "to User (%s)", peerinfo->hostname);
- goto out;
- }
-
- glusterd_xfer_cli_probe_resp (req, -1, ENOTCONN, errstr,
- peerinfo->hostname, peerinfo->port);
-
- new_event->peerinfo = peerinfo;
- ret = glusterd_friend_sm_inject_event (new_event);
- glusterd_friend_sm ();
-
- } else {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Unable to create event for removing peer %s",
- peerinfo->hostname);
- }
-
-out:
- return ret;
-}
-
-int
glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event,
void *data)
{
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- int ret = 0;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_peerctx_t *peerctx = NULL;
- uuid_t owner = {0,};
- uuid_t *peer_uuid = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ int ret = 0;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_peerctx_t *peerctx = NULL;
peerctx = mydata;
if (!peerctx)
@@ -2861,48 +3856,15 @@ glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
}
case RPC_CLNT_DISCONNECT:
- {
- gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT %d",
- peerinfo->state.state);
-
- peerinfo->connected = 0;
-
- /*
- local glusterd (thinks that it) is the owner of the cluster
- lock and 'fails' the operation on the first disconnect from
- a peer.
- */
- glusterd_get_lock_owner (&owner);
- if (!uuid_compare (conf->uuid, owner)) {
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_START_UNLOCK,
- NULL);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Unable"
- " to enqueue cluster unlock event");
- break;
- }
-
- peer_uuid = GF_CALLOC (1, sizeof (*peer_uuid), gf_common_mt_char);
- if (!peer_uuid) {
- ret = -1;
- break;
- }
-
- uuid_copy (*peer_uuid, peerinfo->uuid);
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP,
- peer_uuid);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Unable"
- " to enque local lock flush event.");
//Inject friend disconnected here
- if (peerinfo->state.state == GD_FRIEND_STATE_DEFAULT) {
- glusterd_friend_remove_notify (peerctx);
- }
+
+ gf_log (this->name, GF_LOG_DEBUG, "got RPC_CLNT_DISCONNECT");
+ peerinfo->connected = 0;
//default_notify (this, GF_EVENT_CHILD_DOWN, NULL);
break;
- }
+
default:
gf_log (this->name, GF_LOG_TRACE,
"got some other RPC event %d", event);
@@ -2910,8 +3872,6 @@ glusterd_peer_rpc_notify (struct rpc_clnt *rpc, void *mydata,
break;
}
- glusterd_friend_sm ();
- glusterd_op_sm ();
return ret;
}
@@ -2923,74 +3883,99 @@ glusterd_null (rpcsvc_request_t *req)
}
rpcsvc_actor_t gd_svc_mgmt_actors[] = {
- [GLUSTERD_MGMT_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, NULL, 0},
- [GLUSTERD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GLUSTERD_MGMT_CLUSTER_LOCK, glusterd_handle_cluster_lock, NULL, NULL, 0},
- [GLUSTERD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GLUSTERD_MGMT_CLUSTER_UNLOCK, glusterd_handle_cluster_unlock, NULL, NULL, 0},
- [GLUSTERD_MGMT_STAGE_OP] = { "STAGE_OP", GLUSTERD_MGMT_STAGE_OP, glusterd_handle_stage_op, NULL, NULL, 0},
- [GLUSTERD_MGMT_COMMIT_OP] = { "COMMIT_OP", GLUSTERD_MGMT_COMMIT_OP, glusterd_handle_commit_op, NULL, NULL, 0},
+ [GLUSTERD_MGMT_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, NULL},
+ [GLUSTERD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", GLUSTERD_MGMT_PROBE_QUERY, glusterd_handle_probe_query, NULL, NULL},
+ [GLUSTERD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", GLUSTERD_MGMT_FRIEND_ADD, glusterd_handle_incoming_friend_req, NULL, NULL},
+ [GLUSTERD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", GLUSTERD_MGMT_FRIEND_REMOVE, glusterd_handle_incoming_unfriend_req, NULL, NULL},
+ [GLUSTERD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", GLUSTERD_MGMT_FRIEND_UPDATE, glusterd_handle_friend_update, NULL, NULL},
+ [GLUSTERD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GLUSTERD_MGMT_CLUSTER_LOCK, glusterd_handle_cluster_lock, NULL, NULL},
+ [GLUSTERD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GLUSTERD_MGMT_CLUSTER_UNLOCK, glusterd_handle_cluster_unlock, NULL, NULL},
+ [GLUSTERD_MGMT_STAGE_OP] = { "STAGE_OP", GLUSTERD_MGMT_STAGE_OP, glusterd_handle_stage_op, NULL, NULL},
+ [GLUSTERD_MGMT_COMMIT_OP] = { "COMMIT_OP", GLUSTERD_MGMT_COMMIT_OP, glusterd_handle_commit_op, NULL, NULL},
};
struct rpcsvc_program gd_svc_mgmt_prog = {
.progname = "GlusterD svc mgmt",
.prognum = GD_MGMT_PROGRAM,
.progver = GD_MGMT_VERSION,
- .numactors = GLUSTERD_MGMT_MAXVALUE,
+ .numactors = GD_MGMT_PROCCNT,
.actors = gd_svc_mgmt_actors,
};
-rpcsvc_actor_t gd_svc_peer_actors[] = {
- [GLUSTERD_FRIEND_NULL] = { "NULL", GLUSTERD_MGMT_NULL, glusterd_null, NULL, NULL, 0},
- [GLUSTERD_PROBE_QUERY] = { "PROBE_QUERY", GLUSTERD_PROBE_QUERY, glusterd_handle_probe_query, NULL, NULL, 0},
- [GLUSTERD_FRIEND_ADD] = { "FRIEND_ADD", GLUSTERD_FRIEND_ADD, glusterd_handle_incoming_friend_req, NULL, NULL, 0},
- [GLUSTERD_FRIEND_REMOVE] = { "FRIEND_REMOVE", GLUSTERD_FRIEND_REMOVE, glusterd_handle_incoming_unfriend_req, NULL, NULL, 0},
- [GLUSTERD_FRIEND_UPDATE] = { "FRIEND_UPDATE", GLUSTERD_FRIEND_UPDATE, glusterd_handle_friend_update, NULL, NULL, 0},
-};
-
-struct rpcsvc_program gd_svc_peer_prog = {
- .progname = "GlusterD svc peer",
- .prognum = GD_FRIEND_PROGRAM,
- .progver = GD_FRIEND_VERSION,
- .numactors = GLUSTERD_FRIEND_MAXVALUE,
- .actors = gd_svc_peer_actors,
-};
-
-
-
rpcsvc_actor_t gd_svc_cli_actors[] = {
- [GLUSTER_CLI_PROBE] = { "CLI_PROBE", GLUSTER_CLI_PROBE, glusterd_handle_cli_probe, NULL, NULL, 0},
- [GLUSTER_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GLUSTER_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL,NULL, 0},
- [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL,NULL, 0},
- [GLUSTER_CLI_DEPROBE] = { "FRIEND_REMOVE", GLUSTER_CLI_DEPROBE, glusterd_handle_cli_deprobe, NULL, NULL, 0},
- [GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, NULL, 0},
- [GLUSTER_CLI_START_VOLUME] = { "START_VOLUME", GLUSTER_CLI_START_VOLUME, glusterd_handle_cli_start_volume, NULL, NULL, 0},
- [GLUSTER_CLI_STOP_VOLUME] = { "STOP_VOLUME", GLUSTER_CLI_STOP_VOLUME, glusterd_handle_cli_stop_volume, NULL, NULL, 0},
- [GLUSTER_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GLUSTER_CLI_DELETE_VOLUME, glusterd_handle_cli_delete_volume, NULL, NULL, 0},
- [GLUSTER_CLI_GET_VOLUME] = { "GET_VOLUME", GLUSTER_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, NULL, 0},
- [GLUSTER_CLI_ADD_BRICK] = { "ADD_BRICK", GLUSTER_CLI_ADD_BRICK, glusterd_handle_add_brick, NULL, NULL, 0},
- [GLUSTER_CLI_REPLACE_BRICK] = { "REPLACE_BRICK", GLUSTER_CLI_REPLACE_BRICK, glusterd_handle_replace_brick, NULL, NULL, 0},
- [GLUSTER_CLI_REMOVE_BRICK] = { "REMOVE_BRICK", GLUSTER_CLI_REMOVE_BRICK, glusterd_handle_remove_brick, NULL, NULL, 0},
- [GLUSTER_CLI_LOG_ROTATE] = { "LOG FILENAME", GLUSTER_CLI_LOG_ROTATE, glusterd_handle_log_rotate, NULL, NULL, 0},
- [GLUSTER_CLI_SET_VOLUME] = { "SET_VOLUME", GLUSTER_CLI_SET_VOLUME, glusterd_handle_set_volume, NULL, NULL, 0},
- [GLUSTER_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GLUSTER_CLI_SYNC_VOLUME, glusterd_handle_sync_volume, NULL, NULL, 0},
- [GLUSTER_CLI_RESET_VOLUME] = { "RESET_VOLUME", GLUSTER_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL, 0},
- [GLUSTER_CLI_FSM_LOG] = { "FSM_LOG", GLUSTER_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL, 0},
- [GLUSTER_CLI_GSYNC_SET] = { "GSYNC_SET", GLUSTER_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL, 0},
- [GLUSTER_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GLUSTER_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL, 0},
- [GLUSTER_CLI_QUOTA] = { "QUOTA", GLUSTER_CLI_QUOTA, glusterd_handle_quota, NULL, NULL, 0},
- [GLUSTER_CLI_GETWD] = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, NULL, 1},
- [GLUSTER_CLI_STATUS_VOLUME] = {"STATUS_VOLUME", GLUSTER_CLI_STATUS_VOLUME, glusterd_handle_status_volume, NULL, NULL, 0},
- [GLUSTER_CLI_MOUNT] = { "MOUNT", GLUSTER_CLI_MOUNT, glusterd_handle_mount, NULL, NULL, 1},
- [GLUSTER_CLI_UMOUNT] = { "UMOUNT", GLUSTER_CLI_UMOUNT, glusterd_handle_umount, NULL, NULL, 1},
- [GLUSTER_CLI_HEAL_VOLUME] = { "HEAL_VOLUME", GLUSTER_CLI_HEAL_VOLUME, glusterd_handle_cli_heal_volume, NULL, NULL, 0},
- [GLUSTER_CLI_STATEDUMP_VOLUME] = {"STATEDUMP_VOLUME", GLUSTER_CLI_STATEDUMP_VOLUME, glusterd_handle_cli_statedump_volume, NULL, NULL, 0},
- [GLUSTER_CLI_LIST_VOLUME] = {"LIST_VOLUME", GLUSTER_CLI_LIST_VOLUME, glusterd_handle_cli_list_volume, NULL, NULL, 0},
- [GLUSTER_CLI_CLRLOCKS_VOLUME] = {"CLEARLOCKS_VOLUME", GLUSTER_CLI_CLRLOCKS_VOLUME, glusterd_handle_cli_clearlocks_volume, NULL, NULL, 0},
+ [GLUSTER_CLI_PROBE] = { "CLI_PROBE", GLUSTER_CLI_PROBE, glusterd_handle_cli_probe, NULL, NULL},
+ [GLUSTER_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GLUSTER_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL,NULL},
+ [GLUSTER_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GLUSTER_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume_v2, NULL,NULL},
+ [GLUSTER_CLI_DEPROBE] = { "FRIEND_REMOVE", GLUSTER_CLI_DEPROBE, glusterd_handle_cli_deprobe, NULL, NULL},
+ [GLUSTER_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GLUSTER_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, NULL},
+ [GLUSTER_CLI_START_VOLUME] = { "START_VOLUME", GLUSTER_CLI_START_VOLUME, glusterd_handle_cli_start_volume, NULL, NULL},
+ [GLUSTER_CLI_STOP_VOLUME] = { "STOP_VOLUME", GLUSTER_CLI_STOP_VOLUME, glusterd_handle_cli_stop_volume, NULL, NULL},
+ [GLUSTER_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GLUSTER_CLI_DELETE_VOLUME, glusterd_handle_cli_delete_volume, NULL, NULL},
+ [GLUSTER_CLI_GET_VOLUME] = { "GET_VOLUME", GLUSTER_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, NULL},
+ [GLUSTER_CLI_ADD_BRICK] = { "ADD_BRICK", GLUSTER_CLI_ADD_BRICK, glusterd_handle_add_brick, NULL, NULL},
+ [GLUSTER_CLI_REPLACE_BRICK] = { "REPLACE_BRICK", GLUSTER_CLI_REPLACE_BRICK, glusterd_handle_replace_brick, NULL, NULL},
+ [GLUSTER_CLI_REMOVE_BRICK] = { "REMOVE_BRICK", GLUSTER_CLI_REMOVE_BRICK, glusterd_handle_remove_brick, NULL, NULL},
+ [GLUSTER_CLI_LOG_FILENAME] = { "LOG FILENAME", GLUSTER_CLI_LOG_FILENAME, glusterd_handle_log_filename, NULL, NULL},
+ [GLUSTER_CLI_LOG_LOCATE] = { "LOG LOCATE", GLUSTER_CLI_LOG_LOCATE, glusterd_handle_log_locate, NULL, NULL},
+ [GLUSTER_CLI_LOG_ROTATE] = { "LOG FILENAME", GLUSTER_CLI_LOG_ROTATE, glusterd_handle_log_rotate, NULL, NULL},
+ [GLUSTER_CLI_SET_VOLUME] = { "SET_VOLUME", GLUSTER_CLI_SET_VOLUME, glusterd_handle_set_volume, NULL, NULL},
+ [GLUSTER_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GLUSTER_CLI_SYNC_VOLUME, glusterd_handle_sync_volume, NULL, NULL},
+ [GLUSTER_CLI_RESET_VOLUME] = { "RESET_VOLUME", GLUSTER_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL},
+ [GLUSTER_CLI_FSM_LOG] = { "FSM_LOG", GLUSTER_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL},
+ [GLUSTER_CLI_GSYNC_SET] = { "GSYNC_SET", GLUSTER_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL},
+ [GLUSTER_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GLUSTER_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL},
+ [GLUSTER_CLI_QUOTA] = { "QUOTA", GLUSTER_CLI_QUOTA, glusterd_handle_quota, NULL, NULL},
+ [GLUSTER_CLI_GETWD] = { "GETWD", GLUSTER_CLI_GETWD, glusterd_handle_getwd, NULL, NULL},
+
};
struct rpcsvc_program gd_svc_cli_prog = {
.progname = "GlusterD svc cli",
.prognum = GLUSTER_CLI_PROGRAM,
.progver = GLUSTER_CLI_VERSION,
- .numactors = GLUSTER_CLI_MAXVALUE,
+ .numactors = GLUSTER_CLI_PROCCNT,
.actors = gd_svc_cli_actors,
};
+
+/* Keeping below programs for backword compatibility */
+
+rpcsvc_actor_t glusterd1_mgmt_actors[] = {
+ [GD_MGMT_NULL] = { "NULL", GD_MGMT_NULL, glusterd_null, NULL, NULL},
+ [GD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", GD_MGMT_PROBE_QUERY, glusterd_handle_probe_query, NULL, NULL},
+ [GD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", GD_MGMT_FRIEND_ADD, glusterd_handle_incoming_friend_req, NULL, NULL},
+ [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", GD_MGMT_FRIEND_REMOVE, glusterd_handle_incoming_unfriend_req, NULL, NULL},
+ [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", GD_MGMT_FRIEND_UPDATE, glusterd_handle_friend_update, NULL, NULL},
+ [GD_MGMT_CLUSTER_LOCK] = { "CLUSTER_LOCK", GD_MGMT_CLUSTER_LOCK, glusterd_handle_cluster_lock, NULL, NULL},
+ [GD_MGMT_CLUSTER_UNLOCK] = { "CLUSTER_UNLOCK", GD_MGMT_CLUSTER_UNLOCK, glusterd_handle_cluster_unlock, NULL, NULL},
+ [GD_MGMT_STAGE_OP] = { "STAGE_OP", GD_MGMT_STAGE_OP, glusterd_handle_stage_op, NULL, NULL},
+ [GD_MGMT_COMMIT_OP] = { "COMMIT_OP", GD_MGMT_COMMIT_OP, glusterd_handle_commit_op, NULL, NULL},
+ [GD_MGMT_CLI_PROBE] = { "CLI_PROBE", GD_MGMT_CLI_PROBE, glusterd_handle_cli_probe, NULL, NULL},
+ [GD_MGMT_CLI_CREATE_VOLUME] = { "CLI_CREATE_VOLUME", GD_MGMT_CLI_CREATE_VOLUME, glusterd_handle_create_volume, NULL,NULL},
+ [GD_MGMT_CLI_DEFRAG_VOLUME] = { "CLI_DEFRAG_VOLUME", GD_MGMT_CLI_DEFRAG_VOLUME, glusterd_handle_defrag_volume, NULL,NULL},
+ [GD_MGMT_CLI_DEPROBE] = { "FRIEND_REMOVE", GD_MGMT_CLI_DEPROBE, glusterd_handle_cli_deprobe, NULL, NULL},
+ [GD_MGMT_CLI_LIST_FRIENDS] = { "LIST_FRIENDS", GD_MGMT_CLI_LIST_FRIENDS, glusterd_handle_cli_list_friends, NULL, NULL},
+ [GD_MGMT_CLI_START_VOLUME] = { "START_VOLUME", GD_MGMT_CLI_START_VOLUME, glusterd_handle_cli_start_volume, NULL, NULL},
+ [GD_MGMT_CLI_STOP_VOLUME] = { "STOP_VOLUME", GD_MGMT_CLI_STOP_VOLUME, glusterd_handle_cli_stop_volume, NULL, NULL},
+ [GD_MGMT_CLI_DELETE_VOLUME] = { "DELETE_VOLUME", GD_MGMT_CLI_DELETE_VOLUME, glusterd_handle_cli_delete_volume, NULL, NULL},
+ [GD_MGMT_CLI_GET_VOLUME] = { "GET_VOLUME", GD_MGMT_CLI_GET_VOLUME, glusterd_handle_cli_get_volume, NULL, NULL},
+ [GD_MGMT_CLI_ADD_BRICK] = { "ADD_BRICK", GD_MGMT_CLI_ADD_BRICK, glusterd_handle_add_brick, NULL, NULL},
+ [GD_MGMT_CLI_REPLACE_BRICK] = { "REPLACE_BRICK", GD_MGMT_CLI_REPLACE_BRICK, glusterd_handle_replace_brick, NULL, NULL},
+ [GD_MGMT_CLI_REMOVE_BRICK] = { "REMOVE_BRICK", GD_MGMT_CLI_REMOVE_BRICK, glusterd_handle_remove_brick, NULL, NULL},
+ [GD_MGMT_CLI_LOG_FILENAME] = { "LOG FILENAME", GD_MGMT_CLI_LOG_FILENAME, glusterd_handle_log_filename, NULL, NULL},
+ [GD_MGMT_CLI_LOG_LOCATE] = { "LOG LOCATE", GD_MGMT_CLI_LOG_LOCATE, glusterd_handle_log_locate, NULL, NULL},
+ [GD_MGMT_CLI_LOG_ROTATE] = { "LOG FILENAME", GD_MGMT_CLI_LOG_ROTATE, glusterd_handle_log_rotate, NULL, NULL},
+ [GD_MGMT_CLI_SET_VOLUME] = { "SET_VOLUME", GD_MGMT_CLI_SET_VOLUME, glusterd_handle_set_volume, NULL, NULL},
+ [GD_MGMT_CLI_SYNC_VOLUME] = { "SYNC_VOLUME", GD_MGMT_CLI_SYNC_VOLUME, glusterd_handle_sync_volume, NULL, NULL},
+ [GD_MGMT_CLI_RESET_VOLUME] = { "RESET_VOLUME", GD_MGMT_CLI_RESET_VOLUME, glusterd_handle_reset_volume, NULL, NULL},
+ [GD_MGMT_CLI_FSM_LOG] = { "FSM_LOG", GD_MGMT_CLI_FSM_LOG, glusterd_handle_fsm_log, NULL, NULL},
+ [GD_MGMT_CLI_GSYNC_SET] = {"GSYNC_SET", GD_MGMT_CLI_GSYNC_SET, glusterd_handle_gsync_set, NULL, NULL},
+ [GD_MGMT_CLI_PROFILE_VOLUME] = { "STATS_VOLUME", GD_MGMT_CLI_PROFILE_VOLUME, glusterd_handle_cli_profile_volume, NULL, NULL}
+};
+
+struct rpcsvc_program glusterd1_mop_prog = {
+ .progname = "GlusterD0.0.1",
+ .prognum = GLUSTERD1_MGMT_PROGRAM,
+ .progver = GLUSTERD1_MGMT_VERSION,
+ .numactors = GLUSTERD1_MGMT_PROCCNT,
+ .actors = glusterd1_mgmt_actors,
+};
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index 42b0ad3ea..dda8a03bb 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -35,18 +35,15 @@
#include "glusterfs3.h"
#include "protocol-common.h"
#include "rpcsvc.h"
-#include "rpc-common-xdr.h"
-extern struct rpc_clnt_program gd_peer_prog;
-extern struct rpc_clnt_program gd_mgmt_prog;
-
-#define TRUSTED_PREFIX "trusted-"
+extern struct rpc_clnt_program glusterd3_1_mgmt_prog;
+extern struct rpc_clnt_program gd_clnt_mgmt_prog;
typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);
static size_t
build_volfile_path (const char *volname, char *path,
- size_t path_len, char *trusted_str)
+ size_t path_len)
{
struct stat stbuf = {0,};
int32_t ret = -1;
@@ -56,17 +53,10 @@ build_volfile_path (const char *volname, char *path,
char *free_ptr = NULL;
char *tmp = NULL;
glusterd_volinfo_t *volinfo = NULL;
- char *server = NULL;
priv = THIS->private;
- if (strstr (volname, "gluster/")) {
- server = strchr (volname, '/') + 1;
- glusterd_get_nodesvc_volfile (server, priv->workdir,
- path, path_len);
- ret = 1;
- goto out;
- } else if (volname[0] != '/') {
+ if (volname[0] != '/') {
/* Normal behavior */
dup_volname = gf_strdup (volname);
} else {
@@ -88,55 +78,63 @@ build_volfile_path (const char *volname, char *path,
if (ret)
goto out;
}
-
- if (!glusterd_auth_get_username (volinfo))
- trusted_str = NULL;
-
ret = snprintf (path, path_len, "%s/vols/%s/%s.vol",
priv->workdir, volinfo->volname, volname);
if (ret == -1)
goto out;
ret = stat (path, &stbuf);
-
if ((ret == -1) && (errno == ENOENT)) {
- snprintf (path, path_len, "%s/vols/%s/%s%s-fuse.vol",
- priv->workdir, volinfo->volname,
- (trusted_str ? trusted_str : ""), dup_volname);
+ ret = snprintf (path, path_len, "%s/vols/%s/%s-fuse.vol",
+ priv->workdir, volinfo->volname, volname);
ret = stat (path, &stbuf);
}
-
if ((ret == -1) && (errno == ENOENT)) {
- snprintf (path, path_len, "%s/vols/%s/%s-tcp.vol",
- priv->workdir, volinfo->volname, volname);
+ ret = snprintf (path, path_len, "%s/vols/%s/%s-tcp.vol",
+ priv->workdir, volinfo->volname, volname);
}
ret = 1;
out:
- GF_FREE (free_ptr);
+ if (free_ptr)
+ GF_FREE (free_ptr);
+ return ret;
+}
+
+static int
+xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc)
+{
+ int ret = -1;
+
+ if (!req)
+ return -1;
+
+ ret = sfunc (req->msg[0], arg);
+
+ if (ret > 0)
+ ret = 0;
+
return ret;
}
+
int
server_getspec (rpcsvc_request_t *req)
{
- int32_t ret = -1;
- int32_t op_errno = 0;
- int32_t spec_fd = -1;
- size_t file_len = 0;
- char filename[PATH_MAX] = {0,};
- struct stat stbuf = {0,};
- char *volume = NULL;
- char *tmp = NULL;
- int cookie = 0;
- rpc_transport_t *trans = NULL;
- gf_getspec_req args = {0,};
- gf_getspec_rsp rsp = {0,};
- char addrstr[RPCSVC_PEER_STRLEN] = {0};
-
-
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_getspec_req)) {
+ int32_t ret = -1;
+ int32_t op_errno = 0;
+ int32_t spec_fd = -1;
+ size_t file_len = 0;
+ char filename[ZR_PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+ char *volume = NULL;
+ int cookie = 0;
+
+ gf_getspec_req args = {0,};
+ gf_getspec_rsp rsp = {0,};
+
+
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_getspec_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto fail;
@@ -144,25 +142,7 @@ server_getspec (rpcsvc_request_t *req)
volume = args.key;
- trans = req->trans;
- ret = rpcsvc_transport_peername (trans, (char *)&addrstr,
- sizeof (addrstr));
- if (ret)
- goto fail;
-
- tmp = strrchr (addrstr, ':');
- *tmp = '\0';
-
- /* we trust the local admin */
- if (!glusterd_is_local_addr (addrstr)) {
-
- ret = build_volfile_path (volume, filename,
- sizeof (filename),
- TRUSTED_PREFIX);
- } else {
- ret = build_volfile_path (volume, filename,
- sizeof (filename), NULL);
- }
+ ret = build_volfile_path (volume, filename, sizeof (filename));
if (ret > 0) {
/* to allocate the proper buffer to hold the file data */
@@ -208,80 +188,22 @@ fail:
rsp.op_errno = cookie;
if (!rsp.spec)
- rsp.spec = strdup ("");
+ rsp.spec = "";
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_getspec_rsp);
- free (args.key);//malloced by xdr
- free (rsp.spec);
+ (gd_serialize_t)xdr_serialize_getspec_rsp);
+ if (args.key)
+ free (args.key);//malloced by xdr
+ if (rsp.spec && (strcmp (rsp.spec, "")))
+ free (rsp.spec);
return 0;
}
-int32_t
-server_event_notify (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- int32_t op_errno = 0;
- gf_event_notify_req args = {0,};
- gf_event_notify_rsp rsp = {0,};
- dict_t *dict = NULL;
- gf_boolean_t need_rsp = _gf_true;
-
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_event_notify_req)) {
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- if (args.dict.dict_len) {
- dict = dict_new ();
- if (!dict)
- return ret;
- ret = dict_unserialize (args.dict.dict_val,
- args.dict.dict_len, &dict);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to unserialize req");
- goto fail;
- }
- }
-
- switch (args.op) {
- case GF_EN_DEFRAG_STATUS:
- gf_log ("", GF_LOG_INFO,
- "recieved defrag status updated");
- if (dict) {
- glusterd_defrag_event_notify_handle (dict);
- need_rsp = _gf_false;
- }
- break;
- default:
- gf_log ("", GF_LOG_ERROR, "Unkown op recieved in in event "
- "notify");
- ret = -1;
- break;
- }
-fail:
- rsp.op_ret = ret;
-
- if (op_errno)
- rsp.op_errno = gf_errno_to_error (op_errno);
-
- if (need_rsp)
- glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_event_notify_rsp);
- if (dict)
- dict_unref (dict);
- free (args.dict.dict_val);//malloced by xdr
-
- return 0;
-}
rpcsvc_actor_t gluster_handshake_actors[] = {
- [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, NULL, 0},
- [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, NULL, 0},
- [GF_HNDSK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_HNDSK_EVENT_NOTIFY, server_event_notify,
- NULL, NULL, 0},
+ [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, NULL },
+ [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, NULL },
};
@@ -367,14 +289,16 @@ glusterd_set_clnt_mgmt_program (glusterd_peerinfo_t *peerinfo,
while (trav) {
/* Select 'programs' */
- if ((gd_mgmt_prog.prognum == trav->prognum) &&
- (gd_mgmt_prog.progver == trav->progver)) {
- peerinfo->mgmt = &gd_mgmt_prog;
+ if ((gd_clnt_mgmt_prog.prognum == trav->prognum) &&
+ (gd_clnt_mgmt_prog.progver == trav->progver)) {
+ peerinfo->mgmt = &gd_clnt_mgmt_prog;
ret = 0;
+ /* Break here, as this gets higher priority */
+ break;
}
- if ((gd_peer_prog.prognum == trav->prognum) &&
- (gd_peer_prog.progver == trav->progver)) {
- peerinfo->peer = &gd_peer_prog;
+ if ((glusterd3_1_mgmt_prog.prognum == trav->prognum) &&
+ (glusterd3_1_mgmt_prog.progver == trav->progver)) {
+ peerinfo->mgmt = &glusterd3_1_mgmt_prog;
ret = 0;
}
if (ret) {
@@ -386,18 +310,12 @@ glusterd_set_clnt_mgmt_program (glusterd_peerinfo_t *peerinfo,
trav = trav->next;
}
- if (peerinfo->mgmt) {
+ if (!ret && peerinfo->mgmt) {
gf_log ("", GF_LOG_INFO,
"Using Program %s, Num (%d), Version (%d)",
peerinfo->mgmt->progname, peerinfo->mgmt->prognum,
peerinfo->mgmt->progver);
}
- if (peerinfo->peer) {
- gf_log ("", GF_LOG_INFO,
- "Using Program %s, Num (%d), Version (%d)",
- peerinfo->peer->progname, peerinfo->peer->prognum,
- peerinfo->peer->progver);
- }
out:
return ret;
@@ -415,7 +333,6 @@ glusterd_peer_dump_version_cbk (struct rpc_req *req, struct iovec *iov,
call_frame_t *frame = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_peerctx_t *peerctx = NULL;
- char msg[1024] = {0,};
this = THIS;
frame = myframe;
@@ -423,25 +340,19 @@ glusterd_peer_dump_version_cbk (struct rpc_req *req, struct iovec *iov,
peerinfo = peerctx->peerinfo;
if (-1 == req->rpc_status) {
- snprintf (msg, sizeof (msg),
- "Error through RPC layer, retry again later");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
+ gf_log ("", GF_LOG_ERROR,
+ "error through RPC layer, retry again later");
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
+ ret = xdr_to_dump_rsp (*iov, &rsp);
if (ret < 0) {
- snprintf (msg, sizeof (msg), "Failed to decode XDR");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
+ gf_log ("", GF_LOG_ERROR, "failed to decode XDR");
goto out;
}
if (-1 == rsp.op_ret) {
- snprintf (msg, sizeof (msg),
- "Failed to get the 'versions' from remote server");
- gf_log (frame->this->name, GF_LOG_ERROR, "%s", msg);
- peerctx->errstr = gf_strdup (msg);
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "failed to get the 'versions' from remote server");
goto out;
}
@@ -509,9 +420,8 @@ glusterd_peer_handshake (xlator_t *this, struct rpc_clnt *rpc,
ret = glusterd_submit_request (peerctx->peerinfo->rpc, &req, frame,
&glusterd_dump_prog, GF_DUMP_DUMP,
- NULL, this,
- glusterd_peer_dump_version_cbk,
- (xdrproc_t)xdr_gf_dump_req);
+ NULL, xdr_from_dump_req, this,
+ glusterd_peer_dump_version_cbk);
out:
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c
deleted file mode 100644
index 7bc932468..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- Copyright (c) 2007-2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "dict.h"
-#include "xlator.h"
-#include "logging.h"
-#include "run.h"
-#include "defaults.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "glusterd.h"
-#include "glusterd-sm.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "glusterd-store.h"
-#include "glusterd-hooks.h"
-
-#include <fnmatch.h>
-
-#define EMPTY ""
-char glusterd_hook_dirnames[GD_OP_MAX][256] =
-{
- [GD_OP_NONE] = EMPTY,
- [GD_OP_CREATE_VOLUME] = "create",
- [GD_OP_START_BRICK] = EMPTY,
- [GD_OP_STOP_BRICK] = EMPTY,
- [GD_OP_DELETE_VOLUME] = "delete",
- [GD_OP_START_VOLUME] = "start",
- [GD_OP_STOP_VOLUME] = "stop",
- [GD_OP_DEFRAG_VOLUME] = EMPTY,
- [GD_OP_ADD_BRICK] = "add-brick",
- [GD_OP_REMOVE_BRICK] = "remove-brick",
- [GD_OP_REPLACE_BRICK] = EMPTY,
- [GD_OP_SET_VOLUME] = "set",
- [GD_OP_RESET_VOLUME] = EMPTY,
- [GD_OP_SYNC_VOLUME] = EMPTY,
- [GD_OP_LOG_ROTATE] = EMPTY,
- [GD_OP_GSYNC_SET] = EMPTY,
- [GD_OP_PROFILE_VOLUME] = EMPTY,
- [GD_OP_QUOTA] = EMPTY,
- [GD_OP_STATUS_VOLUME] = EMPTY,
- [GD_OP_REBALANCE] = EMPTY,
- [GD_OP_HEAL_VOLUME] = EMPTY,
- [GD_OP_STATEDUMP_VOLUME] = EMPTY,
- [GD_OP_LIST_VOLUME] = EMPTY,
- [GD_OP_CLEARLOCKS_VOLUME] = EMPTY,
- [GD_OP_DEFRAG_BRICK_VOLUME] = EMPTY,
-};
-#undef EMPTY
-
-static inline gf_boolean_t
-glusterd_is_hook_enabled (char *script)
-{
- return (script[0] == 'S');
-}
-
-int
-glusterd_hooks_create_hooks_directory (char *basedir)
-{
- int ret = -1;
- int op = GD_OP_NONE;
- int type = GD_COMMIT_HOOK_NONE;
- char version_dir[PATH_MAX] = {0, };
- char path[PATH_MAX] = {0, };
- char *cmd_subdir = NULL;
- char type_subdir[GD_COMMIT_HOOK_MAX][256] = {{0, },
- "pre",
- "post"};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- snprintf (path, sizeof (path), "%s/hooks", basedir);
- ret = mkdir_p (path, 0777, _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due"
- "to %s", path, strerror (errno));
- goto out;
- }
-
- GLUSTERD_GET_HOOKS_DIR (version_dir, GLUSTERD_HOOK_VER, priv);
- ret = mkdir_p (version_dir, 0777, _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to create %s due "
- "to %s", version_dir, strerror (errno));
- goto out;
- }
-
- for (op = GD_OP_NONE+1; op < GD_OP_MAX; op++) {
- cmd_subdir = glusterd_hooks_get_hooks_cmd_subdir (op);
- if (strlen (cmd_subdir) == 0)
- continue;
-
- snprintf (path, sizeof (path), "%s/%s", version_dir,
- cmd_subdir);
- ret = mkdir_p (path, 0777, _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Unable to create %s due to %s",
- path, strerror (errno));
- goto out;
- }
-
- for (type = GD_COMMIT_HOOK_PRE; type < GD_COMMIT_HOOK_MAX;
- type++) {
- snprintf (path, sizeof (path), "%s/%s/%s",
- version_dir, cmd_subdir, type_subdir[type]);
- ret = mkdir_p (path, 0777, _gf_true);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Unable to create %s due to %s",
- path, strerror (errno));
- goto out;
- }
- }
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-char*
-glusterd_hooks_get_hooks_cmd_subdir (glusterd_op_t op)
-{
- GF_ASSERT ((op > GD_OP_NONE) && (op < GD_OP_MAX));
-
- return glusterd_hook_dirnames[op];
-}
-
-int
-glusterd_hooks_set_volume_args (dict_t *dict, runner_t *runner)
-{
- int i = 0;
- int count = 0;
- int ret = -1;
- char query[1024] = {0,};
- char *key = NULL;
- char *value = NULL;
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret)
- goto out;
-
- /* This will not happen unless op_ctx
- * is corrupted*/
- if (!count)
- goto out;
-
- runner_add_arg (runner, "-o");
- for (i = 1; (ret == 0); i++) {
- snprintf (query, sizeof (query), "key%d", i);
- ret = dict_get_str (dict, query, &key);
- if (ret)
- continue;
-
- snprintf (query, sizeof (query), "value%d", i);
- ret = dict_get_str (dict, query, &value);
- if (ret)
- continue;
-
- runner_argprintf (runner, "%s=%s", key, value);
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-glusterd_hooks_add_op_args (runner_t *runner, glusterd_op_t op,
- dict_t *op_ctx, glusterd_commit_hook_type_t type)
-{
- int vol_count = 0;
- gf_boolean_t truth = _gf_false;
- glusterd_volinfo_t *voliter = NULL;
- glusterd_conf_t *priv = NULL;
- int ret = -1;
-
- priv = THIS->private;
- list_for_each_entry (voliter, &priv->volumes,
- vol_list) {
- if (glusterd_is_volume_started (voliter))
- vol_count++;
- }
-
- ret = 0;
- switch (op) {
- case GD_OP_START_VOLUME:
- if (type == GD_COMMIT_HOOK_PRE &&
- vol_count == 0)
- truth = _gf_true;
-
- else if (type == GD_COMMIT_HOOK_POST &&
- vol_count == 1)
- truth = _gf_true;
-
- else
- truth = _gf_false;
-
- runner_argprintf (runner, "--first=%s",
- truth? "yes":"no");
- break;
-
- case GD_OP_STOP_VOLUME:
- if (type == GD_COMMIT_HOOK_PRE &&
- vol_count == 1)
- truth = _gf_true;
-
- else if (type == GD_COMMIT_HOOK_POST &&
- vol_count == 0)
- truth = _gf_true;
-
- else
- truth = _gf_false;
-
- runner_argprintf (runner, "--last=%s",
- truth? "yes":"no");
- break;
-
- case GD_OP_SET_VOLUME:
- ret = glusterd_hooks_set_volume_args (op_ctx, runner);
- break;
-
- default:
- break;
-
- }
-
- return ret;
-}
-
-int
-glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx,
- glusterd_commit_hook_type_t type)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0, };
- struct dirent *entry = NULL;
- DIR *hookdir = NULL;
- char *volname = NULL;
- char **lines = NULL;
- int N = 8; /*arbitrary*/
- int lineno = 0;
- int line_count = 0;
- int ret = -1;
-
- this = THIS;
- priv = this->private;
-
- ret = dict_get_str (op_ctx, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL, "Failed to get volname "
- "from operation context");
- goto out;
- }
-
- hookdir = opendir (hooks_path);
- if (!hookdir) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Failed to open dir %s, due "
- "to %s", hooks_path, strerror (errno));
- goto out;
- }
-
- lines = GF_CALLOC (1, N * sizeof (*lines), gf_gld_mt_charptr);
- if (!lines) {
- ret = -1;
- goto out;
- }
-
- ret = -1;
- line_count = 0;
- glusterd_for_each_entry (entry, hookdir);
- while (entry) {
- if (line_count == N-1) {
- N *= 2;
- lines = GF_REALLOC (lines, N * sizeof (char *));
- if (!lines)
- goto out;
- }
-
- if (glusterd_is_hook_enabled (entry->d_name)) {
- lines[line_count] = gf_strdup (entry->d_name);
- line_count++;
- }
-
- glusterd_for_each_entry (entry, hookdir);
- }
-
- lines[line_count] = NULL;
- lines = GF_REALLOC (lines, (line_count + 1) * sizeof (char *));
- if (!lines)
- goto out;
-
- qsort (lines, line_count, sizeof (*lines), glusterd_compare_lines);
-
- for (lineno = 0; lineno < line_count; lineno++) {
-
- runinit (&runner);
- runner_argprintf (&runner, "%s/%s", hooks_path, lines[lineno]);
- /*Add future command line arguments to hook scripts below*/
- runner_argprintf (&runner, "--volname=%s", volname);
- ret = glusterd_hooks_add_op_args (&runner, op, op_ctx, type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to add "
- "command specific arguments");
- goto out;
- }
-
- ret = runner_run_reuse (&runner);
- if (ret) {
- runner_log (&runner, this->name, GF_LOG_ERROR,
- "Failed to execute script");
- } else {
- runner_log (&runner, this->name, GF_LOG_INFO,
- "Ran script");
- }
- runner_end (&runner);
- }
-
- ret = 0;
-out:
- if (lines) {
- for (lineno = 0; lineno < line_count+1; lineno++)
- GF_FREE (lines[lineno]);
-
- GF_FREE (lines);
- }
-
- if (hookdir)
- closedir (hookdir);
-
- return ret;
-}
-
-int
-glusterd_hooks_post_stub_enqueue (char *scriptdir, glusterd_op_t op,
- dict_t *op_ctx)
-{
- int ret = -1;
- glusterd_hooks_stub_t *stub = NULL;
- glusterd_hooks_private_t *hooks_priv = NULL;
- glusterd_conf_t *conf = NULL;
-
- conf = THIS->private;
- hooks_priv = conf->hooks_priv;
-
- ret = glusterd_hooks_stub_init (&stub, scriptdir, op, op_ctx);
- if (ret)
- goto out;
-
- pthread_mutex_lock (&hooks_priv->mutex);
- {
- hooks_priv->waitcount++;
- list_add_tail (&stub->all_hooks, &hooks_priv->list);
- pthread_cond_signal (&hooks_priv->cond);
- }
- pthread_mutex_unlock (&hooks_priv->mutex);
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_hooks_stub_init (glusterd_hooks_stub_t **stub, char *scriptdir,
- glusterd_op_t op, dict_t *op_ctx)
-{
- int ret = -1;
- glusterd_hooks_stub_t *hooks_stub = NULL;
-
- GF_ASSERT (stub);
- if (!stub)
- goto out;
-
- hooks_stub = GF_CALLOC (1, sizeof (*hooks_stub),
- gf_gld_mt_hooks_stub_t);
- if (!hooks_stub)
- goto out;
-
- INIT_LIST_HEAD (&hooks_stub->all_hooks);
- hooks_stub->op = op;
- hooks_stub->scriptdir = gf_strdup (scriptdir);
- if (!hooks_stub->scriptdir)
- goto out;
-
- hooks_stub->op_ctx = dict_copy_with_ref (op_ctx, hooks_stub->op_ctx);
- if (!hooks_stub->op_ctx)
- goto out;
-
- *stub = hooks_stub;
- ret = 0;
-out:
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to initialize "
- "post hooks stub");
- glusterd_hooks_stub_cleanup (hooks_stub);
- }
-
- return ret;
-}
-
-void
-glusterd_hooks_stub_cleanup (glusterd_hooks_stub_t *stub)
-{
- if (!stub) {
- gf_log_callingfn (THIS->name, GF_LOG_WARNING,
- "hooks_stub is NULL");
- return;
- }
-
- if (stub->op_ctx)
- dict_unref (stub->op_ctx);
-
- GF_FREE (stub->scriptdir);
-
- GF_FREE (stub);
-}
-
-static void*
-hooks_worker (void *args)
-{
- glusterd_conf_t *conf = NULL;
- glusterd_hooks_private_t *hooks_priv = NULL;
- glusterd_hooks_stub_t *stub = NULL;
-
- THIS = args;
- conf = THIS->private;
- hooks_priv = conf->hooks_priv;
-
- for (;;) {
- pthread_mutex_lock (&hooks_priv->mutex);
- {
- while (list_empty (&hooks_priv->list)) {
- pthread_cond_wait (&hooks_priv->cond,
- &hooks_priv->mutex);
- }
- stub = list_entry (hooks_priv->list.next,
- glusterd_hooks_stub_t,
- all_hooks);
- list_del_init (&stub->all_hooks);
- hooks_priv->waitcount--;
-
- }
- pthread_mutex_unlock (&hooks_priv->mutex);
-
- glusterd_hooks_run_hooks (stub->scriptdir, stub->op,
- stub->op_ctx, GD_COMMIT_HOOK_POST);
- glusterd_hooks_stub_cleanup (stub);
- }
-
- return NULL;
-}
-
-int
-glusterd_hooks_priv_init (glusterd_hooks_private_t **new)
-{
- int ret = -1;
- glusterd_hooks_private_t *hooks_priv = NULL;
-
- if (!new)
- goto out;
-
- hooks_priv = GF_CALLOC (1, sizeof (*hooks_priv),
- gf_gld_mt_hooks_priv_t);
- if (!hooks_priv)
- goto out;
-
- pthread_mutex_init (&hooks_priv->mutex, NULL);
- pthread_cond_init (&hooks_priv->cond, NULL);
- INIT_LIST_HEAD (&hooks_priv->list);
- hooks_priv->waitcount = 0;
-
- *new = hooks_priv;
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_hooks_spawn_worker (xlator_t *this)
-{
- int ret = -1;
- glusterd_conf_t *conf = NULL;
- glusterd_hooks_private_t *hooks_priv = NULL;
-
-
- ret = glusterd_hooks_priv_init (&hooks_priv);
- if (ret)
- goto out;
-
- conf = this->private;
- conf->hooks_priv = hooks_priv;
- ret = pthread_create (&hooks_priv->worker, NULL, hooks_worker,
- (void *)this);
- if (ret)
- gf_log (this->name, GF_LOG_CRITICAL, "Failed to spawn post "
- "hooks worker thread");
-out:
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.h b/xlators/mgmt/glusterd/src/glusterd-hooks.h
deleted file mode 100644
index 2584b6bfe..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- Copyright (c) 2006-2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _GLUSTERD_HOOKS_H_
-#define _GLUSTERD_HOOKS_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <fnmatch.h>
-
-#define GLUSTERD_GET_HOOKS_DIR(path, version, priv) \
- snprintf (path, PATH_MAX, "%s/hooks/%d", priv->workdir,\
- version);
-
-#define GLUSTERD_HOOK_VER 1
-
-#define GD_HOOKS_SPECIFIC_KEY "user.*"
-
-typedef enum glusterd_commit_hook_type {
- GD_COMMIT_HOOK_NONE = 0,
- GD_COMMIT_HOOK_PRE,
- GD_COMMIT_HOOK_POST,
- GD_COMMIT_HOOK_MAX
-} glusterd_commit_hook_type_t;
-
-typedef struct hooks_private {
- struct list_head list;
- int waitcount; //debug purposes
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pthread_t worker;
-} glusterd_hooks_private_t;
-
-typedef struct hooks_stub {
- struct list_head all_hooks;
- char *scriptdir;
- glusterd_op_t op;
- dict_t *op_ctx;
-
-} glusterd_hooks_stub_t;
-
-
-static inline gf_boolean_t
-is_key_glusterd_hooks_friendly (char *key)
-{
- gf_boolean_t is_friendly = _gf_false;
-
- /* This is very specific to hooks friendly behavior */
- if (fnmatch (GD_HOOKS_SPECIFIC_KEY, key, FNM_NOESCAPE) == 0) {
- gf_log (THIS->name, GF_LOG_DEBUG, "user namespace key %s", key);
- is_friendly = _gf_true;
- }
-
- return is_friendly;
-}
-
-int
-glusterd_hooks_create_hooks_directory (char *basedir);
-
-char *
-glusterd_hooks_get_hooks_cmd_subdir (glusterd_op_t op);
-
-int
-glusterd_hooks_run_hooks (char *hooks_path, glusterd_op_t op, dict_t *op_ctx,
- glusterd_commit_hook_type_t type);
-int
-glusterd_hooks_spawn_worker (xlator_t *this);
-
-int
-glusterd_hooks_stub_init (glusterd_hooks_stub_t **stub, char *scriptdir,
- glusterd_op_t op, dict_t *op_ctx);
-void
-glusterd_hooks_stub_cleanup (glusterd_hooks_stub_t *stub);
-
-int
-glusterd_hooks_post_stub_enqueue (char *scriptdir, glusterd_op_t op,
- dict_t *op_ctx);
-int
-glusterd_hooks_priv_init (glusterd_hooks_private_t **new);
-#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-log-ops.c b/xlators/mgmt/glusterd/src/glusterd-log-ops.c
deleted file mode 100644
index b5fd5eff6..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-log-ops.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-
-#include <signal.h>
-
-int
-glusterd_handle_log_rotate (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- glusterd_op_t cli_op = GD_OP_LOG_ROTATE;
- char *volname = NULL;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received log rotate req "
- "for volume %s", volname);
-
- ret = dict_set_uint64 (dict, "rotate-key", (uint64_t)time (NULL));
- if (ret)
- goto out;
-
- ret = glusterd_op_begin (req, GD_OP_LOG_ROTATE, dict);
-
-out:
- if (ret && dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
-
- free (cli_req.dict.dict_val);
- return ret;
-}
-
-/* op-sm */
-int
-glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- gf_boolean_t exists = _gf_false;
- char msg[2048] = {0};
- char *brick = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (!exists) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (_gf_false == glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof (msg), "Volume %s needs to be started before"
- " log rotate.", volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- ret = dict_get_str (dict, "brick", &brick);
- /* If no brick is specified, do log-rotate for
- all the bricks in the volume */
- if (ret) {
- ret = 0;
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo, NULL);
- if (ret) {
- snprintf (msg, sizeof (msg), "Incorrect brick %s "
- "for volume %s", brick, volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-
-int
-glusterd_op_log_rotate (dict_t *dict)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- char *volname = NULL;
- char *brick = NULL;
- char path[PATH_MAX] = {0,};
- char logfile[PATH_MAX] = {0,};
- char pidfile[PATH_MAX] = {0,};
- FILE *file = NULL;
- pid_t pid = 0;
- uint64_t key = 0;
- int valid_brick = 0;
- glusterd_brickinfo_t *tmpbrkinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "volname not found");
- goto out;
- }
-
- ret = dict_get_uint64 (dict, "rotate-key", &key);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "rotate key not found");
- goto out;
- }
-
- ret = dict_get_str (dict, "brick", &brick);
- /* If no brick is specified, do log-rotate for
- all the bricks in the volume */
- if (ret)
- goto cont;
-
- ret = glusterd_brickinfo_new_from_brick (brick, &tmpbrkinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "cannot get brickinfo from brick");
- goto out;
- }
-
-cont:
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
-
- ret = -1;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- if (brick &&
- (strcmp (tmpbrkinfo->hostname, brickinfo->hostname) ||
- strcmp (tmpbrkinfo->path,brickinfo->path)))
- continue;
-
- valid_brick = 1;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,
- brickinfo->path);
-
- file = fopen (pidfile, "r+");
- if (!file) {
- gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
- pidfile);
- ret = -1;
- goto out;
- }
-
- ret = fscanf (file, "%d", &pid);
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s",
- pidfile);
- ret = -1;
- goto out;
- }
- fclose (file);
- file = NULL;
-
- snprintf (logfile, PATH_MAX, "%s.%"PRIu64,
- brickinfo->logfile, key);
-
- ret = rename (brickinfo->logfile, logfile);
- if (ret)
- gf_log ("", GF_LOG_WARNING, "rename failed");
-
- ret = kill (pid, SIGHUP);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to SIGHUP to %d", pid);
- goto out;
- }
- ret = 0;
-
- /* If request was for brick, only one iteration is enough */
- if (brick)
- break;
- }
-
- if (ret && !valid_brick)
- ret = 0;
-
-out:
- if (tmpbrkinfo)
- glusterd_brickinfo_delete (tmpbrkinfo);
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
index 9031f83a5..bd7b1b65f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h
+++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -64,18 +64,7 @@ typedef enum gf_gld_mem_types_ {
gf_gld_mt_brick_rsp_ctx_t = gf_common_mt_end + 38,
gf_gld_mt_mop_brick_req_t = gf_common_mt_end + 39,
gf_gld_mt_op_allack_ctx_t = gf_common_mt_end + 40,
- gf_gld_mt_linearr = gf_common_mt_end + 41,
- gf_gld_mt_linebuf = gf_common_mt_end + 42,
- gf_gld_mt_mount_pattern = gf_common_mt_end + 43,
- gf_gld_mt_mount_comp_container = gf_common_mt_end + 44,
- gf_gld_mt_mount_component = gf_common_mt_end + 45,
- gf_gld_mt_mount_spec = gf_common_mt_end + 46,
- gf_gld_mt_georep_meet_spec = gf_common_mt_end + 47,
- gf_gld_mt_nodesrv_t = gf_common_mt_end + 48,
- gf_gld_mt_charptr = gf_common_mt_end + 49,
- gf_gld_mt_hooks_stub_t = gf_common_mt_end + 50,
- gf_gld_mt_hooks_priv_t = gf_common_mt_end + 51,
- gf_gld_mt_end = gf_common_mt_end + 52,
+ gf_gld_mt_end = gf_common_mt_end + 41
} gf_gld_mem_types_t;
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
deleted file mode 100644
index 82fdfb81f..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-#include <inttypes.h>
-#include <fnmatch.h>
-#include <pwd.h>
-
-#include "globals.h"
-#include "glusterfs.h"
-#include "compat.h"
-#include "dict.h"
-#include "list.h"
-#include "logging.h"
-#include "defaults.h"
-#include "compat.h"
-#include "compat-errno.h"
-#include "run.h"
-#include "glusterd-mem-types.h"
-#include "glusterd.h"
-#include "glusterd-utils.h"
-#include "common-utils.h"
-#include "glusterd-mountbroker.h"
-#include "glusterd-op-sm.h"
-
-static int
-seq_dict_foreach (dict_t *dict,
- int (*fn)(char *str, void *data),
- void *data)
-{
- char index[] = "4294967296"; // 1<<32
- int i = 0;
- char *val = NULL;
- int ret = 0;
-
- for (;;i++) {
- snprintf(index, sizeof(index), "%d", i);
- ret = dict_get_str (dict, index, &val);
- if (ret != 0)
- return ret == -ENOENT ? 0 : ret;
- ret = fn (val, data);
- if (ret != 0)
- return ret;
- }
-}
-
-int
-parse_mount_pattern_desc (gf_mount_spec_t *mspec, char *pdesc)
-#define SYNTAX_ERR -2
-{
- char *curs = NULL;
- char *c2 = NULL;
- char sc = '\0';
- char **cc = NULL;
- gf_mount_pattern_t *pat = NULL;
- int pnum = 0;
- int ret = 0;
- int lastsup = -1;
- int incl = -1;
- char **pcc = NULL;
- int pnc = 0;
-
- skipwhite (&pdesc);
-
- /* a bow to theory */
- if (!*pdesc)
- return 0;
-
- /* count number of components, separated by '&' */
- mspec->len = 0;
- for (curs = pdesc; *curs; curs++) {
- if (*curs == ')')
- mspec->len++;
- }
-
- mspec->patterns = GF_CALLOC (mspec->len, sizeof (*mspec->patterns),
- gf_gld_mt_mount_pattern);
- if (!mspec->patterns) {
- ret = -1;
- goto out;
- }
-
- pat = mspec->patterns;
- curs = pdesc;
- skipwhite (&curs);
- for (;;) {
- incl = -1;
-
- /* check for pattern signedness modifier */
- if (*curs == '-') {
- pat->negative = _gf_true;
- curs++;
- }
-
- /* now should come condition specifier,
- * then opening paren
- */
- c2 = nwstrtail (curs, "SUB(");
- if (c2) {
- pat->condition = SET_SUB;
- goto got_cond;
- }
- c2 = nwstrtail (curs, "SUP(");
- if (c2) {
- pat->condition = SET_SUPER;
- lastsup = pat - mspec->patterns;
- goto got_cond;
- }
- c2 = nwstrtail (curs, "EQL(");
- if (c2) {
- pat->condition = SET_EQUAL;
- goto got_cond;
- }
- c2 = nwstrtail (curs, "MEET(");
- if (c2) {
- pat->condition = SET_INTERSECT;
- goto got_cond;
- }
- c2 = nwstrtail (curs, "SUB+(");
- if (c2) {
- pat->condition = SET_SUB;
- incl = lastsup;
- goto got_cond;
- }
-
- ret = SYNTAX_ERR;
- goto out;
-
- got_cond:
- curs = c2;
- skipwhite (&curs);
- /* count the number of components for pattern */
- pnum = *curs == ')' ? 0 : 1;
- for (c2 = curs ;*c2 != ')';) {
- if (strchr ("&|", *c2)) {
- ret = SYNTAX_ERR;
- goto out;
- }
- while (!strchr ("|&)", *c2) && !isspace (*c2))
- c2++;
- skipwhite (&c2);
- switch (*c2) {
- case ')':
- break;
- case '\0':
- case '&':
- ret = SYNTAX_ERR;
- goto out;
- case '|':
- *c2 = ' ';
- skipwhite (&c2);
- /* fall through */
- default:
- pnum++;
- }
- }
- if (incl >= 0) {
- pnc = 0;
- for (pcc = mspec->patterns[incl].components; *pcc; pcc++)
- pnc++;
- pnum += pnc;
- }
- pat->components = GF_CALLOC (pnum + 1, sizeof (*pat->components),
- gf_gld_mt_mount_comp_container);
- if (!pat->components) {
- ret = -1;
- goto out;
- }
-
- cc = pat->components;
- /* copy over included component set */
- if (incl >= 0) {
- memcpy (pat->components,
- mspec->patterns[incl].components,
- pnc * sizeof (*pat->components));
- cc += pnc;
- }
- /* parse and add components */
- c2 = ""; /* reset c2 */
- while (*c2 != ')') {
- c2 = curs;
- while (!isspace (*c2) && *c2 != ')')
- c2++;
- sc = *c2;
- *c2 = '\0';;
- *cc = gf_strdup (curs);
- if (!*cc) {
- ret = -1;
- goto out;
- }
- *c2 = sc;
- skipwhite (&c2);
- curs = c2;
- cc++;
- }
-
- curs++;
- skipwhite (&curs);
- if (*curs == '&') {
- curs++;
- skipwhite (&curs);
- }
-
- if (!*curs)
- break;
- pat++;
- }
-
- out:
- if (ret == SYNTAX_ERR) {
- gf_log ("", GF_LOG_ERROR, "cannot parse mount patterns %s",
- pdesc);
- }
-
- /* We've allocted a lotta stuff here but don't bother with freeing
- * on error, in that case we'll terminate anyway
- */
- return ret ? -1 : 0;
-}
-#undef SYNTAX_ERR
-
-
-const char *georep_mnt_desc_template =
- "SUP("
- "xlator-option=\\*-dht.assert-no-child-down=true "
- "volfile-server=localhost "
- "client-pid=%d "
- "user-map-root=%s "
- ")"
- "SUB+("
- "log-file="DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"*/* "
- "log-level=* "
- "volfile-id=* "
- ")"
- "MEET("
- "%s"
- ")";
-
-const char *hadoop_mnt_desc_template =
- "SUP("
- "volfile-server=%s "
- "client-pid=%d "
- "volfile-id=%s "
- "user-map-root=%s "
- ")"
- "SUB+("
- "log-file="DEFAULT_LOG_FILE_DIRECTORY"/"GHADOOP"*/* "
- "log-level=* "
- ")";
-
-int
-make_georep_mountspec (gf_mount_spec_t *mspec, const char *volnames,
- char *user)
-{
- char *georep_mnt_desc = NULL;
- char *meetspec = NULL;
- char *vols = NULL;
- char *vol = NULL;
- char *p = NULL;
- char *savetok = NULL;
- char *fa[3] = {0,};
- size_t siz = 0;
- int vc = 0;
- int i = 0;
- int ret = 0;
-
- vols = gf_strdup ((char *)volnames);
- if (!vols)
- goto out;
-
- for (vc = 1, p = vols; *p; p++) {
- if (*p == ',')
- vc++;
- }
- siz = strlen (volnames) + vc * strlen("volfile-id=");
- meetspec = GF_CALLOC (1, siz + 1, gf_gld_mt_georep_meet_spec);
- if (!meetspec)
- goto out;
-
- for (p = vols;;) {
- vol = strtok_r (p, ",", &savetok);
- if (!vol) {
- GF_ASSERT (vc == 0);
- break;
- }
- p = NULL;
- strcat (meetspec, "volfile-id=");
- strcat (meetspec, vol);
- if (--vc > 0)
- strcat (meetspec, " ");
- }
-
- ret = gf_asprintf (&georep_mnt_desc, georep_mnt_desc_template,
- GF_CLIENT_PID_GSYNCD, user, meetspec);
- if (ret == -1) {
- georep_mnt_desc = NULL;
- goto out;
- }
-
- ret = parse_mount_pattern_desc (mspec, georep_mnt_desc);
-
- out:
- fa[0] = meetspec;
- fa[1] = vols;
- fa[2] = georep_mnt_desc;
-
- for (i = 0; i < 3; i++) {
- if (fa[i] == NULL)
- ret = -1;
- else
- GF_FREE (fa[i]);
- }
-
- return ret;
-}
-
-int
-make_ghadoop_mountspec (gf_mount_spec_t *mspec, const char *volname,
- char *user, char *server)
-{
- char *hadoop_mnt_desc = NULL;
- int ret = 0;
-
- ret = gf_asprintf (&hadoop_mnt_desc, hadoop_mnt_desc_template,
- server, GF_CLIENT_PID_HADOOP, volname, user);
- if (ret == -1)
- return ret;
-
- return parse_mount_pattern_desc (mspec, hadoop_mnt_desc);
-}
-
-static gf_boolean_t
-match_comp (char *str, char *patcomp)
-{
- char *c1 = patcomp;
- char *c2 = str;
-
- GF_ASSERT (c1);
- GF_ASSERT (c2);
-
- while (*c1 == *c2) {
- if (!*c1)
- return _gf_true;
- c1++;
- c2++;
- if (c1[-1] == '=')
- break;
- }
-
- return fnmatch (c1, c2, 0) == 0 ? _gf_true : _gf_false;
-}
-
-struct gf_set_descriptor {
- gf_boolean_t priv[2];
- gf_boolean_t common;
-};
-
-static int
-_gf_set_dict_iter1 (char *val, void *data)
-{
- void **dataa = data;
- struct gf_set_descriptor *sd = dataa[0];
- char **curs = dataa[1];
- gf_boolean_t priv = _gf_true;
-
- while (*curs) {
- if (match_comp (val, *curs)) {
- priv = _gf_false;
- sd->common = _gf_true;
- }
- curs++;
- }
-
- if (priv)
- sd->priv[0] = _gf_true;
-
- return 0;
-}
-
-static int
-_gf_set_dict_iter2 (char *val, void *data)
-{
- void **dataa = data;
- gf_boolean_t *boo = dataa[0];
- char *comp = dataa[1];
-
- if (match_comp (val, comp))
- *boo = _gf_true;
-
- return 0;
-}
-
-static void
-relate_sets (struct gf_set_descriptor *sd, dict_t *argdict, char **complist)
-{
- void *dataa[] = {NULL, NULL};
- gf_boolean_t boo = _gf_false;
-
- memset (sd, 0, sizeof (*sd));
-
- dataa[0] = sd;
- dataa[1] = complist;
- seq_dict_foreach (argdict, _gf_set_dict_iter1, dataa);
-
- while (*complist) {
- boo = _gf_false;
- dataa[0] = &boo;
- dataa[1] = *complist;
- seq_dict_foreach (argdict, _gf_set_dict_iter2, dataa);
-
- if (boo)
- sd->common = _gf_true;
- else
- sd->priv[1] = _gf_true;
-
- complist++;
- }
-}
-
-static int
-_arg_parse_uid (char *val, void *data)
-{
- char *user = strtail (val, "user-map-root=");
- struct passwd *pw = NULL;
-
- if (!user)
- return 0;
- pw = getpwnam (user);
- if (!pw)
- return -EINVAL;
-
- if (*(int *)data >= 0)
- /* uid ambiguity, already found */
- return -EINVAL;
-
- *(int *)data = pw->pw_uid;
- return 0;
-}
-
-static int
-evaluate_mount_request (gf_mount_spec_t *mspec, dict_t *argdict)
-{
- struct gf_set_descriptor sd = {{0,},};
- int i = 0;
- int uid = -1;
- int ret = 0;
- gf_boolean_t match = _gf_false;
-
- for (i = 0; i < mspec->len; i++) {
- relate_sets (&sd, argdict, mspec->patterns[i].components);
- switch (mspec->patterns[i].condition) {
- case SET_SUB:
- match = !sd.priv[0];
- break;
- case SET_SUPER:
- match = !sd.priv[1];
- break;
- case SET_EQUAL:
- match = (!sd.priv[0] && !sd.priv[1]);
- break;
- case SET_INTERSECT:
- match = sd.common;
- break;
- default:
- GF_ASSERT(!"unreached");
- }
- if (mspec->patterns[i].negative)
- match = !match;
-
- if (!match)
- return -EPERM;
- }
-
- ret = seq_dict_foreach (argdict, _arg_parse_uid, &uid);
- if (ret != 0)
- return ret;
-
- return uid;
-}
-
-static int
-_volname_get (char *val, void *data)
-{
- char **volname = data;
-
- *volname = strtail (val, "volfile-id=");
-
- return *volname ? 1 : 0;
-}
-
-static int
-_runner_add (char *val, void *data)
-{
- runner_t *runner = data;
-
- runner_argprintf (runner, "--%s", val);
-
- return 0;
-}
-
-int
-glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno)
-{
- glusterd_conf_t *priv = NULL;
- char *mountbroker_root = NULL;
- gf_mount_spec_t *mspec = NULL;
- int uid = -ENOENT;
- char *volname = NULL;
- glusterd_volinfo_t *vol = NULL;
- char *mtptemp = NULL;
- char *mntlink = NULL;
- char *cookieswitch = NULL;
- char *cookie = NULL;
- char *sla = NULL;
- struct stat st = {0,};
- runner_t runner = {0,};
- int ret = 0;
- xlator_t *this = THIS;
-
- priv = this->private;
- GF_ASSERT (priv);
-
- GF_ASSERT (op_errno);
- *op_errno = 0;
-
- if (dict_get_str (this->options, "mountbroker-root",
- &mountbroker_root) != 0) {
- *op_errno = ENOENT;
- goto out;
- }
-
- GF_ASSERT (label);
- if (!*label) {
- *op_errno = EINVAL;
- goto out;
- }
-
- /* look up spec for label */
- list_for_each_entry (mspec, &priv->mount_specs,
- speclist) {
- if (strcmp (mspec->label, label) != 0)
- continue;
- uid = evaluate_mount_request (mspec, argdict);
- break;
- }
- if (uid < 0) {
- *op_errno = -uid;
- goto out;
- }
-
- /* some sanity check on arguments */
- seq_dict_foreach (argdict, _volname_get, &volname);
- if (!volname) {
- *op_errno = EINVAL;
- goto out;
- }
- if (glusterd_volinfo_find (volname, &vol) != 0 ||
- !glusterd_is_volume_started (vol)) {
- *op_errno = ENOENT;
- goto out;
- }
-
- /* go do mount */
-
- /** create actual mount dir */
-
- /*** "overload" string name to be possible to used for cookie
- creation, see below */
- ret = gf_asprintf (&mtptemp, "%s/user%d/mtpt-%s-XXXXXX/cookie",
- mountbroker_root, uid, label);
- if (ret == -1) {
- mtptemp = NULL;
- *op_errno = ENOMEM;
- goto out;
- }
- /*** hide cookie part */
- cookieswitch = strrchr (mtptemp, '/');
- *cookieswitch = '\0';
-
- sla = strrchr (mtptemp, '/');
- *sla = '\0';
- ret = mkdir (mtptemp, 0700);
- if (ret == 0)
- ret = chown (mtptemp, uid, 0);
- else if (errno == EEXIST)
- ret = 0;
- if (ret == -1) {
- *op_errno = errno;
- goto out;
- }
- ret = lstat (mtptemp, &st);
- if (ret == -1) {
- *op_errno = errno;
- goto out;
- }
- if (!(S_ISDIR (st.st_mode) && (st.st_mode & ~S_IFMT) == 0700 &&
- st.st_uid == uid && st.st_gid == 0)) {
- *op_errno = EACCES;
- goto out;
- }
- *sla = '/';
-
- if (!mkdtemp (mtptemp)) {
- *op_errno = errno;
- goto out;
- }
-
- /** create private "cookie" symlink */
-
- /*** occupy an entry in the hive dir via mkstemp */
- ret = gf_asprintf (&cookie, "%s/"MB_HIVE"/mntXXXXXX",
- mountbroker_root);
- if (ret == -1) {
- cookie = NULL;
- *op_errno = ENOMEM;
- goto out;
- }
- ret = mkstemp (cookie);
- if (ret == -1) {
- *op_errno = errno;
- goto out;
- }
- close (ret);
-
- /*** assembly the path from cookie to mountpoint */
- sla = strchr (sla - 1, '/');
- GF_ASSERT (sla);
- ret = gf_asprintf (&mntlink, "../user%d%s", uid, sla);
- if (ret == -1) {
- *op_errno = ENOMEM;
- goto out;
- }
-
- /*** create cookie link in (to-be) mountpoint,
- move it over to the final place */
- *cookieswitch = '/';
- ret = symlink (mntlink, mtptemp);
- if (ret != -1)
- ret = rename (mtptemp, cookie);
- *cookieswitch = '\0';
- if (ret == -1) {
- *op_errno = errno;
- goto out;
- }
-
- /** invoke glusterfs on the mountpoint */
-
- runinit (&runner);
- runner_add_arg (&runner, SBIN_DIR"/glusterfs");
- seq_dict_foreach (argdict, _runner_add, &runner);
- runner_add_arg (&runner, mtptemp);
- ret = runner_run_reuse (&runner);
- if (ret == -1) {
- *op_errno = EIO; /* XXX hacky fake */
- runner_log (&runner, "", GF_LOG_ERROR, "command failed");
- }
- runner_end (&runner);
-
- out:
-
- if (*op_errno) {
- ret = -1;
- gf_log ("", GF_LOG_WARNING, "unsuccessful mount request (%s)",
- strerror (*op_errno));
- if (mtptemp) {
- *cookieswitch = '/';
- unlink (mtptemp);
- *cookieswitch = '\0';
- rmdir (mtptemp);
- }
- if (cookie) {
- unlink (cookie);
- GF_FREE (cookie);
- }
-
- } else {
- ret = 0;
- *path = cookie;
- }
-
- GF_FREE (mtptemp);
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.h b/xlators/mgmt/glusterd/src/glusterd-mountbroker.h
deleted file mode 100644
index 729cf3fbc..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#define MB_HIVE "mb_hive"
-
-typedef enum {
- SET_SUB = 1,
- SET_SUPER,
- SET_EQUAL,
- SET_INTERSECT
-} gf_setrel_t;
-
-struct gf_mount_pattern {
- char **components;
- gf_setrel_t condition;
- gf_boolean_t negative;
-};
-typedef struct gf_mount_pattern gf_mount_pattern_t;
-
-struct gf_mount_spec {
- struct list_head speclist;
- char *label;
- gf_mount_pattern_t *patterns;
- size_t len;
-};
-typedef struct gf_mount_spec gf_mount_spec_t;
-
-
-int parse_mount_pattern_desc (gf_mount_spec_t *mspec, char *pdesc);
-
-int make_georep_mountspec (gf_mount_spec_t *mspec, const char *volname,
- char *user);
-int make_ghadoop_mountspec (gf_mount_spec_t *mspec, const char *volname,
- char *user, char *server);
-
-int glusterd_do_mount (char *label, dict_t *argdict, char **path, int *op_errno);
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index d46974348..b88370b29 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ GlusterFS is GF_FREE software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -45,16 +45,16 @@
#include "glusterd-op-sm.h"
#include "glusterd-utils.h"
#include "glusterd-store.h"
-#include "glusterd-hooks.h"
#include "glusterd-volgen.h"
#include "syscall.h"
-#include "cli1-xdr.h"
+#include "cli1.h"
#include "common-utils.h"
-#include "run.h"
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
+#define glusterd_op_start_volume_args_get(dict, volname, flags) \
+ glusterd_op_stop_volume_args_get (dict, volname, flags)
static struct list_head gd_op_sm_queue;
pthread_mutex_t gd_op_sm_lock;
@@ -75,7 +75,6 @@ static char *glusterd_op_sm_state_names[] = {
"Brick op failed",
"Brick op Committed",
"Brick op Commit failed",
- "Ack drain",
"Invalid",
};
@@ -93,10 +92,26 @@ static char *glusterd_op_sm_event_names[] = {
"GD_OP_EVENT_UNLOCK",
"GD_OP_EVENT_START_UNLOCK",
"GD_OP_EVENT_ALL_ACK",
- "GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP",
"GD_OP_EVENT_INVALID"
};
+static char *gsync_reserved_opts[] = {
+ "gluster-command",
+ "pid-file",
+ "state-file",
+ "session-owner",
+ NULL
+};
+
+typedef struct glusterd_quota_child_info {
+ pid_t pid;
+ char mountdir [15];
+} glusterd_quota_child_info_t;
+
+static int
+glusterd_restart_brick_servers (glusterd_volinfo_t *);
+
+
char*
glusterd_op_sm_state_name_get (int state)
{
@@ -136,6 +151,27 @@ glusterd_is_volume_started (glusterd_volinfo_t *volinfo)
return (volinfo->status == GLUSTERD_STATUS_STARTED);
}
+gf_boolean_t
+glusterd_are_all_volumes_stopped ()
+{
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ glusterd_volinfo_t *voliter = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ list_for_each_entry (voliter, &priv->volumes, vol_list) {
+ if (voliter->status == GLUSTERD_STATUS_STARTED)
+ return _gf_false;
+ }
+
+ return _gf_true;
+
+}
+
static int
glusterd_op_sm_inject_all_acc ()
{
@@ -151,9 +187,11 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin
{
int ret = -1;
gd1_mgmt_brick_op_req *brick_req = NULL;
- char *volname = NULL;
- char name[1024] = {0,};
- gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID;
+ gf1_cli_top_op top_op = 0;
+ double throughput = 0;
+ double time = 0;
+ int32_t blk_size = 0;
+ int32_t blk_count = 0;
GF_ASSERT (op < GD_OP_MAX);
GF_ASSERT (op > GD_OP_NONE);
@@ -169,7 +207,7 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin
gf_log ("", GF_LOG_ERROR, "Out of Memory");
goto out;
}
- brick_req->op = GLUSTERD_BRICK_TERMINATE;
+ brick_req->op = GF_BRICK_TERMINATE;
brick_req->name = "";
break;
case GD_OP_PROFILE_VOLUME:
@@ -181,122 +219,976 @@ glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickin
goto out;
}
- brick_req->op = GLUSTERD_BRICK_XLATOR_INFO;
+ brick_req->op = GF_BRICK_XLATOR_INFO;
brick_req->name = brickinfo->path;
+ ret = dict_get_int32 (dict, "top-op", (int32_t*)&top_op);
+ if (ret)
+ goto cont;
+ if (top_op == GF_CLI_TOP_READ_PERF ||
+ top_op == GF_CLI_TOP_WRITE_PERF) {
+
+ ret = dict_get_int32 (dict, "blk-size", &blk_size);
+ if (ret) {
+ goto cont;
+ }
+ ret = dict_get_int32 (dict, "blk-cnt", &blk_count);
+ if (ret)
+ goto out;
+ if (top_op == GF_CLI_TOP_READ_PERF)
+ ret = glusterd_volume_stats_read_perf (
+ brickinfo->path, blk_size, blk_count,
+ &throughput, &time);
+ else if (!ret && top_op == GF_CLI_TOP_WRITE_PERF)
+ ret = glusterd_volume_stats_write_perf (
+ brickinfo->path, blk_size, blk_count,
+ &throughput, &time);
+
+ if (ret)
+ goto out;
+
+ ret = dict_set_double (dict, "throughput",
+ throughput);
+ if (ret)
+ goto out;
+ ret = dict_set_double (dict, "time", time);
+ if (ret)
+ goto out;
+ }
break;
- case GD_OP_HEAL_VOLUME:
- {
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
+ default:
+ goto out;
+ break;
+ }
+
+cont:
+ ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
+ (size_t*)&brick_req->input.input_len);
+ if (ret)
+ goto out;
+ *req = brick_req;
+ ret = 0;
+
+out:
+ if (ret && brick_req)
+ GF_FREE (brick_req);
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ gf_boolean_t exists = _gf_false;
+ char *bricks = NULL;
+ char *brick_list = NULL;
+ char *free_ptr = NULL;
+ glusterd_brickinfo_t *brick_info = NULL;
+ int32_t brick_count = 0;
+ int32_t i = 0;
+ char *brick = NULL;
+ char *tmpptr = NULL;
+ char cmd_str[1024];
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char msg[2048] = {0};
+
+ this = THIS;
+ if (!this) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "this is NULL");
+ goto out;
+ }
+
+ priv = this->private;
+ if (!priv) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "priv is NULL");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+
+ if (exists) {
+ snprintf (msg, sizeof (msg), "Volume %s already exists",
+ volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ } else {
+ ret = 0;
+ }
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
+ goto out;
+ }
+
+ if (bricks) {
+ brick_list = gf_strdup (bricks);
+ if (!brick_list) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
goto out;
+ } else {
+ free_ptr = brick_list;
+ }
+ }
- brick_req->op = GLUSTERD_BRICK_XLATOR_OP;
- brick_req->name = "";
- ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op);
+ while ( i < brick_count) {
+ i++;
+ brick= strtok_r (brick_list, " \n", &tmpptr);
+ brick_list = tmpptr;
+ ret = glusterd_brickinfo_from_brick (brick, &brick_info);
if (ret)
goto out;
- ret = dict_set_int32 (dict, "xl-op", heal_op);
- }
- break;
- case GD_OP_STATUS_VOLUME:
- {
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req) {
- gf_log (THIS->name, GF_LOG_ERROR, "Out of memory");
+ snprintf (cmd_str, 1024, "%s", brick_info->path);
+ ret = glusterd_resolve_brick (brick_info);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR, "cannot resolve "
+ "brick: %s:%s", brick_info->hostname,
+ brick_info->path);
goto out;
}
- brick_req->op = GLUSTERD_BRICK_STATUS;
- brick_req->name = "";
+
+ if (!uuid_compare (brick_info->uuid, priv->uuid)) {
+ ret = glusterd_brick_create_path (brick_info->hostname,
+ brick_info->path,
+ 0777, op_errstr);
+ if (ret)
+ goto out;
+ brick_list = tmpptr;
+ }
+ glusterd_brickinfo_delete (brick_info);
+ brick_info = NULL;
}
- break;
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
+out:
+ if (free_ptr)
+ GF_FREE (free_ptr);
+ if (brick_info)
+ glusterd_brickinfo_delete (brick_info);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+glusterd_op_stop_volume_args_get (dict_t *dict, char** volname,
+ int *flags)
+{
+ int ret = -1;
+
+ if (!dict || !volname || !flags)
+ goto out;
+
+ ret = dict_get_str (dict, "volname", volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "flags", flags);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get flags");
+ goto out;
+ }
+out:
+ return ret;
+}
+
+static int
+glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ int flags = 0;
+ gf_boolean_t exists = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char msg[2048];
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+ if (!priv) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "priv is NULL");
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_op_start_volume_args_get (dict, &volname, &flags);
+ if (ret)
+ goto out;
+
+ exists = glusterd_check_volume_exists (volname);
+
+ if (!exists) {
+ snprintf (msg, sizeof (msg), "Volume %s does not exist", volname);
+ gf_log ("", GF_LOG_ERROR, "%s",
+ msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret)
+ goto out;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to resolve brick %s:%s",
+ brickinfo->hostname, brickinfo->path);
goto out;
+ }
- brick_req->op = GLUSTERD_BRICK_XLATOR_DEFRAG;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
+ if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
+ ret = glusterd_brick_create_path (brickinfo->hostname,
+ brickinfo->path,
+ 0777, op_errstr);
+ if (ret)
+ goto out;
+ }
+
+ if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
+ if (glusterd_is_volume_started (volinfo)) {
+ snprintf (msg, sizeof (msg), "Volume %s already"
+ " started", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ }
+ }
+
+ ret = 0;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = -1;
+ char *volname = NULL;
+ int flags = 0;
+ gf_boolean_t exists = _gf_false;
+ gf_boolean_t is_run = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ char msg[2048] = {0};
+
+
+ ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
+ if (ret)
+ goto out;
+
+ exists = glusterd_check_volume_exists (volname);
+
+ if (!exists) {
+ snprintf (msg, sizeof (msg), "Volume %s does not exist", volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ } else {
+ ret = 0;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret)
+ goto out;
+
+ if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
+ if (_gf_false == glusterd_is_volume_started (volinfo)) {
+ snprintf (msg, sizeof(msg), "Volume %s "
+ "is not in the started state", volname);
+ gf_log ("", GF_LOG_ERROR, "Volume %s "
+ "has not been started", volname);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ ret = glusterd_check_gsync_running (volinfo, &is_run);
+ if (ret && (is_run == _gf_false))
+ gf_log ("", GF_LOG_WARNING, "Unable to get the status"
+ " of active "GEOREP" session");
+ if (is_run) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"
+ "for the volume %s ", volname);
+ snprintf (msg, sizeof(msg), GEOREP" sessions are active "
+ "for the volume '%s'.\nUse 'volume "GEOREP" "
+ "status' command for more info. Use 'force'"
+ "option to ignore and stop stop the volume",
+ volname);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
goto out;
- snprintf (name, 1024, "%s-dht",volname);
- brick_req->name = gf_strdup (name);
+ }
- break;
- default:
+ }
+
+
+out:
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ gf_boolean_t exists = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ char msg[2048] = {0};
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
goto out;
- break;
}
- ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
- &brick_req->input.input_len);
+ exists = glusterd_check_volume_exists (volname);
+
+ if (!exists) {
+ snprintf (msg, sizeof (msg), "Volume %s does not exist",
+ volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ } else {
+ ret = 0;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
if (ret)
goto out;
- *req = brick_req;
+
+ if (glusterd_is_volume_started (volinfo)) {
+ snprintf (msg, sizeof (msg), "Volume %s has been started."
+ "Volume needs to be stopped before deletion.",
+ volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
ret = 0;
out:
- if (ret && brick_req)
- GF_FREE (brick_req);
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
return ret;
}
-int
-glusterd_node_op_build_payload (glusterd_op_t op, gd1_mgmt_brick_op_req **req,
- dict_t *dict)
+static int
+glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr)
{
- int ret = -1;
- gd1_mgmt_brick_op_req *brick_req = NULL;
+ int ret = 0;
+ char *volname = NULL;
+ int count = 0;
+ int i = 0;
+ char *bricks = NULL;
+ char *brick_list = NULL;
+ char *saveptr = NULL;
+ char *free_ptr = NULL;
+ char *brick = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ char cmd_str[1024];
+ glusterd_conf_t *priv = NULL;
+ char msg[2048] = {0,};
+ gf_boolean_t brick_alloc = _gf_false;
+ char *all_bricks = NULL;
+ char *str_ret = NULL;
- GF_ASSERT (op < GD_OP_MAX);
- GF_ASSERT (op > GD_OP_NONE);
- GF_ASSERT (req);
+ priv = THIS->private;
+ if (!priv)
+ goto out;
- switch (op) {
- case GD_OP_PROFILE_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to find volume: %s", volname);
+ goto out;
+ }
+
+ if (glusterd_is_defrag_on(volinfo)) {
+ snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
+ "progress. Please retry after completion", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
+ goto out;
+ }
+
+ if (bricks) {
+ brick_list = gf_strdup (bricks);
+ all_bricks = gf_strdup (bricks);
+ free_ptr = brick_list;
+ }
+
+ /* Check whether any of the bricks given is the destination brick of the
+ replace brick running */
+
+ str_ret = glusterd_check_brick_rb_part (all_bricks, count, volinfo);
+ if (str_ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "%s", str_ret);
+ *op_errstr = gf_strdup (str_ret);
+ ret = -1;
+ goto out;
+ }
+
+ if (count)
+ brick = strtok_r (brick_list+1, " \n", &saveptr);
+
+
+ while ( i < count) {
+ ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
+ &brickinfo);
+ if (!ret) {
+ gf_log ("", GF_LOG_ERROR, "Adding duplicate brick: %s",
+ brick);
+ ret = -1;
+ goto out;
+ } else {
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Add-brick: Unable"
+ " to get brickinfo");
+ goto out;
+ }
+ brick_alloc = _gf_true;
+ }
+
+ snprintf (cmd_str, 1024, "%s", brickinfo->path);
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "resolve brick failed");
goto out;
+ }
- brick_req->op = GLUSTERD_NODE_PROFILE;
- brick_req->name = "";
+ if (!uuid_compare (brickinfo->uuid, priv->uuid)) {
+ ret = glusterd_brick_create_path (brickinfo->hostname,
+ brickinfo->path,
+ 0777, op_errstr);
+ if (ret)
+ goto out;
+ }
- break;
+ glusterd_brickinfo_delete (brickinfo);
+ brick_alloc = _gf_false;
+ brickinfo = NULL;
+ brick = strtok_r (NULL, " \n", &saveptr);
+ i++;
+ }
- case GD_OP_STATUS_VOLUME:
- brick_req = GF_CALLOC (1, sizeof (*brick_req),
- gf_gld_mt_mop_brick_req_t);
- if (!brick_req)
+out:
+ if (free_ptr)
+ GF_FREE (free_ptr);
+ if (brick_alloc && brickinfo)
+ glusterd_brickinfo_delete (brickinfo);
+ if (str_ret)
+ GF_FREE (str_ret);
+ if (all_bricks)
+ GF_FREE (all_bricks);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+char *
+glusterd_check_brick_rb_part (char *bricks, int count, glusterd_volinfo_t *volinfo)
+{
+ char *saveptr = NULL;
+ char *brick = NULL;
+ char *brick_list = NULL;
+ int ret = 0;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ uint32_t i = 0;
+ char *str = NULL;
+ char msg[2048] = {0,};
+
+ brick_list = gf_strdup (bricks);
+ if (!brick_list) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ if (count)
+ brick = strtok_r (brick_list+1, " \n", &saveptr);
+
+
+ while ( i < count) {
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret) {
+ snprintf (msg, sizeof(msg), "Unable to"
+ " get brickinfo");
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ ret = -1;
goto out;
+ }
- brick_req->op = GLUSTERD_NODE_STATUS;
- brick_req->name = "";
+ if (glusterd_is_replace_running (volinfo, brickinfo)) {
+ snprintf (msg, sizeof(msg), "Volume %s: replace brick is running"
+ " and the brick %s:%s you are trying to add is the destination brick"
+ " for replace brick", volinfo->volname, brickinfo->hostname, brickinfo->path);
+ ret = -1;
+ goto out;
+ }
+ glusterd_brickinfo_delete (brickinfo);
+ brickinfo = NULL;
+ brick = strtok_r (NULL, " \n", &saveptr);
+ i++;
+ }
+
+out:
+ if (brick_list)
+ GF_FREE(brick_list);
+ if (brickinfo)
+ glusterd_brickinfo_delete (brickinfo);
+ if (ret)
+ str = gf_strdup (msg);
+ return str;
+}
+
+static int
+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t **brickinfo)
+{
+ int32_t ret = -1;
+
+ if (!volinfo || !brickinfo)
+ goto out;
+
+ *brickinfo = volinfo->dst_brick;
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
+ dict_t *rsp_dict)
+{
+ int ret = 0;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ char *volname = NULL;
+ int replace_op = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *src_brickinfo = NULL;
+ char *host = NULL;
+ char *path = NULL;
+ char msg[2048] = {0};
+ char *dup_dstbrick = NULL;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ glusterd_brickinfo_t *dst_brickinfo = NULL;
+ gf_boolean_t is_run = _gf_false;
+
+ ret = dict_get_str (dict, "src-brick", &src_brick);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG, "src brick=%s", src_brick);
+
+ ret = dict_get_str (dict, "dst-brick", &dst_brick);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get dest brick");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG, "dst brick=%s", dst_brick);
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "dict get on replace-brick operation failed");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "volume: %s does not exist",
+ volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (GLUSTERD_STATUS_STARTED != volinfo->status) {
+ ret = -1;
+ snprintf (msg, sizeof (msg), "volume: %s is not started",
+ volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ ret = glusterd_check_gsync_running (volinfo, &is_run);
+ if (ret && (is_run == _gf_false))
+ gf_log ("", GF_LOG_WARNING, "Unable to get the status"
+ " of active "GEOREP" session");
+ if (is_run) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"
+ "for the volume %s ", volname);
+ snprintf (msg, sizeof(msg), GEOREP" sessions are active "
+ "for the volume %s.\nStop "GEOREP "sessions "
+ "involved in this volume. Use 'volume "GEOREP
+ " status' command for more info.",
+ volname);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if (glusterd_is_defrag_on(volinfo)) {
+ snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
+ "progress. Please retry after completion", volname);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ switch (replace_op) {
+ case GF_REPLACE_OP_START:
+ if (glusterd_is_rb_started (volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is already "
+ "started for volume ");
+ ret = -1;
+ goto out;
+ }
+ break;
+ case GF_REPLACE_OP_PAUSE:
+ if (glusterd_is_rb_paused (volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is already "
+ "paused for volume ");
+ ret = -1;
+ goto out;
+ } else if (!glusterd_is_rb_started(volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is not"
+ " started for volume ");
+ ret = -1;
+ goto out;
+ }
+ break;
+
+ case GF_REPLACE_OP_ABORT:
+ if ((!glusterd_is_rb_paused (volinfo)) &&
+ (!glusterd_is_rb_started (volinfo))) {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is not"
+ " started or paused for volume ");
+ ret = -1;
+ goto out;
+ }
+ break;
+
+ case GF_REPLACE_OP_COMMIT:
+ if (!glusterd_is_rb_started (volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is not "
+ "started for volume ");
+ ret = -1;
+ goto out;
+ }
break;
+ case GF_REPLACE_OP_COMMIT_FORCE: break;
+ case GF_REPLACE_OP_STATUS:
+ break;
default:
+ ret = -1;
goto out;
}
- ret = dict_allocate_and_serialize (dict, &brick_req->input.input_val,
- &brick_req->input.input_len);
+ ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
+ &src_brickinfo);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "brick: %s does not exist in "
+ "volume: %s", src_brick, volname);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
- if (ret)
+ if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_DEBUG,
+ "I AM THE SOURCE HOST");
+ if (src_brickinfo->port && rsp_dict) {
+ ret = dict_set_int32 (rsp_dict, "src-brick-port",
+ src_brickinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not set src-brick-port=%d",
+ src_brickinfo->port);
+ }
+ }
+
+ }
+
+ dup_dstbrick = gf_strdup (dst_brick);
+ if (!dup_dstbrick) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Memory allocation failed");
goto out;
+ }
+ host = strtok (dup_dstbrick, ":");
+ path = strtok (NULL, ":");
- *req = brick_req;
+ if (!host || !path) {
+ gf_log ("", GF_LOG_ERROR,
+ "dst brick %s is not of form <HOSTNAME>:<export-dir>",
+ dst_brick);
+ ret = -1;
+ goto out;
+ }
+ if (!glusterd_brickinfo_get (NULL, host, path, NULL)) {
+ snprintf(msg, sizeof(msg), "Brick: %s:%s already in use",
+ host, path);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if ((volinfo->rb_status ==GF_RB_STATUS_NONE) &&
+ (replace_op == GF_REPLACE_OP_START)) {
+ ret = glusterd_brickinfo_from_brick (dst_brick, &dst_brickinfo);
+ volinfo->src_brick = src_brickinfo;
+ volinfo->dst_brick = dst_brickinfo;
+ } else {
+ ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
+ }
+
+ if (glusterd_rb_check_bricks (volinfo, src_brickinfo, dst_brickinfo)) {
+ gf_log ("", GF_LOG_ERROR, "replace brick: incorrect source or"
+ " destination bricks specified");
+ ret = -1;
+ goto out;
+ }
+ if (!glusterd_is_local_addr (host)) {
+ ret = glusterd_brick_create_path (host, path, 0777, op_errstr);
+ if (ret)
+ goto out;
+ } else {
+ ret = glusterd_friend_find (NULL, host, &peerinfo);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "%s, is not a friend",
+ host);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ if (!peerinfo->connected) {
+ snprintf (msg, sizeof (msg), "%s, is not connected at "
+ "the moment", host);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if (GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state) {
+ snprintf (msg, sizeof (msg), "%s, is not befriended "
+ "at the moment", host);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+ }
ret = 0;
out:
- if (ret && brick_req)
- GF_FREE (brick_req);
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+ if (dup_dstbrick)
+ GF_FREE (dup_dstbrick);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+glusterd_op_stage_log_filename (dict_t *dict, char **op_errstr)
+{
+ int ret = -1;
+ char *volname = NULL;
+ gf_boolean_t exists = _gf_false;
+ char msg[2048] = {0};
+ char *path = NULL;
+ char hostname[2048] = {0};
+ char *brick = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (!exists || ret) {
+ snprintf (msg, sizeof (msg), "Volume %s does not exist",
+ volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "brick", &brick);
+ if (ret)
+ goto out;
+
+ if (strchr (brick, ':')) {
+ ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
+ NULL);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "Incorrect brick %s "
+ "for volume %s", brick, volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+ }
+
+ ret = dict_get_str (dict, "path", &path);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "path not found");
+ goto out;
+ }
+
+ ret = gethostname (hostname, sizeof (hostname));
+ if (ret) {
+ snprintf (msg, sizeof (msg), "Failed to get hostname, error:%s",
+ strerror (errno));
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+
+ ret = glusterd_brick_create_path (hostname, path, 0777, op_errstr);
+ if (ret)
+ goto out;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
+glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr)
+{
+ int ret = -1;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ gf_boolean_t exists = _gf_false;
+ char msg[2048] = {0};
+ char *brick = NULL;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (!exists) {
+ snprintf (msg, sizeof (msg), "Volume %s does not exist",
+ volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ if (_gf_false == glusterd_is_volume_started (volinfo)) {
+ snprintf (msg, sizeof (msg), "Volume %s needs to be started before"
+ " log rotate.", volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "brick", &brick);
+ if (ret)
+ goto out;
+
+ if (strchr (brick, ':')) {
+ ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
+ NULL);
+ if (ret) {
+ snprintf (msg, sizeof (msg), "Incorrect brick %s "
+ "for volume %s", brick, volname);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
+ goto out;
+ }
+ }
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
return ret;
}
@@ -305,12 +1197,12 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
{
int ret = 0;
char *volname = NULL;
- int exists = 0;
- char *key = NULL;
+ int exists = 0;
+ char *key = NULL;
char *key_fixed = NULL;
char *value = NULL;
- char str[100] = {0, };
- int count = 0;
+ char str[100] = {0, };
+ int count = 0;
int dict_count = 0;
char errstr[2048] = {0, };
glusterd_volinfo_t *volinfo = NULL;
@@ -330,52 +1222,19 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
if (!val_dict)
goto out;
- ret = dict_get_int32 (dict, "count", &dict_count);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Count(dict),not set in Volume-Set");
- goto out;
- }
-
- if ( dict_count == 0 ) {
- /*No options would be specified of volume set help */
- if (dict_get (dict, "help" )) {
- ret = 0;
- goto out;
- }
-
- if (dict_get (dict, "help-xml" )) {
-
-#if (HAVE_LIB_XML)
- ret = 0;
- goto out;
-#else
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "libxml not present in the system");
- *op_errstr = gf_strdup ("Error: xml libraries not "
- "present to produce xml-output");
- goto out;
-#endif
- }
- gf_log (this->name, GF_LOG_ERROR, "No options received ");
- *op_errstr = gf_strdup ("Options not specified");
- ret = -1;
- goto out;
- }
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
goto out;
}
exists = glusterd_check_volume_exists (volname);
+
if (!exists) {
snprintf (errstr, sizeof (errstr), "Volume %s does not exist",
volname);
- gf_log (this->name, GF_LOG_ERROR, "%s", errstr);
+ gf_log ("", GF_LOG_ERROR, "%s", errstr);
*op_errstr = gf_strdup (errstr);
ret = -1;
goto out;
@@ -383,50 +1242,47 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to allocate memory");
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
goto out;
}
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- for ( count = 1; ret != 1 ; count++ ) {
- global_opt = _gf_false;
- sprintf (str, "key%d", count);
- ret = dict_get_str (dict, str, &key);
- if (ret)
- break;
+ ret = dict_get_int32 (dict, "count", &dict_count);
- sprintf (str, "value%d", count);
- ret = dict_get_str (dict, str, &value);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid key,value pair in 'volume set'");
- ret = -1;
- goto out;
- }
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Count(dict),not set in Volume-Set");
+ goto out;
+ }
- if (strcmp (key, "memory-accounting") == 0) {
- gf_log (this->name, GF_LOG_INFO,
- "enabling memory accounting for volume %s",
- volname);
+ if ( dict_count == 1 ) {
+ if (dict_get (dict, "history" )) {
ret = 0;
goto out;
}
- if (is_key_glusterd_hooks_friendly (key))
- continue;
+ gf_log ("", GF_LOG_ERROR, "No options received ");
+ *op_errstr = gf_strdup ("Options not specified");
+ ret = -1;
+ goto out;
+ }
+
+
+
+ for ( count = 1; ret != 1 ; count++ ) {
+ global_opt = _gf_false;
+ sprintf (str, "key%d", count);
+ ret = dict_get_str (dict, str, &key);
+
+
+ if (ret)
+ break;
- exists = glusterd_check_option_exists (key, &key_fixed);
+ exists = glusterd_check_option_exists (key, &key_fixed);
if (exists == -1) {
ret = -1;
goto out;
}
- if (!exists) {
- gf_log (this->name, GF_LOG_ERROR,
- "Option with name: %s "
+ if (!exists) {
+ gf_log ("", GF_LOG_ERROR, "Option with name: %s "
"does not exist", key);
ret = snprintf (errstr, 2048,
"option : %s does not exist",
@@ -437,18 +1293,29 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
*op_errstr = gf_strdup (errstr);
ret = -1;
goto out;
+ }
+
+ sprintf (str, "value%d", count);
+ ret = dict_get_str (dict, str, &value);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "invalid key,value pair in 'volume set'");
+ ret = -1;
+ goto out;
}
if (key_fixed)
key = key_fixed;
- if (glusterd_check_globaloption (key))
+ ret = glusterd_check_globaloption (key);
+ if (ret)
global_opt = _gf_true;
ret = dict_set_str (val_dict, key, value);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log ("", GF_LOG_ERROR,
"Unable to set the options in 'volume set'");
ret = -1;
goto out;
@@ -467,7 +1334,7 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr)
}
if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Could not create temp "
+ gf_log ("glusterd", GF_LOG_DEBUG, "Could not create temp "
"volfile, some option failed: %s", *op_errstr);
goto out;
}
@@ -486,16 +1353,17 @@ out:
if (val_dict)
dict_unref (val_dict);
- GF_FREE (key_fixed);
+ if (key_fixed)
+ GF_FREE (key_fixed);
if (ret) {
if (!(*op_errstr)) {
*op_errstr = gf_strdup ("Error, Validation Failed");
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log ("glsuterd", GF_LOG_DEBUG,
"Error, Cannot Validate option :%s",
*op_errstr);
} else {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log ("glsuterd", GF_LOG_DEBUG,
"Error, Cannot Validate option");
}
}
@@ -509,9 +1377,6 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr)
char *volname = NULL;
gf_boolean_t exists = _gf_false;
char msg[2048] = {0};
- char *key = NULL;
- char *key_fixed = NULL;
- glusterd_volinfo_t *volinfo = NULL;
ret = dict_get_str (dict, "volname", &volname);
@@ -530,49 +1395,274 @@ glusterd_op_stage_reset_volume (dict_t *dict, char **op_errstr)
ret = -1;
goto out;
}
- ret = glusterd_volinfo_find (volname, &volinfo);
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+
+static int
+glusterd_op_perform_remove_brick (glusterd_volinfo_t *volinfo, char *brick)
+{
+
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char *dup_brick = NULL;
+ glusterd_conf_t *priv = NULL;
+ int32_t ret = -1;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (brick);
+
+ priv = THIS->private;
+
+ dup_brick = gf_strdup (brick);
+ if (!dup_brick)
+ goto out;
+
+ ret = glusterd_volume_brickinfo_get_by_brick (dup_brick, volinfo, &brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status) {
+ ret = glusterd_brick_stop (volinfo, brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to stop "
+ "glusterfs, ret: %d", ret);
+ goto out;
+ }
+ }
+ glusterd_delete_brick (volinfo, brickinfo);
+out:
+ if (dup_brick)
+ GF_FREE (dup_brick);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
+ char *old_brick, char *new_brick)
+{
+ glusterd_brickinfo_t *old_brickinfo = NULL;
+ glusterd_brickinfo_t *new_brickinfo = NULL;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+
+ GF_ASSERT (volinfo);
+
+ ret = glusterd_brickinfo_from_brick (new_brick,
+ &new_brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volume_brickinfo_get_by_brick (old_brick, volinfo,
+ &old_brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_resolve_brick (new_brickinfo);
if (ret)
goto out;
- ret = glusterd_validate_volume_id (dict, volinfo);
+ list_add_tail (&new_brickinfo->brick_list,
+ &old_brickinfo->brick_list);
+
+ volinfo->brick_count++;
+
+ ret = glusterd_op_perform_remove_brick (volinfo, old_brick);
+ if (ret)
+ goto out;
+
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret)
goto out;
- ret = dict_get_str (dict, "key", &key);
+ if (GLUSTERD_STATUS_STARTED == volinfo->status) {
+ ret = glusterd_brick_start (volinfo, new_brickinfo);
+ if (ret)
+ goto out;
+ }
+
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_op_perform_add_bricks (glusterd_volinfo_t *volinfo, int32_t count,
+ char *bricks)
+{
+ glusterd_brickinfo_t *brickinfo = NULL;
+ char *brick = NULL;
+ int32_t i = 1;
+ char *brick_list = NULL;
+ char *free_ptr1 = NULL;
+ char *free_ptr2 = NULL;
+ char *saveptr = NULL;
+ int32_t ret = -1;
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+
+ GF_ASSERT (volinfo);
+
+ if (bricks) {
+ brick_list = gf_strdup (bricks);
+ free_ptr1 = brick_list;
+ }
+
+ if (count)
+ brick = strtok_r (brick_list+1, " \n", &saveptr);
+
+ while ( i <= count) {
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret)
+ goto out;
+ list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
+ brick = strtok_r (NULL, " \n", &saveptr);
+ i++;
+ volinfo->brick_count++;
+
+ }
+
+ brick_list = gf_strdup (bricks);
+ free_ptr2 = brick_list;
+ i = 1;
+
+ if (count)
+ brick = strtok_r (brick_list+1, " \n", &saveptr);
+
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ if (ret)
+ goto out;
+
+ while (i <= count) {
+
+ ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
+ &brickinfo);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status) {
+ ret = glusterd_brick_start (volinfo, brickinfo);
+ if (ret)
+ goto out;
+ }
+ i++;
+ brick = strtok_r (NULL, " \n", &saveptr);
+ }
+
+out:
+ if (free_ptr1)
+ GF_FREE (free_ptr1);
+ if (free_ptr2)
+ GF_FREE (free_ptr2);
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+
+static int
+glusterd_op_stage_remove_brick (dict_t *dict)
+{
+ int ret = -1;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ dict_t *ctx = NULL;
+ char *errstr = NULL;
+ int32_t brick_count = 0;
+
+ ret = dict_get_str (dict, "volname", &volname);
+
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to get option key");
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
goto out;
}
- if (strcmp(key, "all")) {
- exists = glusterd_check_option_exists (key, &key_fixed);
- if (exists == -1) {
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Volume %s does not exist", volname);
+ goto out;
+ }
+
+ if (glusterd_is_defrag_on(volinfo)) {
+ ctx = glusterd_op_get_ctx (GD_OP_REMOVE_BRICK);
+ errstr = gf_strdup("Rebalance is in progress. Please retry"
+ " after completion");
+ if (!errstr) {
ret = -1;
goto out;
}
- if (!exists) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Option %s does not exist", key);
- ret = snprintf (msg, 2048,
- "Option %s does not exist", key);
- if (key_fixed)
- snprintf (msg + ret, 2048 - ret,
- "\nDid you mean %s?", key_fixed);
- *op_errstr = gf_strdup (msg);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", errstr);
+ ret = dict_set_dynstr (ctx, "errstr", errstr);
+ if (ret) {
+ GF_FREE (errstr);
+ gf_log ("", GF_LOG_DEBUG,
+ "failed to set errstr ctx");
+ goto out;
+ }
+
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get brick count");
+ goto out;
+ }
+
+ if (volinfo->brick_count == brick_count) {
+ ctx = glusterd_op_get_ctx (GD_OP_REMOVE_BRICK);
+ if (!ctx) {
+ gf_log ("", GF_LOG_ERROR,
+ "Operation Context is not present");
+ ret = -1;
+ goto out;
+ }
+ errstr = gf_strdup ("Deleting all the bricks of the "
+ "volume is not allowed");
+ if (!errstr) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
ret = -1;
goto out;
}
+
+ ret = dict_set_dynstr (ctx, "errstr", errstr);
+ if (ret) {
+ GF_FREE (errstr);
+ gf_log ("", GF_LOG_DEBUG,
+ "failed to set pump status in ctx");
+ goto out;
+ }
+
+ ret = -1;
+ goto out;
}
out:
- GF_FREE (key_fixed);
-
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-
-
static int
glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr)
{
@@ -582,7 +1672,6 @@ glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr)
gf_boolean_t exists = _gf_false;
glusterd_peerinfo_t *peerinfo = NULL;
char msg[2048] = {0,};
- glusterd_volinfo_t *volinfo = NULL;
ret = dict_get_str (dict, "hostname", &hostname);
if (ret) {
@@ -622,13 +1711,6 @@ glusterd_op_stage_sync_volume (dict_t *dict, char **op_errstr)
ret = -1;
goto out;
}
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
} else {
ret = 0;
}
@@ -640,130 +1722,718 @@ out:
return ret;
}
-static int
-glusterd_op_stage_status_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- uint32_t cmd = 0;
- char msg[2048] = {0,};
- char *volname = NULL;
- char *brick = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- dict_t *vol_opts = NULL;
- gf_boolean_t nfs_disabled = _gf_false;
- gf_boolean_t shd_enabled = _gf_true;
- GF_ASSERT (dict);
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT(priv);
+int
+glusterd_query_extutil (char *resbuf, char *cmd)
+{
+ FILE *in = NULL;
+ char *ptr = NULL;
+ int ret = 0;
+
+ if (!(in = popen(cmd, "r"))) {
+ gf_log ("", GF_LOG_ERROR, "popen failed");
+ return -1;
+ }
+
+ ptr = fgets(resbuf, PATH_MAX, in);
+ if (ptr)
+ resbuf[strlen(resbuf)-1] = '\0'; //strip off \n
+
+ ret |= pclose (in);
- ret = dict_get_uint32 (dict, "cmd", &cmd);
if (ret)
+ gf_log ("", GF_LOG_ERROR, "popen failed");
+
+ return ret ? -1 : 0;
+}
+
+static int
+glusterd_get_canon_url (char *cann, char *name, gf_boolean_t cann_esc)
+{
+ char cmd[PATH_MAX] = {0, };
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ snprintf (cmd, PATH_MAX, GSYNCD_PREFIX"/gsyncd --canonicalize-%surl %s",
+ cann_esc? "escape-": "",name);
+
+ return glusterd_query_extutil (cann, cmd);
+}
+
+int
+glusterd_gsync_get_param_file (char *prmfile, const char *param, char *master,
+ char *slave, char *gl_workdir)
+{
+ char cmd[PATH_MAX] = {0, };
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ snprintf (cmd, PATH_MAX,
+ GSYNCD_PREFIX"/gsyncd -c %s/"GSYNC_CONF" :%s %s --config-get %s-file",
+ gl_workdir, master, slave, param);
+
+ return glusterd_query_extutil (prmfile, cmd);
+}
+
+static int
+gsyncd_getpidfile (char *master, char *slave, char *pidfile)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ GF_VALIDATE_OR_GOTO ("gsync", master, out);
+ GF_VALIDATE_OR_GOTO ("gsync", slave, out);
+
+ ret = glusterd_gsync_get_param_file (pidfile, "pid", master,
+ slave, priv->workdir);
+ if (ret == -1) {
+ ret = -2;
+ gf_log ("", GF_LOG_WARNING, "failed to create the pidfile string");
goto out;
+ }
+
+ ret = open (pidfile, O_RDWR);
+
+ out:
+ return ret;
+}
+
+static int
+gsync_status_byfd (int fd)
+{
+ GF_ASSERT (fd >= -1);
+
+ if (lockf (fd, F_TEST, 0) == -1 &&
+ (errno == EAGAIN || errno == EACCES))
+ /* gsyncd keeps the pidfile locked */
+ return 0;
+
+ return -1;
+}
+
+/* status: return 0 when gsync is running
+ * return -1 when not running
+ */
+int
+gsync_status (char *master, char *slave, int *status)
+{
+ char pidfile[PATH_MAX] = {0,};
+ int fd = -1;
+
+ fd = gsyncd_getpidfile (master, slave, pidfile);
+ if (fd == -2)
+ return -1;
+
+ *status = gsync_status_byfd (fd);
- if (cmd & GF_CLI_STATUS_ALL)
+ close (fd);
+ return 0;
+}
+
+
+int32_t
+glusterd_gsync_volinfo_dict_set (glusterd_volinfo_t *volinfo,
+ char *key, char *value)
+{
+ int32_t ret = -1;
+ char *gsync_status = NULL;
+
+ gsync_status = gf_strdup (value);
+ if (!gsync_status) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
goto out;
+ }
- ret = dict_get_str (dict, "volname", &volname);
+ ret = dict_set_dynstr (volinfo->dict, key, gsync_status);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to get volume name");
+ gf_log ("", GF_LOG_ERROR, "Unable to set dict");
goto out;
}
- ret = glusterd_volinfo_find (volname, &volinfo);
+ ret = 0;
+out:
+ return 0;
+}
+
+int
+gsync_verify_config_options (dict_t *dict, char **op_errstr)
+{
+ char cmd[PATH_MAX] = {0,};
+ char **resopt = NULL;
+ int i = 0;
+ char *subop = NULL;
+ char *slave = NULL;
+ char *op_name = NULL;
+ char *op_value = NULL;
+ gf_boolean_t banned = _gf_true;
+
+ if (dict_get_str (dict, "subop", &subop) != 0) {
+ gf_log ("", GF_LOG_WARNING, "missing subop");
+ *op_errstr = gf_strdup ("Invalid config request");
+ return -1;
+ }
+
+ if (dict_get_str (dict, "slave", &slave) != 0) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" CONFIG: no slave given");
+ *op_errstr = gf_strdup ("Slave required");
+ return -1;
+ }
+
+ if (strcmp (subop, "get-all") == 0)
+ return 0;
+
+ if (dict_get_str (dict, "op_name", &op_name) != 0) {
+ gf_log ("", GF_LOG_WARNING, "option name missing");
+ *op_errstr = gf_strdup ("Option name missing");
+ return -1;
+ }
+
+ snprintf (cmd, PATH_MAX, GSYNCD_PREFIX"/gsyncd --config-check %s", op_name);
+ if (system (cmd)) {
+ gf_log ("", GF_LOG_WARNING, "Invalid option %s", op_name);
+ *op_errstr = gf_strdup ("Invalid option");
+
+ return -1;
+ }
+
+ if (strcmp (subop, "get") == 0)
+ return 0;
+
+ if (strcmp (subop, "set") != 0 && strcmp (subop, "del") != 0) {
+ gf_log ("", GF_LOG_WARNING, "unknown subop %s", subop);
+ *op_errstr = gf_strdup ("Invalid config request");
+ return -1;
+ }
+
+ if (strcmp (subop, "set") == 0 &&
+ dict_get_str (dict, "op_value", &op_value) != 0) {
+ gf_log ("", GF_LOG_WARNING, "missing value for set");
+ *op_errstr = gf_strdup ("missing value");
+ }
+
+ /* match option name against reserved options, modulo -/_
+ * difference
+ */
+ for (resopt = gsync_reserved_opts; *resopt; resopt++) {
+ banned = _gf_true;
+ for (i = 0; (*resopt)[i] && op_name[i]; i++) {
+ if ((*resopt)[i] == op_name[i] ||
+ ((*resopt)[i] == '-' && op_name[i] == '_'))
+ continue;
+ banned = _gf_false;
+ }
+ if (banned) {
+ gf_log ("", GF_LOG_WARNING, "Reserved option %s", op_name);
+ *op_errstr = gf_strdup ("Reserved option");
+
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void
+_get_status_mst_slv (dict_t *this, char *key, data_t *value, void *data)
+{
+ glusterd_gsync_status_temp_t *param = NULL;
+ char *slave = NULL;
+ int ret = 0;
+
+ param = (glusterd_gsync_status_temp_t *)data;
+
+ GF_ASSERT (param);
+ GF_ASSERT (param->volinfo);
+
+ slave = strchr(value->data, ':');
+ if (slave)
+ slave ++;
+ else
+ return;
+
+ ret = glusterd_get_gsync_status_mst_slv(param->volinfo,
+ slave, param->rsp_dict);
+
+}
+
+/* The return status indicates success (ret_status = 0) if the host uuid
+ * matches, status indicates failure (ret_status = -1) if the host uuid
+ * mismatches, status indicates not found if the slave is not found to be
+ * spawned for the given master */
+static void
+_compare_host_uuid (dict_t *this, char *key, data_t *value, void *data)
+{
+ glusterd_gsync_slaves_t *status = NULL;
+ char *slave = NULL;
+ int uuid_len = 0;
+
+ status = (glusterd_gsync_slaves_t *)data;
+
+ if ((status->ret_status == -1) || (status->ret_status == 0))
+ return;
+ slave = strchr(value->data, ':');
+ if (slave)
+ slave ++;
+
+ uuid_len = (slave - value->data - 1);
+
+ if (strncmp (slave, status->slave, PATH_MAX) == 0) {
+ if (strncmp (value->data, status->host_uuid, uuid_len) == 0) {
+ status->ret_status = 0;
+ } else {
+ status->ret_status = -1;
+ strncpy (status->rmt_hostname, value->data, uuid_len);
+ status->rmt_hostname[uuid_len] = '\0';
+ }
+ }
+
+}
+
+static void
+_get_max_gsync_slave_num (dict_t *this, char *key, data_t *value, void *data)
+{
+ int tmp_slvnum = 0;
+ glusterd_gsync_slaves_t *status = NULL;
+
+ status = (glusterd_gsync_slaves_t *)data;
+
+ sscanf (key, "slave%d", &tmp_slvnum);
+ if (tmp_slvnum > status->ret_status)
+ status->ret_status = tmp_slvnum;
+}
+
+static void
+_remove_gsync_slave (dict_t *this, char *key, data_t *value, void *data)
+{
+ glusterd_gsync_slaves_t *status = NULL;
+ char *slave = NULL;
+
+
+ status = (glusterd_gsync_slaves_t *)data;
+
+ slave = strchr(value->data, ':');
+ if (slave)
+ slave ++;
+
+ if (strncmp (slave, status->slave, PATH_MAX) == 0)
+ dict_del (this, key);
+
+}
+
+static int
+glusterd_remove_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,
+ char *host_uuid, char **op_errstr)
+{
+ int ret = 0;
+ glusterd_gsync_slaves_t status = {0, };
+ char cann_slave[PATH_MAX] = {0, };
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (host_uuid);
+
+ ret = glusterd_get_canon_url (cann_slave, slave, _gf_false);
+ if (ret)
+ goto out;
+
+ status.slave = cann_slave;
+ status.host_uuid = host_uuid;
+ status.ret_status = 1;
+
+ dict_foreach (volinfo->gsync_slaves, _remove_gsync_slave, &status);
+
+ ret = glusterd_store_volinfo (volinfo,
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret) {
- snprintf (msg, sizeof(msg), "Volume %s does not exist",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup ("Failed to store the Volume"
+ "information");
+ goto out;
+ }
+ out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+
+}
+
+static int
+glusterd_gsync_get_uuid (char *slave, glusterd_volinfo_t *vol,
+ uuid_t uuid)
+{
+
+ int ret = 0;
+ glusterd_gsync_slaves_t status = {0, };
+ char cann_slave[PATH_MAX] = {0, };
+ char host_uuid_str[64] = {0};
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+ GF_ASSERT (vol);
+ GF_ASSERT (slave);
+
+ uuid_utoa_r (priv->uuid, host_uuid_str);
+ ret = glusterd_get_canon_url (cann_slave, slave, _gf_false);
+ if (ret)
+ goto out;
+
+ status.slave = cann_slave;
+ status.host_uuid = host_uuid_str;
+ status.ret_status = 1;
+ dict_foreach (vol->gsync_slaves, _compare_host_uuid, &status);
+ if (status.ret_status == 0) {
+ uuid_copy (uuid, priv->uuid);
+ } else if (status.ret_status == -1) {
+ uuid_parse (status.rmt_hostname, uuid);
+ } else {
ret = -1;
goto out;
}
+ ret = 0;
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
+}
+
+static int
+glusterd_check_gsync_running_local (char *master, char *slave,
+ gf_boolean_t *is_run)
+{
+ int ret = -1;
+ int ret_status = 0;
+
+ GF_ASSERT (master);
+ GF_ASSERT (slave);
+ GF_ASSERT (is_run);
+
+ *is_run = _gf_false;
+ ret = gsync_status (master, slave, &ret_status);
+ if (ret == 0 && ret_status == 0) {
+ *is_run = _gf_true;
+ } else if (ret == -1) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" start validation "
+ " failed");
+ goto out;
+ }
+ ret = 0;
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
+}
+
+static int
+glusterd_store_slave_in_info (glusterd_volinfo_t *volinfo, char *slave,
+ char *host_uuid, char **op_errstr)
+{
+ int ret = 0;
+ glusterd_gsync_slaves_t status = {0, };
+ char cann_slave[PATH_MAX] = {0, };
+ char *value = NULL;
+ char key[512] = {0, };
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (host_uuid);
- ret = glusterd_validate_volume_id (dict, volinfo);
+ ret = glusterd_get_canon_url (cann_slave, slave, _gf_false);
if (ret)
goto out;
- ret = glusterd_is_volume_started (volinfo);
- if (!ret) {
- snprintf (msg, sizeof (msg), "Volume %s is not started",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ status.slave = cann_slave;
+ status.host_uuid = host_uuid;
+ status.ret_status = 1;
+ dict_foreach (volinfo->gsync_slaves, _compare_host_uuid, &status);
+
+ if (status.ret_status == -1) {
+ gf_log ("", GF_LOG_ERROR, GEOREP" has already been invoked for "
+ "the %s (master) and %s (slave)"
+ "from a different machine",
+ volinfo->volname, slave);
+ *op_errstr = gf_strdup (GEOREP" already running in an an"
+ "orhter machine");
ret = -1;
goto out;
}
- vol_opts = volinfo->dict;
+ memset (&status, 0, sizeof (status));
- if ((cmd & GF_CLI_STATUS_NFS) != 0) {
- nfs_disabled = dict_get_str_boolean (vol_opts, "nfs.disable",
- _gf_false);
- if (nfs_disabled) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "NFS server is disabled for volume %s",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ dict_foreach (volinfo->gsync_slaves, _get_max_gsync_slave_num, &status);
+
+ gf_asprintf (&value, "%s:%s", host_uuid, cann_slave);
+ snprintf (key, 512, "slave%d", status.ret_status +1);
+ ret = dict_set_dynstr (volinfo->gsync_slaves, key, value);
+
+ if (ret)
+ goto out;
+ ret = glusterd_store_volinfo (volinfo,
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret) {
+ *op_errstr = gf_strdup ("Failed to store the Volume"
+ "information");
+ goto out;
+ }
+ ret = 0;
+ out:
+ return ret;
+}
+
+
+static int
+glusterd_op_verify_gsync_start_options (glusterd_volinfo_t *volinfo,
+ char *slave, char **op_errstr)
+{
+ int ret = -1;
+ gf_boolean_t is_running = _gf_false;
+ char msg[2048] = {0};
+ uuid_t uuid = {0};
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (op_errstr);
+ GF_ASSERT (this && this->private);
+
+ priv = this->private;
+
+ if (GLUSTERD_STATUS_STARTED != volinfo->status) {
+ snprintf (msg, sizeof (msg), "Volume %s needs to be started "
+ "before "GEOREP" start", volinfo->volname);
+ goto out;
+ }
+ /*Check if the gsync is already started in cmd. inited host
+ * If so initiate add it into the glusterd's priv*/
+ ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
+ if ((ret == 0) && (uuid_compare (priv->uuid, uuid) == 0)) {
+ ret = glusterd_check_gsync_running_local (volinfo->volname,
+ slave, &is_running);
+ if (ret) {
+ snprintf (msg, sizeof (msg), GEOREP" start option "
+ "validation failed ");
goto out;
}
- } else if ((cmd & GF_CLI_STATUS_SHD) != 0) {
- if (!glusterd_is_volume_replicate (volinfo)) {
+ if (_gf_true == is_running) {
+ snprintf (msg, sizeof (msg), GEOREP " session between"
+ " %s & %s already started", volinfo->volname,
+ slave);
ret = -1;
- snprintf (msg, sizeof (msg),
- "Volume %s is not of type replicate",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
goto out;
}
+ }
+ ret = 0;
+out:
+ if (ret && (msg[0] != '\0')) {
+ *op_errstr = gf_strdup (msg);
+ }
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
- shd_enabled = dict_get_str_boolean (vol_opts,
- "cluster.self-heal-daemon",
- _gf_true);
- if (!shd_enabled) {
- ret = -1;
- snprintf (msg, sizeof (msg),
- "Self-heal Daemon is disabled for volume %s",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
+int
+glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag)
+{
- } else if ((cmd & GF_CLI_STATUS_BRICK) != 0) {
- ret = dict_get_str (dict, "brick", &brick);
- if (ret)
- goto out;
+ GF_ASSERT (volinfo);
+ GF_ASSERT (flag);
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- &brickinfo);
- if (ret) {
- snprintf (msg, sizeof(msg), "No brick %s in"
- " volume %s", brick, volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
+ if (volinfo->gsync_slaves->count)
+ *flag = _gf_true;
+ else
+ *flag = _gf_false;
- ret = -1;
- goto out;
- }
+ return 0;
+}
+
+static int
+glusterd_op_verify_gsync_running (glusterd_volinfo_t *volinfo,
+ char *slave, char **op_errstr)
+{
+ int ret = -1;
+ char msg[2048] = {0};
+ uuid_t uuid = {0};
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS && THIS->private);
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (op_errstr);
+
+ priv = THIS->private;
+
+ if (GLUSTERD_STATUS_STARTED != volinfo->status) {
+ snprintf (msg, sizeof (msg), "Volume %s needs to be started "
+ "before "GEOREP" start", volinfo->volname);
+
+ goto out;
+ }
+ ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
+ if (ret == -1) {
+ snprintf (msg, sizeof (msg), GEOREP" session between %s & %s"
+ " not active", volinfo->volname, slave);
+ goto out;
}
ret = 0;
+out:
+ if (ret && (msg[0] != '\0')) {
+ *op_errstr = gf_strdup (msg);
+ }
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_verify_gsync_status_opts (dict_t *dict, char **op_errstr)
+{
+ char *slave = NULL;
+ char *volname = NULL;
+ char errmsg[PATH_MAX] = {0, };
+ gf_boolean_t exists = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+
+ ret = dict_get_str (dict, "master", &volname);
+ if (ret < 0) {
+ ret = 0;
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if ((ret) || (!exists)) {
+ gf_log ("", GF_LOG_WARNING, "volume name does not exist");
+ snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
+ " exist", volname);
+ *op_errstr = gf_strdup (errmsg);
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "slave", &slave);
+ if (ret < 0) {
+ ret = 0;
+ goto out;
+ }
out:
- if (ret) {
- if (msg[0] != '\0')
- *op_errstr = gf_strdup (msg);
- else
- *op_errstr = gf_strdup ("Validation Failed for Status");
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
+}
+
+
+static int
+glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,
+ char **master, char **slave)
+{
+
+ int ret = -1;
+ GF_ASSERT (dict);
+ GF_ASSERT (op_errstr);
+ GF_ASSERT (master);
+ GF_ASSERT (slave);
+
+ ret = dict_get_str (dict, "master", master);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "master not found");
+ *op_errstr = gf_strdup ("master not found");
+ goto out;
}
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning: %d", ret);
+ ret = dict_get_str (dict, "slave", slave);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "slave not found");
+ *op_errstr = gf_strdup ("slave not found");
+ goto out;
+ }
+
+
+ ret = 0;
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
+static int
+glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ int type = 0;
+ char *volname = NULL;
+ char *slave = NULL;
+ gf_boolean_t exists = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ char errmsg[PATH_MAX] = {0,};
+
+
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "command type not found");
+ *op_errstr = gf_strdup ("command unsuccessful");
+ goto out;
+ }
+
+ switch (type) {
+ case GF_GSYNC_OPTION_TYPE_STATUS:
+ ret = glusterd_verify_gsync_status_opts (dict, op_errstr);
+
+ goto out;
+ case GF_GSYNC_OPTION_TYPE_CONFIG:
+ ret = gsync_verify_config_options (dict, op_errstr);
+
+ goto out;
+ }
+
+ ret = glusterd_op_gsync_args_get (dict, op_errstr, &volname, &slave);
+ if (ret)
+ goto out;
+
+ exists = glusterd_check_volume_exists (volname);
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if ((ret) || (!exists)) {
+ gf_log ("", GF_LOG_WARNING, "volume name does not exist");
+ snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
+ " exist", volname);
+ *op_errstr = gf_strdup (errmsg);
+ ret = -1;
+ goto out;
+ }
+
+ switch (type) {
+ case GF_GSYNC_OPTION_TYPE_START:
+ ret = glusterd_op_verify_gsync_start_options (volinfo, slave,
+ op_errstr);
+ break;
+ case GF_GSYNC_OPTION_TYPE_STOP:
+ ret = glusterd_op_verify_gsync_running (volinfo, slave,
+ op_errstr);
+ break;
+ }
+
+out:
+ return ret;
+}
static gf_boolean_t
glusterd_is_profile_on (glusterd_volinfo_t *volinfo)
@@ -811,10 +2481,6 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr)
goto out;
}
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
ret = dict_get_int32 (dict, "op", &stats_op);
if (ret) {
snprintf (msg, sizeof (msg), "Volume profile op get failed");
@@ -828,7 +2494,6 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr)
ret = -1;
goto out;
}
-
}
if ((GF_CLI_STATS_STOP == stats_op) ||
(GF_CLI_STATS_INFO == stats_op)) {
@@ -836,7 +2501,6 @@ glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr)
snprintf (msg, sizeof (msg), "Profile on Volume %s is"
" not started", volinfo->volname);
ret = -1;
-
goto out;
}
}
@@ -860,24 +2524,1422 @@ out:
return ret;
}
+static int
+glusterd_op_create_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+ char *brick = NULL;
+ int32_t count = 0;
+ int32_t i = 1;
+ char *bricks = NULL;
+ char *brick_list = NULL;
+ char *free_ptr = NULL;
+ char *saveptr = NULL;
+ int32_t sub_count = 0;
+ char *trans_type = NULL;
+ char *str = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
-static void
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = glusterd_volinfo_new (&volinfo);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME);
+ GF_ASSERT (volinfo->volname);
+
+ ret = dict_get_int32 (dict, "type", &volinfo->type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get type");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &volinfo->brick_count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "port", &volinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get port");
+ goto out;
+ }
+
+ count = volinfo->brick_count;
+
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
+ goto out;
+ }
+
+ if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) {
+ ret = dict_get_int32 (dict, "replica-count",
+ &sub_count);
+ if (ret)
+ goto out;
+ } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) {
+ ret = dict_get_int32 (dict, "stripe-count",
+ &sub_count);
+ if (ret)
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "transport", &trans_type);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get transport");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "volume-id", &str);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume-id");
+ goto out;
+ }
+ ret = uuid_parse (str, volinfo->volume_id);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "unable to parse uuid %s", str);
+ goto out;
+ }
+
+ if (strcasecmp (trans_type, "rdma") == 0) {
+ volinfo->transport_type = GF_TRANSPORT_RDMA;
+ } else if (strcasecmp (trans_type, "tcp") == 0) {
+ volinfo->transport_type = GF_TRANSPORT_TCP;
+ } else {
+ volinfo->transport_type = GF_TRANSPORT_BOTH_TCP_RDMA;
+ }
+
+ volinfo->sub_count = sub_count;
+
+ if (bricks) {
+ brick_list = gf_strdup (bricks);
+ free_ptr = brick_list;
+ }
+
+ if (count)
+ brick = strtok_r (brick_list+1, " \n", &saveptr);
+
+ while ( i <= count) {
+ ret = glusterd_brickinfo_from_brick (brick, &brickinfo);
+ if (ret)
+ goto out;
+
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret)
+ goto out;
+ list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
+ brick = strtok_r (NULL, " \n", &saveptr);
+ i++;
+ }
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret) {
+ *op_errstr = gf_strdup ("Failed to store the Volume information");
+ goto out;
+ }
+
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ if (ret) {
+ *op_errstr = gf_strdup ("Failed to create volume files");
+ goto out;
+ }
+
+ ret = glusterd_volume_compute_cksum (volinfo);
+ if (ret) {
+ *op_errstr = gf_strdup ("Failed to compute checksum of volume");
+ goto out;
+ }
+
+ volinfo->defrag_status = 0;
+ list_add_tail (&volinfo->vol_list, &priv->volumes);
+out:
+ if (free_ptr)
+ GF_FREE(free_ptr);
+
+ return ret;
+}
+
+static int
+glusterd_op_add_brick (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ xlator_t *this = NULL;
+ char *bricks = NULL;
+ int32_t count = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ goto out;
+ }
+
+
+ ret = dict_get_str (dict, "bricks", &bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
+ goto out;
+ }
+
+ ret = glusterd_op_perform_add_bricks (volinfo, count, bricks);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to add bricks");
+ goto out;
+ }
+
+ volinfo->defrag_status = 0;
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status)
+ ret = glusterd_check_generate_start_nfs ();
+
+out:
+ return ret;
+}
+
+static int
+rb_regenerate_volfiles (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo,
+ int32_t pump_needed)
+{
+ dict_t *dict = NULL;
+ int ret = 0;
+
+ dict = volinfo->dict;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "attempting to set pump value=%d", pump_needed);
+
+ ret = dict_set_int32 (dict, "enable-pump", pump_needed);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "could not dict_set enable-pump");
+ goto out;
+ }
+
+ ret = glusterd_create_rb_volfiles (volinfo, brickinfo);
+
+out:
+ return ret;
+}
+
+static int
+rb_src_brick_restart (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ int activate_pump)
+{
+ int ret = 0;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Attempting to kill src");
+
+ ret = glusterd_nfs_server_stop ();
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to stop nfs, ret: %d",
+ ret);
+ }
+
+ ret = glusterd_volume_stop_glusterfs (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to stop "
+ "glusterfs, ret: %d", ret);
+ goto out;
+ }
+
+ glusterd_delete_volfile (volinfo, src_brickinfo);
+
+ if (activate_pump) {
+ ret = rb_regenerate_volfiles (volinfo, src_brickinfo, 1);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not regenerate volfiles with pump");
+ goto out;
+ }
+ } else {
+ ret = rb_regenerate_volfiles (volinfo, src_brickinfo, 0);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not regenerate volfiles without pump");
+ goto out;
+ }
+
+ }
+
+ sleep (2);
+ ret = glusterd_volume_start_glusterfs (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to start "
+ "glusterfs, ret: %d", ret);
+ goto out;
+ }
+
+out:
+ ret = glusterd_nfs_server_start ();
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to start nfs, ret: %d",
+ ret);
+ }
+ return ret;
+}
+
+static int
+rb_send_xattr_command (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo,
+ const char *xattr_key,
+ const char *value)
+{
+ glusterd_conf_t *priv = NULL;
+ char mount_point_path[PATH_MAX] = {0,};
+ struct stat buf;
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = stat (mount_point_path, &buf);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "stat failed. Could not send "
+ " %s command", xattr_key);
+ goto out;
+ }
+
+ ret = sys_lsetxattr (mount_point_path, xattr_key,
+ value,
+ strlen (value) + 1,
+ 0);
+
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "setxattr failed");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_spawn_dst_brick (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char cmd_str[8192] = {0,};
+ int ret = -1;
+ int32_t port = 0;
+
+ priv = THIS->private;
+
+ port = pmap_registry_alloc (THIS);
+ brickinfo->port = port;
+
+ GF_ASSERT (port);
+
+ snprintf (cmd_str, 8192,
+ "%s/sbin/glusterfs -f %s/vols/%s/%s -p %s/vols/%s/%s "
+ "--xlator-option src-server.listen-port=%d",
+ GFS_PREFIX, priv->workdir, volinfo->volname,
+ RB_DSTBRICKVOL_FILENAME,
+ priv->workdir, volinfo->volname,
+ RB_DSTBRICK_PIDFILE,
+ port);
+
+ ret = gf_system (cmd_str);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not start glusterfs");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Successfully started glusterfs: brick=%s:%s",
+ brickinfo->hostname, brickinfo->path);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_spawn_glusterfs_client (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char cmd_str[8192] = {0,};
+ struct stat buf;
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (cmd_str, 4096,
+ "%s/sbin/glusterfs -f %s/vols/%s/%s %s/vols/%s/%s",
+ GFS_PREFIX, priv->workdir, volinfo->volname,
+ RB_CLIENTVOL_FILENAME,
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = gf_system (cmd_str);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not start glusterfs");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Successfully started glusterfs: brick=%s:%s",
+ brickinfo->hostname, brickinfo->path);
+
+ memset (cmd_str, 0, sizeof (cmd_str));
+
+ snprintf (cmd_str, 4096, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = stat (cmd_str, &buf);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "stat on mountpoint failed");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "stat on mountpoint succeeded");
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static const char *client_volfile_str = "volume mnt-client\n"
+ " type protocol/client\n"
+ " option remote-host %s\n"
+ " option remote-subvolume %s\n"
+ " option remote-port %d\n"
+ "end-volume\n"
+ "volume mnt-wb\n"
+ " type performance/write-behind\n"
+ " subvolumes mnt-client\n"
+ "end-volume\n";
+
+static int
+rb_generate_client_volfile (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ FILE *file = NULL;
+ char filename[PATH_MAX];
+ int ret = -1;
+
+ priv = THIS->private;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Creating volfile");
+
+ snprintf (filename, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENTVOL_FILENAME);
+
+ file = fopen (filename, "w+");
+ if (!file) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Open of volfile failed");
+ ret = -1;
+ goto out;
+ }
+
+ GF_ASSERT (src_brickinfo->port);
+
+ fprintf (file, client_volfile_str, src_brickinfo->hostname,
+ src_brickinfo->path, src_brickinfo->port);
+
+ fclose (file);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static const char *dst_brick_volfile_str = "volume src-posix\n"
+ " type storage/posix\n"
+ " option directory %s\n"
+ "end-volume\n"
+ "volume %s\n"
+ " type features/locks\n"
+ " subvolumes src-posix\n"
+ "end-volume\n"
+ "volume src-server\n"
+ " type protocol/server\n"
+ " option auth.addr.%s.allow *\n"
+ " option transport-type tcp\n"
+ " subvolumes %s\n"
+ "end-volume\n";
+
+static int
+rb_generate_dst_brick_volfile (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ FILE *file = NULL;
+ char filename[PATH_MAX];
+ int ret = -1;
+
+ priv = THIS->private;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Creating volfile");
+
+ snprintf (filename, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_DSTBRICKVOL_FILENAME);
+
+ file = fopen (filename, "w+");
+ if (!file) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Open of volfile failed");
+ ret = -1;
+ goto out;
+ }
+
+ fprintf (file, dst_brick_volfile_str, dst_brickinfo->path,
+ dst_brickinfo->path, dst_brickinfo->path,
+ dst_brickinfo->path);
+
+ fclose (file);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_mountpoint_mkdir (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char mount_point_path[PATH_MAX] = {0,};
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = mkdir (mount_point_path, 0777);
+ if (ret && (errno != EEXIST)) {
+ gf_log ("", GF_LOG_DEBUG, "mkdir failed, errno: %d",
+ errno);
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_mountpoint_rmdir (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char mount_point_path[PATH_MAX] = {0,};
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = rmdir (mount_point_path);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "rmdir failed");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_destroy_maintenance_client (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char cmd_str[8192] = {0,};
+ char filename[PATH_MAX] = {0,};
+ struct stat buf;
+ char mount_point_path[PATH_MAX] = {0,};
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = stat (mount_point_path, &buf);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "stat failed. Cannot destroy maintenance "
+ "client");
+ goto out;
+ }
+
+ snprintf (cmd_str, 8192, "/bin/umount -f %s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = gf_system (cmd_str);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "umount failed on maintenance client");
+ goto out;
+ }
+
+ ret = rb_mountpoint_rmdir (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "rmdir of mountpoint failed");
+ goto out;
+ }
+
+ snprintf (filename, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENTVOL_FILENAME);
+
+ ret = unlink (filename);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "unlink failed");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_spawn_maintenance_client (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo)
+{
+ int ret = -1;
+
+ ret = rb_generate_client_volfile (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to generate client "
+ "volfile");
+ goto out;
+ }
+
+ ret = rb_mountpoint_mkdir (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to mkdir "
+ "mountpoint");
+ goto out;
+ }
+
+ ret = rb_spawn_glusterfs_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static int
+rb_spawn_destination_brick (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+
+{
+ int ret = -1;
+
+ ret = rb_generate_dst_brick_volfile (volinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to generate client "
+ "volfile");
+ goto out;
+ }
+
+ ret = rb_spawn_dst_brick (volinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static int
+rb_do_operation_start (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ char start_value[8192] = {0,};
+ int ret = -1;
+
+
+ gf_log ("", GF_LOG_DEBUG,
+ "replace-brick sending start xattr");
+
+ ret = rb_spawn_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not spawn maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "mounted the replace brick client");
+
+ snprintf (start_value, 8192, "%s:%s:%d",
+ dst_brickinfo->hostname,
+ dst_brickinfo->path,
+ dst_brickinfo->port);
+
+
+ ret = rb_send_xattr_command (volinfo, src_brickinfo,
+ dst_brickinfo, RB_PUMP_START_CMD,
+ start_value);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to send command to pump");
+ }
+
+ ret = rb_destroy_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to destroy maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "unmounted the replace brick client");
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_do_operation_pause (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ int ret = -1;
+
+ gf_log ("", GF_LOG_INFO,
+ "replace-brick send pause xattr");
+
+ ret = rb_spawn_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not spawn maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "mounted the replace brick client");
+
+ ret = rb_send_xattr_command (volinfo, src_brickinfo,
+ dst_brickinfo, RB_PUMP_PAUSE_CMD,
+ "jargon");
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to send command to pump");
+
+ }
+
+ ret = rb_destroy_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to destroy maintenance "
+ "client");
+ goto out;
+ }
+
+
+ gf_log ("", GF_LOG_DEBUG,
+ "unmounted the replace brick client");
+
+ ret = 0;
+
+out:
+ if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
+ ret = rb_src_brick_restart (volinfo, src_brickinfo,
+ 0);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not restart src-brick");
+ }
+ }
+ return ret;
+}
+
+static int
+rb_kill_destination_brick (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ glusterd_conf_t *priv = NULL;
+ char pidfile[PATH_MAX] = {0,};
+
+ priv = THIS->private;
+
+ snprintf (pidfile, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_DSTBRICK_PIDFILE);
+
+ return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_true);
+}
+
+static int
+rb_do_operation_abort (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ int ret = -1;
+
+ gf_log ("", GF_LOG_DEBUG,
+ "replace-brick sending abort xattr");
+
+ ret = rb_spawn_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not spawn maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "mounted the replace brick client");
+
+ ret = rb_send_xattr_command (volinfo, src_brickinfo,
+ dst_brickinfo, RB_PUMP_ABORT_CMD,
+ "jargon");
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to send command to pump");
+ }
+
+ ret = rb_destroy_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to destroy maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "unmounted the replace brick client");
+
+ ret = 0;
+
+out:
+ if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
+ ret = rb_src_brick_restart (volinfo, src_brickinfo,
+ 0);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not restart src-brick");
+ }
+ }
+ return ret;
+}
+
+
+static int
+rb_get_xattr_command (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo,
+ const char *xattr_key,
+ char *value)
+{
+ glusterd_conf_t *priv = NULL;
+ char mount_point_path[PATH_MAX] = {0,};
+ struct stat buf;
+ int ret = -1;
+
+ priv = THIS->private;
+
+ snprintf (mount_point_path, PATH_MAX, "%s/vols/%s/%s",
+ priv->workdir, volinfo->volname,
+ RB_CLIENT_MOUNTPOINT);
+
+ ret = stat (mount_point_path, &buf);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "stat failed. Could not send "
+ " %s command", xattr_key);
+ goto out;
+ }
+
+ ret = lgetxattr (mount_point_path, xattr_key,
+ value,
+ 8192);
+
+ if (ret < 0) {
+ gf_log ("", GF_LOG_DEBUG,
+ "getxattr failed");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+rb_do_operation_status (glusterd_volinfo_t *volinfo,
+ glusterd_brickinfo_t *src_brickinfo,
+ glusterd_brickinfo_t *dst_brickinfo)
+{
+ char status[2048] = {0,};
+ char *status_reply = NULL;
+ dict_t *ctx = NULL;
+ int ret = 0;
+ gf_boolean_t origin = _gf_false;
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (!ctx) {
+ gf_log ("", GF_LOG_ERROR,
+ "Operation Context is not present");
+ goto out;
+ }
+
+ origin = _gf_true;
+
+ if (origin) {
+ ret = rb_spawn_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not spawn maintenance "
+ "client");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "mounted the replace brick client");
+
+ ret = rb_get_xattr_command (volinfo, src_brickinfo,
+ dst_brickinfo, RB_PUMP_STATUS_CMD,
+ status);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to get status from pump");
+ goto umount;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "pump status is %s", status);
+
+ status_reply = gf_strdup (status);
+ if (!status_reply) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ ret = -1;
+ goto umount;
+ }
+
+ ret = dict_set_dynstr (ctx, "status-reply",
+ status_reply);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "failed to set pump status in ctx");
+
+ }
+
+ umount:
+ ret = rb_destroy_maintenance_client (volinfo, src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to destroy maintenance "
+ "client");
+ goto out;
+ }
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "unmounted the replace brick client");
+out:
+ return ret;
+}
+
+/* Set src-brick's port number to be used in the maintainance mount
+ * after all commit acks are received.
+ */
+static int
+rb_update_srcbrick_port (glusterd_brickinfo_t *src_brickinfo, dict_t *rsp_dict,
+ dict_t *req_dict, int32_t replace_op)
+{
+ xlator_t *this = NULL;
+ dict_t *ctx = NULL;
+ int ret = 0;
+ int dict_ret = 0;
+ int src_port = 0;
+
+ this = THIS;
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ dict_ret = dict_get_int32 (req_dict, "src-brick-port", &src_port);
+ if (src_port)
+ src_brickinfo->port = src_port;
+ }
+
+ if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_INFO,
+ "adding src-brick port no");
+
+ src_brickinfo->port = pmap_registry_search (this,
+ src_brickinfo->path, GF_PMAP_PORT_BRICKSERVER);
+ if (!src_brickinfo->port &&
+ replace_op != GF_REPLACE_OP_COMMIT_FORCE ) {
+ gf_log ("", GF_LOG_ERROR,
+ "Src brick port not available");
+ ret = -1;
+ goto out;
+ }
+
+ if (rsp_dict) {
+ ret = dict_set_int32 (rsp_dict, "src-brick-port", src_brickinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not set src-brick port no");
+ goto out;
+ }
+ }
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ ret = dict_set_int32 (ctx, "src-brick-port", src_brickinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not set src-brick port no");
+ goto out;
+ }
+ }
+
+ }
+
+out:
+ return ret;
+
+}
+
+static int
+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
+ dict_t *req_dict, int32_t replace_op)
+{
+ dict_t *ctx = NULL;
+ int ret = 0;
+ int dict_ret = 0;
+ int dst_port = 0;
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
+ if (dst_port)
+ dst_brickinfo->port = dst_port;
+
+ }
+
+ if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_INFO,
+ "adding dst-brick port no");
+
+ if (rsp_dict) {
+ ret = dict_set_int32 (rsp_dict, "dst-brick-port",
+ dst_brickinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not set dst-brick port no in rsp dict");
+ goto out;
+ }
+ }
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ ret = dict_set_int32 (ctx, "dst-brick-port",
+ dst_brickinfo->port);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not set dst-brick port no");
+ goto out;
+ }
+ }
+ }
+out:
+ return ret;
+}
+
+
+
+static int
+glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
+{
+ int ret = 0;
+ dict_t *ctx = NULL;
+ int replace_op = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ glusterd_brickinfo_t *src_brickinfo = NULL;
+ glusterd_brickinfo_t *dst_brickinfo = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "src-brick", &src_brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "src brick=%s", src_brick);
+
+ ret = dict_get_str (dict, "dst-brick", &dst_brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get dst brick");
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "dst brick=%s", dst_brick);
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
+ if (ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "dict_get on operation failed");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo, &src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");
+ goto out;
+ }
+
+
+ ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get "
+ "replace brick destination brickinfo");
+ goto out;
+ }
+
+ ret = glusterd_resolve_brick (dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to resolve dst-brickinfo");
+ goto out;
+ }
+
+ ret = rb_update_srcbrick_port (src_brickinfo, rsp_dict,
+ dict, replace_op);
+ if (ret)
+ goto out;
+
+ if ((GF_REPLACE_OP_START != replace_op)) {
+ ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
+ dict, replace_op);
+ if (ret)
+ goto out;
+ }
+
+ switch (replace_op) {
+ case GF_REPLACE_OP_START:
+ {
+ if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_INFO,
+ "I AM THE DESTINATION HOST");
+ if (!glusterd_is_rb_paused (volinfo)) {
+ ret = rb_spawn_destination_brick (volinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to spawn destination brick");
+ goto out;
+ }
+ } else {
+ gf_log ("", GF_LOG_ERROR, "Replace brick is already "
+ "started=> no need to restart dst brick ");
+ }
+ }
+
+
+ if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
+ ret = rb_src_brick_restart (volinfo, src_brickinfo,
+ 1);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Could not restart src-brick");
+ goto out;
+ }
+ }
+
+ if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_INFO,
+ "adding dst-brick port no");
+
+ ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
+ dict, replace_op);
+ if (ret)
+ goto out;
+ }
+
+ glusterd_set_rb_status (volinfo, GF_RB_STATUS_STARTED);
+ break;
+ }
+
+ case GF_REPLACE_OP_COMMIT:
+ case GF_REPLACE_OP_COMMIT_FORCE:
+ {
+ ret = dict_set_int32 (volinfo->dict, "enable-pump", 0);
+ gf_log ("", GF_LOG_DEBUG,
+ "Received commit - will be adding dst brick and "
+ "removing src brick");
+
+ if (!glusterd_is_local_addr (dst_brickinfo->hostname) &&
+ replace_op != GF_REPLACE_OP_COMMIT_FORCE) {
+ gf_log ("", GF_LOG_INFO,
+ "I AM THE DESTINATION HOST");
+ ret = rb_kill_destination_brick (volinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to kill destination brick");
+ goto out;
+ }
+ }
+
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "Unable to cleanup dst brick");
+ goto out;
+ }
+
+
+ ret = glusterd_nfs_server_stop ();
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Unable to stop nfs server, ret: %d", ret);
+ }
+
+ ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
+ dst_brick);
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL, "Unable to add "
+ "dst-brick: %s to volume: %s",
+ dst_brick, volinfo->volname);
+ (void) glusterd_check_generate_start_nfs ();
+ goto out;
+ }
+
+ volinfo->defrag_status = 0;
+
+ ret = glusterd_check_generate_start_nfs ();
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL,
+ "Failed to generate nfs volume file");
+ }
+
+ ret = glusterd_store_volinfo (volinfo,
+ GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+
+ if (ret)
+ goto out;
+
+ ret = glusterd_fetchspec_notify (THIS);
+ glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE);
+ glusterd_brickinfo_delete (volinfo->dst_brick);
+ volinfo->src_brick = volinfo->dst_brick = NULL;
+ }
+ break;
+
+ case GF_REPLACE_OP_PAUSE:
+ {
+ gf_log ("", GF_LOG_DEBUG,
+ "Received pause - doing nothing");
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ ret = rb_do_operation_pause (volinfo, src_brickinfo,
+ dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Pause operation failed");
+ goto out;
+ }
+ }
+
+ glusterd_set_rb_status (volinfo, GF_RB_STATUS_PAUSED);
+ }
+ break;
+
+ case GF_REPLACE_OP_ABORT:
+ {
+
+ ret = dict_set_int32 (volinfo->dict, "enable-pump", 0);
+ if (ret) {
+ gf_log ("", GF_LOG_CRITICAL, "Unable to disable pump");
+ }
+
+ if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
+ gf_log ("", GF_LOG_INFO,
+ "I AM THE DESTINATION HOST");
+ ret = rb_kill_destination_brick (volinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "Failed to kill destination brick");
+ goto out;
+ }
+ }
+
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ ret = rb_do_operation_abort (volinfo, src_brickinfo, dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "Abort operation failed");
+ goto out;
+ }
+ }
+ glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE);
+ glusterd_brickinfo_delete (volinfo->dst_brick);
+ volinfo->src_brick = volinfo->dst_brick = NULL;
+ }
+ break;
+
+ case GF_REPLACE_OP_STATUS:
+ {
+ gf_log ("", GF_LOG_DEBUG,
+ "received status - doing nothing");
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (ctx) {
+ ret = rb_do_operation_status (volinfo, src_brickinfo,
+ dst_brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ }
+ break;
+
+ default:
+ ret = -1;
+ goto out;
+ }
+
+ if (ret)
+ goto out;
+
+out:
+ return ret;
+}
+
+void
_delete_reconfig_opt (dict_t *this, char *key, data_t *value, void *data)
{
- int32_t *is_force = 0;
+ int exists = 0;
+ int32_t is_force = 0;
GF_ASSERT (data);
- is_force = (int32_t*)data;
+ is_force = *((int32_t*)data);
+ exists = glusterd_check_option_exists(key, NULL);
+
+ if (exists != 1)
+ goto out;
- if (*is_force != 1 &&
+ if ((!is_force) &&
(_gf_true == glusterd_check_voloption_flags (key,
- OPT_FLAG_FORCE))) {
- /* indicate to caller that we don't set the option
- * due to being protected
- */
- *is_force = -1;
+ OPT_FLAG_FORCE)))
goto out;
- }
gf_log ("", GF_LOG_DEBUG, "deleting dict with key=%s,value=%s",
key, value->data);
@@ -886,37 +3948,16 @@ out:
return;
}
-static int
-glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
- int32_t *is_force)
+int
+glusterd_options_reset (glusterd_volinfo_t *volinfo, int32_t is_force)
{
int ret = 0;
- data_t *value = NULL;
- char *key_fixed = NULL;
gf_log ("", GF_LOG_DEBUG, "Received volume set reset command");
GF_ASSERT (volinfo->dict);
- GF_ASSERT (key);
- if (!strncmp(key, "all", 3))
- dict_foreach (volinfo->dict, _delete_reconfig_opt, is_force);
- else {
- if (glusterd_check_option_exists (key, &key_fixed) != 1) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "volinfo dict inconsistency: option %s not found",
- key);
- ret = -1;
- goto out;
- }
- value = dict_get (volinfo->dict, key_fixed);
- if (!value) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "no value set for option %s", key_fixed);
- goto out;
- }
- _delete_reconfig_opt (volinfo->dict, key_fixed, value, is_force);
- }
+ dict_foreach (volinfo->dict, _delete_reconfig_opt, &is_force);
ret = glusterd_create_volfiles_and_notify_services (volinfo);
@@ -931,29 +3972,26 @@ glusterd_options_reset (glusterd_volinfo_t *volinfo, char *key,
if (ret)
goto out;
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_nodesvcs_handle_reconfigure (volinfo);
- if (ret)
- goto out;
- }
+ if (GLUSTERD_STATUS_STARTED == volinfo->status)
+ ret = glusterd_check_generate_start_nfs ();
+ if (ret)
+ goto out;
ret = 0;
out:
- GF_FREE (key_fixed);
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
static int
-glusterd_op_reset_volume (dict_t *dict, char **op_errstr)
+glusterd_op_reset_volume (dict_t *dict)
{
- glusterd_volinfo_t *volinfo = NULL;
- int ret = -1;
- char *volname = NULL;
- char *key = NULL;
- int32_t is_force = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = -1;
+ char *volname = NULL;
+ int32_t is_force = 0;
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
@@ -965,33 +4003,1287 @@ glusterd_op_reset_volume (dict_t *dict, char **op_errstr)
if (ret)
is_force = 0;
- ret = dict_get_str (dict, "key", &key);
+ ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to get option key");
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
goto out;
}
- ret = glusterd_volinfo_find (volname, &volinfo);
+ ret = glusterd_options_reset (volinfo, is_force);
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "'volume reset' returning %d", ret);
+ return ret;
+
+}
+
+int
+stop_gsync (char *master, char *slave, char **op_errstr)
+{
+ int32_t ret = 0;
+ int pfd = -1;
+ pid_t pid = 0;
+ char pidfile[PATH_MAX] = {0,};
+ char buf [1024] = {0,};
+ int i = 0;
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ pfd = gsyncd_getpidfile (master, slave, pidfile);
+ if (pfd == -2) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" stop validation "
+ " failed");
+ if (op_errstr)
+ *op_errstr = gf_strdup (GEOREP" stop internal error");
+ ret = -1;
+ goto out;
+ }
+ if (gsync_status_byfd (pfd) == -1) {
+ ret = -1;
+ gf_log ("", GF_LOG_WARNING, "gsyncd is not running");
+ if (op_errstr)
+ *op_errstr = gf_strdup ("warning: "GEOREP" session is"
+ "not running");
+ goto out;
+ }
+
+ ret = read (pfd, buf, 1024);
+ if (ret > 0) {
+ pid = strtol (buf, NULL, 10);
+ ret = kill (-pid, SIGTERM);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to kill gsyncd");
+ goto out;
+ }
+ for (i = 0; i < 20; i++) {
+ if (gsync_status_byfd (pfd) == -1) {
+ /* monitor gsyncd is dead but worker may
+ * still be alive, give some more time
+ * before SIGKILL (hack)
+ */
+ usleep (50000);
+ break;
+ }
+ usleep (50000);
+ }
+ kill (-pid, SIGKILL);
+ unlink (pidfile);
+ }
+ ret = 0;
+
+out:
+ close (pfd);
+ return ret;
+}
+
+int
+glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave);
+
+int
+glusterd_gsync_configure (glusterd_volinfo_t *volinfo, char *slave,
+ dict_t *dict, char **op_errstr)
+{
+ int32_t ret = -1;
+ char *op_name = NULL;
+ char *op_value = NULL;
+ char cmd[1024] = {0,};
+ glusterd_conf_t *priv = NULL;
+ char *subop = NULL;
+ char *q1 = NULL;
+ char *q2 = NULL;
+ char *cm = NULL;
+ char *master = NULL;
+
+ GF_ASSERT (slave);
+ GF_ASSERT (op_errstr);
+
+ ret = dict_get_str (dict, "subop", &subop);
+ if (ret != 0)
+ goto out;
+
+ if (strcmp (subop, "get") == 0 || strcmp (subop, "get-all") == 0) {
+ /* deferred to cli */
+ gf_log ("", GF_LOG_DEBUG, "Returning 0");
+ return 0;
+ }
+
+ ret = dict_get_str (dict, "op_name", &op_name);
+ if (ret != 0)
+ goto out;
+
+ if (strcmp (subop, "set") == 0) {
+ ret = dict_get_str (dict, "op_value", &op_value);
+ if (ret != 0)
+ goto out;
+ q1 = " \"";
+ q2 = "\"";
+ } else {
+ q1 = "";
+ op_value = "";
+ q2 = "";
+ }
+
+ if (THIS)
+ priv = THIS->private;
+ if (priv == NULL) {
+ gf_log ("", GF_LOG_ERROR, "priv of glusterd not present");
+ *op_errstr = gf_strdup ("glusterd defunct");
+ goto out;
+ }
+
+ if (volinfo) {
+ cm = ":";
+ master = volinfo->volname;
+ } else {
+ cm = "";
+ master = "";
+ }
+
+ ret = snprintf (cmd, 1024, GSYNCD_PREFIX"/gsyncd -c %s/"GSYNC_CONF" %s%s %s"
+ " --config-%s %s" "%s%s%s", priv->workdir,
+ cm, master, slave, subop, op_name,
+ q1, op_value, q2);
+ ret = system (cmd);
if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ gf_log ("", GF_LOG_WARNING, "gsyncd failed to "
+ "%s %s option for %s %s peers",
+ subop, op_name, master, slave);
+
+ gf_asprintf (op_errstr, GEOREP" config-%s failed for %s %s",
+ subop, master, slave);
+
goto out;
}
+ ret = 0;
+ gf_asprintf (op_errstr, "config-%s successful", subop);
- ret = glusterd_options_reset (volinfo, key, &is_force);
- if (is_force == -1) {
+out:
+ if (!ret && volinfo) {
+ ret = glusterd_check_restart_gsync_session (volinfo, slave);
+ if (ret)
+ *op_errstr = gf_strdup ("internal error");
+ }
+
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_gsync_read_frm_status (char *path, char *data)
+{
+ int ret = 0;
+ FILE *status_file = NULL;
+
+ GF_ASSERT (path);
+ GF_ASSERT (data);
+ status_file = fopen (path, "r");
+ if (status_file == NULL) {
+ gf_log ("", GF_LOG_WARNING, "Unable to read gsyncd status"
+ " file");
+ return -1;
+ }
+ ret = fread (data, PATH_MAX, 1, status_file);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_WARNING, "Status file of gsyncd is corrupt");
+ return -1;
+ }
+
+ data[strlen(data)-1] = '\0';
+
+ return 0;
+}
+
+int
+glusterd_read_status_file (char *master, char *slave,
+ dict_t *dict)
+{
+ glusterd_conf_t *priv = NULL;
+ int ret = 0;
+ char statusfile[PATH_MAX] = {0, };
+ char buff[PATH_MAX] = {0, };
+ char mst[PATH_MAX] = {0, };
+ char slv[PATH_MAX] = {0, };
+ char sts[PATH_MAX] = {0, };
+ int gsync_count = 0;
+ int status = 0;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+ ret = glusterd_gsync_get_param_file (statusfile, "state", master,
+ slave, priv->workdir);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "Unable to get the name of status"
+ "file for %s(master), %s(slave)", master, slave);
+ goto out;
+
+ }
+
+ ret = gsync_status (master, slave, &status);
+ if (ret == 0 && status == -1) {
+ strncpy (buff, "corrupt", sizeof (buff));
+ goto done;
+ } else if (ret == -1)
+ goto out;
+
+ ret = glusterd_gsync_read_frm_status (statusfile, buff);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "Unable to read the status"
+ "file for %s(master), %s(slave)", master, slave);
+ goto out;
+
+ }
+
+ done:
+ ret = dict_get_int32 (dict, "gsync-count", &gsync_count);
+
+ if (ret)
+ gsync_count = 1;
+ else
+ gsync_count++;
+
+ snprintf (mst, sizeof (mst), "master%d", gsync_count);
+ ret = dict_set_dynstr (dict, mst, gf_strdup (master));
+ if (ret)
+ goto out;
+
+ snprintf (slv, sizeof (slv), "slave%d", gsync_count);
+ ret = dict_set_dynstr (dict, slv, gf_strdup (slave));
+ if (ret)
+ goto out;
+
+ snprintf (sts, sizeof (slv), "status%d", gsync_count);
+ ret = dict_set_dynstr (dict, sts, gf_strdup (buff));
+ if (ret)
+ goto out;
+ ret = dict_set_int32 (dict, "gsync-count", gsync_count);
+ if (ret)
+ goto out;
+
+ ret = 0;
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d ", ret);
+ return ret;
+}
+
+int
+glusterd_check_restart_gsync_session (glusterd_volinfo_t *volinfo, char *slave)
+{
+
+ int ret = 0;
+ uuid_t uuid = {0, };
+ glusterd_conf_t *priv = NULL;
+ gf_boolean_t is_running = _gf_false;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ if (glusterd_gsync_get_uuid (slave, volinfo, uuid))
+ /* session does not exist, nothing to do */
+ goto out;
+ if (uuid_compare (priv->uuid, uuid) == 0) {
+ ret = glusterd_check_gsync_running_local (volinfo->volname,
+ slave, &is_running);
+ if (ret)
+ goto out;
+
+ if (_gf_true == is_running) {
+ ret = stop_gsync (volinfo->volname, slave, NULL);
+ gf_log ("", GF_LOG_INFO, GEOREP " not running,"
+ " retart the process");
+ }
+
+ ret = glusterd_start_gsync (volinfo->volname, slave,
+ uuid_utoa(priv->uuid), NULL);
+ if (ret)
+ goto out;
+ }
+
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_marker_create_volfile (glusterd_volinfo_t *volinfo)
+{
+ int32_t ret = 0;
+
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to create volfile"
+ " for setting of marker while '"GEOREP" start'");
ret = -1;
- gf_asprintf(op_errstr, "'%s' is protected. To reset use 'force'.",
- key);
+ goto out;
}
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status)
+ ret = glusterd_check_generate_start_nfs ();
+ ret = 0;
out:
- gf_log ("", GF_LOG_DEBUG, "'volume reset' returning %d", ret);
return ret;
+}
+
+int
+glusterd_set_marker_gsync (glusterd_volinfo_t *volinfo)
+{
+ int ret = -1;
+ int marker_set = _gf_false;
+ char *gsync_status = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ marker_set = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME);
+ if (marker_set == -1) {
+ gf_log ("", GF_LOG_ERROR, "failed to get the marker status");
+ ret = -1;
+ goto out;
+ }
+
+ if (marker_set == _gf_false) {
+ gsync_status = gf_strdup ("on");
+ if (gsync_status == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_gsync_volinfo_dict_set (volinfo,
+ VKEY_MARKER_XTIME, gsync_status);
+ if (ret < 0)
+ goto out;
+
+ ret = glusterd_marker_create_volfile (volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Setting dict failed");
+ goto out;
+ }
+ }
+ ret = 0;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+
+
+
+int
+glusterd_get_gsync_status_mst_slv( glusterd_volinfo_t *volinfo,
+ char *slave, dict_t *rsp_dict)
+{
+ uuid_t uuid = {0, };
+ glusterd_conf_t *priv = NULL;
+ int ret = 0;
+
+ GF_ASSERT (volinfo);
+ GF_ASSERT (slave);
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+
+ priv = THIS->private;
+
+ ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
+ if ((ret == 0) && (uuid_compare (priv->uuid, uuid) != 0))
+ goto out;
+
+ if (ret) {
+ ret = 0;
+ gf_log ("", GF_LOG_INFO, "geo-replication status %s %s :"
+ "session is not active", volinfo->volname, slave);
+ goto out;
+ }
+
+ ret = glusterd_read_status_file (volinfo->volname, slave, rsp_dict);
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+}
+
+static int
+glusterd_get_gsync_status_mst (glusterd_volinfo_t *volinfo, dict_t *rsp_dict)
+{
+ glusterd_gsync_status_temp_t param = {0, };
+
+ GF_ASSERT (volinfo);
+
+ param.rsp_dict = rsp_dict;
+ param.volinfo = volinfo;
+ dict_foreach (volinfo->gsync_slaves, _get_status_mst_slv, &param);
+
+ return 0;
+}
+
+static int
+glusterd_get_gsync_status_all ( dict_t *rsp_dict)
+{
+
+ int32_t ret = 0;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+
+ GF_ASSERT (THIS);
+ priv = THIS->private;
+
+ GF_ASSERT (priv);
+
+ list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+ ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict);
+ if (ret)
+ goto out;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
+ return ret;
+
+}
+
+static int
+glusterd_get_gsync_status (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+{
+ char *slave = NULL;
+ char *volname = NULL;
+ char errmsg[PATH_MAX] = {0, };
+ gf_boolean_t exists = _gf_false;
+ glusterd_volinfo_t *volinfo = NULL;
+ int ret = 0;
+
+
+ ret = dict_get_str (dict, "master", &volname);
+ if (ret < 0){
+ ret = glusterd_get_gsync_status_all (rsp_dict);
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if ((ret) || (!exists)) {
+ gf_log ("", GF_LOG_WARNING, "volume name does not exist");
+ snprintf (errmsg, sizeof(errmsg), "Volume name %s does not"
+ " exist", volname);
+ *op_errstr = gf_strdup (errmsg);
+ ret = -1;
+ goto out;
+ }
+
+
+ ret = dict_get_str (dict, "slave", &slave);
+ if (ret < 0) {
+ ret = glusterd_get_gsync_status_mst (volinfo, rsp_dict);
+ goto out;
+ }
+
+ ret = glusterd_get_gsync_status_mst_slv (volinfo, slave, rsp_dict);
+
+ out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+
}
int
+glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+{
+ int32_t ret = -1;
+ int32_t type = -1;
+ dict_t *ctx = NULL;
+ dict_t *resp_dict = NULL;
+ char *host_uuid = NULL;
+ char *slave = NULL;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ uuid_t uuid = {0, };
+
+ GF_ASSERT (THIS);
+ GF_ASSERT (THIS->private);
+ GF_ASSERT (dict);
+ GF_ASSERT (op_errstr);
+
+ priv = THIS->private;
+
+ ret = dict_get_int32 (dict, "type", &type);
+ if (ret < 0)
+ goto out;
+
+ ret = dict_get_str (dict, "host-uuid", &host_uuid);
+ if (ret < 0)
+ goto out;
+
+ if (type == GF_GSYNC_OPTION_TYPE_STATUS) {
+ ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET);
+ resp_dict = ctx ? ctx : rsp_dict;
+
+ ret = glusterd_get_gsync_status (dict, op_errstr, resp_dict);
+ goto out;
+
+ }
+
+ ret = dict_get_str (dict, "slave", &slave);
+ if (ret < 0)
+ goto out;
+
+ if (dict_get_str (dict, "master", &volname) == 0) {
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "Volinfo for %s (master) not found",
+ volname);
+ goto out;
+ }
+ }
+
+ if (type == GF_GSYNC_OPTION_TYPE_CONFIG) {
+ ret = glusterd_gsync_configure (volinfo, slave, dict,
+ op_errstr);
+ goto out;
+ }
+
+ if (!volinfo) {
+ ret = -1;
+ goto out;
+ }
+
+ if (type == GF_GSYNC_OPTION_TYPE_START) {
+
+ ret = glusterd_set_marker_gsync (volinfo);
+ if (ret != 0) {
+ gf_log ("", GF_LOG_WARNING, "marker start failed");
+ *op_errstr = gf_strdup ("failed to initialize indexing");
+ ret = -1;
+ goto out;
+ }
+ ret = glusterd_store_slave_in_info(volinfo, slave,
+ host_uuid, op_errstr);
+ if (ret)
+ goto out;
+
+ ret = glusterd_start_gsync (volname, slave, host_uuid,
+ op_errstr);
+ }
+
+ if (type == GF_GSYNC_OPTION_TYPE_STOP) {
+
+ ret = glusterd_gsync_get_uuid (slave, volinfo, uuid);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, GEOREP" is not set up for"
+ "%s(master) and %s(slave)", volname, slave);
+ *op_errstr = strdup (GEOREP" is not set up");
+ goto out;
+ }
+
+ ret = glusterd_remove_slave_in_info(volinfo, slave,
+ host_uuid, op_errstr);
+ if (ret)
+ goto out;
+
+ if (uuid_compare (priv->uuid, uuid) != 0) {
+ goto out;
+ }
+
+ ret = stop_gsync (volname, slave, op_errstr);
+ if (ret)
+ goto out;
+
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG,"Returning %d", ret);
+ return ret;
+}
+
+int32_t
+glusterd_check_if_quota_trans_enabled (glusterd_volinfo_t *volinfo)
+{
+ int32_t ret = 0;
+ int flag = _gf_false;
+
+ flag = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA);
+ if (flag == -1) {
+ gf_log ("", GF_LOG_ERROR, "failed to get the quota status");
+ ret = -1;
+ goto out;
+ }
+
+ if (flag == _gf_false) {
+ gf_log ("", GF_LOG_ERROR, "first enable the quota translator");
+ ret = -1;
+ goto out;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+_glusterd_quota_remove_limits (char **quota_limits, char *path)
+{
+ int ret = 0;
+ int i = 0;
+ int size = 0;
+ int len = 0;
+ int pathlen = 0;
+ int skiplen = 0;
+ int flag = 0;
+ char *limits = NULL;
+ char *qlimits = NULL;
+
+ if (*quota_limits == NULL)
+ return -1;
+
+ qlimits = *quota_limits;
+
+ pathlen = strlen (path);
+
+ len = strlen (qlimits);
+
+ limits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char);
+
+ if (!limits)
+ return -1;
+
+ while (i < len) {
+ if (!memcmp ((void *) &qlimits [i], (void *)path, pathlen))
+ if (qlimits [i + pathlen] == ':')
+ flag = 1;
+
+ while (qlimits [i + size] != ',' &&
+ qlimits [i + size] != '\0')
+ size++;
+
+ if (!flag) {
+ memcpy ((void *) &limits [i], (void *) &qlimits [i], size + 1);
+ } else {
+ skiplen = size + 1;
+ size = len - i - size;
+ memcpy ((void *) &limits [i], (void *) &qlimits [i + skiplen], size);
+ break;
+ }
+
+ i += size + 1;
+ size = 0;
+ }
+
+ if (!flag) {
+ ret = 1;
+ } else {
+ len = strlen (limits);
+
+ if (len == 0) {
+ GF_FREE (qlimits);
+
+ *quota_limits = NULL;
+
+ goto out;
+ }
+
+ if (limits[len - 1] == ',') {
+ limits[len - 1] = '\0';
+ len --;
+ }
+
+ GF_FREE (qlimits);
+
+ qlimits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char);
+
+ if (!qlimits) {
+ ret = -1;
+ goto out;
+ }
+
+ memcpy ((void *) qlimits, (void *) limits, len + 1);
+
+ *quota_limits = qlimits;
+
+ ret = 0;
+ }
+
+out:
+ if (limits)
+ GF_FREE (limits);
+
+ return ret;
+}
+
+
+static void *
+glusterd_quota_child_waitpid (void *arg)
+{
+ char cmd [PATH_MAX] = {0,};
+ glusterd_quota_child_info_t *child_info = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", arg, out);
+
+ child_info = (glusterd_quota_child_info_t *)arg;
+
+#ifdef GF_LINUX_HOST_OS
+ usleep (200000);
+ snprintf (cmd, sizeof (cmd), "umount -l %s",
+ child_info->mountdir);
+ system (cmd);
+
+ waitpid (child_info->pid, NULL, 0);
+#else
+ waitpid (child_info->pid, NULL, 0);
+ snprintf (cmd, sizeof (cmd), "umount %s",
+ child_info->mountdir);
+ system (cmd);
+#endif
+ rmdir (child_info->mountdir);
+
+ GF_FREE (child_info);
+
+out:
+ return NULL;
+}
+
+int32_t
+glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname)
+{
+ int32_t ret = 0;
+ pthread_t th;
+ pid_t pid;
+ int32_t idx = 0;
+ char mountdir [] = "/tmp/mntXXXXXX";
+ char cmd_str [PATH_MAX + 1024] = {0, };
+ glusterd_quota_child_info_t *child_info = NULL;
+
+ if (mkdtemp (mountdir) == NULL) {
+ gf_log ("glusterd", GF_LOG_DEBUG,
+ "failed to create a temporary mount directory");
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (cmd_str, sizeof (cmd_str), "%s/sbin/glusterfs -s localhost "
+ "--volfile-id %s %s", GFS_PREFIX, volname, mountdir);
+
+ ret = gf_system (cmd_str);
+ if (ret == -1) {
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
+ goto out;
+ }
+
+ if ((pid = fork ()) < 0) {
+ gf_log ("glusterd", GF_LOG_WARNING, "fork from parent failed");
+ ret = -1;
+ goto err;
+ } else if (pid == 0) {//first child
+ ret = chdir (mountdir);
+ if (ret == -1) {
+ gf_log ("glusterd", GF_LOG_WARNING, "chdir %s failed, "
+ "reason: %s", mountdir, strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+
+ /* close all fd's */
+ for (idx = 3; idx < 65536; idx++) {
+ close (idx);
+ }
+
+ execl ("/usr/bin/find", "find", ".", (char *) 0);
+ _exit (0);
+ } else {
+ ret = -1;
+
+ child_info = GF_MALLOC (sizeof (glusterd_quota_child_info_t),
+ gf_common_mt_char);
+ if (child_info == NULL)
+ goto err;
+
+ strcpy (child_info->mountdir, mountdir);
+
+ child_info->pid = pid;
+ pthread_create (&th, NULL, glusterd_quota_child_waitpid, child_info);
+
+ ret = 0;
+
+ goto out;
+ }
+err:
+ if (ret < 0) {
+ umount (mountdir);
+ if (child_info)
+ GF_FREE (child_info);
+ }
+
+out:
+ return ret;
+}
+
+char *
+glusterd_quota_get_limit_value (char *quota_limits, char *path)
+{
+ int32_t i, j, k, l, len;
+ int32_t pat_len, diff;
+ char *ret_str = NULL;
+
+ len = strlen (quota_limits);
+ pat_len = strlen (path);
+ i = 0;
+ j = 0;
+
+ while (i < len) {
+ j = i;
+ k = 0;
+ while (path [k] == quota_limits [j]) {
+ j++;
+ k++;
+ }
+
+ l = j;
+
+ while (quota_limits [j] != ',' &&
+ quota_limits [j] != '\0')
+ j++;
+
+ if (quota_limits [l] == ':' && pat_len == (l - i)) {
+ diff = j - i;
+ ret_str = GF_CALLOC (diff + 1, sizeof (char),
+ gf_gld_mt_char);
+
+ strncpy (ret_str, &quota_limits [i], diff);
+
+ break;
+ }
+ i = ++j; //skip ','
+ }
+
+ return ret_str;
+}
+
+char*
+_glusterd_quota_get_limit_usages (glusterd_volinfo_t *volinfo,
+ char *path, char **op_errstr)
+{
+ int32_t ret = 0;
+ char *quota_limits = NULL;
+ char *ret_str = NULL;
+
+ if (volinfo == NULL)
+ return NULL;
+
+ ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
+ &quota_limits);
+ if (ret)
+ return NULL;
+ if (quota_limits == NULL) {
+ ret_str = NULL;
+ *op_errstr = gf_strdup ("Limits not set any directory");
+ } else if (path == NULL)
+ ret_str = gf_strdup (quota_limits);
+ else
+ ret_str = glusterd_quota_get_limit_value (quota_limits, path);
+
+ return ret_str;
+}
+
+int32_t
+glusterd_quota_get_limit_usages (glusterd_conf_t *priv,
+ glusterd_volinfo_t *volinfo,
+ char *volname,
+ dict_t *dict,
+ char **op_errstr)
+{
+ int32_t i = 0;
+ int32_t ret = 0;
+ int32_t count = 0;
+ char *path = NULL;
+ dict_t *ctx = NULL;
+ char cmd_str [1024] = {0, };
+ char *ret_str = NULL;
+
+ ctx = glusterd_op_get_ctx (GD_OP_QUOTA);
+ if (ctx == NULL)
+ return -1;
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret < 0)
+ goto out;
+
+ if (count == 0) {
+ ret_str = _glusterd_quota_get_limit_usages (volinfo, NULL, op_errstr);
+ } else {
+ i = 0;
+ while (count--) {
+ snprintf (cmd_str, 1024, "path%d", i++);
+
+ ret = dict_get_str (dict, cmd_str, &path);
+ if (ret < 0)
+ goto out;
+
+ ret_str = _glusterd_quota_get_limit_usages (volinfo, path, op_errstr);
+ }
+ }
+
+ if (ret_str) {
+ ret = dict_set_dynstr (ctx, "limit_list", ret_str);
+ }
+out:
+ return ret;
+}
+
+int32_t
+glusterd_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr,
+ gf_boolean_t *crawl)
+{
+ int32_t ret = -1;
+ char *quota_status = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", crawl, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
+
+ ret = glusterd_check_if_quota_trans_enabled (volinfo);
+ if (ret == 0) {
+ *op_errstr = gf_strdup ("Quota is already enabled");
+ goto out;
+ }
+
+ quota_status = gf_strdup ("on");
+ if (!quota_status) {
+ gf_log ("", GF_LOG_ERROR, "memory allocation failed");
+ *op_errstr = gf_strdup ("Enabling quota has been unsuccessful");
+ goto out;
+ }
+
+ ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "dict set failed");
+ *op_errstr = gf_strdup ("Enabling quota has been unsuccessful");
+ goto out;
+ }
+
+ *op_errstr = gf_strdup ("Enabling quota has been successful");
+
+ *crawl = _gf_true;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr)
+{
+ int32_t ret = -1;
+ char *quota_status = NULL, *quota_limits = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
+
+ ret = glusterd_check_if_quota_trans_enabled (volinfo);
+ if (ret == -1) {
+ *op_errstr = gf_strdup ("Quota is already disabled");
+ goto out;
+ }
+
+ quota_status = gf_strdup ("off");
+ if (!quota_status) {
+ gf_log ("", GF_LOG_ERROR, "memory allocation failed");
+ *op_errstr = gf_strdup ("Disabling quota has been unsuccessful");
+ goto out;
+ }
+
+ ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "dict set failed");
+ *op_errstr = gf_strdup ("Disabling quota has been unsuccessful");
+ goto out;
+ }
+
+ *op_errstr = gf_strdup ("Disabling quota has been successful");
+
+ ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
+ &quota_limits);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING, "failed to get the quota limits");
+ } else {
+ GF_FREE (quota_limits);
+ }
+
+ dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE);
+
+out:
+ return ret;
+}
+
+int32_t
+glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr)
+{
+ int32_t ret = -1;
+ char *path = NULL;
+ char *limit = NULL;
+ char *value = NULL;
+ char msg [1024] = {0,};
+ char *quota_limits = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", dict, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
+
+ ret = glusterd_check_if_quota_trans_enabled (volinfo);
+ if (ret == -1) {
+ *op_errstr = gf_strdup ("Quota is disabled, "
+ "please enable to set limit");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
+ &quota_limits);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "failed to get the quota limits");
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "path", &path);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "limit", &limit);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+
+ if (quota_limits) {
+ ret = _glusterd_quota_remove_limits (&quota_limits, path);
+ if (ret == -1) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+ }
+
+ if (quota_limits == NULL) {
+ ret = gf_asprintf (&value, "%s:%s", path, limit);
+ if (ret == -1) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+ } else {
+ ret = gf_asprintf (&value, "%s,%s:%s",
+ quota_limits, path, limit);
+ if (ret == -1) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+
+ GF_FREE (quota_limits);
+ }
+
+ quota_limits = value;
+
+ ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE,
+ quota_limits);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" );
+ *op_errstr = gf_strdup ("failed to set limit");
+ goto out;
+ }
+ snprintf (msg, 1024, "limit set on %s", path);
+ *op_errstr = gf_strdup (msg);
+
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+glusterd_quota_remove_limits (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr)
+{
+ int32_t ret = -1;
+ char str [PATH_MAX + 1024] = {0,};
+ char *quota_limits = NULL;
+ char *path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("glusterd", dict, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
+ GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
+
+ ret = glusterd_check_if_quota_trans_enabled (volinfo);
+ if (ret == -1)
+ goto out;
+
+ ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
+ &quota_limits);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "failed to get the quota limits");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "path", &path);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
+ goto out;
+ }
+
+ ret = _glusterd_quota_remove_limits (&quota_limits, path);
+ if (ret == -1) {
+ snprintf (str, sizeof (str), "Removing limit on %s has been unsuccessful", path);
+ *op_errstr = gf_strdup (str);
+ goto out;
+ } else {
+ snprintf (str, sizeof (str), "Removed quota limit on %s", path);
+ *op_errstr = gf_strdup (str);
+ }
+
+ if (quota_limits) {
+ ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE,
+ quota_limits);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" );
+ goto out;
+ }
+ } else {
+ dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE);
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+int
+glusterd_op_quota (dict_t *dict, char **op_errstr)
+{
+ glusterd_volinfo_t *volinfo = NULL;
+ int32_t ret = -1;
+ char *volname = NULL;
+ dict_t *ctx = NULL;
+ int type = -1;
+ gf_boolean_t start_crawl = _gf_false;
+ glusterd_conf_t *priv = NULL;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (op_errstr);
+
+ priv = THIS->private;
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name " );
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "type", &type);
+
+ if (type == GF_QUOTA_OPTION_TYPE_ENABLE) {
+ ret = glusterd_quota_enable (volinfo, op_errstr, &start_crawl);
+ if (ret < 0)
+ goto out;
+
+ goto create_vol;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_DISABLE) {
+ ret = glusterd_quota_disable (volinfo, op_errstr);
+ if (ret < 0)
+ goto out;
+
+ goto create_vol;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) {
+ ret = glusterd_quota_limit_usage (volinfo, dict, op_errstr);
+ if (ret < 0)
+ goto out;
+
+ goto create_vol;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_REMOVE) {
+ ret = glusterd_quota_remove_limits (volinfo, dict, op_errstr);
+ if (ret < 0)
+ goto out;
+
+ goto create_vol;
+ }
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ ret = glusterd_check_if_quota_trans_enabled (volinfo);
+ if (ret == -1) {
+ *op_errstr = gf_strdup ("cannot list the limits, "
+ "quota feature is disabled");
+ goto out;
+ }
+
+ glusterd_quota_get_limit_usages (priv, volinfo, volname, dict, op_errstr);
+
+ goto out;
+ }
+create_vol:
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to re-create volfile for"
+ " 'quota'");
+ ret = -1;
+ goto out;
+ }
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status)
+ ret = glusterd_check_generate_start_nfs ();
+
+ ret = 0;
+
+out:
+ ctx = glusterd_op_get_ctx (GD_OP_QUOTA);
+ if (ctx && start_crawl == _gf_true)
+ glusterd_quota_initiate_fs_crawl (priv, volname);
+
+ if (ctx && *op_errstr) {
+ ret = dict_set_dynstr (ctx, "errstr", *op_errstr);
+ if (ret) {
+ GF_FREE (*op_errstr);
+ gf_log ("", GF_LOG_DEBUG,
+ "failed to set error message in ctx");
+ }
+ *op_errstr = NULL;
+ }
+
+ return ret;
+}
+
+int
glusterd_stop_bricks (glusterd_volinfo_t *volinfo)
{
glusterd_brickinfo_t *brickinfo = NULL;
@@ -1018,22 +5310,22 @@ glusterd_start_bricks (glusterd_volinfo_t *volinfo)
}
static int
-glusterd_volset_help (dict_t *dict)
+glusterd_restart_brick_servers (glusterd_volinfo_t *volinfo)
{
- int ret = -1;
- gf_boolean_t xml_out = _gf_false;
-
- if (dict_get (dict, "help" ))
- xml_out = _gf_false;
- else if (dict_get (dict, "help-xml" ))
- xml_out = _gf_true;
- else
- goto out;
-
- ret = glusterd_get_volopt_content (xml_out);
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ if (!volinfo)
+ return -1;
+ if (glusterd_stop_bricks (volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Restart Failed: Unable to "
+ "stop brick servers");
+ return -1;
+ }
+ usleep (500000);
+ if (glusterd_start_bricks (volinfo)) {
+ gf_log ("", GF_LOG_ERROR, "Restart Failed: Unable to "
+ "start brick servers");
+ return -1;
+ }
+ return 0;
}
static int
@@ -1045,13 +5337,13 @@ glusterd_op_set_volume (dict_t *dict)
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int count = 1;
- char *key = NULL;
- char *key_fixed = NULL;
- char *value = NULL;
- char str[50] = {0, };
+ int restart_flag = 0;
+ char *key = NULL;
+ char *key_fixed = NULL;
+ char *value = NULL;
+ char str[50] = {0, };
gf_boolean_t global_opt = _gf_false;
- glusterd_volinfo_t *voliter = NULL;
- int32_t dict_count = 0;
+ glusterd_volinfo_t *voliter = NULL;
this = THIS;
GF_ASSERT (this);
@@ -1059,73 +5351,57 @@ glusterd_op_set_volume (dict_t *dict)
priv = this->private;
GF_ASSERT (priv);
- ret = dict_get_int32 (dict, "count", &dict_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Count(dict),not set in Volume-Set");
- goto out;
- }
-
- if (dict_count == 0) {
- ret = glusterd_volset_help (dict);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR, "Volume set"
- " help internal error");
- goto out;
- }
-
ret = dict_get_str (dict, "volname", &volname);
+
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name");
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
goto out;
}
ret = glusterd_volinfo_find (volname, &volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to allocate memory");
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
goto out;
}
- for (count = 1; ret != -1 ; count++) {
+ for ( count = 1; ret != -1 ; count++ ) {
global_opt = _gf_false;
sprintf (str, "key%d", count);
ret = dict_get_str (dict, str, &key);
- if (ret)
- break;
- sprintf (str, "value%d", count);
- ret = dict_get_str (dict, str, &value);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "invalid key,value pair in 'volume set'");
- ret = -1;
- goto out;
- }
-
- if (strcmp (key, "memory-accounting") == 0) {
- ret = gf_string2boolean (value,
- &volinfo->memory_accounting);
- goto out;
+ break;
}
- if (!is_key_glusterd_hooks_friendly (key)) {
+ if (!ret) {
ret = glusterd_check_option_exists (key, &key_fixed);
GF_ASSERT (ret);
- if (ret <= 0) {
+ if (ret == -1) {
key_fixed = NULL;
goto out;
}
-
+ ret = 0;
}
- if (glusterd_check_globaloption (key))
+ ret = glusterd_check_globaloption (key);
+ if (ret)
global_opt = _gf_true;
+ sprintf (str, "value%d", count);
+ ret = dict_get_str (dict, str, &value);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR,
+ "invalid key,value pair in 'volume set'");
+ ret = -1;
+ goto out;
+ }
+
if (!global_opt)
value = gf_strdup (value);
if (!value) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log ("", GF_LOG_ERROR,
"Unable to set the options in 'volume set'");
ret = -1;
goto out;
@@ -1141,7 +5417,8 @@ glusterd_op_set_volume (dict_t *dict)
if (ret)
goto out;
}
- } else {
+ }
+ else {
ret = dict_set_dynstr (volinfo->dict, key, value);
if (ret)
goto out;
@@ -1149,12 +5426,14 @@ glusterd_op_set_volume (dict_t *dict)
if (key_fixed) {
GF_FREE (key_fixed);
+
key_fixed = NULL;
}
}
- if (count == 1) {
- gf_log (this->name, GF_LOG_ERROR, "No options received ");
+
+ if ( count == 1 ) {
+ gf_log ("", GF_LOG_ERROR, "No options received ");
ret = -1;
goto out;
}
@@ -1162,47 +5441,60 @@ glusterd_op_set_volume (dict_t *dict)
if (!global_opt) {
ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to create volfile for"
+ gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
" 'volume set'");
ret = -1;
goto out;
}
+ if (restart_flag) {
+ if (glusterd_restart_brick_servers (volinfo)) {
+ ret = -1;
+ goto out;
+ }
+ }
+
ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret)
goto out;
if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_nodesvcs_handle_reconfigure (volinfo);
+ ret = glusterd_check_generate_start_nfs ();
if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log ("", GF_LOG_WARNING,
"Unable to restart NFS-Server");
goto out;
}
}
- } else {
+ }
+ else {
list_for_each_entry (voliter, &priv->volumes, vol_list) {
volinfo = voliter;
ret = glusterd_create_volfiles_and_notify_services (volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to create volfile for"
+ gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
" 'volume set'");
ret = -1;
goto out;
}
+ if (restart_flag) {
+ if (glusterd_restart_brick_servers (volinfo)) {
+ ret = -1;
+ goto out;
+ }
+ }
+
ret = glusterd_store_volinfo (volinfo,
GLUSTERD_VOLINFO_VER_AC_INCREMENT);
if (ret)
goto out;
if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_nodesvcs_handle_reconfigure (volinfo);
+ ret = glusterd_check_generate_start_nfs ();
if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log ("", GF_LOG_WARNING,
"Unable to restart NFS-Server");
goto out;
}
@@ -1210,15 +5502,434 @@ glusterd_op_set_volume (dict_t *dict)
}
}
+
+
ret = 0;
- out:
- GF_FREE (key_fixed);
- gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
+
+out:
+ if (key_fixed)
+ GF_FREE (key_fixed);
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_op_remove_brick (dict_t *dict)
+{
+ int ret = -1;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *brick = NULL;
+ int32_t count = 0;
+ int32_t i = 1;
+ char key[256] = {0,};
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "count", &count);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get count");
+ goto out;
+ }
+
+
+ while ( i <= count) {
+ snprintf (key, 256, "brick%d", i);
+ ret = dict_get_str (dict, key, &brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get %s", key);
+ goto out;
+ }
+
+ ret = glusterd_op_perform_remove_brick (volinfo, brick);
+ if (ret)
+ goto out;
+ i++;
+ }
+
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ if (ret)
+ goto out;
+
+ volinfo->defrag_status = 0;
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+
+ if (ret)
+ goto out;
+
+ if (GLUSTERD_STATUS_STARTED == volinfo->status)
+ ret = glusterd_check_generate_start_nfs ();
+
+out:
return ret;
}
static int
+glusterd_op_delete_volume (dict_t *dict)
+{
+ int ret = 0;
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret)
+ goto out;
+
+ ret = glusterd_delete_volume (volinfo);
+out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
+static int
+glusterd_op_start_volume (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ int flags = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+
+ ret = glusterd_op_start_volume_args_get (dict, &volname, &flags);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret)
+ goto out;
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ ret = glusterd_brick_start (volinfo, brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STARTED);
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret)
+ goto out;
+
+ ret = glusterd_check_generate_start_nfs ();
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d ", ret);
+ return ret;
+}
+
+static int
+glusterd_op_log_filename (dict_t *dict)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+ char *volname = NULL;
+ char *brick = NULL;
+ char *path = NULL;
+ char logfile[PATH_MAX] = {0,};
+ char exp_path[PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+ int valid_brick = 0;
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+ char* new_logdir = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "volname not found");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "path", &path);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "path not found");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "brick", &brick);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret)
+ goto out;
+
+ if (!strchr (brick, ':')) {
+ brick = NULL;
+ ret = stat (path, &stbuf);
+ if (ret || !S_ISDIR (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "not a directory");
+ goto out;
+ }
+ new_logdir = gf_strdup (path);
+ if (!new_logdir) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ goto out;
+ }
+ if (volinfo->logdir)
+ GF_FREE (volinfo->logdir);
+ volinfo->logdir = new_logdir;
+ } else {
+ ret = glusterd_brickinfo_from_brick (brick, &tmpbrkinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "cannot get brickinfo from brick");
+ goto out;
+ }
+ }
+
+
+ ret = -1;
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+
+ if (uuid_is_null (brickinfo->uuid)) {
+ ret = glusterd_resolve_brick (brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ /* check if the brickinfo belongs to the 'this' machine */
+ if (uuid_compare (brickinfo->uuid, priv->uuid))
+ continue;
+
+ if (brick && strcmp (tmpbrkinfo->path,brickinfo->path))
+ continue;
+
+ valid_brick = 1;
+
+ /* If there are more than one brick in 'this' server, its an
+ * extra check, but it doesn't harm functionality
+ */
+ ret = stat (path, &stbuf);
+ if (ret || !S_ISDIR (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "not a directory");
+ goto out;
+ }
+
+ GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, exp_path);
+
+ snprintf (logfile, PATH_MAX, "%s/%s.log", path, exp_path);
+
+ if (brickinfo->logfile)
+ GF_FREE (brickinfo->logfile);
+ brickinfo->logfile = gf_strdup (logfile);
+ ret = 0;
+
+ /* If request was for brick, only one iteration is enough */
+ if (brick)
+ break;
+ }
+
+ if (ret && !valid_brick)
+ ret = 0;
+out:
+ if (tmpbrkinfo)
+ glusterd_brickinfo_delete (tmpbrkinfo);
+
+ return ret;
+}
+
+static int
+glusterd_op_log_rotate (dict_t *dict)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ xlator_t *this = NULL;
+ char *volname = NULL;
+ char *brick = NULL;
+ char path[PATH_MAX] = {0,};
+ char logfile[PATH_MAX] = {0,};
+ char pidfile[PATH_MAX] = {0,};
+ FILE *file = NULL;
+ pid_t pid = 0;
+ uint64_t key = 0;
+ int valid_brick = 0;
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "volname not found");
+ goto out;
+ }
+
+ ret = dict_get_uint64 (dict, "rotate-key", &key);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "rotate key not found");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "brick", &brick);
+ if (ret)
+ goto out;
+
+ if (!strchr (brick, ':'))
+ brick = NULL;
+ else {
+ ret = glusterd_brickinfo_from_brick (brick, &tmpbrkinfo);
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "cannot get brickinfo from brick");
+ goto out;
+ }
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret)
+ goto out;
+
+ ret = -1;
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ if (uuid_compare (brickinfo->uuid, priv->uuid))
+ continue;
+
+ if (brick &&
+ (strcmp (tmpbrkinfo->hostname, brickinfo->hostname) ||
+ strcmp (tmpbrkinfo->path,brickinfo->path)))
+ continue;
+
+ valid_brick = 1;
+
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+ GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,
+ brickinfo->path);
+
+ file = fopen (pidfile, "r+");
+ if (!file) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
+ pidfile);
+ ret = -1;
+ goto out;
+ }
+
+ ret = fscanf (file, "%d", &pid);
+ if (ret <= 0) {
+ gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s",
+ pidfile);
+ ret = -1;
+ goto out;
+ }
+ fclose (file);
+ file = NULL;
+
+ snprintf (logfile, PATH_MAX, "%s.%"PRIu64,
+ brickinfo->logfile, key);
+
+ ret = rename (brickinfo->logfile, logfile);
+ if (ret)
+ gf_log ("", GF_LOG_WARNING, "rename failed");
+
+ ret = kill (pid, SIGHUP);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to SIGHUP to %d", pid);
+ goto out;
+ }
+ ret = 0;
+
+ /* If request was for brick, only one iteration is enough */
+ if (brick)
+ break;
+ }
+
+ if (ret && !valid_brick)
+ ret = 0;
+
+out:
+ if (tmpbrkinfo)
+ glusterd_brickinfo_delete (tmpbrkinfo);
+
+ return ret;
+}
+
+
+static int
+glusterd_op_stop_volume (dict_t *dict)
+{
+ int ret = 0;
+ int flags = 0;
+ char *volname = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+
+ ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
+ if (ret)
+ goto out;
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+
+ if (ret)
+ goto out;
+
+ list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
+ ret = glusterd_brick_stop (volinfo, brickinfo);
+ if (ret)
+ goto out;
+ }
+
+ glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED);
+
+ ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
+ if (ret)
+ goto out;
+
+ if (glusterd_are_all_volumes_stopped ()) {
+ if (glusterd_is_nfs_started ()) {
+ ret = glusterd_nfs_server_stop ();
+ if (ret)
+ goto out;
+ }
+ } else {
+ ret = glusterd_check_generate_start_nfs ();
+ }
+
+out:
+ return ret;
+}
+
+static int
glusterd_op_sync_volume (dict_t *dict, char **op_errstr,
dict_t *rsp_dict)
{
@@ -1390,13 +6101,13 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr,
goto out;
break;
}
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
+ ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
+ if (ret) {
gf_log ("", GF_LOG_ERROR, "Unable to create volfile for"
- " 'volume set'");
- ret = -1;
- goto out;
+ " 'volume set'");
+ ret = -1;
+ goto out;
}
ret = glusterd_store_volinfo (volinfo,
@@ -1405,7 +6116,7 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr,
goto out;
if (GLUSTERD_STATUS_STARTED == volinfo->status)
- ret = glusterd_nodesvcs_handle_reconfigure (volinfo);
+ ret = glusterd_check_generate_start_nfs ();
ret = 0;
@@ -1416,185 +6127,6 @@ out:
}
static int
-glusterd_op_status_volume (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = -1;
- int node_count = 0;
- int brick_index = -1;
- int other_count = 0;
- int other_index = 0;
- uint32_t cmd = 0;
- char *volname = NULL;
- char *brick = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *vol_opts = NULL;
- gf_boolean_t nfs_disabled = _gf_false;
- gf_boolean_t shd_enabled = _gf_true;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
-
- GF_ASSERT (priv);
-
- GF_ASSERT (dict);
-
- ret = dict_get_uint32 (dict, "cmd", &cmd);
- if (ret)
- goto out;
-
- if (!rsp_dict) {
- //this should happen only on source
- ret = 0;
- rsp_dict = glusterd_op_get_ctx ();
-
- if ((cmd & GF_CLI_STATUS_ALL)) {
- ret = glusterd_get_all_volnames (rsp_dict);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to get all volume "
- "names for status");
- }
-
- }
-
- ret = dict_set_uint32 (rsp_dict, "cmd", cmd);
- if (ret)
- goto out;
-
- if (cmd & GF_CLI_STATUS_ALL)
- goto out;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Volume with name: %s "
- "does not exist", volname);
- goto out;
- }
- vol_opts = volinfo->dict;
-
- if ((cmd & GF_CLI_STATUS_NFS) != 0) {
- ret = glusterd_add_node_to_dict ("nfs", rsp_dict, 0, vol_opts);
- if (ret)
- goto out;
- other_count++;
- node_count++;
-
- } else if ((cmd & GF_CLI_STATUS_SHD) != 0) {
- ret = glusterd_add_node_to_dict ("glustershd", rsp_dict, 0,
- vol_opts);
- if (ret)
- goto out;
- other_count++;
- node_count++;
-
- } else if ((cmd & GF_CLI_STATUS_BRICK) != 0) {
- ret = dict_get_str (dict, "brick", &brick);
- if (ret)
- goto out;
-
- ret = glusterd_volume_brickinfo_get_by_brick (brick,
- volinfo,
- &brickinfo);
- if (ret)
- goto out;
-
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- goto out;
-
- glusterd_add_brick_to_dict (volinfo, brickinfo, rsp_dict,
- ++brick_index);
- if (cmd & GF_CLI_STATUS_DETAIL)
- glusterd_add_brick_detail_to_dict (volinfo, brickinfo,
- rsp_dict,
- brick_index);
- node_count++;
-
- } else {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_index++;
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- glusterd_add_brick_to_dict (volinfo, brickinfo,
- rsp_dict, brick_index);
-
- if (cmd & GF_CLI_STATUS_DETAIL) {
- glusterd_add_brick_detail_to_dict (volinfo,
- brickinfo,
- rsp_dict,
- brick_index);
- }
- node_count++;
- }
-
- if ((cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE) {
- other_index = brick_index + 1;
-
- nfs_disabled = dict_get_str_boolean (vol_opts,
- "nfs.disable",
- _gf_false);
- if (!nfs_disabled) {
- ret = glusterd_add_node_to_dict ("nfs",
- rsp_dict,
- other_index,
- vol_opts);
- if (ret)
- goto out;
- other_index++;
- other_count++;
- node_count++;
- }
-
- shd_enabled = dict_get_str_boolean
- (vol_opts, "cluster.self-heal-daemon",
- _gf_true);
- if (glusterd_is_volume_replicate (volinfo)
- && shd_enabled) {
- ret = glusterd_add_node_to_dict ("glustershd",
- rsp_dict,
- other_index,
- vol_opts);
- if (ret)
- goto out;
- other_count++;
- node_count++;
- }
- }
- }
-
- ret = dict_set_int32 (rsp_dict, "brick-index-max", brick_index);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting brick-index-max to dict");
- goto out;
- }
- ret = dict_set_int32 (rsp_dict, "other-count", other_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting other-count to dict");
- goto out;
- }
- ret = dict_set_int32 (rsp_dict, "count", node_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting node count to dict");
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
glusterd_op_ac_none (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
@@ -1659,7 +6191,7 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx)
priv = this->private;
GF_ASSERT (priv);
- /*ret = glusterd_unlock (MY_UUID);
+ /*ret = glusterd_unlock (priv->uuid);
if (ret)
goto out;
@@ -1694,32 +6226,11 @@ glusterd_op_ac_send_unlock (glusterd_op_sm_event_t *event, void *ctx)
}
static int
-glusterd_op_ac_ack_drain (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
-
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
-
- if (!opinfo.pending_count)
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_ALL_ACK, NULL);
-
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_send_unlock_drain (glusterd_op_sm_event_t *event, void *ctx)
-{
- return glusterd_op_ac_ack_drain (event, ctx);
-}
-
-static int
glusterd_op_ac_lock (glusterd_op_sm_event_t *event, void *ctx)
{
+ int ret = 0;
glusterd_op_lock_ctx_t *lock_ctx = NULL;
- int32_t ret = 0;
+ int32_t status = 0;
GF_ASSERT (event);
@@ -1727,11 +6238,13 @@ glusterd_op_ac_lock (glusterd_op_sm_event_t *event, void *ctx)
lock_ctx = (glusterd_op_lock_ctx_t *)ctx;
- ret = glusterd_lock (lock_ctx->uuid);
+ status = glusterd_lock (lock_ctx->uuid);
+
+ gf_log ("", GF_LOG_DEBUG, "Lock Returned %d", status);
- gf_log ("", GF_LOG_DEBUG, "Lock Returned %d", ret);
+ ret = glusterd_op_lock_send_resp (lock_ctx->req, status);
- glusterd_op_lock_send_resp (lock_ctx->req, ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
@@ -1751,25 +6264,9 @@ glusterd_op_ac_unlock (glusterd_op_sm_event_t *event, void *ctx)
gf_log ("", GF_LOG_DEBUG, "Unlock Returned %d", ret);
- glusterd_op_unlock_send_resp (lock_ctx->req, ret);
-
- return ret;
-}
-
-static int
-glusterd_op_ac_local_unlock (glusterd_op_sm_event_t *event, void *ctx)
-{
- int ret = 0;
- uuid_t *originator = NULL;
-
- GF_ASSERT (event);
- GF_ASSERT (ctx);
-
- originator = (uuid_t *) ctx;
-
- ret = glusterd_unlock (*originator);
+ ret = glusterd_op_unlock_send_resp (lock_ctx->req, ret);
- gf_log ("", GF_LOG_DEBUG, "Unlock Returned %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
@@ -1795,59 +6292,22 @@ out:
return ret;
}
-static int
-glusterd_dict_set_volid (dict_t *dict, char *volname, char **op_errstr)
-{
- int ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- char *volid = NULL;
- char msg[1024] = {0,};
-
- if (!dict || !volname)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
- volid = gf_strdup (uuid_utoa (volinfo->volume_id));
- if (!volid) {
- ret = -1;
- goto out;
- }
- ret = dict_set_dynstr (dict, "vol-id", volid);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to set volume id in dictionary");
- goto out;
- }
-out:
- return ret;
-}
-
int
-glusterd_op_build_payload (dict_t **req, char **op_errstr)
+glusterd_op_build_payload (glusterd_op_t op, dict_t **req)
{
int ret = -1;
void *ctx = NULL;
dict_t *req_dict = NULL;
- glusterd_op_t op = GD_OP_NONE;
- char *volname = NULL;
- uint32_t status_cmd = GF_CLI_STATUS_NONE;
- char *errstr = NULL;
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
GF_ASSERT (req);
req_dict = dict_new ();
if (!req_dict)
goto out;
- op = glusterd_op_get_op ();
- ctx = (void*)glusterd_op_get_ctx ();
+ ctx = (void*)glusterd_op_get_ctx (op);
if (!ctx) {
gf_log ("", GF_LOG_ERROR, "Null Context for "
"op %d", op);
@@ -1860,99 +6320,38 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr)
{
dict_t *dict = ctx;
++glusterfs_port;
- ret = dict_set_int32 (dict, "port",
- glusterfs_port);
+ ret = dict_set_int32 (dict, "port", glusterfs_port);
if (ret)
goto out;
dict_copy (dict, req_dict);
}
break;
- case GD_OP_GSYNC_SET:
- {
- dict_t *dict = ctx;
- ret = glusterd_op_gsync_args_get (dict,
- &errstr,
- &volname,
- NULL);
- if (ret == 0) {
- ret = glusterd_dict_set_volid
- (dict, volname, op_errstr);
- if (ret)
- goto out;
- }
- dict_copy (dict, req_dict);
- }
- break;
-
- case GD_OP_SET_VOLUME:
+ case GD_OP_DELETE_VOLUME:
{
- dict_t *dict = ctx;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "volname is not present in "
- "operation ctx");
+ glusterd_op_delete_volume_ctx_t *ctx1 = ctx;
+ ret = dict_set_str (req_dict, "volname",
+ ctx1->volume_name);
+ if (ret)
goto out;
- }
- if (strcmp (volname, "help") &&
- strcmp (volname, "help-xml")) {
- ret = glusterd_dict_set_volid
- (dict, volname, op_errstr);
- if (ret)
- goto out;
- }
- dict_copy (dict, req_dict);
}
break;
- case GD_OP_STATUS_VOLUME:
- {
- dict_t *dict = ctx;
- ret = dict_get_uint32 (dict, "cmd",
- &status_cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Status command not present "
- "in op ctx");
- goto out;
- }
- if (GF_CLI_STATUS_ALL & status_cmd) {
- dict_copy (dict, req_dict);
- break;
- }
- }
-
- case GD_OP_DELETE_VOLUME:
case GD_OP_START_VOLUME:
case GD_OP_STOP_VOLUME:
case GD_OP_ADD_BRICK:
case GD_OP_REPLACE_BRICK:
+ case GD_OP_SET_VOLUME:
case GD_OP_RESET_VOLUME:
case GD_OP_REMOVE_BRICK:
+ case GD_OP_LOG_FILENAME:
case GD_OP_LOG_ROTATE:
case GD_OP_SYNC_VOLUME:
case GD_OP_QUOTA:
+ case GD_OP_GSYNC_SET:
case GD_OP_PROFILE_VOLUME:
- case GD_OP_REBALANCE:
- case GD_OP_HEAL_VOLUME:
- case GD_OP_STATEDUMP_VOLUME:
- case GD_OP_CLEARLOCKS_VOLUME:
- case GD_OP_DEFRAG_BRICK_VOLUME:
{
- dict_t *dict = ctx;
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "volname is not present in "
- "operation ctx");
- goto out;
- }
-
- ret = glusterd_dict_set_volid (dict, volname,
- op_errstr);
- if (ret)
- goto out;
+ dict_t *dict = ctx;
dict_copy (dict, req_dict);
}
break;
@@ -1978,7 +6377,7 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx)
glusterd_peerinfo_t *peerinfo = NULL;
dict_t *dict = NULL;
char *op_errstr = NULL;
- glusterd_op_t op = GD_OP_NONE;
+ int i = 0;
uint32_t pending_count = 0;
this = THIS;
@@ -1986,17 +6385,27 @@ glusterd_op_ac_send_stage_op (glusterd_op_sm_event_t *event, void *ctx)
priv = this->private;
GF_ASSERT (priv);
- op = glusterd_op_get_op ();
+ for ( i = GD_OP_NONE; i < GD_OP_MAX; i++) {
+ if (opinfo.pending_op[i])
+ break;
+ }
- ret = glusterd_op_build_payload (&dict, &op_errstr);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Building payload failed");
- opinfo.op_errstr = op_errstr;
- goto out;
+ if (GD_OP_MAX == i) {
+ //No pending ops, inject stage_acc
+ ret = glusterd_op_sm_inject_event
+ (GD_OP_EVENT_STAGE_ACC, NULL);
+
+ return ret;
}
+ glusterd_op_clear_pending_op (i);
+
+ ret = glusterd_op_build_payload (i, &dict);
+ if (ret)
+ goto out;
+
/* rsp_dict NULL from source */
- ret = glusterd_op_stage_validate (op, dict, &op_errstr, NULL);
+ ret = glusterd_op_stage_validate (i, dict, &op_errstr, NULL);
if (ret) {
gf_log ("", GF_LOG_ERROR, "Staging failed");
opinfo.op_errstr = op_errstr;
@@ -2056,7 +6465,6 @@ glusterd_op_start_rb_timer (dict_t *dict)
struct timeval timeout = {0, };
glusterd_conf_t *priv = NULL;
int32_t ret = -1;
- dict_t *rb_ctx = NULL;
GF_ASSERT (dict);
priv = THIS->private;
@@ -2068,25 +6476,18 @@ glusterd_op_start_rb_timer (dict_t *dict)
goto out;
}
- if (op != GF_REPLACE_OP_START) {
- ret = glusterd_op_sm_inject_all_acc ();
- goto out;
- }
+ if (op == GF_REPLACE_OP_START ||
+ op == GF_REPLACE_OP_ABORT)
+ timeout.tv_sec = 5;
+ else
+ timeout.tv_sec = 1;
- timeout.tv_sec = 5;
timeout.tv_usec = 0;
- rb_ctx = dict_copy (dict, rb_ctx);
- if (!rb_ctx) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't copy "
- "replace brick context. Can't start replace brick");
- ret = -1;
- goto out;
- }
priv->timer = gf_timer_call_after (THIS->ctx, timeout,
glusterd_do_replace_brick,
- (void *) rb_ctx);
+ (void *) dict);
ret = 0;
@@ -2094,229 +6495,6 @@ out:
return ret;
}
-/* This function takes a dict and converts the uuid values of key specified
- * into hostnames
- */
-static int
-glusterd_op_volume_dict_uuid_to_hostname (dict_t *dict, const char *key_fmt,
- int idx_min, int idx_max)
-{
- int ret = -1;
- int i = 0;
- char key[1024];
- char *uuid_str = NULL;
- uuid_t uuid = {0,};
- char *hostname = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (key_fmt);
-
- for (i = idx_min; i < idx_max; i++) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), key_fmt, i);
- ret = dict_get_str (dict, key, &uuid_str);
- if (ret)
- continue;
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Got uuid %s",
- uuid_str);
-
- ret = uuid_parse (uuid_str, uuid);
- /* if parsing fails don't error out
- * let the original value be retained
- */
- if (ret)
- continue;
-
- hostname = glusterd_uuid_to_hostname (uuid);
- if (hostname) {
- gf_log (THIS->name, GF_LOG_DEBUG, "%s -> %s",
- uuid_str, hostname);
- ret = dict_set_dynstr (dict, key, hostname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting hostname to dict");
- GF_FREE (hostname);
- goto out;
- }
- }
- }
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* This function is used to modify the op_ctx dict before sending it back
- * to cli. This is useful in situations like changing the peer uuids to
- * hostnames etc.
- */
-void
-glusterd_op_modify_op_ctx (glusterd_op_t op)
-{
- int ret = -1;
- dict_t *op_ctx = NULL;
- int brick_index_max = -1;
- int other_count = 0;
- int count = 0;
- uint32_t cmd = GF_CLI_STATUS_NONE;
-
- op_ctx = glusterd_op_get_ctx();
- if (!op_ctx) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Operation context is not present.");
- goto out;
- }
-
- switch (op) {
- case GD_OP_STATUS_VOLUME:
- ret = dict_get_uint32 (op_ctx, "cmd", &cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Failed to get status cmd");
- goto out;
- }
- if (!(cmd & GF_CLI_STATUS_NFS || cmd & GF_CLI_STATUS_SHD ||
- (cmd & GF_CLI_STATUS_MASK) == GF_CLI_STATUS_NONE)) {
- gf_log (THIS->name, GF_LOG_INFO,
- "op_ctx modification not required for status "
- "operation being performed");
- goto out;
- }
-
- ret = dict_get_int32 (op_ctx, "brick-index-max",
- &brick_index_max);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Failed to get brick-index-max");
- goto out;
- }
-
- ret = dict_get_int32 (op_ctx, "other-count", &other_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Failed to get other-count");
- goto out;
- }
-
- count = brick_index_max + other_count + 1;
-
- ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
- "brick%d.path",
- 0, count);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "Failed uuid to hostname conversion");
-
- break;
-
- case GD_OP_PROFILE_VOLUME:
- ret = dict_get_str_boolean (op_ctx, "nfs", _gf_false);
- if (!ret)
- goto out;
-
- ret = dict_get_int32 (op_ctx, "count", &count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Failed to get brick count");
- goto out;
- }
-
- ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
- "%d-brick",
- 1, (count + 1));
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "Failed uuid to hostname conversion");
-
- break;
-
- /* For both rebalance and remove-brick status, the glusterd op is the
- * same
- */
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = dict_get_int32 (op_ctx, "count", &count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Failed to get count");
- goto out;
- }
-
- ret = glusterd_op_volume_dict_uuid_to_hostname (op_ctx,
- "node-uuid-%d",
- 1, (count + 1));
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "Failed uuid to hostname conversion");
- break;
-
- default:
- ret = 0;
- gf_log (THIS->name, GF_LOG_INFO,
- "op_ctx modification not required");
- break;
-
- }
-
-out:
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING,
- "op_ctx modification failed");
- return;
-}
-
-static int
-glusterd_op_commit_hook (glusterd_op_t op, dict_t *op_ctx, glusterd_commit_hook_type_t type)
-{
- glusterd_conf_t *priv = NULL;
- char hookdir[PATH_MAX] = {0, };
- char scriptdir[PATH_MAX] = {0, };
- char type_subdir[256] = {0, };
- char *cmd_subdir = NULL;
- int ret = -1;
-
- priv = THIS->private;
- switch (type) {
- case GD_COMMIT_HOOK_NONE:
- case GD_COMMIT_HOOK_MAX:
- /*Won't be called*/
- break;
-
- case GD_COMMIT_HOOK_PRE:
- strcpy (type_subdir, "pre");
- break;
- case GD_COMMIT_HOOK_POST:
- strcpy (type_subdir, "post");
- break;
- }
-
- cmd_subdir = glusterd_hooks_get_hooks_cmd_subdir (op);
- if (strlen (cmd_subdir) == 0)
- return -1;
-
- GLUSTERD_GET_HOOKS_DIR (hookdir, GLUSTERD_HOOK_VER, priv);
- snprintf (scriptdir, sizeof (scriptdir), "%s/%s/%s",
- hookdir, cmd_subdir, type_subdir);
-
- switch (type) {
- case GD_COMMIT_HOOK_NONE:
- case GD_COMMIT_HOOK_MAX:
- /*Won't be called*/
- break;
-
- case GD_COMMIT_HOOK_PRE:
- ret = glusterd_hooks_run_hooks (scriptdir, op, op_ctx,
- type);
- break;
- case GD_COMMIT_HOOK_POST:
- ret = glusterd_hooks_post_stub_enqueue (scriptdir, op,
- op_ctx);
- break;
- }
-
- return ret;
-}
-
static int
glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx)
{
@@ -2328,34 +6506,38 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx)
dict_t *op_dict = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
char *op_errstr = NULL;
- glusterd_op_t op = GD_OP_NONE;
- uint32_t pending_count = 0;
+ int i = 0;
+ uint32_t pending_count = 0;
this = THIS;
GF_ASSERT (this);
priv = this->private;
GF_ASSERT (priv);
- op = glusterd_op_get_op ();
- op_dict = glusterd_op_get_ctx ();
+ for ( i = GD_OP_NONE; i < GD_OP_MAX; i++) {
+ if (opinfo.commit_op[i])
+ break;
+ }
- ret = glusterd_op_build_payload (&dict, &op_errstr);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Building payload failed");
- opinfo.op_errstr = op_errstr;
- goto out;
+ if (GD_OP_MAX == i) {
+ //No pending ops, return
+ return 0;
}
- glusterd_op_commit_hook (op, op_dict, GD_COMMIT_HOOK_PRE);
- ret = glusterd_op_commit_perform (op, dict, &op_errstr, NULL); //rsp_dict invalid for source
+ glusterd_op_clear_commit_op (i);
+
+ ret = glusterd_op_build_payload (i, &dict);
+
+ if (ret)
+ goto out;
+
+ ret = glusterd_op_commit_perform (i, dict, &op_errstr, NULL); //rsp_dict invalid for source
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Commit failed");
+ gf_log ("", GF_LOG_ERROR, "Commit failed");
opinfo.op_errstr = op_errstr;
goto out;
}
- glusterd_op_commit_hook (op, op_dict, GD_COMMIT_HOOK_POST);
-
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
GF_ASSERT (peerinfo);
@@ -2370,8 +6552,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx)
if (proc->fn) {
ret = dict_set_static_ptr (dict, "peerinfo", peerinfo);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set peerinfo");
+ gf_log ("", GF_LOG_ERROR, "failed to set peerinfo");
goto out;
}
ret = proc->fn (NULL, this, dict);
@@ -2382,7 +6563,7 @@ glusterd_op_ac_send_commit_op (glusterd_op_sm_event_t *event, void *ctx)
}
opinfo.pending_count = pending_count;
- gf_log (THIS->name, GF_LOG_INFO, "Sent op req to %d peers",
+ gf_log ("glusterd", GF_LOG_INFO, "Sent op req to %d peers",
opinfo.pending_count);
out:
if (dict)
@@ -2393,18 +6574,18 @@ out:
}
if (!opinfo.pending_count) {
- if (op == GD_OP_REPLACE_BRICK) {
- ret = glusterd_op_start_rb_timer (op_dict);
-
- } else {
- glusterd_op_modify_op_ctx (op);
+ op_dict = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (!op_dict) {
ret = glusterd_op_sm_inject_all_acc ();
+ goto err;
}
- goto err;
+
+ op_dict = dict_ref (op_dict);
+ ret = glusterd_op_start_rb_timer (op_dict);
}
err:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
@@ -2478,15 +6659,19 @@ glusterd_op_ac_brick_op_failed (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
gf_boolean_t free_errstr = _gf_false;
GF_ASSERT (event);
GF_ASSERT (ctx);
ev_ctx = ctx;
+ brickinfo = ev_ctx->brickinfo;
+ GF_ASSERT (brickinfo);
- ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, ev_ctx->pending_node->node);
+ ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, brickinfo);
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "unknown response received ");
+ gf_log ("glusterd", GF_LOG_ERROR, "unknown response received "
+ "from %s:%s", brickinfo->hostname, brickinfo->path);
ret = -1;
free_errstr = _gf_true;
goto out;
@@ -2517,53 +6702,201 @@ out:
return ret;
}
-static int
-glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
+void
+glusterd_op_brick_disconnect (void *data)
{
- dict_t *op_ctx = NULL;
- int ret = 0;
- gf_boolean_t commit_ack_inject = _gf_true;
- glusterd_op_t op = GD_OP_NONE;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL;
- op = glusterd_op_get_op ();
- GF_ASSERT (event);
+ ev_ctx = data;
+ GF_ASSERT (ev_ctx);
+ brickinfo = ev_ctx->brickinfo;
+ GF_ASSERT (brickinfo);
- if (opinfo.pending_count > 0)
- opinfo.pending_count--;
+ if (brickinfo->timer) {
+ gf_timer_call_cancel (THIS->ctx, brickinfo->timer);
+ brickinfo->timer = NULL;
+ gf_log ("", GF_LOG_DEBUG,
+ "Cancelled timer thread");
+ }
- if (opinfo.pending_count > 0)
+ glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_ACC, ev_ctx);
+ glusterd_op_sm ();
+}
+
+void
+glusterd_do_replace_brick (void *data)
+{
+ glusterd_volinfo_t *volinfo = NULL;
+ int32_t op = 0;
+ int32_t src_port = 0;
+ int32_t dst_port = 0;
+ dict_t *dict = NULL;
+ char *src_brick = NULL;
+ char *dst_brick = NULL;
+ char *volname = NULL;
+ glusterd_brickinfo_t *src_brickinfo = NULL;
+ glusterd_brickinfo_t *dst_brickinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ int ret = 0;
+
+ dict = data;
+
+ GF_ASSERT (THIS);
+
+ priv = THIS->private;
+
+ if (priv->timer) {
+ gf_timer_call_cancel (THIS->ctx, priv->timer);
+ priv->timer = NULL;
+ gf_log ("", GF_LOG_DEBUG,
+ "Cancelled timer thread");
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "Replace brick operation detected");
+
+ ret = dict_get_int32 (dict, "operation", &op);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG,
+ "dict_get on operation failed");
+ goto out;
+ }
+ ret = dict_get_str (dict, "src-brick", &src_brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "src brick=%s", src_brick);
+
+ ret = dict_get_str (dict, "dst-brick", &dst_brick);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get dst brick");
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_DEBUG,
+ "dst brick=%s", dst_brick);
+
+ ret = dict_get_str (dict, "volname", &volname);
+
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
goto out;
+ }
- if (op == GD_OP_REPLACE_BRICK) {
- op_ctx = glusterd_op_get_ctx ();
- if (!op_ctx) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Operation "
- "context is not present.");
+ ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo, &src_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");
+ goto out;
+ }
+
+ ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
+ if (!dst_brickinfo) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to get dst-brickinfo");
+ goto out;
+ }
+
+ ret = glusterd_resolve_brick (dst_brickinfo);
+ if (ret) {
+ gf_log ("", GF_LOG_DEBUG, "Unable to resolve dst-brickinfo");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "src-brick-port", &src_port);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get src-brick port");
+ goto out;
+ }
+
+ ret = dict_get_int32 (dict, "dst-brick-port", &dst_port);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get dst-brick port");
+ }
+
+ dst_brickinfo->port = dst_port;
+ src_brickinfo->port = src_port;
+
+ switch (op) {
+ case GF_REPLACE_OP_START:
+ if (!dst_port) {
ret = -1;
goto out;
}
- ret = glusterd_op_start_rb_timer (op_ctx);
+ ret = rb_do_operation_start (volinfo, src_brickinfo, dst_brickinfo);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't start "
- "replace-brick operation.");
+ glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE);
goto out;
}
-
- commit_ack_inject = _gf_false;
+ break;
+ case GF_REPLACE_OP_PAUSE:
+ case GF_REPLACE_OP_ABORT:
+ case GF_REPLACE_OP_COMMIT:
+ case GF_REPLACE_OP_COMMIT_FORCE:
+ case GF_REPLACE_OP_STATUS:
+ break;
+ default:
+ ret = -1;
goto out;
}
+out:
+ if (ret)
+ ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, NULL);
+ else
+ ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC, NULL);
+
+// if (dict)
+// dict_unref (dict);
+
+ glusterd_op_sm ();
+}
+
+
+static int
+glusterd_op_ac_rcvd_commit_op_acc (glusterd_op_sm_event_t *event, void *ctx)
+{
+ glusterd_conf_t *priv = NULL;
+ dict_t *dict = NULL;
+ int ret = 0;
+ gf_boolean_t commit_ack_inject = _gf_false;
+
+ priv = THIS->private;
+ GF_ASSERT (event);
+
+ if (opinfo.pending_count > 0)
+ opinfo.pending_count--;
+
+ if (opinfo.pending_count > 0)
+ goto out;
+
+ dict = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
+ if (dict) {
+ ret = glusterd_op_start_rb_timer (dict);
+ if (ret)
+ goto out;
+ commit_ack_inject = _gf_false;
+ goto out;
+ }
+
+ commit_ack_inject = _gf_true;
out:
if (commit_ack_inject) {
if (ret)
ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, NULL);
- else if (!opinfo.pending_count) {
- glusterd_op_modify_op_ctx (op);
+ else
ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC, NULL);
- }
- /*else do nothing*/
}
return ret;
@@ -2590,6 +6923,7 @@ out:
return ret;
}
+
int32_t
glusterd_op_clear_errstr() {
opinfo.op_errstr = NULL;
@@ -2597,20 +6931,26 @@ glusterd_op_clear_errstr() {
}
int32_t
-glusterd_op_set_ctx (void *ctx)
+glusterd_op_set_ctx (glusterd_op_t op, void *ctx)
{
- opinfo.op_ctx = ctx;
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.op_ctx[op] = ctx;
return 0;
}
int32_t
-glusterd_op_reset_ctx ()
+glusterd_op_reset_ctx (glusterd_op_t op)
{
- glusterd_op_set_ctx (NULL);
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ glusterd_op_set_ctx (op, NULL);
return 0;
}
@@ -2623,39 +6963,53 @@ glusterd_op_txn_complete ()
int32_t op = -1;
int32_t op_ret = 0;
int32_t op_errno = 0;
+ int32_t cli_op = 0;
rpcsvc_request_t *req = NULL;
void *ctx = NULL;
+ gf_boolean_t ctx_free = _gf_false;
char *op_errstr = NULL;
priv = THIS->private;
GF_ASSERT (priv);
- op = glusterd_op_get_op ();
- ctx = glusterd_op_get_ctx ();
+ ret = glusterd_unlock (priv->uuid);
+
+ if (ret) {
+ gf_log ("glusterd", GF_LOG_CRITICAL,
+ "Unable to clear local lock, ret: %d", ret);
+ goto out;
+ }
+
+ gf_log ("glusterd", GF_LOG_INFO, "Cleared local lock");
+
op_ret = opinfo.op_ret;
op_errno = opinfo.op_errno;
+ cli_op = opinfo.cli_op;
req = opinfo.req;
if (opinfo.op_errstr)
op_errstr = opinfo.op_errstr;
+
opinfo.op_ret = 0;
opinfo.op_errno = 0;
- glusterd_op_clear_op ();
- glusterd_op_reset_ctx ();
- glusterd_op_clear_errstr ();
- ret = glusterd_unlock (MY_UUID);
+ op = glusterd_op_get_op ();
- /* unlock cant/shouldnt fail here!! */
- if (ret) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "Unable to clear local lock, ret: %d", ret);
- } else {
- gf_log ("glusterd", GF_LOG_INFO, "Cleared local lock");
+ if (op != -1) {
+ glusterd_op_clear_pending_op (op);
+ glusterd_op_clear_commit_op (op);
+ glusterd_op_clear_op (op);
+ ctx = glusterd_op_get_ctx (op);
+ ctx_free = glusterd_op_get_ctx_free (op);
+ glusterd_op_reset_ctx (op);
+ glusterd_op_clear_ctx_free (op);
+ glusterd_op_clear_errstr ();
}
- ret = glusterd_op_send_cli_response (op, op_ret,
+out:
+ pthread_mutex_unlock (&opinfo.lock);
+ ret = glusterd_op_send_cli_response (cli_op, op_ret,
op_errno, req, ctx, op_errstr);
if (ret) {
@@ -2665,11 +7019,11 @@ glusterd_op_txn_complete ()
ret = 0;
}
- glusterd_op_free_ctx (op, ctx);
+ if (ctx_free && ctx && (op != -1))
+ glusterd_op_free_ctx (op, ctx, ctx_free);
if (op_errstr && (strcmp (op_errstr, "")))
GF_FREE (op_errstr);
-
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -2689,6 +7043,38 @@ glusterd_op_ac_unlocked_all (glusterd_op_sm_event_t *event, void *ctx)
}
static int
+glusterd_op_stage_quota (dict_t *dict, char **op_errstr)
+{
+ int ret = 0;
+ char *volname = NULL;
+ gf_boolean_t exists = _gf_false;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (op_errstr);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
+ goto out;
+ }
+
+ exists = glusterd_check_volume_exists (volname);
+ if (!exists) {
+ gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
+ "does not exist",
+ volname);
+ *op_errstr = gf_strdup ("Invalid volume name");
+ ret = -1;
+ goto out;
+ }
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+static int
glusterd_op_ac_stage_op (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = -1;
@@ -2735,22 +7121,16 @@ glusterd_op_ac_stage_op (glusterd_op_sm_event_t *event, void *ctx)
static gf_boolean_t
glusterd_need_brick_op (glusterd_op_t op)
{
- gf_boolean_t ret = _gf_false;
-
- GF_ASSERT (GD_OP_NONE < op && op < GD_OP_MAX);
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
switch (op) {
case GD_OP_PROFILE_VOLUME:
- case GD_OP_STATUS_VOLUME:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- case GD_OP_HEAL_VOLUME:
- ret = _gf_true;
- break;
+ return _gf_true;
default:
- ret = _gf_false;
+ return _gf_false;
}
-
- return ret;
+ return _gf_false;
}
static dict_t*
@@ -2759,10 +7139,11 @@ glusterd_op_init_commit_rsp_dict (glusterd_op_t op)
dict_t *rsp_dict = NULL;
dict_t *op_ctx = NULL;
- GF_ASSERT (GD_OP_NONE < op && op < GD_OP_MAX);
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
if (glusterd_need_brick_op (op)) {
- op_ctx = glusterd_op_get_ctx ();
+ op_ctx = glusterd_op_get_ctx (op);
GF_ASSERT (op_ctx);
rsp_dict = dict_ref (op_ctx);
} else {
@@ -2776,11 +7157,11 @@ static int
glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
- glusterd_req_ctx_t *req_ctx = NULL;
+ glusterd_req_ctx_t *req_ctx = NULL;
int32_t status = 0;
char *op_errstr = NULL;
dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
+ dict_t *rsp_dict = NULL;
GF_ASSERT (ctx);
@@ -2791,38 +7172,23 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx)
rsp_dict = glusterd_op_init_commit_rsp_dict (req_ctx->op);
if (NULL == rsp_dict)
return -1;
-
- glusterd_op_commit_hook (req_ctx->op, dict, GD_COMMIT_HOOK_PRE);
-
- if (GD_OP_CLEARLOCKS_VOLUME == req_ctx->op) {
- /*clear locks should be run only on
- * originator glusterd*/
- status = 0;
-
- } else {
- status = glusterd_op_commit_perform (req_ctx->op, dict,
- &op_errstr, rsp_dict);
- }
+ status = glusterd_op_commit_perform (req_ctx->op, dict, &op_errstr,
+ rsp_dict);
if (status) {
- gf_log (THIS->name, GF_LOG_ERROR, "Commit failed: %d", status);
- } else {
- /* On successful commit */
- glusterd_op_commit_hook (req_ctx->op, dict,
- GD_COMMIT_HOOK_POST);
+ gf_log ("", GF_LOG_ERROR, "Commit failed: %d", status);
}
ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op,
status, op_errstr, rsp_dict);
- glusterd_op_fini_ctx ();
+ glusterd_op_fini_ctx (req_ctx->op);
if (op_errstr && (strcmp (op_errstr, "")))
GF_FREE (op_errstr);
if (rsp_dict)
dict_unref (rsp_dict);
-
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
@@ -2838,13 +7204,13 @@ glusterd_op_ac_send_commit_failed (glusterd_op_sm_event_t *event, void *ctx)
req_ctx = ctx;
- op_ctx = glusterd_op_get_ctx ();
+ op_ctx = glusterd_op_get_ctx (req_ctx->op);
ret = glusterd_op_commit_send_resp (req_ctx->req, req_ctx->op,
opinfo.op_ret, opinfo.op_errstr,
op_ctx);
- glusterd_op_fini_ctx ();
+ glusterd_op_fini_ctx (req_ctx->op);
if (opinfo.op_errstr && (strcmp (opinfo.op_errstr, ""))) {
GF_FREE (opinfo.op_errstr);
opinfo.op_errstr = NULL;
@@ -2917,7 +7283,11 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,
break;
case GD_OP_REMOVE_BRICK:
- ret = glusterd_op_stage_remove_brick (dict, op_errstr);
+ ret = glusterd_op_stage_remove_brick (dict);
+ break;
+
+ case GD_OP_LOG_FILENAME:
+ ret = glusterd_op_stage_log_filename (dict, op_errstr);
break;
case GD_OP_LOG_ROTATE:
@@ -2940,28 +7310,6 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,
ret = glusterd_op_stage_quota (dict, op_errstr);
break;
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_op_stage_status_volume (dict, op_errstr);
- break;
-
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_op_stage_rebalance (dict, op_errstr);
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_op_stage_heal_volume (dict, op_errstr);
- break;
-
- case GD_OP_STATEDUMP_VOLUME:
- ret = glusterd_op_stage_statedump_volume (dict,
- op_errstr);
- break;
- case GD_OP_CLEARLOCKS_VOLUME:
- ret = glusterd_op_stage_clearlocks_volume (dict,
- op_errstr);
- break;
-
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
op);
@@ -3009,11 +7357,15 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
break;
case GD_OP_RESET_VOLUME:
- ret = glusterd_op_reset_volume (dict, op_errstr);
+ ret = glusterd_op_reset_volume (dict);
break;
case GD_OP_REMOVE_BRICK:
- ret = glusterd_op_remove_brick (dict, op_errstr);
+ ret = glusterd_op_remove_brick (dict);
+ break;
+
+ case GD_OP_LOG_FILENAME:
+ ret = glusterd_op_log_filename (dict);
break;
case GD_OP_LOG_ROTATE:
@@ -3037,27 +7389,6 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
ret = glusterd_op_quota (dict, op_errstr);
break;
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_op_status_volume (dict, op_errstr, rsp_dict);
- break;
-
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_op_rebalance (dict, op_errstr, rsp_dict);
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_op_heal_volume (dict, op_errstr);
- break;
-
- case GD_OP_STATEDUMP_VOLUME:
- ret = glusterd_op_statedump_volume (dict, op_errstr);
- break;
-
- case GD_OP_CLEARLOCKS_VOLUME:
- ret = glusterd_op_clearlocks_volume (dict, op_errstr);
- break;
-
default:
gf_log ("", GF_LOG_ERROR, "Unknown op %d",
op);
@@ -3085,29 +7416,21 @@ _profile_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
}
int
-glusterd_profile_volume_brick_rsp (void *pending_entry,
+glusterd_profile_volume_brick_rsp (glusterd_brickinfo_t *brickinfo,
dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr, gd_node_type type)
+ char **op_errstr)
{
- int ret = 0;
- glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
- int32_t count = 0;
- char brick[PATH_MAX+1024] = {0};
- char key[256] = {0};
- char *full_brick = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
+ int ret = 0;
+ glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
+ int32_t count = 0;
+ char brick[PATH_MAX+1024] = {0};
+ char key[256] = {0};
+ char *full_brick = NULL;
GF_ASSERT (rsp_dict);
GF_ASSERT (op_ctx);
GF_ASSERT (op_errstr);
- GF_ASSERT (pending_entry);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
+ GF_ASSERT (brickinfo);
ret = dict_get_int32 (op_ctx, "count", &count);
if (ret) {
@@ -3116,13 +7439,8 @@ glusterd_profile_volume_brick_rsp (void *pending_entry,
count++;
}
snprintf (key, sizeof (key), "%d-brick", count);
- if (type == GD_NODE_BRICK) {
- brickinfo = pending_entry;
- snprintf (brick, sizeof (brick), "%s:%s", brickinfo->hostname,
- brickinfo->path);
- } else if (type == GD_NODE_NFS) {
- snprintf (brick, sizeof (brick), "%s", uuid_utoa (MY_UUID));
- }
+ snprintf (brick, sizeof (brick), "%s:%s", brickinfo->hostname,
+ brickinfo->path);
full_brick = gf_strdup (brick);
GF_ASSERT (full_brick);
ret = dict_set_dynstr (op_ctx, key, full_brick);
@@ -3135,280 +7453,21 @@ glusterd_profile_volume_brick_rsp (void *pending_entry,
return ret;
}
-//input-key: <replica-id>:<child-id>-*
-//output-key: <brick-id>-*
-void
-_heal_volume_add_shd_rsp (dict_t *this, char *key, data_t *value, void *data)
-{
- char new_key[256] = {0,};
- char int_str[16] = {0};
- data_t *new_value = NULL;
- char *rxl_end = NULL;
- char *rxl_child_end = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int rxl_id = 0;
- int rxl_child_id = 0;
- int brick_id = 0;
- int int_len = 0;
- int ret = 0;
- glusterd_heal_rsp_conv_t *rsp_ctx = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- rsp_ctx = data;
- rxl_end = strchr (key, '-');
- if (!rxl_end)
- goto out;
-
- int_len = strlen (key) - strlen (rxl_end);
- strncpy (int_str, key, int_len);
- int_str[int_len] = '\0';
- ret = gf_string2int (int_str, &rxl_id);
- if (ret)
- goto out;
-
- rxl_child_end = strchr (rxl_end + 1, '-');
- if (!rxl_child_end)
- goto out;
-
- int_len = strlen (rxl_end) - strlen (rxl_child_end) - 1;
- strncpy (int_str, rxl_end + 1, int_len);
- int_str[int_len] = '\0';
- ret = gf_string2int (int_str, &rxl_child_id);
- if (ret)
- goto out;
-
- volinfo = rsp_ctx->volinfo;
- brick_id = rxl_id * volinfo->replica_count + rxl_child_id;
-
- if (!strcmp (rxl_child_end, "-status")) {
- brickinfo = glusterd_get_brickinfo_by_position (volinfo,
- brick_id);
- if (!brickinfo)
- goto out;
- if (!glusterd_is_local_brick (rsp_ctx->this, volinfo,
- brickinfo))
- goto out;
- }
- new_value = data_copy (value);
- snprintf (new_key, sizeof (new_key), "%d%s", brick_id, rxl_child_end);
- dict_set (rsp_ctx->dict, new_key, new_value);
-
-out:
- return;
-}
-
-int
-glusterd_heal_volume_brick_rsp (dict_t *req_dict, dict_t *rsp_dict,
- dict_t *op_ctx, char **op_errstr)
-{
- int ret = 0;
- glusterd_heal_rsp_conv_t rsp_ctx = {0};
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_ctx);
- GF_ASSERT (op_errstr);
-
- ret = dict_get_str (req_dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- rsp_ctx.dict = op_ctx;
- rsp_ctx.volinfo = volinfo;
- rsp_ctx.this = THIS;
- dict_foreach (rsp_dict, _heal_volume_add_shd_rsp, &rsp_ctx);
-
-out:
- return ret;
-}
-
-void
-_status_volume_add_brick_rsp (dict_t *this, char *key, data_t *value,
- void *data)
-{
- char new_key[256] = {0,};
- data_t *new_value = 0;
- glusterd_pr_brick_rsp_conv_t *rsp_ctx = NULL;
-
- rsp_ctx = data;
- new_value = data_copy (value);
- snprintf (new_key, sizeof (new_key), "brick%d.%s", rsp_ctx->count, key);
- dict_set (rsp_ctx->dict, new_key, new_value);
-
- return;
-}
-
-int
-glusterd_status_volume_brick_rsp (dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr)
-{
- int ret = 0;
- glusterd_pr_brick_rsp_conv_t rsp_ctx = {0};
- int32_t count = 0;
- int index = 0;
-
- GF_ASSERT (rsp_dict);
- GF_ASSERT (op_ctx);
- GF_ASSERT (op_errstr);
-
- ret = dict_get_int32 (op_ctx, "count", &count);
- if (ret) {
- count = 0;
- } else {
- count++;
- }
- ret = dict_get_int32 (rsp_dict, "index", &index);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get node index");
- goto out;
- }
- dict_del (rsp_dict, "index");
-
- rsp_ctx.count = index;
- rsp_ctx.dict = op_ctx;
- dict_foreach (rsp_dict, _status_volume_add_brick_rsp, &rsp_ctx);
- ret = dict_set_int32 (op_ctx, "count", count);
-
-out:
- return ret;
-}
-
-int
-glusterd_defrag_volume_node_rsp (dict_t *req_dict, dict_t *rsp_dict,
- dict_t *op_ctx)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char key[256] = {0,};
- int32_t i = 0;
- char buf[1024] = {0,};
- char *node_str = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (req_dict);
-
- ret = dict_get_str (req_dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- if (rsp_dict) {
- ret = glusterd_defrag_volume_status_update (volinfo,
- rsp_dict);
- }
-
- if (!op_ctx) {
- dict_copy (rsp_dict, op_ctx);
- goto out;
- }
-
- ret = dict_get_int32 (op_ctx, "count", &i);
- i++;
-
- ret = dict_set_int32 (op_ctx, "count", i);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to set count");
-
- snprintf (buf, 1024, "%s", uuid_utoa (MY_UUID));
- node_str = gf_strdup (buf);
-
- snprintf (key, 256, "node-uuid-%d",i);
- ret = dict_set_dynstr (op_ctx, key, node_str);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set node-uuid");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "files-%d", i);
- ret = dict_set_uint64 (op_ctx, key, volinfo->rebalance_files);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set file count");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "size-%d", i);
- ret = dict_set_uint64 (op_ctx, key, volinfo->rebalance_data);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set size of xfer");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "lookups-%d", i);
- ret = dict_set_uint64 (op_ctx, key, volinfo->lookedup_files);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set lookedup file count");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "status-%d", i);
- ret = dict_set_int32 (op_ctx, key, volinfo->defrag_status);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set status");
-
- memset (key, 0 , 256);
- snprintf (key, 256, "failures-%d", i);
- ret = dict_set_uint64 (op_ctx, key, volinfo->rebalance_failures);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set failure count");
-
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", i);
- ret = dict_set_double (op_ctx, key, volinfo->rebalance_time);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set run-time");
-
-out:
- return ret;
-}
-
int32_t
-glusterd_handle_node_rsp (glusterd_req_ctx_t *req_ctx, void *pending_entry,
- glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx,
- char **op_errstr, gd_node_type type)
+glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo,
+ glusterd_op_t op, dict_t *rsp_dict, dict_t *op_ctx,
+ char **op_errstr)
{
- int ret = 0;
+ int ret = 0;
GF_ASSERT (op_errstr);
switch (op) {
case GD_OP_PROFILE_VOLUME:
- ret = glusterd_profile_volume_brick_rsp (pending_entry,
- rsp_dict, op_ctx,
- op_errstr, type);
- break;
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_status_volume_brick_rsp (rsp_dict, op_ctx,
- op_errstr);
- break;
-
- case GD_OP_DEFRAG_BRICK_VOLUME:
- glusterd_defrag_volume_node_rsp (req_ctx->dict,
- rsp_dict, op_ctx);
- break;
+ ret = glusterd_profile_volume_brick_rsp (brickinfo, rsp_dict,
+ op_ctx, op_errstr);
+ break;
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_heal_volume_brick_rsp (req_ctx->dict, rsp_dict,
- op_ctx, op_errstr);
- break;
default:
break;
}
@@ -3446,7 +7505,6 @@ glusterd_bricks_select_stop_volume (dict_t *dict, char **op_errstr)
goto out;
} else {
pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
list_add_tail (&pending_node->list, &opinfo.pending_bricks);
pending_node = NULL;
}
@@ -3469,7 +7527,6 @@ glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr)
int32_t i = 1;
char key[256] = {0,};
glusterd_pending_node_t *pending_node = NULL;
- int32_t force = 0;
ret = dict_get_str (dict, "volname", &volname);
@@ -3491,12 +7548,6 @@ glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr)
goto out;
}
- ret = dict_get_int32 (dict, "force", &force);
- if (ret) {
- gf_log (THIS->name, GF_LOG_INFO, "force flag is not set");
- ret = 0;
- goto out;
- }
while ( i <= count) {
snprintf (key, 256, "brick%d", i);
@@ -3518,7 +7569,6 @@ glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr)
goto out;
} else {
pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
list_add_tail (&pending_node->list, &opinfo.pending_bricks);
pending_node = NULL;
}
@@ -3549,7 +7599,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
priv = this->private;
GF_ASSERT (priv);
-
ret = dict_get_str (dict, "volname", &volname);
if (ret) {
gf_log ("glusterd", GF_LOG_ERROR, "volume name get failed");
@@ -3578,30 +7627,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
goto out;
break;
case GF_CLI_STATS_INFO:
- ret = dict_get_str_boolean (dict, "nfs", _gf_false);
- if (ret) {
- if (!glusterd_nodesvc_is_running ("nfs")) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "NFS server"
- " is not running");
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- }
- pending_node->node = priv->nfs;
- pending_node->type = GD_NODE_NFS;
- list_add_tail (&pending_node->list,
- &opinfo.pending_bricks);
- pending_node = NULL;
-
- ret = 0;
- goto out;
-
- }
list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
if (glusterd_is_brick_started (brickinfo)) {
pending_node = GF_CALLOC (1, sizeof (*pending_node),
@@ -3611,7 +7636,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
goto out;
} else {
pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
list_add_tail (&pending_node->list,
&opinfo.pending_bricks);
pending_node = NULL;
@@ -3621,40 +7645,13 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
break;
case GF_CLI_STATS_TOP:
- ret = dict_get_str_boolean (dict, "nfs", _gf_false);
- if (ret) {
- if (!glusterd_nodesvc_is_running ("nfs")) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "NFS server"
- " is not running");
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- }
- pending_node->node = priv->nfs;
- pending_node->type = GD_NODE_NFS;
- list_add_tail (&pending_node->list,
- &opinfo.pending_bricks);
- pending_node = NULL;
-
- ret = 0;
- goto out;
-
- }
ret = dict_get_str (dict, "brick", &brick);
if (!ret) {
- ret = glusterd_volume_brickinfo_get_by_brick (brick, volinfo,
- &brickinfo);
+ ret = glusterd_volume_brickinfo_get_by_brick (brick,
+ volinfo, &brickinfo);
if (ret)
goto out;
- if (!glusterd_is_brick_started (brickinfo))
- goto out;
-
pending_node = GF_CALLOC (1, sizeof (*pending_node),
gf_gld_mt_pending_node_t);
if (!pending_node) {
@@ -3662,7 +7659,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
goto out;
} else {
pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
list_add_tail (&pending_node->list,
&opinfo.pending_bricks);
pending_node = NULL;
@@ -3679,7 +7675,6 @@ glusterd_bricks_select_profile_volume (dict_t *dict, char **op_errstr)
goto out;
} else {
pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
list_add_tail (&pending_node->list,
&opinfo.pending_bricks);
pending_node = NULL;
@@ -3705,371 +7700,6 @@ out:
}
static int
-_add_rxlator_to_dict (dict_t *dict, char *volname, int index, int count)
-{
- int ret = -1;
- char key[128] = {0,};
- char *xname = NULL;
-
- snprintf (key, sizeof (key), "xl-%d", count);
- ret = gf_asprintf (&xname, "%s-replicate-%d", volname, index);
- if (ret == -1)
- goto out;
-
- ret = dict_set_dynstr (dict, key, xname);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (dict, xname, index);
-out:
- return ret;
-}
-
-int
-_select_rxlators_with_local_bricks (xlator_t *this, glusterd_volinfo_t *volinfo,
- dict_t *dict)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int index = 1;
- int rxlator_count = 0;
- int replica_count = 0;
- gf_boolean_t add = _gf_false;
-
- priv = this->private;
- replica_count = volinfo->replica_count;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_is_null (brickinfo->uuid))
- (void)glusterd_resolve_brick (brickinfo);
-
- if (!uuid_compare (MY_UUID, brickinfo->uuid))
- add = _gf_true;
- if (index % replica_count == 0) {
- if (add) {
- _add_rxlator_to_dict (dict, volinfo->volname,
- (index-1)/replica_count,
- rxlator_count);
- rxlator_count++;
- }
- add = _gf_false;
- }
-
- index++;
- }
- return rxlator_count;
-}
-
-int
-_select_rxlators_for_full_self_heal (xlator_t *this,
- glusterd_volinfo_t *volinfo,
- dict_t *dict)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int index = 1;
- int rxlator_count = 0;
- int replica_count = 0;
- uuid_t candidate = {0};
-
- priv = this->private;
- replica_count = volinfo->replica_count;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_is_null (brickinfo->uuid))
- (void)glusterd_resolve_brick (brickinfo);
-
- if (uuid_compare (brickinfo->uuid, candidate) > 0)
- uuid_copy (candidate, brickinfo->uuid);
-
- if (index % replica_count == 0) {
- if (!uuid_compare (MY_UUID, candidate)) {
- _add_rxlator_to_dict (dict, volinfo->volname,
- (index-1)/replica_count,
- rxlator_count);
- rxlator_count++;
- }
- uuid_clear (candidate);
- }
-
- index++;
- }
- return rxlator_count;
-}
-
-static int
-glusterd_bricks_select_heal_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- char msg[2048] = {0,};
- glusterd_pending_node_t *pending_node = NULL;
- gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID;
- int rxlator_count = 0;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "volume name get failed");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist",
- volname);
-
- *op_errstr = gf_strdup (msg);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op);
- if (ret || (heal_op == GF_AFR_OP_INVALID)) {
- gf_log ("glusterd", GF_LOG_ERROR, "heal op invalid");
- goto out;
- }
-
- switch (heal_op) {
- case GF_AFR_OP_HEAL_FULL:
- rxlator_count = _select_rxlators_for_full_self_heal (this,
- volinfo,
- dict);
- break;
- default:
- rxlator_count = _select_rxlators_with_local_bricks (this,
- volinfo,
- dict);
- break;
- }
- if (!rxlator_count)
- goto out;
- ret = dict_set_int32 (dict, "count", rxlator_count);
- if (ret)
- goto out;
-
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- } else {
- pending_node->node = priv->shd;
- pending_node->type = GD_NODE_SHD;
- list_add_tail (&pending_node->list,
- &opinfo.pending_bricks);
- pending_node = NULL;
- }
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning ret %d", ret);
- return ret;
-
-}
-
-
-static int
-glusterd_bricks_select_rebalance_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- char msg[2048] = {0,};
- glusterd_pending_node_t *pending_node = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "volume name get failed");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist",
- volname);
-
- *op_errstr = gf_strdup (msg);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- } else {
- pending_node->node = volinfo;
- pending_node->type = GD_NODE_REBALANCE;
- list_add_tail (&pending_node->list,
- &opinfo.pending_bricks);
- pending_node = NULL;
- }
-
-out:
- return ret;
-}
-
-
-
-
-static int
-glusterd_bricks_select_status_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- int cmd = 0;
- int brick_index = -1;
- char *volname = NULL;
- char *brickname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_pending_node_t *pending_node = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (dict);
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_int32 (dict, "cmd", &cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get status type");
- goto out;
- }
-
- if (cmd & GF_CLI_STATUS_ALL)
- goto out;
-
- switch (cmd & GF_CLI_STATUS_MASK) {
- case GF_CLI_STATUS_MEM:
- case GF_CLI_STATUS_CLIENTS:
- case GF_CLI_STATUS_INODE:
- case GF_CLI_STATUS_FD:
- case GF_CLI_STATUS_CALLPOOL:
- case GF_CLI_STATUS_NFS:
- case GF_CLI_STATUS_SHD:
- break;
- default:
- goto out;
- }
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get volname");
- goto out;
- }
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- goto out;
- }
-
- if ( (cmd & GF_CLI_STATUS_BRICK) != 0) {
- ret = dict_get_str (dict, "brick", &brickname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get brick");
- goto out;
- }
- ret = glusterd_volume_brickinfo_get_by_brick (brickname,
- volinfo,
- &brickinfo);
- if (ret)
- goto out;
-
- if (uuid_compare (brickinfo->uuid, MY_UUID)||
- !glusterd_is_brick_started (brickinfo))
- goto out;
-
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- }
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- pending_node->index = 0;
- list_add_tail (&pending_node->list, &opinfo.pending_bricks);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_NFS) != 0) {
- if (!glusterd_nodesvc_is_running ("nfs")) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "NFS server is not running");
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- }
- pending_node->node = priv->nfs;
- pending_node->type = GD_NODE_NFS;
- pending_node->index = 0;
- list_add_tail (&pending_node->list, &opinfo.pending_bricks);
-
- ret = 0;
- } else if ((cmd & GF_CLI_STATUS_SHD) != 0) {
- if (!glusterd_nodesvc_is_running ("glustershd")) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Self-heal daemon is not running");
- goto out;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- goto out;
- }
- pending_node->node = priv->shd;
- pending_node->type = GD_NODE_SHD;
- pending_node->index = 0;
- list_add_tail (&pending_node->list, &opinfo.pending_bricks);
-
- ret = 0;
- } else {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- brick_index++;
- if (uuid_compare (brickinfo->uuid, MY_UUID) ||
- !glusterd_is_brick_started (brickinfo)) {
- continue;
- }
- pending_node = GF_CALLOC (1, sizeof (*pending_node),
- gf_gld_mt_pending_node_t);
- if (!pending_node) {
- ret = -1;
- gf_log (THIS->name ,GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- }
- pending_node->node = brickinfo;
- pending_node->type = GD_NODE_BRICK;
- pending_node->index = brick_index;
- list_add_tail (&pending_node->list,
- &opinfo.pending_bricks);
- pending_node = NULL;
- }
- }
-out:
- return ret;
-}
-
-static int
glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
@@ -4078,7 +7708,6 @@ glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx)
xlator_t *this = NULL;
glusterd_op_t op = GD_OP_NONE;
glusterd_req_ctx_t *req_ctx = NULL;
- char *op_errstr = NULL;
this = THIS;
priv = this->private;
@@ -4090,17 +7719,13 @@ glusterd_op_ac_send_brick_op (glusterd_op_sm_event_t *event, void *ctx)
gf_gld_mt_op_allack_ctx_t);
op = glusterd_op_get_op ();
req_ctx->op = op;
- uuid_copy (req_ctx->uuid, MY_UUID);
- ret = glusterd_op_build_payload (&req_ctx->dict, &op_errstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Building payload failed");
- opinfo.op_errstr = op_errstr;
+ uuid_copy (req_ctx->uuid, priv->uuid);
+ ret = glusterd_op_build_payload (op, &req_ctx->dict);
+ if (ret)//TODO:what to do??
goto out;
- }
}
- proc = &priv->gfs_mgmt->proctable[GLUSTERD_BRICK_OP];
+ proc = &priv->gfs_mgmt->proctable[GD_MGMT_BRICK_OP];
if (proc->fn) {
ret = proc->fn (NULL, this, req_ctx);
if (ret)
@@ -4124,12 +7749,12 @@ glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx)
{
int ret = 0;
glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
char *op_errstr = NULL;
glusterd_op_t op = GD_OP_NONE;
- gd_node_type type = GD_NODE_NONE;
dict_t *op_ctx = NULL;
+ gf_boolean_t free_errstr = _gf_true;
glusterd_req_ctx_t *req_ctx = NULL;
- void *pending_entry = NULL;
GF_ASSERT (event);
GF_ASSERT (ctx);
@@ -4138,25 +7763,25 @@ glusterd_op_ac_rcvd_brick_op_acc (glusterd_op_sm_event_t *event, void *ctx)
req_ctx = ev_ctx->commit_ctx;
GF_ASSERT (req_ctx);
- op = req_ctx->op;
- op_ctx = glusterd_op_get_ctx ();
- pending_entry = ev_ctx->pending_node->node;
- type = ev_ctx->pending_node->type;
+ brickinfo = ev_ctx->brickinfo;
+ GF_ASSERT (brickinfo);
- ret = glusterd_remove_pending_entry (&opinfo.pending_bricks,
- pending_entry);
+ ret = glusterd_remove_pending_entry (&opinfo.pending_bricks, brickinfo);
if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "unknown response received ");
+ gf_log ("glusterd", GF_LOG_ERROR, "unknown response received "
+ "from %s:%s", brickinfo->hostname, brickinfo->path);
ret = -1;
+ free_errstr = _gf_true;
goto out;
}
if (opinfo.brick_pending_count > 0)
opinfo.brick_pending_count--;
+ op = req_ctx->op;
+ op_ctx = glusterd_op_get_ctx (op);
- glusterd_handle_node_rsp (req_ctx, pending_entry, op, ev_ctx->rsp_dict,
- op_ctx, &op_errstr, type);
-
+ glusterd_handle_brick_rsp (brickinfo, op, ev_ctx->rsp_dict,
+ op_ctx, &op_errstr);
if (opinfo.brick_pending_count > 0)
goto out;
@@ -4194,17 +7819,6 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr)
ret = glusterd_bricks_select_profile_volume (dict, op_errstr);
break;
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_bricks_select_heal_volume (dict, op_errstr);
- break;
-
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_bricks_select_status_volume (dict, op_errstr);
- break;
-
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_bricks_select_rebalance_volume (dict, op_errstr);
- break;
default:
break;
}
@@ -4228,32 +7842,30 @@ glusterd_op_sm_t glusterd_op_state_default [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_lock_sent [] = {
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_rcvd_lock_acc}, //EVENT_RCVD_ACC
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_send_stage_op}, //EVENT_ALL_ACC
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, //EVENT_RCVD_RJT
+ {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_RCVD_RJT
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_LOCK_SENT, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_locked [] = {
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_LOCKED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_LOCKED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_RCVD_ACC
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4264,32 +7876,30 @@ glusterd_op_sm_t glusterd_op_state_locked [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_LOCKED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_stage_op_sent [] = {
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_rcvd_stage_op_acc}, //EVENT_RCVD_ACC
- {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, //EVENT_ALL_ACC
+ {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, //EVENT_ALL_ACC
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_send_brick_op}, //EVENT_STAGE_ACC
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, //EVENT_RCVD_RJT
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_STAGE_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_stage_op_failed [] = {
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_stage_op_failed}, //EVENT_RCVD_ACC
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4298,16 +7908,15 @@ glusterd_op_sm_t glusterd_op_state_stage_op_failed [] = {
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK
- {GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_STAGE_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_staged [] = {
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_STAGED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_STAGED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_RCVD_ACC
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4318,14 +7927,13 @@ glusterd_op_sm_t glusterd_op_state_staged [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_STAGED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_brick_op_sent [] = {
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_rcvd_brick_op_acc}, //EVENT_RCVD_ACC
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4334,16 +7942,15 @@ glusterd_op_sm_t glusterd_op_state_brick_op_sent [] = {
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_BRICK_OP
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_send_commit_op}, //EVENT_ALL_ACK
- {GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_BRICK_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_brick_op_failed [] = {
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_ACC
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4352,16 +7959,15 @@ glusterd_op_sm_t glusterd_op_state_brick_op_failed [] = {
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_BRICK_OP
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK
- {GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_BRICK_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_brick_committed [] = {
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_rcvd_brick_op_acc}, //EVENT_RCVD_ACC
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4372,14 +7978,13 @@ glusterd_op_sm_t glusterd_op_state_brick_committed [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_COMMITED, glusterd_op_ac_commit_op}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_BRICK_COMMITTED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_brick_commit_failed [] = {
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_brick_op_failed}, //EVENT_RCVD_ACC
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4390,14 +7995,13 @@ glusterd_op_sm_t glusterd_op_state_brick_commit_failed [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_send_commit_failed}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_BRICK_COMMIT_FAILED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_commit_op_failed [] = {
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_commit_op_failed}, //EVENT_RCVD_ACC
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4406,16 +8010,15 @@ glusterd_op_sm_t glusterd_op_state_commit_op_failed [] = {
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK
- {GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_COMMIT_OP_FAILED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_commit_op_sent [] = {
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_rcvd_commit_op_acc}, //EVENT_RCVD_ACC
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACC
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4424,16 +8027,15 @@ glusterd_op_sm_t glusterd_op_state_commit_op_sent [] = {
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_START_UNLOCK
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_COMMIT_OP_SENT, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_committed [] = {
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_COMMITED, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_COMMITED, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_RCVD_ACC
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_ALL_ACC
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_STAGE_ACC
@@ -4444,45 +8046,26 @@ glusterd_op_sm_t glusterd_op_state_committed [] = {
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_local_unlock}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_COMMITED, glusterd_op_ac_none}, //EVENT_MAX
};
glusterd_op_sm_t glusterd_op_state_unlock_sent [] = {
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_NONE
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_lock}, //EVENT_LOCK
+ {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_LOCK
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_rcvd_unlock_acc}, //EVENT_RCVD_ACC
{GD_OP_STATE_DEFAULT, glusterd_op_ac_unlocked_all}, //EVENT_ALL_ACC
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_STAGE_ACC
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_rcvd_unlock_acc}, //EVENT_RCVD_RJT
+ {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_RCVD_RJT
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_STAGE_OP
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
+ {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
+ {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_START_UNLOCK
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_ALL_ACK
- {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
{GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_none}, //EVENT_MAX
};
-glusterd_op_sm_t glusterd_op_state_ack_drain [] = {
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_NONE
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none},//EVENT_START_LOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_lock}, //EVENT_LOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, //EVENT_RCVD_ACC
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_ALL_ACC
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_STAGE_ACC
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_COMMIT_ACC
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_send_unlock_drain}, //EVENT_RCVD_RJT
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_STAGE_OP
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_COMMIT_OP
- {GD_OP_STATE_DEFAULT, glusterd_op_ac_unlock}, //EVENT_UNLOCK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_START_UNLOCK
- {GD_OP_STATE_UNLOCK_SENT, glusterd_op_ac_send_unlock}, //EVENT_ALL_ACK
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_LOCAL_UNLOCK_NO_RESP
- {GD_OP_STATE_ACK_DRAIN, glusterd_op_ac_none}, //EVENT_MAX
-};
glusterd_op_sm_t *glusterd_op_state_table [] = {
glusterd_op_state_default,
@@ -4498,8 +8081,7 @@ glusterd_op_sm_t *glusterd_op_state_table [] = {
glusterd_op_state_brick_op_sent,
glusterd_op_state_brick_op_failed,
glusterd_op_state_brick_committed,
- glusterd_op_state_brick_commit_failed,
- glusterd_op_state_ack_drain
+ glusterd_op_state_brick_commit_failed
};
int
@@ -4541,7 +8123,7 @@ glusterd_op_sm_inject_event (glusterd_op_sm_event_type_t event_type,
event->ctx = ctx;
- gf_log ("glusterd", GF_LOG_DEBUG, "Enqueue event: '%s'",
+ gf_log ("glusterd", GF_LOG_DEBUG, "Enqueuing event: '%s'",
glusterd_op_sm_event_name_get (event->event));
list_add_tail (&event->list, &gd_op_sm_queue);
@@ -4560,14 +8142,6 @@ glusterd_destroy_req_ctx (glusterd_req_ctx_t *ctx)
}
void
-glusterd_destroy_local_unlock_ctx (uuid_t *ctx)
-{
- if (!ctx)
- return;
- GF_FREE (ctx);
-}
-
-void
glusterd_destroy_op_event_ctx (glusterd_op_sm_event_t *event)
{
if (!event)
@@ -4582,9 +8156,6 @@ glusterd_destroy_op_event_ctx (glusterd_op_sm_event_t *event)
case GD_OP_EVENT_ALL_ACK:
glusterd_destroy_req_ctx (event->ctx);
break;
- case GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP:
- glusterd_destroy_local_unlock_ctx (event->ctx);
- break;
default:
break;
}
@@ -4596,16 +8167,11 @@ glusterd_op_sm ()
glusterd_op_sm_event_t *event = NULL;
glusterd_op_sm_event_t *tmp = NULL;
int ret = -1;
- int lock_err = 0;
glusterd_op_sm_ac_fn handler = NULL;
glusterd_op_sm_t *state = NULL;
glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
- if ((lock_err = pthread_mutex_trylock (&gd_op_sm_lock))) {
- gf_log (THIS->name, GF_LOG_DEBUG, "lock failed due to %s",
- strerror (lock_err));
- goto lock_failed;
- }
+ (void ) pthread_mutex_lock (&gd_op_sm_lock);
while (!list_empty (&gd_op_sm_queue)) {
@@ -4655,8 +8221,6 @@ glusterd_op_sm ()
(void ) pthread_mutex_unlock (&gd_op_sm_lock);
ret = 0;
-lock_failed:
-
return ret;
}
@@ -4667,7 +8231,9 @@ glusterd_op_set_op (glusterd_op_t op)
GF_ASSERT (op < GD_OP_MAX);
GF_ASSERT (op > GD_OP_NONE);
- opinfo.op = op;
+ opinfo.op[op] = 1;
+ opinfo.pending_op[op] = 1;
+ opinfo.commit_op[op] = 1;
return 0;
@@ -4677,10 +8243,42 @@ int32_t
glusterd_op_get_op ()
{
- return opinfo.op;
+ int i = 0;
+ int32_t ret = 0;
+
+ for ( i = 0; i < GD_OP_MAX; i++) {
+ if (opinfo.op[i])
+ break;
+ }
+
+ if ( i == GD_OP_MAX)
+ ret = -1;
+ else
+ ret = i;
+
+ return ret;
}
+
+int32_t
+glusterd_op_set_cli_op (glusterd_op_t op)
+{
+
+ int32_t ret = 0;
+
+ ret = pthread_mutex_trylock (&opinfo.lock);
+
+ if (ret)
+ goto out;
+
+ opinfo.cli_op = op;
+
+out:
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
int32_t
glusterd_op_set_req (rpcsvc_request_t *req)
{
@@ -4691,10 +8289,39 @@ glusterd_op_set_req (rpcsvc_request_t *req)
}
int32_t
+glusterd_op_clear_pending_op (glusterd_op_t op)
+{
+
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.pending_op[op] = 0;
+
+ return 0;
+
+}
+
+int32_t
+glusterd_op_clear_commit_op (glusterd_op_t op)
+{
+
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.commit_op[op] = 0;
+
+ return 0;
+
+}
+
+int32_t
glusterd_op_clear_op (glusterd_op_t op)
{
- opinfo.op = GD_OP_NONE;
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.op[op] = 0;
return 0;
@@ -4706,8 +8333,6 @@ glusterd_op_init_ctx (glusterd_op_t op)
int ret = 0;
dict_t *dict = NULL;
- GF_ASSERT (GD_OP_NONE < op && op < GD_OP_MAX);
-
if (_gf_false == glusterd_need_brick_op (op)) {
gf_log ("", GF_LOG_DEBUG, "Received op: %d, returning", op);
goto out;
@@ -4717,7 +8342,10 @@ glusterd_op_init_ctx (glusterd_op_t op)
ret = -1;
goto out;
}
- ret = glusterd_op_set_ctx (dict);
+ ret = glusterd_op_set_ctx (op, dict);
+ if (ret)
+ goto out;
+ ret = glusterd_op_set_ctx_free (op, _gf_true);
if (ret)
goto out;
out:
@@ -4728,32 +8356,36 @@ out:
int32_t
-glusterd_op_fini_ctx ()
+glusterd_op_fini_ctx (glusterd_op_t op)
{
dict_t *dict = NULL;
- dict = glusterd_op_get_ctx ();
- if (dict)
- dict_unref (dict);
-
- glusterd_op_reset_ctx ();
+ if (glusterd_op_get_ctx_free (op)) {
+ dict = glusterd_op_get_ctx (op);
+ if (dict)
+ dict_unref (dict);
+ }
+ glusterd_op_reset_ctx (op);
return 0;
}
int32_t
-glusterd_op_free_ctx (glusterd_op_t op, void *ctx)
+glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free)
{
- if (ctx) {
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ if (ctx && ctx_free) {
switch (op) {
case GD_OP_CREATE_VOLUME:
- case GD_OP_DELETE_VOLUME:
case GD_OP_STOP_VOLUME:
case GD_OP_ADD_BRICK:
case GD_OP_REMOVE_BRICK:
case GD_OP_REPLACE_BRICK:
+ case GD_OP_LOG_FILENAME:
case GD_OP_LOG_ROTATE:
case GD_OP_SYNC_VOLUME:
case GD_OP_SET_VOLUME:
@@ -4762,30 +8394,63 @@ glusterd_op_free_ctx (glusterd_op_t op, void *ctx)
case GD_OP_GSYNC_SET:
case GD_OP_QUOTA:
case GD_OP_PROFILE_VOLUME:
- case GD_OP_STATUS_VOLUME:
- case GD_OP_REBALANCE:
- case GD_OP_HEAL_VOLUME:
- case GD_OP_STATEDUMP_VOLUME:
- case GD_OP_CLEARLOCKS_VOLUME:
- case GD_OP_DEFRAG_BRICK_VOLUME:
dict_unref (ctx);
break;
+ case GD_OP_DELETE_VOLUME:
+ GF_FREE (ctx);
+ break;
default:
GF_ASSERT (0);
break;
}
}
-
- glusterd_op_reset_ctx ();
return 0;
}
void *
-glusterd_op_get_ctx ()
+glusterd_op_get_ctx (glusterd_op_t op)
+{
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ return opinfo.op_ctx[op];
+
+}
+
+int32_t
+glusterd_op_set_ctx_free (glusterd_op_t op, gf_boolean_t ctx_free)
+{
+
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.ctx_free[op] = ctx_free;
+
+ return 0;
+
+}
+
+int32_t
+glusterd_op_clear_ctx_free (glusterd_op_t op)
+{
+
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
+
+ opinfo.ctx_free[op] = _gf_false;
+
+ return 0;
+
+}
+
+gf_boolean_t
+glusterd_op_get_ctx_free (glusterd_op_t op)
{
+ GF_ASSERT (op < GD_OP_MAX);
+ GF_ASSERT (op > GD_OP_NONE);
- return opinfo.op_ctx;
+ return opinfo.ctx_free[op];
}
@@ -4797,3 +8462,163 @@ glusterd_op_sm_init ()
return 0;
}
+int32_t
+glusterd_opinfo_unlock(){
+ return (pthread_mutex_unlock(&opinfo.lock));
+}
+int32_t
+glusterd_volume_stats_write_perf (char *brick_path, int32_t blk_size,
+ int32_t blk_count, double *throughput, double *time)
+{
+ int32_t fd = -1;
+ int32_t input_fd = -1;
+ char export_path[1024];
+ char *buf = NULL;
+ int32_t iter = 0;
+ int32_t ret = -1;
+ int64_t total_blks = 0;
+ struct timeval begin, end = {0, };
+
+
+ GF_VALIDATE_OR_GOTO ("stripe", brick_path, out);
+
+ snprintf (export_path, sizeof(export_path), "%s/%s",
+ brick_path, ".gf_tmp_stats_perf");
+ fd = open (export_path, O_CREAT|O_RDWR, S_IRWXU);
+ if (fd == -1)
+ return errno;
+ buf = GF_MALLOC (blk_size * sizeof(*buf), gf_common_mt_char);
+
+ if (!buf)
+ return ret;
+
+ input_fd = open("/dev/zero", O_RDONLY);
+ if (input_fd == -1)
+ return errno;
+ gettimeofday (&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (input_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ ret = 0;
+ if (total_blks != (blk_size * blk_count)) {
+ gf_log ("glusterd", GF_LOG_WARNING, "Errors in write");
+ ret = -1;
+ goto out;
+ }
+
+ gettimeofday (&end, NULL);
+ *time = (end.tv_sec - begin.tv_sec) * 1e6
+ + (end.tv_usec - begin.tv_usec);
+
+ *throughput = total_blks / *time;
+ gf_log ("glusterd", GF_LOG_INFO, "Throughput %.2f MBps time %.2f secs bytes "
+ "written %"PRId64, *throughput, *time / 1e6, total_blks);
+out:
+ if (fd >= 0)
+ close (fd);
+ if (input_fd >= 0)
+ close (input_fd);
+ if (buf)
+ GF_FREE (buf);
+ unlink (export_path);
+ return ret;
+}
+
+int32_t
+glusterd_volume_stats_read_perf (char *brick_path, int32_t blk_size,
+ int32_t blk_count, double *throughput, double *time)
+{
+ int32_t fd = -1;
+ int32_t output_fd = -1;
+ int32_t input_fd = -1;
+ char export_path[1024];
+ char *buf = NULL;
+ int32_t iter = 0;
+ int32_t ret = -1;
+ int64_t total_blks = 0;
+ struct timeval begin, end = {0, };
+
+
+ GF_VALIDATE_OR_GOTO ("glusterd", brick_path, out);
+
+ snprintf (export_path, sizeof(export_path), "%s/%s",
+ brick_path, ".gf_tmp_stats_perf");
+ fd = open (export_path, O_CREAT|O_RDWR, S_IRWXU);
+ if (fd == -1)
+ return errno;
+ buf = GF_MALLOC (blk_size * sizeof(*buf), gf_common_mt_char);
+
+ if (!buf)
+ return ret;
+
+ output_fd = open("/dev/null", O_RDWR);
+ if (output_fd == -1)
+ return errno;
+ input_fd = open("/dev/zero", O_RDONLY);
+ if (input_fd == -1)
+ return errno;
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (input_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ }
+
+
+ lseek (fd, 0L, 0);
+ gettimeofday (&begin, NULL);
+ for (iter = 0; iter < blk_count; iter++) {
+ ret = read (fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ ret = write (output_fd, buf, blk_size);
+ if (ret != blk_size) {
+ ret = -1;
+ goto out;
+ }
+ total_blks += ret;
+ }
+ ret = 0;
+ if (total_blks != (blk_size * blk_count)) {
+ gf_log ("glusterd", GF_LOG_WARNING, "Errors in write");
+ ret = -1;
+ goto out;
+ }
+
+ gettimeofday (&end, NULL);
+ *time = (end.tv_sec - begin.tv_sec) * 1e6
+ + (end.tv_usec - begin.tv_usec);
+
+ *throughput = total_blks / *time;
+ gf_log ("glusterd", GF_LOG_INFO, "Throughput %.2f MBps time %.2f secs bytes "
+ "read %"PRId64, *throughput, *time / 1e6, total_blks);
+out:
+ if (fd >= 0)
+ close (fd);
+ if (input_fd >= 0)
+ close (input_fd);
+ if (output_fd >= 0)
+ close (output_fd);
+ if (buf)
+ GF_FREE (buf);
+ unlink (export_path);
+ return ret;
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
index 7316b6fbb..78036acb7 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -58,7 +58,6 @@ typedef enum glusterd_op_sm_state_ {
GD_OP_STATE_BRICK_OP_FAILED,
GD_OP_STATE_BRICK_COMMITTED,
GD_OP_STATE_BRICK_COMMIT_FAILED,
- GD_OP_STATE_ACK_DRAIN,
GD_OP_STATE_MAX,
} glusterd_op_sm_state_t;
@@ -76,7 +75,6 @@ typedef enum glusterd_op_sm_event_type_ {
GD_OP_EVENT_UNLOCK,
GD_OP_EVENT_START_UNLOCK,
GD_OP_EVENT_ALL_ACK,
- GD_OP_EVENT_LOCAL_UNLOCK_NO_RESP,
GD_OP_EVENT_MAX
} glusterd_op_sm_event_type_t;
@@ -106,18 +104,29 @@ struct glusterd_op_info_ {
int32_t pending_count;
int32_t brick_pending_count;
int32_t op_count;
- glusterd_op_t op;
+ glusterd_op_t op[GD_OP_MAX];
+ glusterd_op_t pending_op[GD_OP_MAX];
+ glusterd_op_t commit_op[GD_OP_MAX];
struct list_head op_peers;
- void *op_ctx;
+ void *op_ctx[GD_OP_MAX];
rpcsvc_request_t *req;
int32_t op_ret;
int32_t op_errno;
+ pthread_mutex_t lock;
+ int32_t cli_op;
+ gf_boolean_t ctx_free[GD_OP_MAX];
char *op_errstr;
struct list_head pending_bricks;
};
typedef struct glusterd_op_info_ glusterd_op_info_t;
+struct glusterd_op_delete_volume_ctx_ {
+ char volume_name[GD_VOLUME_NAME_MAX];
+};
+
+typedef struct glusterd_op_delete_volume_ctx_ glusterd_op_delete_volume_ctx_t;
+
struct glusterd_op_log_filename_ctx_ {
char volume_name[GD_VOLUME_NAME_MAX];
char brick[GD_VOLUME_NAME_MAX];
@@ -146,7 +155,7 @@ typedef struct glusterd_op_brick_rsp_ctx_ {
char *op_errstr;
dict_t *rsp_dict;
glusterd_req_ctx_t *commit_ctx;
- glusterd_pending_node_t *pending_node;
+ glusterd_brickinfo_t *brickinfo;
} glusterd_op_brick_rsp_ctx_t;
typedef struct glusterd_pr_brick_rsp_conv_t {
@@ -154,18 +163,12 @@ typedef struct glusterd_pr_brick_rsp_conv_t {
dict_t *dict;
} glusterd_pr_brick_rsp_conv_t;
-typedef struct glusterd_heal_rsp_conv_ {
- dict_t *dict;
- glusterd_volinfo_t *volinfo;
- xlator_t *this;
-} glusterd_heal_rsp_conv_t;
-
-typedef struct glusterd_status_rsp_conv_ {
- int count;
- int brick_index_max;
- int other_count;
- dict_t *dict;
-} glusterd_status_rsp_conv_t;
+typedef struct glusterd_gsync_slaves {
+ char *slave;
+ char *host_uuid;
+ int ret_status;
+ char rmt_hostname[256];
+} glusterd_gsync_slaves_t;
typedef struct glusterd_gsync_status_temp {
dict_t *rsp_dict;
@@ -185,13 +188,19 @@ int
glusterd_op_sm ();
int32_t
-glusterd_op_set_ctx (void *ctx);
+glusterd_op_set_ctx (glusterd_op_t op, void *ctx);
int32_t
glusterd_op_set_op (glusterd_op_t op);
+int32_t
+glusterd_op_clear_pending_op (glusterd_op_t op);
+
+int32_t
+glusterd_op_clear_commit_op (glusterd_op_t op);
+
int
-glusterd_op_build_payload (dict_t **req, char **op_errstr);
+glusterd_op_build_payload (glusterd_op_t op, dict_t **req);
int32_t
glusterd_op_stage_validate (glusterd_op_t op, dict_t *req, char **op_errstr,
@@ -202,12 +211,15 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *req, char **op_errstr,
dict_t* dict);
void *
-glusterd_op_get_ctx ();
+glusterd_op_get_ctx (glusterd_op_t op);
int32_t
glusterd_op_set_req (rpcsvc_request_t *req);
int32_t
+glusterd_op_set_cli_op (glusterd_op_t op);
+
+int32_t
glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
int32_t op_errno, rpcsvc_request_t *req,
void *ctx, char *op_errstr);
@@ -215,10 +227,28 @@ int32_t
glusterd_op_get_op ();
int32_t
-glusterd_op_clear_op ();
+glusterd_op_clear_pending_op (glusterd_op_t op);
+
+int32_t
+glusterd_op_clear_commit_op (glusterd_op_t op);
int32_t
-glusterd_op_free_ctx (glusterd_op_t op, void *ctx);
+glusterd_op_clear_op (glusterd_op_t op);
+
+int32_t
+glusterd_op_free_ctx (glusterd_op_t op, void *ctx, gf_boolean_t ctx_free);
+
+int32_t
+glusterd_opinfo_unlock();
+
+int32_t
+glusterd_op_set_ctx_free (glusterd_op_t op, gf_boolean_t ctx_free);
+
+int32_t
+glusterd_op_clear_ctx_free (glusterd_op_t op);
+
+gf_boolean_t
+glusterd_op_get_ctx_free (glusterd_op_t op);
int
glusterd_check_option_exists(char *optstring, char **completion);
@@ -226,8 +256,13 @@ glusterd_check_option_exists(char *optstring, char **completion);
int
set_xlator_option (dict_t *dict, char *key, char *value);
+char *
+glusterd_check_brick_rb_part (char *bricks, int count, glusterd_volinfo_t *volinfo);
+
void
glusterd_do_replace_brick (void *data);
+int
+glusterd_options_reset (glusterd_volinfo_t *volinfo, int32_t is_force);
char*
glusterd_op_sm_state_name_get (int state);
@@ -239,17 +274,15 @@ glusterd_op_bricks_select (glusterd_op_t op, dict_t *dict, char **op_errstr);
int
glusterd_brick_op_build_payload (glusterd_op_t op, glusterd_brickinfo_t *brickinfo,
gd1_mgmt_brick_op_req **req, dict_t *dict);
-int
-glusterd_node_op_build_payload (glusterd_op_t op, gd1_mgmt_brick_op_req **req,
- dict_t *dict);
int32_t
-glusterd_handle_brick_rsp (void *pending_entry, glusterd_op_t op,
- dict_t *rsp_dict, dict_t *ctx_dict, char **op_errstr,
- gd_node_type type);
+glusterd_handle_brick_rsp (glusterd_brickinfo_t *brickinfo,
+ glusterd_op_t op, dict_t *rsp_dict, dict_t *ctx_dict,
+ char **op_errstr);
+void glusterd_op_brick_disconnect (void *data);
int32_t
glusterd_op_init_ctx (glusterd_op_t op);
int32_t
-glusterd_op_fini_ctx ();
+glusterd_op_fini_ctx (glusterd_op_t op);
int32_t
glusterd_volume_stats_read_perf (char *brick_path, int32_t blk_size,
int32_t blk_count, double *throughput, double *time);
@@ -265,12 +298,14 @@ glusterd_are_all_volumes_stopped ();
int
glusterd_stop_bricks (glusterd_volinfo_t *volinfo);
int
+glusterd_get_gsync_status_mst_slv( glusterd_volinfo_t *volinfo,
+ char *slave, dict_t *rsp_dict);
+int
gsync_status (char *master, char *slave, int *status);
int
-glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag);
-
+glusterd_gsync_get_param_file (char *prmfile, const char *ext, char *master,
+ char *slave, char *gl_workdir);
int
-glusterd_defrag_volume_node_rsp (dict_t *req_dict, dict_t *rsp_dict,
- dict_t *op_ctx);
+glusterd_check_gsync_running (glusterd_volinfo_t *volinfo, gf_boolean_t *flag);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.c b/xlators/mgmt/glusterd/src/glusterd-pmap.c
index 75c72abcc..f1f49fc60 100644
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.c
+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -30,8 +30,7 @@
#include "glusterd.h"
#include "glusterd-utils.h"
-#include "portmap-xdr.h"
-#include "xdr-generic.h"
+#include "portmap.h"
#include "protocol-common.h"
#include "rpcsvc.h"
@@ -79,8 +78,8 @@ pmap_registry_new (void)
pmap->ports[i].type = GF_PMAP_PORT_FOREIGN;
}
- pmap->base_port = GF_IANA_PRIV_PORTS_START;
- pmap->last_alloc = GF_IANA_PRIV_PORTS_START;
+ pmap->base_port = GF_DEFAULT_BASE_PORT + 2;
+ pmap->last_alloc = GF_DEFAULT_BASE_PORT + 2;
return pmap;
}
@@ -228,7 +227,8 @@ pmap_registry_bind (xlator_t *this, int port, const char *brickname,
p = port;
pmap->ports[p].type = type;
- free (pmap->ports[p].brickname);
+ if (pmap->ports[p].brickname)
+ free (pmap->ports[p].brickname);
pmap->ports[p].brickname = strdup (brickname);
pmap->ports[p].type = type;
pmap->ports[p].xprt = xprt;
@@ -280,7 +280,8 @@ remove:
gf_log ("pmap", GF_LOG_INFO, "removing brick %s on port %d",
pmap->ports[p].brickname, p);
- free (pmap->ports[p].brickname);
+ if (pmap->ports[p].brickname)
+ free (pmap->ports[p].brickname);
pmap->ports[p].brickname = NULL;
pmap->ports[p].xprt = NULL;
@@ -289,6 +290,27 @@ out:
return 0;
}
+
+typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);
+
+
+static int
+xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc)
+{
+ int ret = -1;
+
+ if (!req)
+ return -1;
+
+ ret = sfunc (req->msg[0], arg);
+
+ if (ret > 0)
+ ret = 0;
+
+ return ret;
+}
+
+
int
gluster_pmap_portbybrick (rpcsvc_request_t *req)
{
@@ -297,8 +319,7 @@ gluster_pmap_portbybrick (rpcsvc_request_t *req)
char *brick = NULL;
int port = 0;
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_port_by_brick_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_port_by_brick_req)) {
req->rpc_err = GARBAGE_ARGS;
goto fail;
}
@@ -314,8 +335,9 @@ gluster_pmap_portbybrick (rpcsvc_request_t *req)
fail:
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_port_by_brick_rsp);
- free (args.brick);//malloced by xdr
+ (gd_serialize_t)xdr_from_pmap_port_by_brick_rsp);
+ if (args.brick)
+ free (args.brick);//malloced by xdr
return 0;
}
@@ -327,8 +349,7 @@ gluster_pmap_brickbyport (rpcsvc_request_t *req)
pmap_brick_by_port_req args = {0,};
pmap_brick_by_port_rsp rsp = {0,};
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_brick_by_port_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_brick_by_port_req)) {
req->rpc_err = GARBAGE_ARGS;
goto fail;
}
@@ -341,7 +362,7 @@ gluster_pmap_brickbyport (rpcsvc_request_t *req)
fail:
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_brick_by_port_rsp);
+ (gd_serialize_t)xdr_from_pmap_brick_by_port_rsp);
return 0;
}
@@ -362,8 +383,7 @@ gluster_pmap_signup (rpcsvc_request_t *req)
pmap_signup_rsp rsp = {0,};
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signup_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signup_req)) {
req->rpc_err = GARBAGE_ARGS;
goto fail;
}
@@ -373,8 +393,9 @@ gluster_pmap_signup (rpcsvc_request_t *req)
fail:
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signup_rsp);
- free (args.brick);//malloced by xdr
+ (gd_serialize_t)xdr_from_pmap_signup_rsp);
+ if (args.brick)
+ free (args.brick);//malloced by xdr
return 0;
}
@@ -387,8 +408,7 @@ gluster_pmap_signin (rpcsvc_request_t *req)
glusterd_brickinfo_t *brickinfo = NULL;
int ret = -1;
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signin_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signin_req)) {
req->rpc_err = GARBAGE_ARGS;
goto fail;
}
@@ -400,8 +420,9 @@ gluster_pmap_signin (rpcsvc_request_t *req)
&brickinfo);
fail:
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signin_rsp);
- free (args.brick);//malloced by xdr
+ (gd_serialize_t)xdr_from_pmap_signin_rsp);
+ if (args.brick)
+ free (args.brick);//malloced by xdr
if (!ret)
glusterd_brick_update_signin (brickinfo, _gf_true);
@@ -419,8 +440,7 @@ gluster_pmap_signout (rpcsvc_request_t *req)
int ret = -1;
glusterd_brickinfo_t *brickinfo = NULL;
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_pmap_signout_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_pmap_signout_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto fail;
@@ -433,8 +453,9 @@ gluster_pmap_signout (rpcsvc_request_t *req)
&brickinfo);
fail:
glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_signout_rsp);
- free (args.brick);//malloced by xdr
+ (gd_serialize_t)xdr_from_pmap_signout_rsp);
+ if (args.brick)
+ free (args.brick);//malloced by xdr
if (!ret)
glusterd_brick_update_signin (brickinfo, _gf_false);
@@ -443,17 +464,17 @@ fail:
}
rpcsvc_actor_t gluster_pmap_actors[] = {
- [GF_PMAP_NULL] = {"NULL", GF_PMAP_NULL, NULL, NULL, NULL, 0},
+ [GF_PMAP_NULL] = {"NULL", GF_HNDSK_NULL, NULL, NULL, NULL },
[GF_PMAP_PORTBYBRICK] = {"PORTBYBRICK", GF_PMAP_PORTBYBRICK,
- gluster_pmap_portbybrick, NULL, NULL, 0},
+ gluster_pmap_portbybrick, NULL, NULL },
[GF_PMAP_BRICKBYPORT] = {"BRICKBYPORT", GF_PMAP_BRICKBYPORT,
- gluster_pmap_brickbyport, NULL, NULL, 0},
+ gluster_pmap_brickbyport, NULL, NULL },
[GF_PMAP_SIGNIN] = {"SIGNIN", GF_PMAP_SIGNIN,
- gluster_pmap_signin, NULL, NULL, 0},
+ gluster_pmap_signin, NULL, NULL },
[GF_PMAP_SIGNOUT] = {"SIGNOUT", GF_PMAP_SIGNOUT,
- gluster_pmap_signout, NULL, NULL, 0},
+ gluster_pmap_signout, NULL, NULL },
[GF_PMAP_SIGNUP] = {"SIGNUP", GF_PMAP_SIGNUP,
- gluster_pmap_signup, NULL, NULL, 0},
+ gluster_pmap_signup, NULL, NULL },
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-pmap.h b/xlators/mgmt/glusterd/src/glusterd-pmap.h
index bb2bbc86e..a87efed5a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-pmap.h
+++ b/xlators/mgmt/glusterd/src/glusterd-pmap.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -38,8 +38,6 @@
#include "rpcsvc.h"
-#define GF_IANA_PRIV_PORTS_START 49152 /* RFC 6335 */
-
struct pmap_port_status {
gf_pmap_port_type_t type;
char *brickname;
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c
deleted file mode 100644
index 8d034c455..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-quota.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-#include "run.h"
-
-#include <sys/wait.h>
-
-int
-glusterd_handle_quota (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- glusterd_op_t cli_op = GD_OP_QUOTA;
- char operation[256] = {0, };
- char *volname = NULL;
- int32_t type = 0;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Unable to get volume name, while"
- "handling quota command");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "Unable to get type of cmd. , while"
- "handling quota command");
- goto out;
- }
-
- switch (type) {
- case GF_QUOTA_OPTION_TYPE_ENABLE:
- strncpy (operation, "enable", sizeof (operation));
- break;
-
- case GF_QUOTA_OPTION_TYPE_DISABLE:
- strncpy (operation, "disable", sizeof (operation));
- break;
-
- case GF_QUOTA_OPTION_TYPE_LIMIT_USAGE:
- strncpy (operation, "limit-usage", sizeof (operation));
- break;
-
- case GF_QUOTA_OPTION_TYPE_REMOVE:
- strncpy (operation, "remove", sizeof (operation));
- break;
- }
- gf_cmd_log ("volume quota", " %s command on %s", operation, volname);
- ret = glusterd_op_begin (req, GD_OP_QUOTA, dict);
- gf_cmd_log ("volume quota", " %s command on %s %s", operation,volname,
- (ret != 0)? "FAILED" : "SUCCEEDED");
-
-out:
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (dict)
- dict_unref (dict);
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- }
-
- return ret;
-}
-
-int32_t
-glusterd_check_if_quota_trans_enabled (glusterd_volinfo_t *volinfo)
-{
- int32_t ret = 0;
- int flag = _gf_false;
-
- flag = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA);
- if (flag == -1) {
- gf_log ("", GF_LOG_ERROR, "failed to get the quota status");
- ret = -1;
- goto out;
- }
-
- if (flag == _gf_false) {
- gf_log ("", GF_LOG_ERROR, "first enable the quota translator");
- ret = -1;
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-/* At the end of the function, the variable found will be set
- * to true if the path to be removed was present in the limit-list,
- * else will be false.
- */
-int32_t
-_glusterd_quota_remove_limits (char **quota_limits, char *path,
- gf_boolean_t *found)
-{
- int ret = 0;
- int i = 0;
- int size = 0;
- int len = 0;
- int pathlen = 0;
- int skiplen = 0;
- int flag = 0;
- char *limits = NULL;
- char *qlimits = NULL;
-
- if (found != NULL)
- *found = _gf_false;
-
- if (*quota_limits == NULL)
- return -1;
-
- qlimits = *quota_limits;
-
- pathlen = strlen (path);
-
- len = strlen (qlimits);
-
- limits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char);
- if (!limits)
- return -1;
-
- while (i < len) {
- if (!memcmp ((void *) &qlimits [i], (void *)path, pathlen))
- if (qlimits [i + pathlen] == ':') {
- flag = 1;
- if (found != NULL)
- *found = _gf_true;
- }
-
- while (qlimits [i + size] != ',' &&
- qlimits [i + size] != '\0')
- size++;
-
- if (!flag) {
- memcpy ((void *) &limits [i], (void *) &qlimits [i], size + 1);
- } else {
- skiplen = size + 1;
- size = len - i - size;
- memcpy ((void *) &limits [i], (void *) &qlimits [i + skiplen], size);
- break;
- }
-
- i += size + 1;
- size = 0;
- }
-
- if (!flag) {
- ret = 1;
- } else {
- len = strlen (limits);
-
- if (len == 0) {
- GF_FREE (qlimits);
-
- *quota_limits = NULL;
-
- goto out;
- }
-
- if (limits[len - 1] == ',') {
- limits[len - 1] = '\0';
- len --;
- }
-
- GF_FREE (qlimits);
-
- qlimits = GF_CALLOC (len + 1, sizeof (char), gf_gld_mt_char);
-
- if (!qlimits) {
- ret = -1;
- goto out;
- }
-
- memcpy ((void *) qlimits, (void *) limits, len + 1);
-
- *quota_limits = qlimits;
-
- ret = 0;
- }
-
-out:
- GF_FREE (limits);
-
- return ret;
-}
-
-int32_t
-glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname)
-{
- pid_t pid;
- int32_t ret = 0;
- int status = 0;
- char mountdir[] = "/tmp/mntXXXXXX";
- runner_t runner = {0};
-
- if (mkdtemp (mountdir) == NULL) {
- gf_log ("glusterd", GF_LOG_DEBUG,
- "failed to create a temporary mount directory");
- ret = -1;
- goto out;
- }
-
- runinit (&runner);
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", "localhost",
- "--volfile-id", volname,
- "-l", DEFAULT_LOG_FILE_DIRECTORY"/quota-crawl.log",
- mountdir, NULL);
-
- ret = runner_run_reuse (&runner);
- if (ret == -1) {
- runner_log (&runner, "glusterd", GF_LOG_DEBUG, "command failed");
- runner_end (&runner);
- goto out;
- }
- runner_end (&runner);
-
- if ((pid = fork ()) < 0) {
- gf_log ("glusterd", GF_LOG_WARNING, "fork from parent failed");
- ret = -1;
- goto out;
- } else if (pid == 0) {//first child
- /* fork one more to not hold back main process on
- * blocking call below
- */
- pid = fork ();
- if (pid)
- _exit (pid > 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-
- ret = chdir (mountdir);
- if (ret == -1) {
- gf_log ("glusterd", GF_LOG_WARNING, "chdir %s failed, "
- "reason: %s", mountdir, strerror (errno));
- exit (EXIT_FAILURE);
- }
- runinit (&runner);
- runner_add_args (&runner, "/usr/bin/find", "find", ".", NULL);
- if (runner_start (&runner) == -1)
- _exit (EXIT_FAILURE);
-
-#ifndef GF_LINUX_HOST_OS
- runner_end (&runner); /* blocks in waitpid */
- runcmd ("umount", mountdir, NULL);
-#else
- runcmd ("umount", "-l", mountdir, NULL);
-#endif
- rmdir (mountdir);
- _exit (EXIT_SUCCESS);
- }
- ret = (waitpid (pid, &status, 0) == pid &&
- WIFEXITED (status) && WEXITSTATUS (status) == EXIT_SUCCESS) ? 0 : -1;
-
-out:
- return ret;
-}
-
-char *
-glusterd_quota_get_limit_value (char *quota_limits, char *path)
-{
- int32_t i, j, k, l, len;
- int32_t pat_len, diff;
- char *ret_str = NULL;
-
- len = strlen (quota_limits);
- pat_len = strlen (path);
- i = 0;
- j = 0;
-
- while (i < len) {
- j = i;
- k = 0;
- while (path [k] == quota_limits [j]) {
- j++;
- k++;
- }
-
- l = j;
-
- while (quota_limits [j] != ',' &&
- quota_limits [j] != '\0')
- j++;
-
- if (quota_limits [l] == ':' && pat_len == (l - i)) {
- diff = j - i;
- ret_str = GF_CALLOC (diff + 1, sizeof (char),
- gf_gld_mt_char);
-
- strncpy (ret_str, &quota_limits [i], diff);
-
- break;
- }
- i = ++j; //skip ','
- }
-
- return ret_str;
-}
-
-char*
-_glusterd_quota_get_limit_usages (glusterd_volinfo_t *volinfo,
- char *path, char **op_errstr)
-{
- int32_t ret = 0;
- char *quota_limits = NULL;
- char *ret_str = NULL;
-
- if (volinfo == NULL)
- return NULL;
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
- &quota_limits);
- if (ret)
- return NULL;
- if (quota_limits == NULL) {
- ret_str = NULL;
- *op_errstr = gf_strdup ("Limit not set on any directory");
- } else if (path == NULL)
- ret_str = gf_strdup (quota_limits);
- else
- ret_str = glusterd_quota_get_limit_value (quota_limits, path);
-
- return ret_str;
-}
-
-int32_t
-glusterd_quota_get_limit_usages (glusterd_conf_t *priv,
- glusterd_volinfo_t *volinfo,
- char *volname,
- dict_t *dict,
- char **op_errstr)
-{
- int32_t i = 0;
- int32_t ret = 0;
- int32_t count = 0;
- char *path = NULL;
- dict_t *ctx = NULL;
- char cmd_str [1024] = {0, };
- char *ret_str = NULL;
-
- ctx = glusterd_op_get_ctx ();
- if (ctx == NULL)
- return 0;
-
- ret = dict_get_int32 (dict, "count", &count);
- if (ret < 0)
- goto out;
-
- if (count == 0) {
- ret_str = _glusterd_quota_get_limit_usages (volinfo, NULL,
- op_errstr);
- } else {
- i = 0;
- while (count--) {
- snprintf (cmd_str, 1024, "path%d", i++);
-
- ret = dict_get_str (dict, cmd_str, &path);
- if (ret < 0)
- goto out;
-
- ret_str = _glusterd_quota_get_limit_usages (volinfo, path, op_errstr);
- }
- }
-
- if (ret_str) {
- ret = dict_set_dynstr (ctx, "limit_list", ret_str);
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_enable (glusterd_volinfo_t *volinfo, char **op_errstr,
- gf_boolean_t *crawl)
-{
- int32_t ret = -1;
- char *quota_status = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
- GF_VALIDATE_OR_GOTO ("glusterd", crawl, out);
- GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
-
- if (glusterd_is_volume_started (volinfo) == 0) {
- *op_errstr = gf_strdup ("Volume is stopped, start volume "
- "to enable quota.");
- goto out;
- }
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == 0) {
- *op_errstr = gf_strdup ("Quota is already enabled");
- goto out;
- }
-
- quota_status = gf_strdup ("on");
- if (!quota_status) {
- gf_log ("", GF_LOG_ERROR, "memory allocation failed");
- *op_errstr = gf_strdup ("Enabling quota has been unsuccessful");
- goto out;
- }
-
- ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "dict set failed");
- *op_errstr = gf_strdup ("Enabling quota has been unsuccessful");
- goto out;
- }
-
- *op_errstr = gf_strdup ("Enabling quota has been successful");
-
- *crawl = _gf_true;
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_disable (glusterd_volinfo_t *volinfo, char **op_errstr)
-{
- int32_t ret = -1;
- char *quota_status = NULL, *quota_limits = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
- GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- *op_errstr = gf_strdup ("Quota is already disabled");
- goto out;
- }
-
- quota_status = gf_strdup ("off");
- if (!quota_status) {
- gf_log ("", GF_LOG_ERROR, "memory allocation failed");
- *op_errstr = gf_strdup ("Disabling quota has been unsuccessful");
- goto out;
- }
-
- ret = dict_set_dynstr (volinfo->dict, VKEY_FEATURES_QUOTA, quota_status);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "dict set failed");
- *op_errstr = gf_strdup ("Disabling quota has been unsuccessful");
- goto out;
- }
-
- *op_errstr = gf_strdup ("Disabling quota has been successful");
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
- &quota_limits);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "failed to get the quota limits");
- } else {
- GF_FREE (quota_limits);
- }
-
- dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE);
-
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_limit_usage (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr)
-{
- int32_t ret = -1;
- char *path = NULL;
- char *limit = NULL;
- char *value = NULL;
- char msg [1024] = {0,};
- char *quota_limits = NULL;
-
- GF_VALIDATE_OR_GOTO ("glusterd", dict, out);
- GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
- GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- *op_errstr = gf_strdup ("Quota is disabled, please enable "
- "quota");
- goto out;
- }
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
- &quota_limits);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "failed to get the quota limits");
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
-
- ret = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
-
- ret = dict_get_str (dict, "limit", &limit);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
-
- if (quota_limits) {
- ret = _glusterd_quota_remove_limits (&quota_limits, path, NULL);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
- }
-
- if (quota_limits == NULL) {
- ret = gf_asprintf (&value, "%s:%s", path, limit);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
- } else {
- ret = gf_asprintf (&value, "%s,%s:%s",
- quota_limits, path, limit);
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
-
- GF_FREE (quota_limits);
- }
-
- quota_limits = value;
-
- ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE,
- quota_limits);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" );
- *op_errstr = gf_strdup ("failed to set limit");
- goto out;
- }
- snprintf (msg, 1024, "limit set on %s", path);
- *op_errstr = gf_strdup (msg);
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-glusterd_quota_remove_limits (glusterd_volinfo_t *volinfo, dict_t *dict, char **op_errstr)
-{
- int32_t ret = -1;
- char str [PATH_MAX + 1024] = {0,};
- char *quota_limits = NULL;
- char *path = NULL;
- gf_boolean_t flag = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("glusterd", dict, out);
- GF_VALIDATE_OR_GOTO ("glusterd", volinfo, out);
- GF_VALIDATE_OR_GOTO ("glusterd", op_errstr, out);
-
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- *op_errstr = gf_strdup ("Quota is disabled, please enable quota");
- goto out;
- }
-
- ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_LIMIT_USAGE,
- &quota_limits);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "failed to get the quota limits");
- goto out;
- }
-
- ret = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to fetch quota limits" );
- goto out;
- }
-
- ret = _glusterd_quota_remove_limits (&quota_limits, path, &flag);
- if (ret == -1) {
- if (flag == _gf_true)
- snprintf (str, sizeof (str), "Removing limit on %s has "
- "been unsuccessful", path);
- else
- snprintf (str, sizeof (str), "%s has no limit set", path);
- *op_errstr = gf_strdup (str);
- goto out;
- } else {
- if (flag == _gf_true)
- snprintf (str, sizeof (str), "Removed quota limit on "
- "%s", path);
- else
- snprintf (str, sizeof (str), "no limit set on %s",
- path);
- *op_errstr = gf_strdup (str);
- }
-
- if (quota_limits) {
- ret = dict_set_str (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE,
- quota_limits);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to set quota limits" );
- goto out;
- }
- } else {
- dict_del (volinfo->dict, VKEY_FEATURES_LIMIT_USAGE);
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-int
-glusterd_op_quota (dict_t *dict, char **op_errstr)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int32_t ret = -1;
- char *volname = NULL;
- dict_t *ctx = NULL;
- int type = -1;
- gf_boolean_t start_crawl = _gf_false;
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- priv = THIS->private;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name " );
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
-
- if (type == GF_QUOTA_OPTION_TYPE_ENABLE) {
- ret = glusterd_quota_enable (volinfo, op_errstr, &start_crawl);
- if (ret < 0)
- goto out;
-
- goto create_vol;
- }
-
- if (type == GF_QUOTA_OPTION_TYPE_DISABLE) {
- ret = glusterd_quota_disable (volinfo, op_errstr);
- if (ret < 0)
- goto out;
-
- goto create_vol;
- }
-
- if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) {
- ret = glusterd_quota_limit_usage (volinfo, dict, op_errstr);
- if (ret < 0)
- goto out;
-
- goto create_vol;
- }
-
- if (type == GF_QUOTA_OPTION_TYPE_REMOVE) {
- ret = glusterd_quota_remove_limits (volinfo, dict, op_errstr);
- if (ret < 0)
- goto out;
-
- goto create_vol;
- }
-
- if (type == GF_QUOTA_OPTION_TYPE_LIST) {
- ret = glusterd_check_if_quota_trans_enabled (volinfo);
- if (ret == -1) {
- *op_errstr = gf_strdup ("cannot list the limits, "
- "quota is disabled");
- goto out;
- }
-
- ret = glusterd_quota_get_limit_usages (priv, volinfo, volname,
- dict, op_errstr);
-
- goto out;
- }
-create_vol:
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to re-create volfile for"
- " 'quota'");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status)
- ret = glusterd_check_generate_start_nfs ();
-
- ret = 0;
-
-out:
- ctx = glusterd_op_get_ctx ();
- if (ctx && start_crawl == _gf_true)
- glusterd_quota_initiate_fs_crawl (priv, volname);
-
- if (ctx && *op_errstr) {
- ret = dict_set_dynstr (ctx, "errstr", *op_errstr);
- if (ret) {
- GF_FREE (*op_errstr);
- gf_log ("", GF_LOG_DEBUG,
- "failed to set error message in ctx");
- }
- *op_errstr = NULL;
- }
-
- return ret;
-}
-
-int
-glusterd_op_stage_quota (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- int type = 0;
- dict_t *ctx = NULL;
-
- GF_ASSERT (dict);
- GF_ASSERT (op_errstr);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
- if (!exists) {
- gf_log ("", GF_LOG_ERROR, "Volume with name: %s "
- "does not exist",
- volname);
- *op_errstr = gf_strdup ("Invalid volume name");
- ret = -1;
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get 'type' for quota op");
- *op_errstr = gf_strdup ("Volume quota failed, internal error "
- ", unable to get type of operation");
- goto out;
- }
-
-
- ctx = glusterd_op_get_ctx();
- if (ctx && (type == GF_QUOTA_OPTION_TYPE_ENABLE
- || type == GF_QUOTA_OPTION_TYPE_LIST)) {
- /* Fuse mount req. only for enable & list-usage options*/
- if (!glusterd_is_fuse_available ()) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to open /dev/"
- "fuse (%s), quota command failed",
- strerror (errno));
- *op_errstr = gf_strdup ("Fuse unavailable");
- ret = -1;
- goto out;
- }
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
index c9397b394..59d4963d4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -21,12 +21,8 @@
#define _CONFIG_H
#include "config.h"
#endif
-
#include <inttypes.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <sys/resource.h>
-#include <sys/statvfs.h>
#include "globals.h"
#include "compat.h"
@@ -40,16 +36,422 @@
#include "glusterd-op-sm.h"
#include "glusterd-utils.h"
#include "glusterd-store.h"
-#include "run.h"
-#include "glusterd-volgen.h"
#include "syscall.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
+#include "cli1.h"
+
+int
+gf_glusterd_rebalance_move_data (glusterd_volinfo_t *volinfo, const char *dir)
+{
+ int ret = -1;
+ int dst_fd = -1;
+ int src_fd = -1;
+ DIR *fd = NULL;
+ glusterd_defrag_info_t *defrag = NULL;
+ struct dirent *entry = NULL;
+ struct stat stbuf = {0,};
+ struct stat new_stbuf = {0,};
+ char full_path[PATH_MAX] = {0,};
+ char tmp_filename[PATH_MAX] = {0,};
+ char value[16] = {0,};
+ char linkinfo[PATH_MAX] = {0,};
+
+ if (!volinfo->defrag)
+ goto out;
+
+ defrag = volinfo->defrag;
+
+ fd = opendir (dir);
+ if (!fd)
+ goto out;
+ while ((entry = readdir (fd))) {
+ if (!entry)
+ break;
+
+ if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
+ continue;
+
+ snprintf (full_path, PATH_MAX, "%s/%s", dir, entry->d_name);
+
+ ret = stat (full_path, &stbuf);
+ if (ret == -1)
+ continue;
+
+ if (!S_ISREG (stbuf.st_mode))
+ continue;
+
+ defrag->num_files_lookedup += 1;
+
+ if (stbuf.st_nlink > 1)
+ continue;
+
+ /* if distribute is present, it will honor this key.
+ -1 is returned if distribute is not present or file doesn't
+ have a link-file. If file has link-file, the path of
+ link-file will be the value */
+ ret = sys_lgetxattr (full_path, GF_XATTR_LINKINFO_KEY,
+ &linkinfo, PATH_MAX);
+ if (ret <= 0)
+ continue;
+
+ /* If the file is open, don't run rebalance on it */
+ ret = sys_lgetxattr (full_path, GLUSTERFS_OPEN_FD_COUNT,
+ &value, 16);
+ if ((ret < 0) || !strncmp (value, "1", 1))
+ continue;
+
+ /* If its a regular file, and sticky bit is set, we need to
+ rebalance that */
+ snprintf (tmp_filename, PATH_MAX, "%s/.%s.gfs%llu", dir,
+ entry->d_name,
+ (unsigned long long)stbuf.st_size);
+
+ dst_fd = creat (tmp_filename, stbuf.st_mode);
+ if (dst_fd == -1)
+ continue;
+
+ src_fd = open (full_path, O_RDONLY);
+ if (src_fd == -1) {
+ close (dst_fd);
+ continue;
+ }
+
+ while (1) {
+ ret = read (src_fd, defrag->databuf, 131072);
+ if (!ret || (ret < 0)) {
+ break;
+ }
+ ret = write (dst_fd, defrag->databuf, ret);
+ if (ret < 0) {
+ break;
+ }
+ }
+
+ ret = stat (full_path, &new_stbuf);
+ if (ret < 0) {
+ close (dst_fd);
+ close (src_fd);
+ continue;
+ }
+ /* No need to rebalance, if there is some
+ activity on source file */
+ if (new_stbuf.st_mtime != stbuf.st_mtime) {
+ close (dst_fd);
+ close (src_fd);
+ continue;
+ }
+
+ ret = fchown (dst_fd, stbuf.st_uid, stbuf.st_gid);
+ if (ret) {
+ gf_log ("", GF_LOG_WARNING,
+ "failed to set the uid/gid of file %s: %s",
+ tmp_filename, strerror (errno));
+ }
+
+ ret = rename (tmp_filename, full_path);
+ if (ret != -1) {
+ LOCK (&defrag->lock);
+ {
+ defrag->total_files += 1;
+ defrag->total_data += stbuf.st_size;
+ }
+ UNLOCK (&defrag->lock);
+ }
+
+ close (dst_fd);
+ close (src_fd);
+
+ if (volinfo->defrag_status == GF_DEFRAG_STATUS_STOPED) {
+ closedir (fd);
+ ret = -1;
+ goto out;
+ }
+ }
+ closedir (fd);
+
+ fd = opendir (dir);
+ if (!fd)
+ goto out;
+ while ((entry = readdir (fd))) {
+ if (!entry)
+ break;
+
+ if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
+ continue;
+
+ snprintf (full_path, 1024, "%s/%s", dir, entry->d_name);
+
+ ret = stat (full_path, &stbuf);
+ if (ret == -1)
+ continue;
+
+ if (!S_ISDIR (stbuf.st_mode))
+ continue;
+
+ ret = gf_glusterd_rebalance_move_data (volinfo, full_path);
+ if (ret)
+ break;
+ }
+ closedir (fd);
+
+ if (!entry)
+ ret = 0;
+out:
+ return ret;
+}
+
+int
+gf_glusterd_rebalance_fix_layout (glusterd_volinfo_t *volinfo, const char *dir)
+{
+ int ret = -1;
+ char value[128] = {0,};
+ char full_path[1024] = {0,};
+ struct stat stbuf = {0,};
+ DIR *fd = NULL;
+ struct dirent *entry = NULL;
+
+ if (!volinfo->defrag)
+ goto out;
+
+ fd = opendir (dir);
+ if (!fd)
+ goto out;
+
+ while ((entry = readdir (fd))) {
+ if (!entry)
+ break;
+
+ if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
+ continue;
+
+ snprintf (full_path, 1024, "%s/%s", dir, entry->d_name);
+
+ ret = stat (full_path, &stbuf);
+ if (ret == -1)
+ continue;
+
+ if (S_ISDIR (stbuf.st_mode)) {
+ /* Fix the layout of the directory */
+ sys_lgetxattr (full_path, "trusted.distribute.fix.layout",
+ &value, 128);
+
+ volinfo->defrag->total_files += 1;
+
+ /* Traverse into subdirectory */
+ ret = gf_glusterd_rebalance_fix_layout (volinfo,
+ full_path);
+ if (ret)
+ break;
+ }
+
+ if (volinfo->defrag_status == GF_DEFRAG_STATUS_STOPED) {
+ closedir (fd);
+ ret = -1;
+ goto out;
+ }
+ }
+ closedir (fd);
+
+ if (!entry)
+ ret = 0;
+
+out:
+ return ret;
+}
+
+void *
+glusterd_defrag_start (void *data)
+{
+ glusterd_volinfo_t *volinfo = data;
+ glusterd_defrag_info_t *defrag = NULL;
+ char cmd_str[1024] = {0,};
+ int ret = -1;
+ struct stat stbuf = {0,};
+ char value[128] = {0,};
+
+ defrag = volinfo->defrag;
+ if (!defrag)
+ goto out;
+
+ sleep (1);
+ ret = stat (defrag->mount, &stbuf);
+ if ((ret == -1) && (errno == ENOTCONN)) {
+ /* Wait for some more time before starting rebalance */
+ sleep (2);
+ ret = stat (defrag->mount, &stbuf);
+ if (ret == -1) {
+ volinfo->defrag_status = GF_DEFRAG_STATUS_FAILED;
+ volinfo->rebalance_files = 0;
+ volinfo->rebalance_data = 0;
+ volinfo->lookedup_files = 0;
+ goto out;
+ }
+ }
+
+ /* Fix the root ('/') first */
+ sys_lgetxattr (defrag->mount, "trusted.distribute.fix.layout",
+ &value, 128);
+
+ if ((defrag->cmd == GF_DEFRAG_CMD_START) ||
+ (defrag->cmd == GF_DEFRAG_CMD_START_LAYOUT_FIX)) {
+ /* root's layout got fixed */
+ defrag->total_files = 1;
+
+ /* Step 1: Fix layout of all the directories */
+ ret = gf_glusterd_rebalance_fix_layout (volinfo, defrag->mount);
+ if (ret) {
+ volinfo->defrag_status = GF_DEFRAG_STATUS_FAILED;
+ goto out;
+ }
+
+ /* Completed first step */
+ volinfo->defrag_status = GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE;
+ }
+
+ if ((defrag->cmd == GF_DEFRAG_CMD_START) ||
+ (defrag->cmd == GF_DEFRAG_CMD_START_MIGRATE_DATA)) {
+ /* It was used by number of layout fixes on directories */
+ defrag->total_files = 0;
+
+ volinfo->defrag_status = GF_DEFRAG_STATUS_MIGRATE_DATA_STARTED;
-int32_t
-glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe);
+ /* Step 2: Iterate over directories to move data */
+ ret = gf_glusterd_rebalance_move_data (volinfo, defrag->mount);
+ if (ret) {
+ volinfo->defrag_status = GF_DEFRAG_STATUS_FAILED;
+ goto out;
+ }
+
+ /* Completed second step */
+ volinfo->defrag_status = GF_DEFRAG_STATUS_MIGRATE_DATA_COMPLETE;
+ }
+
+ /* Completed whole process */
+ if (defrag->cmd == GF_DEFRAG_CMD_START)
+ volinfo->defrag_status = GF_DEFRAG_STATUS_COMPLETE;
+
+ volinfo->rebalance_files = defrag->total_files;
+ volinfo->rebalance_data = defrag->total_data;
+ volinfo->lookedup_files = defrag->num_files_lookedup;
+out:
+ volinfo->defrag = NULL;
+ if (defrag) {
+ gf_log ("rebalance", GF_LOG_INFO, "rebalance on %s complete",
+ defrag->mount);
+
+ usleep (200000);
+ snprintf (cmd_str, 1024, "umount -l %s", defrag->mount);
+ ret = system (cmd_str);
+ LOCK_DESTROY (&defrag->lock);
+ GF_FREE (defrag);
+ }
+
+ return NULL;
+}
+
+int
+glusterd_defrag_stop_validate (glusterd_volinfo_t *volinfo,
+ char *op_errstr, size_t len)
+{
+ int ret = -1;
+ if (glusterd_is_defrag_on (volinfo) == 0) {
+ snprintf (op_errstr, len, "Rebalance on %s is either Completed "
+ "or not yet started", volinfo->volname);
+ goto out;
+ }
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_defrag_stop (glusterd_volinfo_t *volinfo, u_quad_t *files,
+ u_quad_t *size, char *op_errstr, size_t len)
+{
+ /* TODO: set a variaeble 'stop_defrag' here, it should be checked
+ in defrag loop */
+ int ret = -1;
+ GF_ASSERT (volinfo);
+ GF_ASSERT (files);
+ GF_ASSERT (size);
+ GF_ASSERT (op_errstr);
+
+ ret = glusterd_defrag_stop_validate (volinfo, op_errstr, len);
+ if (ret)
+ goto out;
+ if (!volinfo || !volinfo->defrag) {
+ ret = -1;
+ goto out;
+ }
+
+ LOCK (&volinfo->defrag->lock);
+ {
+ volinfo->defrag_status = GF_DEFRAG_STATUS_STOPED;
+ *files = volinfo->defrag->total_files;
+ *size = volinfo->defrag->total_data;
+ }
+ UNLOCK (&volinfo->defrag->lock);
+
+ ret = 0;
+out:
+ gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+int
+glusterd_defrag_status_get_v2 (glusterd_volinfo_t *volinfo,
+ gf2_cli_defrag_vol_rsp *rsp)
+{
+ if (!volinfo)
+ goto out;
+
+ if (volinfo->defrag) {
+ LOCK (&volinfo->defrag->lock);
+ {
+ rsp->files = volinfo->defrag->total_files;
+ rsp->size = volinfo->defrag->total_data;
+ rsp->lookedup_files = volinfo->defrag->num_files_lookedup;
+ }
+ UNLOCK (&volinfo->defrag->lock);
+ } else {
+ rsp->files = volinfo->rebalance_files;
+ rsp->size = volinfo->rebalance_data;
+ rsp->lookedup_files = volinfo->lookedup_files;
+ }
+
+ rsp->op_errno = volinfo->defrag_status;
+ rsp->op_ret = 0;
+out:
+ return 0;
+}
+
+int
+glusterd_defrag_status_get (glusterd_volinfo_t *volinfo,
+ gf1_cli_defrag_vol_rsp *rsp)
+{
+ if (!volinfo)
+ goto out;
+
+ if (volinfo->defrag) {
+ LOCK (&volinfo->defrag->lock);
+ {
+ rsp->files = volinfo->defrag->total_files;
+ rsp->size = volinfo->defrag->total_data;
+ rsp->lookedup_files = volinfo->defrag->num_files_lookedup;
+ }
+ UNLOCK (&volinfo->defrag->lock);
+ } else {
+ rsp->files = volinfo->rebalance_files;
+ rsp->size = volinfo->rebalance_data;
+ rsp->lookedup_files = volinfo->lookedup_files;
+ }
+
+ rsp->op_errno = volinfo->defrag_status;
+ rsp->op_ret = 0;
+out:
+ return 0;
+}
void
glusterd_rebalance_cmd_attempted_log (int cmd, char *volname)
@@ -59,31 +461,26 @@ glusterd_rebalance_cmd_attempted_log (int cmd, char *volname)
gf_cmd_log ("Volume rebalance"," on volname: %s "
"cmd: start fix layout , attempted",
volname);
- gf_log ("glusterd", GF_LOG_INFO, "Received rebalance "
- "volume start layout fix on %s", volname);
break;
- case GF_DEFRAG_CMD_START_FORCE:
+ case GF_DEFRAG_CMD_START_MIGRATE_DATA:
gf_cmd_log ("Volume rebalance"," on volname: %s "
- "cmd: start data force attempted",
+ "cmd: start data migrate attempted",
volname);
- gf_log ("glusterd", GF_LOG_INFO, "Received rebalance "
- "volume start migrate data on %s", volname);
break;
case GF_DEFRAG_CMD_START:
gf_cmd_log ("Volume rebalance"," on volname: %s "
"cmd: start, attempted", volname);
- gf_log ("glusterd", GF_LOG_INFO, "Received rebalance "
- "volume start on %s", volname);
break;
case GF_DEFRAG_CMD_STOP:
gf_cmd_log ("Volume rebalance"," on volname: %s "
"cmd: stop, attempted", volname);
- gf_log ("glusterd", GF_LOG_INFO, "Received rebalance "
- "volume stop on %s", volname);
break;
default:
break;
}
+
+ gf_log ("glusterd", GF_LOG_INFO, "Received rebalance volume %d on %s",
+ cmd, volname);
}
void
@@ -113,9 +510,9 @@ glusterd_defrag_start_validate (glusterd_volinfo_t *volinfo, char *op_errstr,
if (glusterd_is_rb_started (volinfo) ||
glusterd_is_rb_paused (volinfo)) {
gf_log ("glusterd", GF_LOG_DEBUG,
- "Rebalance failed as replace brick is in progress on volume %s",
+ "Replace brick is in progress on volume %s",
volinfo->volname);
- snprintf (op_errstr, len, "Rebalance failed as replace brick is in progress on "
+ snprintf (op_errstr, len, "Replace brick is in progress on "
"volume %s", volinfo->volname);
goto out;
}
@@ -125,111 +522,15 @@ out:
return ret;
}
-int32_t
-glusterd_defrag_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data)
-{
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_defrag_info_t *defrag = NULL;
- int ret = 0;
- char pidfile[PATH_MAX];
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- if (!priv)
- return 0;
-
- volinfo = mydata;
- if (!volinfo)
- return 0;
-
- defrag = volinfo->defrag;
- if (!defrag)
- return 0;
-
- if ((event == RPC_CLNT_DISCONNECT) && defrag->connected)
- volinfo->defrag = NULL;
-
- GLUSTERD_GET_DEFRAG_PID_FILE(pidfile, volinfo, priv);
-
- switch (event) {
- case RPC_CLNT_CONNECT:
- {
- if (defrag->connected)
- return 0;
-
- LOCK (&defrag->lock);
- {
- defrag->connected = 1;
- }
- UNLOCK (&defrag->lock);
-
- gf_log ("", GF_LOG_DEBUG, "%s got RPC_CLNT_CONNECT",
- rpc->conn.trans->name);
- break;
- }
-
- case RPC_CLNT_DISCONNECT:
- {
- if (!defrag->connected)
- return 0;
-
- LOCK (&defrag->lock);
- {
- defrag->connected = 0;
- }
- UNLOCK (&defrag->lock);
-
- if (!glusterd_is_service_running (pidfile, NULL)) {
- if (volinfo->defrag_status ==
- GF_DEFRAG_STATUS_STARTED) {
- volinfo->defrag_status =
- GF_DEFRAG_STATUS_FAILED;
- } else {
- volinfo->defrag_cmd = 0;
- }
- }
-
- glusterd_store_perform_node_state_store (volinfo);
-
- if (defrag->rpc) {
- rpc_clnt_unref (defrag->rpc);
- defrag->rpc = NULL;
- }
- if (defrag->cbk_fn)
- defrag->cbk_fn (volinfo, volinfo->defrag_status);
-
- GF_FREE (defrag);
- gf_log ("", GF_LOG_DEBUG, "%s got RPC_CLNT_DISCONNECT",
- rpc->conn.trans->name);
- break;
- }
- default:
- gf_log ("", GF_LOG_TRACE,
- "got some other RPC event %d", event);
- ret = 0;
- break;
- }
-
- return ret;
-}
-
int
glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, int cmd, defrag_cbk_fn_t cbk)
+ size_t len, int cmd)
{
int ret = -1;
glusterd_defrag_info_t *defrag = NULL;
- runner_t runner = {0,};
+ char cmd_str[4096] = {0,};
glusterd_conf_t *priv = NULL;
- char defrag_path[PATH_MAX];
- char sockfile[PATH_MAX] = {0,};
- char pidfile[PATH_MAX] = {0,};
- char logfile[PATH_MAX] = {0,};
- dict_t *options = NULL;
-#ifdef DEBUG
- char valgrind_logfile[PATH_MAX] = {0,};
-#endif
+
priv = THIS->private;
GF_ASSERT (volinfo);
@@ -249,131 +550,45 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
defrag->cmd = cmd;
LOCK_INIT (&defrag->lock);
+ snprintf (defrag->mount, 1024, "%s/mount/%s",
+ priv->workdir, volinfo->volname);
+ /* Create a directory, mount glusterfs over it, start glusterfs-defrag */
+ snprintf (cmd_str, sizeof (cmd_str), "mkdir -p %s", defrag->mount);
+ ret = system (cmd_str);
- volinfo->defrag_status = GF_DEFRAG_STATUS_STARTED;
-
- glusterd_volinfo_reset_defrag_stats (volinfo);
- volinfo->defrag_cmd = cmd;
- glusterd_store_perform_node_state_store (volinfo);
-
- GLUSTERD_GET_DEFRAG_DIR (defrag_path, volinfo, priv);
- ret = mkdir_p (defrag_path, 0777, _gf_true);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to create "
- "directory %s", defrag_path);
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
goto out;
}
- GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo, priv);
- GLUSTERD_GET_DEFRAG_PID_FILE (pidfile, volinfo, priv);
- snprintf (logfile, PATH_MAX, "%s/%s-rebalance.log",
- DEFAULT_LOG_FILE_DIRECTORY, volinfo->volname);
- runinit (&runner);
-#ifdef DEBUG
- if (priv->valgrind) {
- snprintf (valgrind_logfile, PATH_MAX,
- "%s/valgrind-%s-rebalance.log",
- DEFAULT_LOG_FILE_DIRECTORY,
- volinfo->volname);
-
- runner_add_args (&runner, "valgrind", "--leak-check=full",
- "--trace-children=yes", NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-#endif
-
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", "localhost", "--volfile-id", volinfo->volname,
- "--xlator-option", "*dht.use-readdirp=yes",
- "--xlator-option", "*dht.lookup-unhashed=yes",
- "--xlator-option", "*dht.assert-no-child-down=yes",
- "--xlator-option", "*replicate*.data-self-heal=off",
- "--xlator-option",
- "*replicate*.metadata-self-heal=off",
- "--xlator-option", "*replicate*.entry-self-heal=off",
- NULL);
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf ( &runner, "*dht.rebalance-cmd=%d",cmd);
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "*dht.node-uuid=%s", uuid_utoa(MY_UUID));
- runner_add_arg (&runner, "--socket-file");
- runner_argprintf (&runner, "%s",sockfile);
- runner_add_arg (&runner, "--pid-file");
- runner_argprintf (&runner, "%s",pidfile);
- runner_add_arg (&runner, "-l");
- runner_argprintf (&runner, logfile);
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
-
- ret = runner_run_reuse (&runner);
+ snprintf (cmd_str, sizeof (cmd_str),
+ "%s/sbin/glusterfs -s localhost --volfile-id %s "
+ "--xlator-option *dht.use-readdirp=yes "
+ "--xlator-option *dht.lookup-unhashed=yes %s",
+ GFS_PREFIX, volinfo->volname,
+ defrag->mount);
+ ret = gf_system (cmd_str);
if (ret) {
- runner_log (&runner, "glusterd", GF_LOG_DEBUG, "command failed");
- runner_end (&runner);
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed", cmd_str);
goto out;
}
- sleep (5);
- ret = rpc_clnt_transport_unix_options_build (&options, sockfile);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unix options build failed");
- goto out;
- }
+ volinfo->defrag_status = GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED;
- ret = glusterd_rpc_create (&defrag->rpc, options,
- glusterd_defrag_notify, volinfo);
+ ret = pthread_create (&defrag->th, NULL, glusterd_defrag_start,
+ volinfo);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "RPC create failed");
- goto out;
+ usleep (200000);
+ snprintf (cmd_str, sizeof (cmd_str), "umount -l %s", defrag->mount);
+ if (system (cmd_str))
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s "
+ "failed", cmd_str);
}
-
- if (cbk)
- defrag->cbk_fn = cbk;
-
out:
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-
-int
-glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo,
- glusterd_conf_t *priv, int cmd)
-{
- dict_t *options = NULL;
- char sockfile[PATH_MAX] = {0,};
- int ret = -1;
- glusterd_defrag_info_t *defrag = NULL;
-
- if (!volinfo->defrag)
- volinfo->defrag = GF_CALLOC (1, sizeof (glusterd_defrag_info_t),
- gf_gld_mt_defrag_info);
- if (!volinfo->defrag)
- goto out;
-
- defrag = volinfo->defrag;
-
- defrag->cmd = cmd;
-
- LOCK_INIT (&defrag->lock);
-
- GLUSTERD_GET_DEFRAG_SOCK_FILE (sockfile, volinfo, priv);
- ret = rpc_clnt_transport_unix_options_build (&options, sockfile);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Unix options build failed");
- goto out;
- }
-
- ret = glusterd_rpc_create (&defrag->rpc, options,
- glusterd_defrag_notify, volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "RPC create failed");
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
int
glusterd_rebalance_cmd_validate (int cmd, char *volname,
glusterd_volinfo_t **volinfo,
@@ -388,14 +603,6 @@ glusterd_rebalance_cmd_validate (int cmd, char *volname,
volname);
goto out;
}
- if ((*volinfo)->brick_count <= (*volinfo)->dist_leaf_count) {
- gf_log ("glusterd", GF_LOG_ERROR, "Volume %s is not a "
- "distribute type or contains only 1 brick", volname);
- snprintf (op_errstr, len, "Volume %s is not a distribute "
- "volume or contains only 1 brick.\n"
- "Not performing rebalance", volname);
- goto out;
- }
if ((*volinfo)->status != GLUSTERD_STATUS_STARTED) {
gf_log ("glusterd", GF_LOG_ERROR, "Received rebalance on stopped"
@@ -404,260 +611,137 @@ glusterd_rebalance_cmd_validate (int cmd, char *volname,
"be started to perform rebalance", volname);
goto out;
}
-
ret = 0;
-
out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int
-glusterd_handle_defrag_volume (rpcsvc_request_t *req)
+glusterd_handle_defrag_volume_v2 (rpcsvc_request_t *req)
{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- glusterd_conf_t *priv = NULL;
- dict_t *dict = NULL;
- char *volname = NULL;
- gf_cli_defrag_type cmd = 0;
+ int32_t ret = -1;
+ gf1_cli_defrag_vol_req cli_req = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ gf2_cli_defrag_vol_rsp rsp = {0,};
+ char msg[2048] = {0};
+ glusterd_conf_t *priv = NULL;
GF_ASSERT (req);
- priv = THIS->private;
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
+ priv = THIS->private;
+ if (!gf_xdr_to_cli_defrag_vol_req (req->msg[0], &cli_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
+ glusterd_rebalance_cmd_attempted_log (cli_req.cmd, cli_req.volname);
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to get volname");
- goto out;
- }
+ rsp.volname = cli_req.volname;
+ rsp.op_ret = -1;
+ rsp.op_errstr = msg;
- ret = dict_get_int32 (dict, "rebalance-command", (int32_t*)&cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to get command");
- goto out;
- }
-
- glusterd_rebalance_cmd_attempted_log (cmd, volname);
-
- ret = dict_set_static_bin (dict, "node-uuid", MY_UUID, 16);
+ ret = glusterd_rebalance_cmd_validate (cli_req.cmd, cli_req.volname,
+ &volinfo, msg, sizeof (msg));
if (ret)
goto out;
- if ((cmd == GF_DEFRAG_CMD_STATUS) ||
- (cmd == GF_DEFRAG_CMD_STOP)) {
- ret = glusterd_op_begin (req, GD_OP_DEFRAG_BRICK_VOLUME,
- dict);
- } else
- ret = glusterd_op_begin (req, GD_OP_REBALANCE, dict);
-
-out:
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (dict)
- dict_unref (dict);
- ret = glusterd_op_send_cli_response (GD_OP_REBALANCE, ret, 0, req,
- NULL, "operation failed");
- }
-
- free (cli_req.dict.dict_val);//malloced by xdr
-
- return 0;
-}
-
-
-int
-glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr)
-{
- char *volname = NULL;
- int ret = 0;
- int32_t cmd = 0;
- char msg[2048] = {0};
- glusterd_volinfo_t *volinfo = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "volname not found");
- goto out;
- }
- ret = dict_get_int32 (dict, "rebalance-command", &cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "cmd not found");
- goto out;
- }
-
- ret = glusterd_rebalance_cmd_validate (cmd, volname, &volinfo,
- msg, sizeof (msg));
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "failed to validate");
- goto out;
- }
- switch (cmd) {
+ switch (cli_req.cmd) {
case GF_DEFRAG_CMD_START:
case GF_DEFRAG_CMD_START_LAYOUT_FIX:
- case GF_DEFRAG_CMD_START_FORCE:
- ret = glusterd_defrag_start_validate (volinfo,
- msg, sizeof (msg));
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "start validate failed");
- goto out;
- }
+ case GF_DEFRAG_CMD_START_MIGRATE_DATA:
+ ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg),
+ cli_req.cmd);
+ rsp.op_ret = ret;
break;
- case GF_DEFRAG_CMD_STATUS:
case GF_DEFRAG_CMD_STOP:
+ ret = glusterd_defrag_stop (volinfo, &rsp.files, &rsp.size,
+ msg, sizeof (msg));
+ rsp.op_ret = ret;
+ break;
+ case GF_DEFRAG_CMD_STATUS:
+ ret = glusterd_defrag_status_get_v2 (volinfo, &rsp);
break;
default:
break;
}
-
- ret = 0;
+ glusterd_rebalance_cmd_log (cli_req.cmd, cli_req.volname, rsp.op_ret);
out:
- if (ret && op_errstr && msg[0])
- *op_errstr = gf_strdup (msg);
- return ret;
-}
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_defrag_vol_rsp_v2);
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
+ return 0;
+}
int
-glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
+glusterd_handle_defrag_volume (rpcsvc_request_t *req)
{
- char *volname = NULL;
- int ret = 0;
- int32_t cmd = 0;
- char msg[2048] = {0};
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_brickinfo_t *tmp = NULL;
- gf_boolean_t volfile_update = _gf_false;
-
- priv = THIS->private;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "volname not given");
- goto out;
- }
+ int32_t ret = -1;
+ gf1_cli_defrag_vol_req cli_req = {0,};
+ glusterd_conf_t *priv = NULL;
+ char cmd_str[4096] = {0,};
+ glusterd_volinfo_t *volinfo = NULL;
+ gf1_cli_defrag_vol_rsp rsp = {0,};
+ char msg[2048] = {0};
- ret = dict_get_int32 (dict, "rebalance-command", &cmd);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "command not given");
- goto out;
- }
+ GF_ASSERT (req);
- ret = glusterd_rebalance_cmd_validate (cmd, volname, &volinfo,
- msg, sizeof (msg));
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "cmd validate failed");
+ priv = THIS->private;
+
+ if (!gf_xdr_to_cli_defrag_vol_req (req->msg[0], &cli_req)) {
+ //failed to decode msg;
+ req->rpc_err = GARBAGE_ARGS;
goto out;
}
- switch (cmd) {
+ glusterd_rebalance_cmd_attempted_log (cli_req.cmd, cli_req.volname);
+
+ rsp.volname = cli_req.volname;
+ rsp.op_ret = -1;
+
+ ret = glusterd_rebalance_cmd_validate (cli_req.cmd, cli_req.volname,
+ &volinfo, msg, sizeof (msg));
+ if (ret)
+ goto out;
+ switch (cli_req.cmd) {
case GF_DEFRAG_CMD_START:
case GF_DEFRAG_CMD_START_LAYOUT_FIX:
- case GF_DEFRAG_CMD_START_FORCE:
+ case GF_DEFRAG_CMD_START_MIGRATE_DATA:
+ {
ret = glusterd_handle_defrag_start (volinfo, msg, sizeof (msg),
- cmd, NULL);
- break;
+ cli_req.cmd);
+ rsp.op_ret = ret;
+ break;
+ }
case GF_DEFRAG_CMD_STOP:
- /* Fall back to the old volume file in case of decommission*/
- list_for_each_entry_safe (brickinfo, tmp, &volinfo->bricks,
- brick_list) {
- if (!brickinfo->decommissioned)
- continue;
- brickinfo->decommissioned = 0;
- volfile_update = _gf_true;
- }
-
- if (volfile_update == _gf_false) {
- ret = 0;
- break;
- }
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to create volfiles");
- goto out;
- }
-
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to store volinfo");
- goto out;
- }
-
- ret = 0;
+ ret = glusterd_defrag_stop (volinfo, &rsp.files, &rsp.size,
+ msg, sizeof (msg));
+ rsp.op_ret = ret;
break;
-
case GF_DEFRAG_CMD_STATUS:
+ ret = glusterd_defrag_status_get (volinfo, &rsp);
break;
default:
break;
}
+ if (ret)
+ gf_log("glusterd", GF_LOG_DEBUG, "command: %s failed",cmd_str);
- glusterd_rebalance_cmd_log (cmd, volname, ret);
-
-out:
- if (ret && op_errstr && msg[0])
- *op_errstr = gf_strdup (msg);
-
- return ret;
-}
-
-int32_t
-glusterd_defrag_event_notify_handle (dict_t *dict)
-{
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- int32_t ret = -1;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to get volname");
- return ret;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Failed to get volinfo for %s"
- , volname);
- return ret;
+ if (cli_req.cmd != GF_DEFRAG_CMD_STATUS) {
+ gf_cmd_log ("volume rebalance"," on volname: %s %d %s",
+ cli_req.volname,
+ cli_req.cmd, ((ret)?"FAILED":"SUCCESS"));
}
- ret = glusterd_defrag_volume_status_update (volinfo, dict);
+out:
+ ret = glusterd_submit_reply (req, &rsp, NULL, 0, NULL,
+ gf_xdr_serialize_cli_defrag_vol_rsp);
+ if (cli_req.volname)
+ free (cli_req.volname);//malloced by xdr
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Failed to update status");
- return ret;
+ return 0;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
deleted file mode 100644
index 86c4d6e2d..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
+++ /dev/null
@@ -1,1845 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterfs.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-#include "run.h"
-#include "syscall.h"
-
-#include <signal.h>
-
-#define GLUSTERD_GET_RB_MNTPT(path, len, volinfo) \
- snprintf (path, len, "/tmp/%s-"RB_CLIENT_MOUNTPOINT, \
- volinfo->volname);
-
-
-int
-glusterd_get_replace_op_str (gf1_cli_replace_op op, char *op_str)
-{
- int ret = -1;
-
- if (!op_str)
- goto out;
-
- switch (op) {
- case GF_REPLACE_OP_START:
- strcpy (op_str, "start");
- break;
- case GF_REPLACE_OP_COMMIT:
- strcpy (op_str, "commit");
- break;
- case GF_REPLACE_OP_PAUSE:
- strcpy (op_str, "pause");
- break;
- case GF_REPLACE_OP_ABORT:
- strcpy (op_str, "abort");
- break;
- case GF_REPLACE_OP_STATUS:
- strcpy (op_str, "status");
- break;
- case GF_REPLACE_OP_COMMIT_FORCE:
- strcpy (op_str, "commit-force");
- break;
- default:
- strcpy (op_str, "unknown");
- break;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_handle_replace_brick (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- int32_t op = 0;
- char operation[256];
- glusterd_op_t cli_op = GD_OP_REPLACE_BRICK;
- char *volname = NULL;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received replace brick req");
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "could not get volname");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "operation", &op);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "dict_get on operation failed");
- goto out;
- }
-
- ret = dict_get_str (dict, "src-brick", &src_brick);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG,
- "src brick=%s", src_brick);
-
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get dest brick");
- goto out;
- }
-
- (void) glusterd_get_replace_op_str (op, operation);
- gf_log ("", GF_LOG_DEBUG, "dst brick=%s", dst_brick);
- gf_log ("glusterd", GF_LOG_INFO, "Received replace brick %s request",
- operation);
- gf_cmd_log ("Volume replace-brick","volname: %s src_brick:%s"
- " dst_brick:%s op:%s", volname, src_brick, dst_brick,
- operation);
-
- ret = glusterd_op_begin (req, GD_OP_REPLACE_BRICK, dict);
- gf_cmd_log ("Volume replace-brick","on volname: %s %s", volname,
- (ret) ? "FAILED" : "SUCCESS");
-
-out:
- if (ret && dict)
- dict_unref (dict);
- free (cli_req.dict.dict_val);//malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
-
- return ret;
-}
-
-static int
-glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t **brickinfo)
-{
- int32_t ret = -1;
-
- if (!volinfo || !brickinfo)
- goto out;
-
- *brickinfo = volinfo->dst_brick;
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict)
-{
- int ret = 0;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *volname = NULL;
- int replace_op = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *src_brickinfo = NULL;
- char *host = NULL;
- char *path = NULL;
- char msg[2048] = {0};
- char *dup_dstbrick = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_brickinfo_t *dst_brickinfo = NULL;
- gf_boolean_t is_run = _gf_false;
- dict_t *ctx = NULL;
- glusterd_conf_t *priv = NULL;
- char *savetok = NULL;
- char voldir[PATH_MAX] = {0};
- char pidfile[PATH_MAX] = {0};
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "src-brick", &src_brick);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG, "src brick=%s", src_brick);
-
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get dest brick");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG, "dst brick=%s", dst_brick);
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "dict get on replace-brick operation failed");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "volume: %s does not exist",
- volname);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (GLUSTERD_STATUS_STARTED != volinfo->status) {
- ret = -1;
- snprintf (msg, sizeof (msg), "volume: %s is not started",
- volname);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (!glusterd_store_is_valid_brickpath (volname, dst_brick) ||
- !glusterd_is_valid_volfpath (volname, dst_brick)) {
- snprintf (msg, sizeof (msg), "brick path %s is too "
- "long.", dst_brick);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
-
- ret = -1;
- goto out;
- }
-
- ret = glusterd_check_gsync_running (volinfo, &is_run);
- if (ret && (is_run == _gf_false))
- gf_log ("", GF_LOG_WARNING, "Unable to get the status"
- " of active "GEOREP" session");
- if (is_run) {
- gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"
- "for the volume %s ", volname);
- snprintf (msg, sizeof(msg), GEOREP" sessions are active "
- "for the volume %s.\nStop "GEOREP " sessions "
- "involved in this volume. Use 'volume "GEOREP
- " status' command for more info.",
- volname);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (glusterd_is_defrag_on(volinfo)) {
- snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
- "progress. Please retry after completion", volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- switch (replace_op) {
- case GF_REPLACE_OP_START:
- if (glusterd_is_rb_started (volinfo)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick is already "
- "started for volume ");
- ret = -1;
- goto out;
- }
- break;
- case GF_REPLACE_OP_PAUSE:
- if (glusterd_is_rb_paused (volinfo)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick is already "
- "paused for volume ");
- ret = -1;
- goto out;
- } else if (!glusterd_is_rb_started(volinfo)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick is not"
- " started for volume ");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_REPLACE_OP_ABORT:
- if (!glusterd_is_rb_ongoing (volinfo)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick is not"
- " started or paused for volume ");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_REPLACE_OP_COMMIT:
- if (!glusterd_is_rb_ongoing (volinfo)) {
- gf_log ("", GF_LOG_ERROR, "Replace brick is not "
- "started for volume ");
- ret = -1;
- goto out;
- }
- break;
-
- case GF_REPLACE_OP_COMMIT_FORCE: break;
-
- case GF_REPLACE_OP_STATUS:
-
- if (glusterd_is_rb_ongoing (volinfo) == _gf_false) {
- ret = gf_asprintf (op_errstr, "replace-brick not"
- " started on volume %s",
- volinfo->volname);
- if (ret < 0) {
- *op_errstr = NULL;
- goto out;
- }
-
- gf_log (THIS->name, GF_LOG_ERROR, "%s", *op_errstr);
- ret = -1;
- goto out;
- }
- break;
-
- default:
- ret = -1;
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
- &src_brickinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "brick: %s does not exist in "
- "volume: %s", src_brick, volname);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ctx = glusterd_op_get_ctx();
- if (ctx) {
- if (!glusterd_is_fuse_available ()) {
- gf_log ("glusterd", GF_LOG_ERROR, "Unable to open /dev/"
- "fuse (%s), replace-brick command failed",
- strerror (errno));
- snprintf (msg, sizeof(msg), "Fuse unavailable\n "
- "Replace-brick failed");
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- }
-
- if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
- gf_log ("", GF_LOG_DEBUG,
- "I AM THE SOURCE HOST");
- if (src_brickinfo->port && rsp_dict) {
- ret = dict_set_int32 (rsp_dict, "src-brick-port",
- src_brickinfo->port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set src-brick-port=%d",
- src_brickinfo->port);
- }
- }
-
- GLUSTERD_GET_VOLUME_DIR (voldir, volinfo, priv);
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, voldir,
- src_brickinfo->hostname,
- src_brickinfo->path);
- if ((replace_op != GF_REPLACE_OP_COMMIT_FORCE) &&
- !glusterd_is_service_running (pidfile, NULL)) {
- snprintf(msg, sizeof(msg), "Source brick %s:%s "
- "is not online.", src_brickinfo->hostname,
- src_brickinfo->path);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
-
- }
-
- dup_dstbrick = gf_strdup (dst_brick);
- if (!dup_dstbrick) {
- ret = -1;
- gf_log ("", GF_LOG_ERROR, "Memory allocation failed");
- goto out;
- }
- host = strtok_r (dup_dstbrick, ":", &savetok);
- path = strtok_r (NULL, ":", &savetok);
-
- if (!host || !path) {
- gf_log ("", GF_LOG_ERROR,
- "dst brick %s is not of form <HOSTNAME>:<export-dir>",
- dst_brick);
- ret = -1;
- goto out;
- }
-
- ret = glusterd_brickinfo_new_from_brick (dst_brick, &dst_brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo,
- msg, sizeof (msg));
- if (ret) {
- *op_errstr = gf_strdup (msg);
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR, *op_errstr);
- goto out;
- }
-
- if (!glusterd_is_rb_ongoing (volinfo) &&
- (replace_op == GF_REPLACE_OP_START ||
- replace_op == GF_REPLACE_OP_COMMIT_FORCE)) {
-
- volinfo->src_brick = src_brickinfo;
- volinfo->dst_brick = dst_brickinfo;
- }
-
- if (glusterd_rb_check_bricks (volinfo, src_brickinfo, dst_brickinfo)) {
-
- ret = -1;
- *op_errstr = gf_strdup ("Incorrect source or "
- "destination brick");
- if (*op_errstr)
- gf_log (THIS->name, GF_LOG_ERROR, "%s", *op_errstr);
- goto out;
- }
-
- if (!glusterd_is_rb_ongoing (volinfo) &&
- !glusterd_is_local_addr (host)) {
- ret = glusterd_brick_create_path (host, path,
- volinfo->volume_id,
- op_errstr);
- if (ret)
- goto out;
- }
-
- if (glusterd_is_local_addr (host)) {
- ret = glusterd_friend_find (NULL, host, &peerinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s, is not a friend",
- host);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (!peerinfo->connected) {
- snprintf (msg, sizeof (msg), "%s, is not connected at "
- "the moment", host);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state) {
- snprintf (msg, sizeof (msg), "%s, is not befriended "
- "at the moment", host);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-
-out:
- GF_FREE (dup_dstbrick);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-static int
-rb_set_mntfd (int mntfd)
-{
- int ret = -1;
- dict_t *ctx = NULL;
-
- ctx = glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Failed to get op ctx");
- goto out;
- }
- ret = dict_set_int32 (ctx, "mntfd", mntfd);
- if (ret)
- gf_log (THIS->name, GF_LOG_DEBUG, "Failed to set mnt fd "
- "in op ctx");
-out:
- return ret;
-}
-
-static int
-rb_get_mntfd (int *mntfd)
-{
- int ret = -1;
- dict_t *ctx = NULL;
-
- ctx = glusterd_op_get_ctx ();
- if (!ctx) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Failed to get op ctx");
- goto out;
- }
- ret = dict_get_int32 (ctx, "mntfd", mntfd);
- if (ret)
- gf_log (THIS->name, GF_LOG_DEBUG, "Failed to get mnt fd "
- "from op ctx");
-out:
- return ret;
-}
-
-static int
-rb_regenerate_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- int32_t pump_needed)
-{
- dict_t *dict = NULL;
- int ret = 0;
-
- dict = volinfo->dict;
-
- gf_log ("", GF_LOG_DEBUG,
- "attempting to set pump value=%d", pump_needed);
-
- ret = dict_set_int32 (dict, "enable-pump", pump_needed);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "could not dict_set enable-pump");
- goto out;
- }
-
- ret = glusterd_create_rb_volfiles (volinfo, brickinfo);
-
-out:
- return ret;
-}
-
-static int
-rb_src_brick_restart (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo,
- int activate_pump)
-{
- int ret = 0;
-
- gf_log ("", GF_LOG_DEBUG,
- "Attempting to kill src");
-
- ret = glusterd_nfs_server_stop (volinfo);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to stop nfs, ret: %d",
- ret);
- }
-
- ret = glusterd_volume_stop_glusterfs (volinfo, src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to stop "
- "glusterfs, ret: %d", ret);
- goto out;
- }
-
- glusterd_delete_volfile (volinfo, src_brickinfo);
-
- if (activate_pump) {
- ret = rb_regenerate_volfiles (volinfo, src_brickinfo, 1);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not regenerate volfiles with pump");
- goto out;
- }
- } else {
- ret = rb_regenerate_volfiles (volinfo, src_brickinfo, 0);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not regenerate volfiles without pump");
- goto out;
- }
-
- }
-
- sleep (2);
- ret = glusterd_volume_start_glusterfs (volinfo, src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to start "
- "glusterfs, ret: %d", ret);
- goto out;
- }
-
-out:
- ret = glusterd_nfs_server_start (volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to start nfs, ret: %d",
- ret);
- }
- return ret;
-}
-
-static int
-rb_send_xattr_command (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo,
- glusterd_brickinfo_t *dst_brickinfo,
- const char *xattr_key, const char *value)
-{
- int ret = -1;
- int mntfd = -1;
-
- ret = rb_get_mntfd (&mntfd);
- if (ret)
- goto out;
-
- ret = sys_fsetxattr (mntfd, xattr_key, value, strlen (value) + 1, 0);
- if (ret)
- gf_log (THIS->name, GF_LOG_DEBUG, "setxattr on key: "
- "%s, reason: %s", xattr_key, strerror (errno));
-
-out:
- return ret;
-}
-
-static int
-rb_spawn_dst_brick (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- int ret = -1;
- int32_t port = 0;
-
- priv = THIS->private;
-
- port = pmap_registry_alloc (THIS);
- brickinfo->port = port;
-
- GF_ASSERT (port);
-
- runinit (&runner);
- runner_add_arg (&runner, SBIN_DIR"/glusterfs");
- runner_argprintf (&runner, "-f" "%s/vols/%s/"RB_DSTBRICKVOL_FILENAME,
- priv->workdir, volinfo->volname);
- runner_argprintf (&runner, "-p" "%s/vols/%s/"RB_DSTBRICK_PIDFILE,
- priv->workdir, volinfo->volname);
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "src-server.listen-port=%d", port);
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
-
- ret = runner_run (&runner);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not start glusterfs");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG,
- "Successfully started glusterfs: brick=%s:%s",
- brickinfo->hostname, brickinfo->path);
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-rb_spawn_glusterfs_client (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- struct stat buf = {0,};
- char mntpt[PATH_MAX] = {0,};
- int mntfd = -1;
- int ret = -1;
-
- this = THIS;
- priv = this->private;
-
- GLUSTERD_GET_RB_MNTPT (mntpt, sizeof (mntpt), volinfo);
- runinit (&runner);
- runner_add_arg (&runner, SBIN_DIR"/glusterfs");
- runner_argprintf (&runner, "-f" "%s/vols/%s/"RB_CLIENTVOL_FILENAME,
- priv->workdir, volinfo->volname);
- runner_add_arg (&runner, mntpt);
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
-
- ret = runner_run_reuse (&runner);
- if (ret) {
- runner_log (&runner, this->name, GF_LOG_DEBUG,
- "Could not start glusterfs");
- runner_end (&runner);
- goto out;
- } else {
- runner_log (&runner, this->name, GF_LOG_DEBUG,
- "Successfully started glusterfs");
- runner_end (&runner);
- }
-
- ret = stat (mntpt, &buf);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "stat on mount point %s "
- "failed", mntpt);
- goto out;
- }
-
- mntfd = open (mntpt, O_DIRECTORY);
- if (mntfd == -1)
- goto out;
-
- ret = rb_set_mntfd (mntfd);
- if (ret)
- goto out;
-
- runinit (&runner);
- runner_add_args (&runner, "/bin/umount", "-l", mntpt, NULL);
- ret = runner_run_reuse (&runner);
- if (ret) {
- runner_log (&runner, this->name, GF_LOG_DEBUG,
- "Lazy unmount failed on maintenance client");
- runner_end (&runner);
- goto out;
- } else {
- runner_log (&runner, this->name, GF_LOG_DEBUG,
- "Successfully unmounted maintenance client");
- runner_end (&runner);
- }
-
-
-out:
-
- return ret;
-}
-
-static const char *client_volfile_str = "volume mnt-client\n"
- " type protocol/client\n"
- " option remote-host %s\n"
- " option remote-subvolume %s\n"
- " option remote-port %d\n"
- " option transport-type %s\n"
- " option username %s\n"
- " option password %s\n"
- "end-volume\n"
- "volume mnt-wb\n"
- " type performance/write-behind\n"
- " subvolumes mnt-client\n"
- "end-volume\n";
-
-static int
-rb_generate_client_volfile (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo)
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- FILE *file = NULL;
- char filename[PATH_MAX] = {0, };
- int ret = -1;
- int fd = -1;
- char *ttype = NULL;
-
- this = THIS;
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG, "Creating volfile");
-
- snprintf (filename, PATH_MAX, "%s/vols/%s/%s",
- priv->workdir, volinfo->volname,
- RB_CLIENTVOL_FILENAME);
-
- fd = open (filename, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s", strerror (errno));
- goto out;
- }
- close (fd);
-
- file = fopen (filename, "w+");
- if (!file) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Open of volfile failed");
- ret = -1;
- goto out;
- }
-
- GF_ASSERT (src_brickinfo->port);
-
- ttype = glusterd_get_trans_type_rb (volinfo->transport_type);
- if (NULL == ttype){
- ret = -1;
- goto out;
- }
-
- fprintf (file, client_volfile_str, src_brickinfo->hostname,
- src_brickinfo->path,
- src_brickinfo->port, ttype,
- glusterd_auth_get_username (volinfo),
- glusterd_auth_get_password (volinfo));
-
- fclose (file);
- GF_FREE (ttype);
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static const char *dst_brick_volfile_str = "volume src-posix\n"
- " type storage/posix\n"
- " option directory %s\n"
- " option volume-id %s\n"
- "end-volume\n"
- "volume %s\n"
- " type features/locks\n"
- " subvolumes src-posix\n"
- "end-volume\n"
- "volume src-server\n"
- " type protocol/server\n"
- " option auth.login.%s.allow %s\n"
- " option auth.login.%s.password %s\n"
- " option auth.addr.%s.allow *\n"
- " option transport-type %s\n"
- " subvolumes %s\n"
- "end-volume\n";
-
-static int
-rb_generate_dst_brick_volfile (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *dst_brickinfo)
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- FILE *file = NULL;
- char filename[PATH_MAX] = {0, };
- int ret = -1;
- int fd = -1;
- char *trans_type = NULL;
-
- this = THIS;
- priv = this->private;
-
- gf_log (this->name, GF_LOG_DEBUG,
- "Creating volfile");
-
- snprintf (filename, PATH_MAX, "%s/vols/%s/%s",
- priv->workdir, volinfo->volname,
- RB_DSTBRICKVOL_FILENAME);
-
- fd = creat (filename, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s", strerror (errno));
- goto out;
- }
- close (fd);
-
- file = fopen (filename, "w+");
- if (!file) {
- gf_log (this->name, GF_LOG_DEBUG,
- "Open of volfile failed");
- ret = -1;
- goto out;
- }
-
- trans_type = glusterd_get_trans_type_rb (volinfo->transport_type);
- if (NULL == trans_type){
- ret = -1;
- goto out;
- }
-
- fprintf (file, dst_brick_volfile_str,
- dst_brickinfo->path,
- uuid_utoa (volinfo->volume_id),
- dst_brickinfo->path,
- dst_brickinfo->path,
- glusterd_auth_get_username (volinfo),
- glusterd_auth_get_username (volinfo),
- glusterd_auth_get_password (volinfo),
- dst_brickinfo->path,
- trans_type,
- dst_brickinfo->path);
-
- GF_FREE (trans_type);
-
- fclose (file);
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-static int
-rb_mountpoint_mkdir (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo)
-{
- char mntpt[PATH_MAX] = {0,};
- int ret = -1;
-
- GLUSTERD_GET_RB_MNTPT (mntpt, sizeof (mntpt), volinfo);
- ret = mkdir (mntpt, 0777);
- if (ret && (errno != EEXIST)) {
- gf_log ("", GF_LOG_DEBUG, "mkdir failed, due to %s",
- strerror (errno));
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-rb_mountpoint_rmdir (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo)
-{
- char mntpt[PATH_MAX] = {0,};
- int ret = -1;
-
- GLUSTERD_GET_RB_MNTPT (mntpt, sizeof (mntpt), volinfo);
- ret = rmdir (mntpt);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "rmdir failed, due to %s",
- strerror (errno));
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-rb_destroy_maintenance_client (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo)
-{
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char volfile[PATH_MAX] = {0,};
- int ret = -1;
- int mntfd = -1;
-
- this = THIS;
- priv = this->private;
-
- ret = rb_get_mntfd (&mntfd);
- if (ret)
- goto out;
-
- ret = close (mntfd);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Failed to close mount "
- "point directory");
- goto out;
- }
-
- ret = rb_mountpoint_rmdir (volinfo, src_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "rmdir of mountpoint "
- "failed");
- goto out;
- }
-
- snprintf (volfile, PATH_MAX, "%s/vols/%s/%s", priv->workdir,
- volinfo->volname, RB_CLIENTVOL_FILENAME);
-
- ret = unlink (volfile);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "unlink of volfile %s "
- "failed", volfile);
- goto out;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-static int
-rb_spawn_maintenance_client (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo)
-{
- int ret = -1;
-
- ret = rb_generate_client_volfile (volinfo, src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to generate client "
- "volfile");
- goto out;
- }
-
- ret = rb_mountpoint_mkdir (volinfo, src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to mkdir "
- "mountpoint");
- goto out;
- }
-
- ret = rb_spawn_glusterfs_client (volinfo, src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-rb_spawn_destination_brick (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *dst_brickinfo)
-
-{
- int ret = -1;
-
- ret = rb_generate_dst_brick_volfile (volinfo, dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to generate client "
- "volfile");
- goto out;
- }
-
- ret = rb_spawn_dst_brick (volinfo, dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to start glusterfs");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-rb_kill_destination_brick (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *dst_brickinfo)
-{
- glusterd_conf_t *priv = NULL;
- char pidfile[PATH_MAX] = {0,};
-
- priv = THIS->private;
-
- snprintf (pidfile, PATH_MAX, "%s/vols/%s/%s",
- priv->workdir, volinfo->volname,
- RB_DSTBRICK_PIDFILE);
-
- return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_true);
-}
-
-static int
-rb_get_xattr_command (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo,
- glusterd_brickinfo_t *dst_brickinfo,
- const char *xattr_key,
- char *value)
-{
- int ret = -1;
- int mntfd = -1;
-
- ret = rb_get_mntfd (&mntfd);
- if (ret)
- goto out;
-
- ret = sys_fgetxattr (mntfd, xattr_key, value, 8192);
-
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_DEBUG, "getxattr on key: %s "
- "failed, reason: %s", xattr_key, strerror (errno));
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-rb_send_cmd (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src,
- glusterd_brickinfo_t *dst,
- gf1_cli_replace_op op)
-{
- char start_value[8192] = {0,};
- char status[8192] = {0,};
- char *status_reply = NULL;
- dict_t *ctx = NULL;
- int ret = 0;
-
- GF_ASSERT (volinfo);
- GF_ASSERT (src);
- GF_ASSERT (dst);
- GF_ASSERT ((op > GF_REPLACE_OP_NONE)
- && (op <= GF_REPLACE_OP_COMMIT_FORCE));
-
- switch (op) {
- case GF_REPLACE_OP_START:
- {
- snprintf (start_value, sizeof (start_value),
- "%s:%s:%d", dst->hostname, dst->path,
- dst->port);
- ret = rb_send_xattr_command (volinfo, src, dst,
- RB_PUMP_CMD_START,
- start_value);
- }
- break;
- case GF_REPLACE_OP_PAUSE:
- {
- ret = rb_send_xattr_command (volinfo, src, dst,
- RB_PUMP_CMD_PAUSE,
- RB_PUMP_DEF_ARG);
- }
- break;
- case GF_REPLACE_OP_ABORT:
- {
- ret = rb_send_xattr_command (volinfo, src, dst,
- RB_PUMP_CMD_ABORT,
- RB_PUMP_DEF_ARG);
- }
- break;
- case GF_REPLACE_OP_COMMIT:
- {
- ret = rb_send_xattr_command (volinfo, src, dst,
- RB_PUMP_CMD_COMMIT,
- RB_PUMP_DEF_ARG);
- }
- break;
- case GF_REPLACE_OP_STATUS:
- {
- ret = rb_get_xattr_command (volinfo, src, dst,
- RB_PUMP_CMD_STATUS,
- status);
- if (ret)
- goto out;
-
- ctx = glusterd_op_get_ctx ();
- GF_ASSERT (ctx);
- if (!ctx) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "ctx is not present.");
- goto out;
- }
-
- status_reply = gf_strdup (status);
- ret = dict_set_dynstr (ctx, "status-reply",
- status_reply);
- if (ret) {
- GF_FREE (status_reply);
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't "
- "set rb status response in context.");
- goto out;
- }
- }
- break;
- default:
- {
- GF_ASSERT (0);
- ret = -1;
- gf_log (THIS->name, GF_LOG_CRITICAL, "Invalid replace"
- " brick subcommand.");
- }
- break;
- }
-out:
- return ret;
-}
-
-static int
-rb_do_operation (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brickinfo,
- glusterd_brickinfo_t *dst_brickinfo,
- gf1_cli_replace_op op)
-{
-
- int ret = -1;
- char op_str[256] = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
-
- ret = rb_spawn_maintenance_client (volinfo, src_brickinfo);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG, "Could not spawn "
- "maintenance client");
- goto umount;
- }
-
- ret = rb_send_cmd (volinfo, src_brickinfo, dst_brickinfo, op);
- if (ret) {
- (void) glusterd_get_replace_op_str (op, op_str);
- gf_log (this->name, GF_LOG_DEBUG, "Sending replace-brick "
- "sub-command %s failed.", op_str);
- }
-
-umount:
- if (rb_destroy_maintenance_client (volinfo, src_brickinfo))
- gf_log (this->name, GF_LOG_DEBUG, "Failed to destroy "
- "maintenance client");
-
- return ret;
-}
-
-/* Set src-brick's port number to be used in the maintenance mount
- * after all commit acks are received.
- */
-static int
-rb_update_srcbrick_port (glusterd_brickinfo_t *src_brickinfo, dict_t *rsp_dict,
- dict_t *req_dict, int32_t replace_op)
-{
- xlator_t *this = NULL;
- dict_t *ctx = NULL;
- int ret = 0;
- int dict_ret = 0;
- int src_port = 0;
-
- this = THIS;
-
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- dict_ret = dict_get_int32 (req_dict, "src-brick-port", &src_port);
- if (src_port)
- src_brickinfo->port = src_port;
- }
-
- if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
- gf_log ("", GF_LOG_INFO,
- "adding src-brick port no");
-
- src_brickinfo->port = pmap_registry_search (this,
- src_brickinfo->path, GF_PMAP_PORT_BRICKSERVER);
- if (!src_brickinfo->port &&
- replace_op != GF_REPLACE_OP_COMMIT_FORCE ) {
- gf_log ("", GF_LOG_ERROR,
- "Src brick port not available");
- ret = -1;
- goto out;
- }
-
- if (rsp_dict) {
- ret = dict_set_int32 (rsp_dict, "src-brick-port", src_brickinfo->port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set src-brick port no");
- goto out;
- }
- }
-
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- ret = dict_set_int32 (ctx, "src-brick-port", src_brickinfo->port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set src-brick port no");
- goto out;
- }
- }
-
- }
-
-out:
- return ret;
-
-}
-
-static int
-rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
- dict_t *req_dict, int32_t replace_op)
-{
- dict_t *ctx = NULL;
- int ret = 0;
- int dict_ret = 0;
- int dst_port = 0;
-
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
- if (dst_port)
- dst_brickinfo->port = dst_port;
-
- }
-
- if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
- gf_log ("", GF_LOG_INFO,
- "adding dst-brick port no");
-
- if (rsp_dict) {
- ret = dict_set_int32 (rsp_dict, "dst-brick-port",
- dst_brickinfo->port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set dst-brick port no in rsp dict");
- goto out;
- }
- }
-
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- ret = dict_set_int32 (ctx, "dst-brick-port",
- dst_brickinfo->port);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not set dst-brick port no");
- goto out;
- }
- }
- }
-out:
- return ret;
-}
-
-static int
-glusterd_op_perform_replace_brick (glusterd_volinfo_t *volinfo,
- char *old_brick, char *new_brick)
-{
- glusterd_brickinfo_t *old_brickinfo = NULL;
- glusterd_brickinfo_t *new_brickinfo = NULL;
- int32_t ret = -1;
-
- GF_ASSERT (volinfo);
-
- ret = glusterd_brickinfo_new_from_brick (new_brick,
- &new_brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (new_brickinfo);
- if (ret)
- goto out;
-
- list_add_tail (&new_brickinfo->brick_list,
- &old_brickinfo->brick_list);
-
- volinfo->brick_count++;
-
- ret = glusterd_op_perform_remove_brick (volinfo, old_brick, 1, NULL);
- if (ret)
- goto out;
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret)
- goto out;
-
- if (GLUSTERD_STATUS_STARTED == volinfo->status) {
- ret = glusterd_brick_start (volinfo, new_brickinfo);
- if (ret)
- goto out;
- }
-
-out:
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
-{
- int ret = 0;
- dict_t *ctx = NULL;
- int replace_op = 0;
- glusterd_volinfo_t *volinfo = NULL;
- char *volname = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- glusterd_brickinfo_t *src_brickinfo = NULL;
- glusterd_brickinfo_t *dst_brickinfo = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "src-brick", &src_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "src brick=%s", src_brick);
-
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get dst brick");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG,
- "dst brick=%s", dst_brick);
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "operation", (int32_t *)&replace_op);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "dict_get on operation failed");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
- &src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");
- goto out;
- }
-
-
- ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get "
- "replace brick destination brickinfo");
- goto out;
- }
-
- ret = glusterd_resolve_brick (dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to resolve dst-brickinfo");
- goto out;
- }
-
- ret = rb_update_srcbrick_port (src_brickinfo, rsp_dict,
- dict, replace_op);
- if (ret)
- goto out;
-
- if ((GF_REPLACE_OP_START != replace_op)) {
- ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
- dict, replace_op);
- if (ret)
- goto out;
- }
-
- switch (replace_op) {
- case GF_REPLACE_OP_START:
- {
- if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
- gf_log ("", GF_LOG_INFO,
- "I AM THE DESTINATION HOST");
- if (!glusterd_is_rb_paused (volinfo)) {
- ret = rb_spawn_destination_brick (volinfo, dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Failed to spawn destination brick");
- goto out;
- }
- } else {
- gf_log ("", GF_LOG_ERROR, "Replace brick is already "
- "started=> no need to restart dst brick ");
- }
- }
-
-
- if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
- ret = rb_src_brick_restart (volinfo, src_brickinfo,
- 1);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Could not restart src-brick");
- goto out;
- }
- }
-
- if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
- gf_log ("", GF_LOG_INFO,
- "adding dst-brick port no");
-
- ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
- dict, replace_op);
- if (ret)
- goto out;
- }
-
- glusterd_set_rb_status (volinfo, GF_RB_STATUS_STARTED);
- break;
- }
-
- case GF_REPLACE_OP_COMMIT:
- {
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- ret = rb_do_operation (volinfo, src_brickinfo,
- dst_brickinfo,
- GF_REPLACE_OP_COMMIT);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Commit operation failed");
- goto out;
- }
- }
- }
- /* fall through */
- case GF_REPLACE_OP_COMMIT_FORCE:
- {
- ret = dict_set_int32 (volinfo->dict, "enable-pump", 0);
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Received commit - will be adding dst brick and "
- "removing src brick");
-
- if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "I AM THE DESTINATION HOST");
- ret = rb_kill_destination_brick (volinfo, dst_brickinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Unable to cleanup dst brick");
- goto out;
- }
- }
-
- ret = glusterd_nodesvcs_stop (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Unable to stop nfs server, ret: %d", ret);
- }
-
- ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
- dst_brick);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to add "
- "dst-brick: %s to volume: %s",
- dst_brick, volinfo->volname);
- (void) glusterd_nodesvcs_handle_graph_change (volinfo);
- goto out;
- }
-
- volinfo->defrag_status = 0;
-
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL,
- "Failed to generate nfs volume file");
- }
-
-
- ret = glusterd_fetchspec_notify (THIS);
- glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE);
- glusterd_brickinfo_delete (volinfo->dst_brick);
- volinfo->src_brick = volinfo->dst_brick = NULL;
- }
- break;
-
- case GF_REPLACE_OP_PAUSE:
- {
- gf_log ("", GF_LOG_DEBUG,
- "Received pause - doing nothing");
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- ret = rb_do_operation (volinfo, src_brickinfo,
- dst_brickinfo,
- GF_REPLACE_OP_PAUSE);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Pause operation failed");
- goto out;
- }
- }
-
- glusterd_set_rb_status (volinfo, GF_RB_STATUS_PAUSED);
- }
- break;
-
- case GF_REPLACE_OP_ABORT:
- {
-
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- ret = rb_do_operation (volinfo, src_brickinfo,
- dst_brickinfo,
- GF_REPLACE_OP_ABORT);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Abort operation failed");
- goto out;
- }
- }
-
- ret = dict_set_int32 (volinfo->dict, "enable-pump", 0);
- if (ret) {
- gf_log (THIS->name, GF_LOG_CRITICAL, "Unable to disable pump");
- }
-
- if (!glusterd_is_local_addr (src_brickinfo->hostname)) {
- ret = rb_src_brick_restart (volinfo, src_brickinfo,
- 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Couldn't restart src brick "
- "with pump xlator disabled.");
- goto out;
- }
- }
-
- if (!glusterd_is_local_addr (dst_brickinfo->hostname)) {
- gf_log (THIS->name, GF_LOG_INFO,
- "I AM THE DESTINATION HOST");
- ret = rb_kill_destination_brick (volinfo, dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "Failed to kill destination brick");
- goto out;
- }
- }
- glusterd_set_rb_status (volinfo, GF_RB_STATUS_NONE);
- glusterd_brickinfo_delete (volinfo->dst_brick);
- volinfo->src_brick = volinfo->dst_brick = NULL;
- }
- break;
-
- case GF_REPLACE_OP_STATUS:
- {
- gf_log ("", GF_LOG_DEBUG,
- "received status - doing nothing");
- ctx = glusterd_op_get_ctx ();
- if (ctx) {
- if (glusterd_is_rb_paused (volinfo)) {
- ret = dict_set_str (ctx, "status-reply",
- "replace brick has been paused");
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set pump status"
- " in ctx");
- goto out;
- }
-
- ret = rb_do_operation (volinfo, src_brickinfo,
- dst_brickinfo,
- GF_REPLACE_OP_STATUS);
- if (ret)
- goto out;
- }
-
- }
- break;
-
- default:
- ret = -1;
- goto out;
- }
- if (!ret && replace_op != GF_REPLACE_OP_STATUS)
- ret = glusterd_store_volinfo (volinfo,
- GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't store"
- " replace brick operation's state");
-
-out:
- return ret;
-}
-
-void
-glusterd_do_replace_brick (void *data)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int32_t op = 0;
- int32_t src_port = 0;
- int32_t dst_port = 0;
- dict_t *dict = NULL;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *volname = NULL;
- glusterd_brickinfo_t *src_brickinfo = NULL;
- glusterd_brickinfo_t *dst_brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
-
- int ret = 0;
-
- dict = data;
-
- GF_ASSERT (THIS);
-
- priv = THIS->private;
-
- if (priv->timer) {
- gf_timer_call_cancel (THIS->ctx, priv->timer);
- priv->timer = NULL;
- gf_log ("", GF_LOG_DEBUG,
- "Cancelling timer thread");
- }
-
- gf_log ("", GF_LOG_DEBUG,
- "Replace brick operation detected");
-
- ret = dict_get_int32 (dict, "operation", &op);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG,
- "dict_get on operation failed");
- goto out;
- }
- ret = dict_get_str (dict, "src-brick", &src_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get src brick");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG,
- "src brick=%s", src_brick);
-
- ret = dict_get_str (dict, "dst-brick", &dst_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get dst brick");
- goto out;
- }
-
- gf_log ("", GF_LOG_DEBUG,
- "dst brick=%s", dst_brick);
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to allocate memory");
- goto out;
- }
-
- ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
- &src_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get src-brickinfo");
- goto out;
- }
-
- ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
- if (!dst_brickinfo) {
- gf_log ("", GF_LOG_DEBUG, "Unable to get dst-brickinfo");
- goto out;
- }
-
- ret = glusterd_resolve_brick (dst_brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Unable to resolve dst-brickinfo");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "src-brick-port", &src_port);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get src-brick port");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "dst-brick-port", &dst_port);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get dst-brick port");
- }
-
- dst_brickinfo->port = dst_port;
- src_brickinfo->port = src_port;
-
- switch (op) {
- case GF_REPLACE_OP_START:
- if (!dst_port) {
- ret = -1;
- goto out;
- }
-
- ret = rb_do_operation (volinfo, src_brickinfo, dst_brickinfo,
- GF_REPLACE_OP_START);
- if (ret)
- goto out;
- break;
- case GF_REPLACE_OP_PAUSE:
- case GF_REPLACE_OP_ABORT:
- case GF_REPLACE_OP_COMMIT:
- case GF_REPLACE_OP_COMMIT_FORCE:
- case GF_REPLACE_OP_STATUS:
- break;
- default:
- ret = -1;
- goto out;
- }
-
-out:
- if (ret)
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT, NULL);
- else
- ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC, NULL);
-
- if (dict)
- dict_unref (dict);
-
- glusterd_op_sm ();
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 7937235be..65ccec4d4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -25,9 +25,8 @@
#include "rpc-clnt.h"
#include "glusterd1-xdr.h"
-#include "cli1-xdr.h"
-
-#include "xdr-generic.h"
+#include "glusterd1.h"
+#include "cli1.h"
#include "compat-errno.h"
#include "glusterd-op-sm.h"
@@ -45,20 +44,19 @@
extern glusterd_op_info_t opinfo;
int32_t
+glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this,
+ void *data);
+int32_t
glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
int32_t op_errno, rpcsvc_request_t *req,
void *op_ctx, char *op_errstr)
{
int32_t ret = -1;
+ gd_serialize_t sfunc = NULL;
void *cli_rsp = NULL;
dict_t *ctx = NULL;
char *free_ptr = NULL;
glusterd_conf_t *conf = NULL;
- xdrproc_t xdrproc = NULL;
- char *errstr = NULL;
- int32_t status = 0;
- int32_t count = 0;
- gf_cli_rsp rsp = {0,};
GF_ASSERT (THIS);
@@ -66,145 +64,363 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
GF_ASSERT (conf);
- ctx = op_ctx;
-
switch (op) {
- case GD_OP_REMOVE_BRICK:
+ case GD_OP_CREATE_VOLUME:
{
- if (ctx)
- ret = dict_get_str (ctx, "errstr", &errstr);
+ gf1_cli_create_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_create_vol_rsp;
break;
}
- case GD_OP_RESET_VOLUME:
+
+ case GD_OP_START_VOLUME:
{
- if (op_ret && !op_errstr)
- errstr = "Error while resetting options";
+ gf1_cli_start_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_start_vol_rsp;
break;
}
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
+
+ case GD_OP_STOP_VOLUME:
{
- if (ctx) {
- ret = dict_get_int32 (ctx, "status", &status);
- if (ret) {
- gf_log (THIS->name, GF_LOG_TRACE,
- "failed to get status");
- }
- }
+ gf1_cli_stop_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_stop_vol_rsp;
break;
}
- case GD_OP_GSYNC_SET:
+
+ case GD_OP_DELETE_VOLUME:
{
- if (ctx) {
- ret = dict_get_str (ctx, "errstr", &errstr);
- ret = dict_set_str (ctx, "glusterd_workdir", conf->workdir);
- /* swallow error here, that will be re-triggered in cli */
+ gf1_cli_delete_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_delete_vol_rsp;
+ break;
+ }
- }
- break;
+ case GD_OP_DEFRAG_VOLUME:
+ {
+ gf1_cli_defrag_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ //rsp.volname = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_defrag_vol_rsp;
+ break;
+ }
+ case GD_OP_ADD_BRICK:
+ {
+ gf1_cli_add_brick_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_add_brick_rsp;
+ break;
}
- case GD_OP_QUOTA:
+
+ case GD_OP_REMOVE_BRICK:
{
- if (ctx && !op_errstr) {
- ret = dict_get_str (ctx, "errstr", &errstr);
- }
+ gf1_cli_remove_brick_rsp rsp = {0,};
+ ctx = op_ctx;
+ if (ctx &&
+ dict_get_str (ctx, "errstr", &rsp.op_errstr))
+ rsp.op_errstr = "";
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_remove_brick_rsp;
break;
}
- case GD_OP_PROFILE_VOLUME:
+
+ case GD_OP_REPLACE_BRICK:
{
- if (ctx && dict_get_int32 (ctx, "count", &count)) {
- ret = dict_set_int32 (ctx, "count", 0);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to set count in dictionary");
- }
- }
+ gf1_cli_replace_brick_rsp rsp = {0,};
+ ctx = op_ctx;
+ if (ctx &&
+ dict_get_str (ctx, "status-reply", &rsp.status))
+ rsp.status = "";
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ rsp.volname = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_replace_brick_rsp;
break;
}
- case GD_OP_START_BRICK:
- case GD_OP_STOP_BRICK:
+
+ case GD_OP_SET_VOLUME:
{
- gf_log ("", GF_LOG_DEBUG, "not supported op %d", op);
+ gf1_cli_set_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_set_vol_rsp;
break;
}
- case GD_OP_NONE:
- case GD_OP_MAX:
+
+ case GD_OP_RESET_VOLUME:
{
- gf_log ("", GF_LOG_ERROR, "invalid operation %d", op);
+ gf_log ("", GF_LOG_DEBUG, "Return value to CLI");
+ gf1_cli_reset_vol_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = 1;
+ rsp.volname = "";
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "Error while resetting options";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_reset_vol_rsp;
+ break;
+ }
+
+ case GD_OP_LOG_FILENAME:
+ {
+ gf1_cli_log_filename_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.errstr = op_errstr;
+ else
+ rsp.errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_log_filename_rsp;
break;
}
- case GD_OP_CREATE_VOLUME:
- case GD_OP_START_VOLUME:
- case GD_OP_STOP_VOLUME:
- case GD_OP_DELETE_VOLUME:
- case GD_OP_DEFRAG_VOLUME:
- case GD_OP_ADD_BRICK:
case GD_OP_LOG_ROTATE:
- case GD_OP_SYNC_VOLUME:
- case GD_OP_STATEDUMP_VOLUME:
- case GD_OP_REPLACE_BRICK:
- case GD_OP_STATUS_VOLUME:
- case GD_OP_SET_VOLUME:
- case GD_OP_LIST_VOLUME:
- case GD_OP_CLEARLOCKS_VOLUME:
- case GD_OP_HEAL_VOLUME:
{
- /*nothing specific to be done*/
+ gf1_cli_log_rotate_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.errstr = op_errstr;
+ else
+ rsp.errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_log_rotate_rsp;
break;
}
+ case GD_OP_SYNC_VOLUME:
+ {
+ gf1_cli_sync_volume_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else
+ rsp.op_errstr = "";
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_from_cli_sync_volume_rsp;
+ break;
}
+ case GD_OP_GSYNC_SET:
+ {
+ int type = 0;
+ char *str = NULL;
+ char *master = NULL;
+ char *slave = NULL;
+ char *op_name = NULL;
+ char *subop = NULL;
+ gf1_cli_gsync_set_rsp rsp = {0,};
+
+ ctx = op_ctx;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.op_errstr = "";
+ rsp.op_name = "";
+ rsp.subop = "";
+ rsp.master = "";
+ rsp.slave = "";
+ rsp.glusterd_workdir = conf->workdir;
+ rsp.gsync_prefix = GSYNCD_PREFIX;
+ if (ctx) {
+ ret = dict_get_str (ctx, "errstr", &str);
+ if (ret == 0)
+ rsp.op_errstr = str;
+ ret = dict_get_int32 (ctx, "type", &type);
+ if (ret == 0)
+ rsp.type = type;
+ ret = dict_get_str (ctx, "master", &master);
+ if (ret == 0)
+ rsp.master = master;
+
+ ret = dict_get_str (ctx, "slave", &slave);
+ if (ret == 0)
+ rsp.slave = slave;
+
+ if (type == GF_GSYNC_OPTION_TYPE_CONFIG) {
+ if (dict_get_str (ctx, "op_name", &op_name) == 0)
+ rsp.op_name = op_name;
+ if (dict_get_str (ctx, "subop", &subop) == 0)
+ rsp.subop = subop;
+ }
- rsp.op_ret = op_ret;
- rsp.op_errno = errno;
- if (errstr)
- rsp.op_errstr = errstr;
- else if (op_errstr)
- rsp.op_errstr = op_errstr;
+ ret = dict_allocate_and_serialize (ctx,
+ &rsp.status_dict.status_dict_val,
+ (size_t*)&rsp.status_dict.status_dict_len);
- if (!rsp.op_errstr)
- rsp.op_errstr = "";
+ if (ret == 0)
+ free_ptr = rsp.status_dict.status_dict_val;
- if (ctx) {
- ret = dict_allocate_and_serialize (ctx, &rsp.dict.dict_val,
- &rsp.dict.dict_len);
- if (ret < 0 )
- gf_log (THIS->name, GF_LOG_ERROR, "failed to "
- "serialize buffer");
+ }
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_gsync_set_rsp;
+ break;
+ }
+ case GD_OP_RENAME_VOLUME:
+ case GD_OP_START_BRICK:
+ case GD_OP_STOP_BRICK:
+ case GD_OP_LOG_LOCATE:
+ {
+ gf_log ("", GF_LOG_DEBUG, "not supported op %d", op);
+ break;
+ }
+ case GD_OP_PROFILE_VOLUME:
+ {
+ gf1_cli_stats_volume_rsp rsp = {0,};
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
else
- free_ptr = rsp.dict.dict_val;
+ rsp.op_errstr = "";
+ ctx = op_ctx;
+ dict_allocate_and_serialize (ctx,
+ &rsp.stats_info.stats_info_val,
+ (size_t*)&rsp.stats_info.stats_info_len);
+ free_ptr = rsp.stats_info.stats_info_val;
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_from_cli_stats_volume_rsp;
+ break;
}
- /* needed by 'rebalance status' */
- if (status)
- rsp.op_errno = status;
+ case GD_OP_QUOTA:
+ {
+ int32_t type;
+ char *str = NULL;
+ char *errstr = NULL;
+ gf1_cli_quota_rsp rsp = {0,};
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = op_errno;
+ rsp.volname = "";
+
+ ctx = op_ctx;
+
+ if (op_errstr)
+ rsp.op_errstr = op_errstr;
+ else {
+ ret = dict_get_str (ctx, "errstr", &errstr);
+ if (ret == 0)
+ rsp.op_errstr = errstr;
+ else
+ rsp.op_errstr = "";
+ }
+
+ rsp.limit_list = "";
+
+ if (op_ret == 0 && ctx) {
+ ret = dict_get_str (ctx, "volname", &str);
+ if (ret == 0)
+ rsp.volname = str;
- cli_rsp = &rsp;
- xdrproc = (xdrproc_t) xdr_gf_cli_rsp;
+ ret = dict_get_int32 (ctx, "type", &type);
+ if (ret == 0)
+ rsp.type = type;
+ else
+ rsp.type = 0;
+
+ if (type == GF_QUOTA_OPTION_TYPE_LIST) {
+ ret = dict_get_str (ctx,"limit_list", &str);
+
+ if (ret == 0)
+ rsp.limit_list = str;
+ }
+ }
+ cli_rsp = &rsp;
+ sfunc = gf_xdr_serialize_cli_quota_rsp;
+ break;
+ }
+
+ case GD_OP_NONE:
+ case GD_OP_MAX:
+ {
+ gf_log ("", GF_LOG_ERROR, "invalid operation %d", op);
+ break;
+ }
+ }
ret = glusterd_submit_reply (req, cli_rsp, NULL, 0, NULL,
- xdrproc);
+ sfunc);
- GF_FREE (free_ptr);
+ if (free_ptr)
+ GF_FREE (free_ptr);
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int
-glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_probe_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_probe_rsp rsp = {{0},};
+ glusterd_conf_t *conf = NULL;
int ret = 0;
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_friend_sm_event_t *event = NULL;
glusterd_probe_ctx_t *ctx = NULL;
+ conf = THIS->private;
+
if (-1 == req->rpc_status) {
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_probe_rsp);
+ ret = gd_xdr_to_mgmt_probe_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
//rsp.op_ret = -1;
@@ -224,7 +440,6 @@ glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
if (ctx->req) {
glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret,
rsp.op_errno,
- rsp.op_errstr,
ctx->hostname, ctx->port);
}
@@ -238,30 +453,6 @@ glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
GF_ASSERT (0);
}
- if (strncasecmp (rsp.hostname, peerinfo->hostname, 1024)) {
- gf_log (THIS->name, GF_LOG_INFO, "Host: %s with uuid: %s "
- "already present in cluster with alias hostname: %s",
- rsp.hostname, uuid_utoa (rsp.uuid), peerinfo->hostname);
-
- ctx = ((call_frame_t *)myframe)->local;
- ((call_frame_t *)myframe)->local = NULL;
-
- GF_ASSERT (ctx);
-
- rsp.op_errno = GF_PROBE_FRIEND;
- if (ctx->req) {
- glusterd_xfer_cli_probe_resp (ctx->req, rsp.op_ret,
- rsp.op_errno,
- rsp.op_errstr,
- ctx->hostname, ctx->port);
- }
-
- glusterd_destroy_probe_ctx (ctx);
- (void) glusterd_friend_remove (NULL, rsp.hostname);
- ret = rsp.op_ret;
- goto out;
- }
-
uuid_copy (peerinfo->uuid, rsp.uuid);
ret = glusterd_friend_sm_new_event
@@ -287,16 +478,18 @@ glusterd_probe_cbk (struct rpc_req *req, struct iovec *iov,
gf_log ("glusterd", GF_LOG_INFO, "Received resp to probe req");
out:
- free (rsp.hostname);//malloced by xdr
+ if (rsp.hostname)
+ free (rsp.hostname);//malloced by xdr
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
int
-glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
+glusterd3_1_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_friend_rsp rsp = {{0},};
+ glusterd_conf_t *conf = NULL;
int ret = -1;
glusterd_friend_sm_event_t *event = NULL;
glusterd_friend_sm_event_type_t event_type = GD_FRIEND_EVENT_NONE;
@@ -306,13 +499,15 @@ glusterd_friend_add_cbk (struct rpc_req * req, struct iovec *iov,
glusterd_probe_ctx_t *ctx = NULL;
glusterd_friend_update_ctx_t *ev_ctx = NULL;
+ conf = THIS->private;
+
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
+ ret = gd_xdr_to_mgmt_friend_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
@@ -370,23 +565,23 @@ out:
GF_ASSERT (ctx);
- if (ctx->req)//reverse probe doesn't have req
+ if (ctx->req)//reverse probe doesnt have req
ret = glusterd_xfer_cli_probe_resp (ctx->req, op_ret, op_errno,
- NULL, ctx->hostname,
- ctx->port);
+ ctx->hostname, ctx->port);
if (!ret) {
glusterd_friend_sm ();
glusterd_op_sm ();
}
if (ctx)
glusterd_destroy_probe_ctx (ctx);
- free (rsp.hostname);//malloced by xdr
+ if (rsp.hostname)
+ free (rsp.hostname);//malloced by xdr
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
int
-glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov,
+glusterd3_1_friend_remove_cbk (struct rpc_req * req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_friend_rsp rsp = {{0},};
@@ -398,7 +593,6 @@ glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov,
int32_t op_ret = -1;
int32_t op_errno = -1;
glusterd_probe_ctx_t *ctx = NULL;
- gf_boolean_t move_sm_now = _gf_true;
conf = THIS->private;
GF_ASSERT (conf);
@@ -410,11 +604,10 @@ glusterd_friend_remove_cbk (struct rpc_req * req, struct iovec *iov,
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- move_sm_now = _gf_false;
goto inject;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_friend_rsp);
+ ret = gd_xdr_to_mgmt_friend_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
@@ -454,17 +647,16 @@ inject:
if (ret)
goto respond;
- /*friend_sm would be moved on CLNT_DISCONNECT, consequently
- cleaning up peerinfo. Else, we run the risk of triggering
- a clnt_destroy within saved_frames_unwind.
- */
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+
op_ret = 0;
respond:
- ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno, NULL,
+ ret = glusterd_xfer_cli_deprobe_resp (ctx->req, op_ret, op_errno,
ctx->hostname);
- if (!ret && move_sm_now) {
+ if (!ret) {
glusterd_friend_sm ();
glusterd_op_sm ();
}
@@ -474,46 +666,51 @@ respond:
glusterd_destroy_probe_ctx (ctx);
}
- free (rsp.hostname);//malloced by xdr
+ if (rsp.hostname)
+ free (rsp.hostname);//malloced by xdr
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
int32_t
-glusterd_friend_update_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_friend_update_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
- int ret = -1;
- gd1_mgmt_friend_update_rsp rsp = {{0}, };
- xlator_t *this = NULL;
+ gd1_mgmt_cluster_lock_rsp rsp = {{0},};
+ int ret = -1;
+ int32_t op_ret = 0;
+ char str[50] = {0,};
GF_ASSERT (req);
- this = THIS;
if (-1 == req->rpc_status) {
- gf_log (this->name, GF_LOG_ERROR, "RPC Error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
goto out;
}
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_friend_update_rsp);
+/* ret = gd_xdr_to_mgmt_friend_update_rsp (*iov, &rsp);
if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to serialize friend"
- " update repsonse");
+ gf_log ("", GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
goto out;
}
+ uuid_unparse (rsp.uuid, str);
- ret = 0;
-out:
- gf_log (this->name, GF_LOG_INFO, "Received %s from uuid: %s",
- (ret)?"RJT":"ACC", uuid_utoa (rsp.uuid));
+ op_ret = rsp.op_ret;
+*/
+ gf_log ("glusterd", GF_LOG_INFO,
+ "Received %s from uuid: %s",
+ (op_ret)?"RJT":"ACC", str);
+out:
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
int32_t
-glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_cluster_lock_rsp rsp = {{0},};
@@ -530,7 +727,7 @@ glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
+ ret = gd_xdr_to_mgmt_cluster_lock_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
@@ -538,7 +735,6 @@ glusterd_cluster_lock_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
-out:
op_ret = rsp.op_ret;
gf_log ("glusterd", GF_LOG_INFO,
@@ -566,12 +762,13 @@ out:
glusterd_op_sm ();
}
+out:
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
int32_t
-glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_cluster_lock_rsp rsp = {{0},};
@@ -589,7 +786,7 @@ glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
+ ret = gd_xdr_to_mgmt_cluster_unlock_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
@@ -597,7 +794,6 @@ glusterd_cluster_unlock_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
}
-out:
op_ret = rsp.op_ret;
gf_log ("glusterd", GF_LOG_INFO,
@@ -625,36 +821,10 @@ out:
glusterd_op_sm ();
}
+out:
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
-
-static int32_t
-glusterd_append_gsync_status (dict_t *dst, dict_t *src)
-{
- int ret = 0;
- char *stop_msg = NULL;
-
- ret = dict_get_str (src, "gsync-status", &stop_msg);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- ret = dict_set_dynstr (dst, "gsync-status", gf_strdup (stop_msg));
- if (ret) {
- gf_log ("glusterd", GF_LOG_WARNING, "Unable to set the stop"
- "message in the ctx dictionary");
- goto out;
- }
-
- ret = 0;
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
static int32_t
glusterd_append_status_dicts (dict_t *dst, dict_t *src)
{
@@ -734,7 +904,7 @@ glusterd_gsync_use_rsp_dict (dict_t *rsp_dict, char *op_errstr)
dict_t *ctx = NULL;
int ret = 0;
- ctx = glusterd_op_get_ctx ();
+ ctx = glusterd_op_get_ctx (GD_OP_GSYNC_SET);
if (!ctx) {
gf_log ("", GF_LOG_ERROR,
"Operation Context is not present");
@@ -745,10 +915,6 @@ glusterd_gsync_use_rsp_dict (dict_t *rsp_dict, char *op_errstr)
ret = glusterd_append_status_dicts (ctx, rsp_dict);
if (ret)
goto out;
-
- ret = glusterd_append_gsync_status (ctx, rsp_dict);
- if (ret)
- goto out;
}
if (strcmp ("", op_errstr)) {
ret = dict_set_dynstr (ctx, "errstr", gf_strdup(op_errstr));
@@ -770,7 +936,7 @@ glusterd_rb_use_rsp_dict (dict_t *rsp_dict)
dict_t *ctx = NULL;
- ctx = glusterd_op_get_ctx ();
+ ctx = glusterd_op_get_ctx (GD_OP_REPLACE_BRICK);
if (!ctx) {
gf_log ("", GF_LOG_ERROR,
"Operation Context is not present");
@@ -819,7 +985,7 @@ out:
}
int32_t
-glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_stage_op_rsp rsp = {{0},};
@@ -836,20 +1002,16 @@ glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("error");
+ rsp.op_errstr = "error";
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
+ ret = gd_xdr_to_mgmt_stage_op_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("xdr decoding failed");
+ rsp.op_errstr = "error";
goto out;
}
@@ -871,7 +1033,6 @@ glusterd_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
}
}
-out:
op_ret = rsp.op_ret;
gf_log ("glusterd", GF_LOG_INFO,
@@ -921,13 +1082,16 @@ out:
glusterd_op_sm ();
}
- free (rsp.op_errstr); //malloced by xdr
+out:
+ if (rsp.op_errstr && strcmp (rsp.op_errstr, "error"))
+ free (rsp.op_errstr); //malloced by xdr
if (dict) {
if (!dict->extra_stdfree && rsp.dict.dict_val)
free (rsp.dict.dict_val); //malloced by xdr
dict_unref (dict);
} else {
- free (rsp.dict.dict_val); //malloced by xdr
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val); //malloced by xdr
}
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
@@ -991,7 +1155,7 @@ glusterd_profile_volume_use_rsp_dict (dict_t *rsp_dict)
op = glusterd_op_get_op ();
GF_ASSERT (GD_OP_PROFILE_VOLUME == op);
- ctx_dict = glusterd_op_get_ctx ();
+ ctx_dict = glusterd_op_get_ctx (op);
ret = dict_get_int32 (ctx_dict, "count", &count);
rsp_ctx.count = count;
@@ -1003,271 +1167,8 @@ out:
return ret;
}
-void
-glusterd_volume_status_add_peer_rsp (dict_t *this, char *key, data_t *value,
- void *data)
-{
- glusterd_status_rsp_conv_t *rsp_ctx = NULL;
- data_t *new_value = NULL;
- char brick_key[1024] = {0,};
- char new_key[1024] = {0,};
- int32_t index = 0;
- int32_t ret = 0;
-
- if (!strcmp (key, "count") || !strcmp (key, "cmd") ||
- !strcmp (key, "brick-index-max") || !strcmp (key, "other-count"))
- return;
-
- rsp_ctx = data;
- new_value = data_copy (value);
- GF_ASSERT (new_value);
-
- sscanf (key, "brick%d.%s", &index, brick_key);
-
- if (index > rsp_ctx->brick_index_max) {
- snprintf (new_key, sizeof (new_key), "brick%d.%s",
- index + rsp_ctx->other_count, brick_key);
- } else {
- strncpy (new_key, key, sizeof (new_key));
- new_key[sizeof (new_key) - 1] = 0;
- }
-
- ret = dict_set (rsp_ctx->dict, new_key, new_value);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Unable to set key: %s in dict",
- key);
-
- return;
-}
-
-int
-glusterd_volume_status_use_rsp_dict (dict_t *rsp_dict)
-{
- int ret = 0;
- glusterd_status_rsp_conv_t rsp_ctx = {0};
- int32_t node_count = 0;
- int32_t rsp_node_count = 0;
- int32_t brick_index_max = -1;
- int32_t other_count = 0;
- int32_t rsp_other_count = 0;
- dict_t *ctx_dict = NULL;
- glusterd_op_t op = GD_OP_NONE;
-
- GF_ASSERT (rsp_dict);
-
- ret = dict_get_int32 (rsp_dict, "count", &rsp_node_count);
- if (ret) {
- ret = 0; //no bricks in the rsp
- goto out;
- }
-
- ret = dict_get_int32 (rsp_dict, "other-count", &rsp_other_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to get other count from rsp_dict");
- goto out;
- }
-
- op = glusterd_op_get_op ();
- GF_ASSERT (GD_OP_STATUS_VOLUME == op);
- ctx_dict = glusterd_op_get_ctx (op);
-
- ret = dict_get_int32 (ctx_dict, "count", &node_count);
- ret = dict_get_int32 (ctx_dict, "brick-index-max", &brick_index_max);
- ret = dict_get_int32 (ctx_dict, "other-count", &other_count);
-
- rsp_ctx.count = node_count;
- rsp_ctx.brick_index_max = brick_index_max;
- rsp_ctx.other_count = other_count;
- rsp_ctx.dict = ctx_dict;
-
- dict_foreach (rsp_dict, glusterd_volume_status_add_peer_rsp, &rsp_ctx);
-
- ret = dict_set_int32 (ctx_dict, "count", node_count + rsp_node_count);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to update node count");
- goto out;
- }
-
- ret = dict_set_int32 (ctx_dict, "other-count",
- (other_count + rsp_other_count));
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to update other-count");
-out:
- return ret;
-}
-
-int
-glusterd_volume_rebalance_use_rsp_dict (dict_t *rsp_dict)
-{
- int ret = 0;
- dict_t *ctx_dict = NULL;
- glusterd_op_t op = GD_OP_NONE;
- uint64_t value = 0;
- int32_t value32 = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char key[256] = {0,};
- int32_t index = 0;
- int32_t i = 0;
- char *node_uuid = NULL;
- char *node_uuid_str = NULL;
- double elapsed_time = 0;
-
- GF_ASSERT (rsp_dict);
-
- op = glusterd_op_get_op ();
- GF_ASSERT ((GD_OP_REBALANCE == op) ||
- (GD_OP_DEFRAG_BRICK_VOLUME == op));
-
- ctx_dict = glusterd_op_get_ctx (op);
-
- if (!ctx_dict)
- goto out;
-
- ret = dict_get_int32 (ctx_dict, "count", &i);
- i++;
- ret = dict_set_int32 (ctx_dict, "count", i);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "Failed to set index");
-
- ret = dict_get_str (ctx_dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- ret = dict_get_int32 (rsp_dict, "count", &index);
- if (ret)
- gf_log ("", GF_LOG_ERROR, "failed to get index");
-
- snprintf (key, 256, "files-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "files-%d", i);
- ret = dict_set_uint64 (ctx_dict, key, value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set the file count");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "size-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "size-%d", i);
- ret = dict_set_uint64 (ctx_dict, key, value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set the size of migration");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "lookups-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "lookups-%d", i);
- ret = dict_set_uint64 (ctx_dict, key, value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set lookuped file count");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", index);
- ret = dict_get_int32 (rsp_dict, key, &value32);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "status-%d", i);
- ret = dict_set_int32 (ctx_dict, key, value32);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set status");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "node-uuid-%d", index);
- ret = dict_get_str (rsp_dict, key, &node_uuid);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "node-uuid-%d", i);
- node_uuid_str = gf_strdup (node_uuid);
- ret = dict_set_dynstr (ctx_dict, key, node_uuid_str);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set node-uuid");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "failures-%d", index);
- ret = dict_get_uint64 (rsp_dict, key, &value);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "failures-%d", i);
- ret = dict_set_uint64 (ctx_dict, key, value);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set failure count");
- }
- }
-
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", index);
- ret = dict_get_double (rsp_dict, key, &elapsed_time);
- if (!ret) {
- memset (key, 0, 256);
- snprintf (key, 256, "run-time-%d", i);
- ret = dict_set_double (ctx_dict, key, elapsed_time);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "failed to set run-time");
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-int
-glusterd_volume_heal_use_rsp_dict (dict_t *rsp_dict)
-{
- int ret = 0;
- dict_t *ctx_dict = NULL;
- glusterd_op_t op = GD_OP_NONE;
-
- GF_ASSERT (rsp_dict);
-
- op = glusterd_op_get_op ();
- GF_ASSERT (GD_OP_HEAL_VOLUME == op);
-
- ctx_dict = glusterd_op_get_ctx (op);
-
- if (!ctx_dict)
- goto out;
- dict_copy (rsp_dict, ctx_dict);
-out:
- return ret;
-}
-
int32_t
-glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd3_1_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_commit_op_rsp rsp = {{0},};
@@ -1285,21 +1186,17 @@ glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("error");
+ rsp.op_errstr = "error";
event_type = GD_OP_EVENT_RCVD_RJT;
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
+ ret = gd_xdr_to_mgmt_commit_op_rsp (*iov, &rsp);
if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "xdr decoding error");
+ gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("xdr decoding error");
+ rsp.op_errstr = "error";
event_type = GD_OP_EVENT_RCVD_RJT;
goto out;
}
@@ -1381,26 +1278,6 @@ glusterd_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
goto out;
break;
- case GD_OP_STATUS_VOLUME:
- ret = glusterd_volume_status_use_rsp_dict (dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_REBALANCE:
- case GD_OP_DEFRAG_BRICK_VOLUME:
- ret = glusterd_volume_rebalance_use_rsp_dict (dict);
- if (ret)
- goto out;
- break;
-
- case GD_OP_HEAL_VOLUME:
- ret = glusterd_volume_heal_use_rsp_dict (dict);
- if (ret)
- goto out;
-
- break;
-
default:
break;
}
@@ -1416,7 +1293,8 @@ out:
if (dict)
dict_unref (dict);
- free (rsp.op_errstr); //malloced by xdr
+ if (rsp.op_errstr && strcmp (rsp.op_errstr, "error"))
+ free (rsp.op_errstr); //malloced by xdr
GLUSTERD_STACK_DESTROY (((call_frame_t *)myframe));
return ret;
}
@@ -1424,8 +1302,8 @@ out:
int32_t
-glusterd_rpc_probe (call_frame_t *frame, xlator_t *this,
- void *data)
+glusterd3_1_probe (call_frame_t *frame, xlator_t *this,
+ void *data)
{
gd1_mgmt_probe_req req = {{0},};
int ret = 0;
@@ -1455,31 +1333,33 @@ glusterd_rpc_probe (call_frame_t *frame, xlator_t *this,
if (ret)
goto out;
- uuid_copy (req.uuid, MY_UUID);
+ uuid_copy (req.uuid, priv->uuid);
req.hostname = gf_strdup (hostname);
req.port = port;
- ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer,
- GLUSTERD_PROBE_QUERY,
- NULL, this, glusterd_probe_cbk,
- (xdrproc_t)xdr_gd1_mgmt_probe_req);
+ ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,
+ GD_MGMT_PROBE_QUERY,
+ NULL, gd_xdr_from_mgmt_probe_req,
+ this, glusterd3_1_probe_cbk);
out:
- GF_FREE (req.hostname);
+ if (req.hostname)
+ GF_FREE (req.hostname);
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int32_t
-glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this,
- void *data)
+glusterd3_1_friend_add (call_frame_t *frame, xlator_t *this,
+ void *data)
{
gd1_mgmt_friend_req req = {{0},};
int ret = 0;
glusterd_peerinfo_t *peerinfo = NULL;
glusterd_conf_t *priv = NULL;
glusterd_friend_sm_event_t *event = NULL;
+ glusterd_friend_req_ctx_t *ctx = NULL;
dict_t *vols = NULL;
@@ -1493,29 +1373,32 @@ glusterd_rpc_friend_add (call_frame_t *frame, xlator_t *this,
GF_ASSERT (priv);
+ ctx = event->ctx;
+
peerinfo = event->peerinfo;
ret = glusterd_build_volume_dict (&vols);
if (ret)
goto out;
- uuid_copy (req.uuid, MY_UUID);
+ uuid_copy (req.uuid, priv->uuid);
req.hostname = peerinfo->hostname;
req.port = peerinfo->port;
ret = dict_allocate_and_serialize (vols, &req.vols.vols_val,
- &req.vols.vols_len);
+ (size_t *)&req.vols.vols_len);
if (ret)
goto out;
- ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer,
- GLUSTERD_FRIEND_ADD,
- NULL, this, glusterd_friend_add_cbk,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
+ ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,
+ GD_MGMT_FRIEND_ADD,
+ NULL, gd_xdr_from_mgmt_friend_req,
+ this, glusterd3_1_friend_add_cbk);
out:
- GF_FREE (req.vols.vols_val);
+ if (req.vols.vols_val)
+ GF_FREE (req.vols.vols_val);
if (vols)
dict_unref (vols);
@@ -1525,8 +1408,8 @@ out:
}
int32_t
-glusterd_rpc_friend_remove (call_frame_t *frame, xlator_t *this,
- void *data)
+glusterd3_1_friend_remove (call_frame_t *frame, xlator_t *this,
+ void *data)
{
gd1_mgmt_friend_req req = {{0},};
int ret = 0;
@@ -1546,13 +1429,13 @@ glusterd_rpc_friend_remove (call_frame_t *frame, xlator_t *this,
peerinfo = event->peerinfo;
- uuid_copy (req.uuid, MY_UUID);
+ uuid_copy (req.uuid, priv->uuid);
req.hostname = peerinfo->hostname;
req.port = peerinfo->port;
- ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->peer,
- GLUSTERD_FRIEND_REMOVE, NULL,
- this, glusterd_friend_remove_cbk,
- (xdrproc_t)xdr_gd1_mgmt_friend_req);
+ ret = glusterd_submit_request (peerinfo->rpc, &req, frame, peerinfo->mgmt,
+ GD_MGMT_FRIEND_REMOVE,
+ NULL, gd_xdr_from_mgmt_friend_req,
+ this, glusterd3_1_friend_remove_cbk);
out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1561,13 +1444,15 @@ out:
int32_t
-glusterd_rpc_friend_update (call_frame_t *frame, xlator_t *this,
- void *data)
+glusterd3_1_friend_update (call_frame_t *frame, xlator_t *this,
+ void *data)
{
gd1_mgmt_friend_update req = {{0},};
int ret = 0;
glusterd_conf_t *priv = NULL;
dict_t *friends = NULL;
+ char *dict_buf = NULL;
+ size_t len = -1;
call_frame_t *dummy_frame = NULL;
glusterd_peerinfo_t *peerinfo = NULL;
@@ -1582,29 +1467,32 @@ glusterd_rpc_friend_update (call_frame_t *frame, xlator_t *this,
if (ret)
goto out;
- ret = dict_allocate_and_serialize (friends, &req.friends.friends_val,
- &req.friends.friends_len);
+ ret = dict_allocate_and_serialize (friends, &dict_buf, (size_t *)&len);
if (ret)
goto out;
- uuid_copy (req.uuid, MY_UUID);
+ req.friends.friends_val = dict_buf;
+ req.friends.friends_len = len;
+
+ uuid_copy (req.uuid, priv->uuid);
dummy_frame = create_frame (this, this->ctx->pool);
ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,
- peerinfo->peer,
- GLUSTERD_FRIEND_UPDATE, NULL,
- this, glusterd_friend_update_cbk,
- (xdrproc_t)xdr_gd1_mgmt_friend_update);
+ peerinfo->mgmt,
+ GD_MGMT_FRIEND_UPDATE,
+ NULL, gd_xdr_from_mgmt_friend_update,
+ this, glusterd3_1_friend_update_cbk);
out:
- GF_FREE (req.friends.friends_val);
+ if (req.friends.friends_val)
+ GF_FREE (req.friends.friends_val);
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int32_t
-glusterd_cluster_lock (call_frame_t *frame, xlator_t *this,
+glusterd3_1_cluster_lock (call_frame_t *frame, xlator_t *this,
void *data)
{
gd1_mgmt_cluster_lock_req req = {{0},};
@@ -1628,17 +1516,17 @@ glusterd_cluster_lock (call_frame_t *frame, xlator_t *this,
goto out;
ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,
- peerinfo->mgmt, GLUSTERD_MGMT_CLUSTER_LOCK,
+ peerinfo->mgmt, GD_MGMT_CLUSTER_LOCK,
NULL,
- this, glusterd_cluster_lock_cbk,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_req);
+ gd_xdr_from_mgmt_cluster_lock_req,
+ this, glusterd3_1_cluster_lock_cbk);
out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int32_t
-glusterd_cluster_unlock (call_frame_t *frame, xlator_t *this,
+glusterd3_1_cluster_unlock (call_frame_t *frame, xlator_t *this,
void *data)
{
gd1_mgmt_cluster_lock_req req = {{0},};
@@ -1662,17 +1550,17 @@ glusterd_cluster_unlock (call_frame_t *frame, xlator_t *this,
goto out;
ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,
- peerinfo->mgmt, GLUSTERD_MGMT_CLUSTER_UNLOCK,
+ peerinfo->mgmt, GD_MGMT_CLUSTER_UNLOCK,
NULL,
- this, glusterd_cluster_unlock_cbk,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_req);
+ gd_xdr_from_mgmt_cluster_unlock_req,
+ this, glusterd3_1_cluster_unlock_cbk);
out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int32_t
-glusterd_stage_op (call_frame_t *frame, xlator_t *this,
+glusterd3_1_stage_op (call_frame_t *frame, xlator_t *this,
void *data)
{
gd1_mgmt_stage_op_req req = {{0,},};
@@ -1702,21 +1590,29 @@ glusterd_stage_op (call_frame_t *frame, xlator_t *this,
glusterd_get_uuid (&req.uuid);
req.op = glusterd_op_get_op ();
- ret = dict_allocate_and_serialize (dict, &req.buf.buf_val,
- &req.buf.buf_len);
- if (ret)
- goto out;
+ if (GD_OP_DELETE_VOLUME == req.op) {
+ ret = dict_get_str (dict, "volname", &req.buf.buf_val);
+ if (ret)
+ goto out;
+ req.buf.buf_len = strlen (req.buf.buf_val);
+ is_alloc = _gf_false;
+ } else {
+ ret = dict_allocate_and_serialize (dict, &req.buf.buf_val,
+ (size_t *)&req.buf.buf_len);
+ if (ret)
+ goto out;
+ }
dummy_frame = create_frame (this, this->ctx->pool);
if (!dummy_frame)
goto out;
ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,
- peerinfo->mgmt, GLUSTERD_MGMT_STAGE_OP,
+ peerinfo->mgmt, GD_MGMT_STAGE_OP,
NULL,
- this, glusterd_stage_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_req);
+ gd_xdr_from_mgmt_stage_op_req,
+ this, glusterd3_1_stage_op_cbk);
out:
if ((_gf_true == is_alloc) && req.buf.buf_val)
@@ -1727,7 +1623,7 @@ out:
}
int32_t
-glusterd_commit_op (call_frame_t *frame, xlator_t *this,
+glusterd3_1_commit_op (call_frame_t *frame, xlator_t *this,
void *data)
{
gd1_mgmt_commit_op_req req = {{0,},};
@@ -1756,20 +1652,29 @@ glusterd_commit_op (call_frame_t *frame, xlator_t *this,
glusterd_get_uuid (&req.uuid);
req.op = glusterd_op_get_op ();
- ret = dict_allocate_and_serialize (dict, &req.buf.buf_val,
- &req.buf.buf_len);
- if (ret)
- goto out;
+ if (GD_OP_DELETE_VOLUME == req.op) {
+ ret = dict_get_str (dict, "volname", &req.buf.buf_val);
+ if (ret)
+ goto out;
+ req.buf.buf_len = strlen (req.buf.buf_val);
+ is_alloc = _gf_false;
+ } else {
+ ret = dict_allocate_and_serialize (dict, &req.buf.buf_val,
+ (size_t *)&req.buf.buf_len);
+
+ if (ret)
+ goto out;
+ }
dummy_frame = create_frame (this, this->ctx->pool);
if (!dummy_frame)
goto out;
ret = glusterd_submit_request (peerinfo->rpc, &req, dummy_frame,
- peerinfo->mgmt, GLUSTERD_MGMT_COMMIT_OP,
+ peerinfo->mgmt, GD_MGMT_COMMIT_OP,
NULL,
- this, glusterd_commit_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_req);
+ gd_xdr_from_mgmt_commit_op_req,
+ this, glusterd3_1_commit_op_cbk);
out:
if ((_gf_true == is_alloc) && req.buf.buf_val)
@@ -1780,7 +1685,31 @@ out:
}
int32_t
-glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
+glusterd_start_brick_disconnect_timer (glusterd_op_brick_rsp_ctx_t *ev_ctx)
+{
+ struct timeval timeout = {0, };
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ brickinfo = ev_ctx->brickinfo;
+ GF_ASSERT (brickinfo);
+ this = THIS;
+ GF_ASSERT (this);
+
+ brickinfo->timer = gf_timer_call_after (this->ctx, timeout,
+ glusterd_op_brick_disconnect,
+ (void *) ev_ctx);
+
+ ret = 0;
+
+ return ret;
+}
+
+int32_t
+glusterd3_1_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
int count, void *myframe)
{
gd1_mgmt_brick_op_rsp rsp = {0};
@@ -1789,31 +1718,26 @@ glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
glusterd_op_sm_event_type_t event_type = GD_OP_EVENT_NONE;
call_frame_t *frame = NULL;
glusterd_op_brick_rsp_ctx_t *ev_ctx = NULL;
+ int32_t op = -1;
dict_t *dict = NULL;
- int index = 0;
- glusterd_req_ctx_t *req_ctx = NULL;
- glusterd_pending_node_t *node = NULL;
GF_ASSERT (req);
frame = myframe;
- req_ctx = frame->local;
if (-1 == req->rpc_status) {
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- /* use standard allocation because to keep uniformity
- in freeing it */
- rsp.op_errstr = strdup ("error");
+ rsp.op_errstr = "error";
event_type = GD_OP_EVENT_RCVD_RJT;
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gd1_mgmt_brick_op_rsp);
+ ret = gd_xdr_to_mgmt_brick_op_rsp (*iov, &rsp);
if (ret < 0) {
gf_log ("", GF_LOG_ERROR, "error");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
- rsp.op_errstr = strdup ("Unable to decode brick op response");
+ rsp.op_errstr = strdup ("Unable to decode response");
event_type = GD_OP_EVENT_RCVD_RJT;
goto out;
}
@@ -1838,19 +1762,6 @@ glusterd_brick_op_cbk (struct rpc_req *req, struct iovec *iov,
op_ret = rsp.op_ret;
- /* Add index to rsp_dict for GD_OP_STATUS_VOLUME */
- if (GD_OP_STATUS_VOLUME == req_ctx->op) {
- node = frame->cookie;
- index = node->index;
- ret = dict_set_int32 (dict, "index", index);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error setting index on brick status rsp dict");
- rsp.op_ret = -1;
- event_type = GD_OP_EVENT_RCVD_RJT;
- goto out;
- }
- }
out:
ev_ctx = GF_CALLOC (1, sizeof (*ev_ctx), gf_gld_mt_brick_rsp_ctx_t);
GF_ASSERT (ev_ctx);
@@ -1861,24 +1772,85 @@ out:
} else {
event_type = GD_OP_EVENT_RCVD_ACC;
}
- ev_ctx->pending_node = frame->cookie;
+ ev_ctx->brickinfo = frame->cookie;
ev_ctx->rsp_dict = dict;
ev_ctx->commit_ctx = frame->local;
- ret = glusterd_op_sm_inject_event (event_type, ev_ctx);
- if (!ret) {
- glusterd_friend_sm ();
- glusterd_op_sm ();
+ op = glusterd_op_get_op ();
+ if ((op == GD_OP_STOP_VOLUME) ||
+ (op == GD_OP_REMOVE_BRICK)) {
+ ret = glusterd_start_brick_disconnect_timer (ev_ctx);
+ } else {
+ ret = glusterd_op_sm_inject_event (event_type, ev_ctx);
+ if (!ret) {
+ glusterd_friend_sm ();
+ glusterd_op_sm ();
+ }
}
if (ret && dict)
dict_unref (dict);
- free (rsp.op_errstr); //malloced by xdr
+ if (rsp.op_errstr && strcmp (rsp.op_errstr, "error"))
+ free (rsp.op_errstr); //malloced by xdr
GLUSTERD_STACK_DESTROY (frame);
return ret;
}
+
+struct rpc_clnt_procedure glusterd3_1_clnt_mgmt_actors[GD_MGMT_MAXVALUE] = {
+ [GD_MGMT_NULL] = {"NULL", NULL },
+ [GD_MGMT_PROBE_QUERY] = { "PROBE_QUERY", glusterd3_1_probe},
+ [GD_MGMT_FRIEND_ADD] = { "FRIEND_ADD", glusterd3_1_friend_add },
+ [GD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd3_1_cluster_lock},
+ [GD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd3_1_cluster_unlock},
+ [GD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op},
+ [GD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op},
+ [GD_MGMT_FRIEND_REMOVE] = { "FRIEND_REMOVE", glusterd3_1_friend_remove},
+ [GD_MGMT_FRIEND_UPDATE] = { "FRIEND_UPDATE", glusterd3_1_friend_update},
+};
+
+struct rpc_clnt_procedure glusterd3_1_fs_mgmt_actors[GD_MGMT_MAXVALUE] = {
+ [GD_MGMT_NULL] = {"NULL", NULL },
+ [GD_MGMT_BRICK_OP] = {"BRICK_OP", glusterd3_1_brick_op},
+};
+
+struct rpc_clnt_program glusterd3_1_mgmt_prog = {
+ .progname = "Mgmt 3.1",
+ .prognum = GLUSTERD1_MGMT_PROGRAM,
+ .progver = GLUSTERD1_MGMT_VERSION,
+ .proctable = glusterd3_1_clnt_mgmt_actors,
+ .numproc = GLUSTERD1_MGMT_PROCCNT,
+};
+
+struct rpc_clnt_procedure gd_clnt_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = {
+ [GLUSTERD_MGMT_NULL] = {"NULL", NULL },
+ [GLUSTERD_MGMT_PROBE_QUERY] = {"PROBE_QUERY", glusterd3_1_probe},
+ [GLUSTERD_MGMT_FRIEND_ADD] = {"FRIEND_ADD", glusterd3_1_friend_add},
+ [GLUSTERD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd3_1_cluster_lock},
+ [GLUSTERD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd3_1_cluster_unlock},
+ [GLUSTERD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd3_1_stage_op},
+ [GLUSTERD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd3_1_commit_op},
+ [GLUSTERD_MGMT_FRIEND_REMOVE] = {"FRIEND_REMOVE", glusterd3_1_friend_remove},
+ [GLUSTERD_MGMT_FRIEND_UPDATE] = {"FRIEND_UPDATE", glusterd3_1_friend_update},
+};
+
+struct rpc_clnt_program gd_clnt_mgmt_prog = {
+ .progname = "glusterd clnt mgmt",
+ .prognum = GD_MGMT_PROGRAM,
+ .progver = GD_MGMT_VERSION,
+ .numproc = GD_MGMT_PROCCNT,
+ .proctable = gd_clnt_mgmt_actors,
+};
+
+struct rpc_clnt_program glusterd_glusterfs_3_1_mgmt_prog = {
+ .progname = "GlusterFS Mops",
+ .prognum = GLUSTERFS_PROGRAM,
+ .progver = GLUSTERFS_VERSION,
+ .proctable = glusterd3_1_fs_mgmt_actors,
+ .numproc = GLUSTERFS_PROCCNT,
+};
+
int32_t
-glusterd_brick_op (call_frame_t *frame, xlator_t *this,
+glusterd3_1_brick_op (call_frame_t *frame, xlator_t *this,
void *data)
{
gd1_mgmt_brick_op_req *req = NULL;
@@ -1887,10 +1859,9 @@ glusterd_brick_op (call_frame_t *frame, xlator_t *this,
call_frame_t *dummy_frame = NULL;
char *op_errstr = NULL;
int pending_bricks = 0;
- glusterd_pending_node_t *pending_node;
- glusterd_req_ctx_t *req_ctx = NULL;
- struct rpc_clnt *rpc = NULL;
- dict_t *op_ctx = NULL;
+ glusterd_pending_node_t *pending_brick;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ glusterd_req_ctx_t *req_ctx = NULL;
if (!this) {
ret = -1;
@@ -1910,64 +1881,32 @@ glusterd_brick_op (call_frame_t *frame, xlator_t *this,
goto out;
}
- list_for_each_entry (pending_node, &opinfo.pending_bricks, list) {
+ list_for_each_entry (pending_brick, &opinfo.pending_bricks, list) {
dummy_frame = create_frame (this, this->ctx->pool);
+ brickinfo = pending_brick->node;
+
if (!dummy_frame)
continue;
+ if (_gf_false == glusterd_is_brick_started (brickinfo))
+ continue;
- if ((pending_node->type == GD_NODE_NFS) ||
- ((pending_node->type == GD_NODE_SHD) &&
- (req_ctx->op == GD_OP_STATUS_VOLUME)))
- ret = glusterd_node_op_build_payload
- (req_ctx->op,
- (gd1_mgmt_brick_op_req **)&req,
- req_ctx->dict);
- else
- ret = glusterd_brick_op_build_payload
- (req_ctx->op, pending_node->node,
- (gd1_mgmt_brick_op_req **)&req,
- req_ctx->dict);
+ ret = glusterd_brick_op_build_payload (req_ctx->op, brickinfo,
+ (gd1_mgmt_brick_op_req **)&req,
+ req_ctx->dict);
if (ret)
goto out;
dummy_frame->local = data;
- dummy_frame->cookie = pending_node;
-
- rpc = glusterd_pending_node_get_rpc (pending_node);
- if (!rpc) {
- if (pending_node->type == GD_NODE_REBALANCE) {
- opinfo.brick_pending_count = 0;
- ret = 0;
- if (req) {
- GF_FREE (req->input.input_val);
- GF_FREE (req);
- req = NULL;
- }
- GLUSTERD_STACK_DESTROY (dummy_frame);
-
- op_ctx = glusterd_op_get_ctx ();
- if (!op_ctx)
- goto out;
- glusterd_defrag_volume_node_rsp (req_ctx->dict,
- NULL, op_ctx);
-
- goto out;
- }
-
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "Brick Op failed "
- "due to rpc failure.");
- goto out;
- }
-
- ret = glusterd_submit_request (rpc, req, dummy_frame,
- priv->gfs_mgmt,
+ dummy_frame->cookie = brickinfo;
+ ret = glusterd_submit_request (brickinfo->rpc, req, dummy_frame,
+ &glusterd_glusterfs_3_1_mgmt_prog,
req->op, NULL,
- this, glusterd_brick_op_cbk,
- (xdrproc_t)xdr_gd1_mgmt_brick_op_req);
+ gd_xdr_from_mgmt_brick_op_req,
+ this, glusterd3_1_brick_op_cbk);
if (req) {
- GF_FREE (req->input.input_val);
+ if (req->input.input_val)
+ GF_FREE (req->input.input_val);
GF_FREE (req);
req = NULL;
}
@@ -1976,7 +1915,7 @@ glusterd_brick_op (call_frame_t *frame, xlator_t *this,
}
gf_log ("glusterd", GF_LOG_DEBUG, "Sent op req to %d bricks",
- pending_bricks);
+ pending_bricks);
opinfo.brick_pending_count = pending_bricks;
out:
@@ -1987,49 +1926,3 @@ out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-
-struct rpc_clnt_procedure gd_brick_actors[GLUSTERD_BRICK_MAXVALUE] = {
- [GLUSTERD_BRICK_NULL] = {"NULL", NULL },
- [GLUSTERD_BRICK_OP] = {"BRICK_OP", glusterd_brick_op},
-};
-
-struct rpc_clnt_procedure gd_peer_actors[GLUSTERD_FRIEND_MAXVALUE] = {
- [GLUSTERD_FRIEND_NULL] = {"NULL", NULL },
- [GLUSTERD_PROBE_QUERY] = {"PROBE_QUERY", glusterd_rpc_probe},
- [GLUSTERD_FRIEND_ADD] = {"FRIEND_ADD", glusterd_rpc_friend_add},
- [GLUSTERD_FRIEND_REMOVE] = {"FRIEND_REMOVE", glusterd_rpc_friend_remove},
- [GLUSTERD_FRIEND_UPDATE] = {"FRIEND_UPDATE", glusterd_rpc_friend_update},
-};
-
-struct rpc_clnt_procedure gd_mgmt_actors[GLUSTERD_MGMT_MAXVALUE] = {
- [GLUSTERD_MGMT_NULL] = {"NULL", NULL },
- [GLUSTERD_MGMT_CLUSTER_LOCK] = {"CLUSTER_LOCK", glusterd_cluster_lock},
- [GLUSTERD_MGMT_CLUSTER_UNLOCK] = {"CLUSTER_UNLOCK", glusterd_cluster_unlock},
- [GLUSTERD_MGMT_STAGE_OP] = {"STAGE_OP", glusterd_stage_op},
- [GLUSTERD_MGMT_COMMIT_OP] = {"COMMIT_OP", glusterd_commit_op},
-};
-
-struct rpc_clnt_program gd_mgmt_prog = {
- .progname = "glusterd mgmt",
- .prognum = GD_MGMT_PROGRAM,
- .progver = GD_MGMT_VERSION,
- .proctable = gd_mgmt_actors,
- .numproc = GLUSTERD_MGMT_MAXVALUE,
-};
-
-struct rpc_clnt_program gd_brick_prog = {
- .progname = "brick operations",
- .prognum = GD_BRICK_PROGRAM,
- .progver = GD_BRICK_VERSION,
- .proctable = gd_brick_actors,
- .numproc = GLUSTERD_BRICK_MAXVALUE,
-};
-
-struct rpc_clnt_program gd_peer_prog = {
- .progname = "Peer mgmt",
- .prognum = GD_FRIEND_PROGRAM,
- .progver = GD_FRIEND_VERSION,
- .proctable = gd_peer_actors,
- .numproc = GLUSTERD_FRIEND_MAXVALUE,
-};
-
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.c b/xlators/mgmt/glusterd/src/glusterd-sm.c
index 951277f63..94e7ca08a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ GlusterFS is GF_FREE software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -100,7 +100,8 @@ glusterd_destroy_probe_ctx (glusterd_probe_ctx_t *ctx)
if (!ctx)
return;
- GF_FREE (ctx->hostname);
+ if (ctx->hostname)
+ GF_FREE (ctx->hostname);
GF_FREE (ctx);
}
@@ -112,7 +113,8 @@ glusterd_destroy_friend_req_ctx (glusterd_friend_req_ctx_t *ctx)
if (ctx->vols)
dict_unref (ctx->vols);
- GF_FREE (ctx->hostname);
+ if (ctx->hostname)
+ GF_FREE (ctx->hostname);
GF_FREE (ctx);
}
@@ -121,7 +123,8 @@ glusterd_destroy_friend_update_ctx (glusterd_friend_update_ctx_t *ctx)
{
if (!ctx)
return;
- GF_FREE (ctx->hostname);
+ if (ctx->hostname)
+ GF_FREE (ctx->hostname);
GF_FREE (ctx);
}
@@ -165,7 +168,7 @@ glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid)
goto out;
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!peerinfo->connected || !peerinfo->peer)
+ if (!peerinfo->connected || !peerinfo->mgmt)
continue;
ret = dict_set_static_ptr (friends, "peerinfo", peerinfo);
@@ -174,7 +177,7 @@ glusterd_broadcast_friend_delete (char *hostname, uuid_t uuid)
goto out;
}
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE];
+ proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_FRIEND_UPDATE];
if (proc->fn) {
ret = proc->fn (NULL, this, friends);
}
@@ -254,9 +257,12 @@ glusterd_ac_reverse_probe_begin (glusterd_friend_sm_event_t *event, void *ctx)
out:
if (ret) {
- GF_FREE (new_event);
- GF_FREE (new_ev_ctx->hostname);
- GF_FREE (new_ev_ctx);
+ if (new_event)
+ GF_FREE (new_event);
+ if (new_ev_ctx->hostname)
+ GF_FREE (new_ev_ctx->hostname);
+ if (new_ev_ctx)
+ GF_FREE (new_ev_ctx);
}
gf_log ("", GF_LOG_DEBUG, "returning with %d", ret);
return ret;
@@ -280,9 +286,9 @@ glusterd_ac_friend_add (glusterd_friend_sm_event_t *event, void *ctx)
GF_ASSERT (conf);
- if (!peerinfo->peer)
+ if (!peerinfo->mgmt)
goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_ADD];
+ proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_FRIEND_ADD];
if (proc->fn) {
frame = create_frame (this, this->ctx->pool);
if (!frame) {
@@ -329,9 +335,9 @@ glusterd_ac_friend_probe (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
}
- if (!peerinfo->peer)
+ if (!peerinfo->mgmt)
goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_PROBE_QUERY];
+ proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_PROBE_QUERY];
if (proc->fn) {
frame = create_frame (this, this->ctx->pool);
if (!frame) {
@@ -409,7 +415,6 @@ glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event,
if (ctx)
ret = glusterd_xfer_cli_deprobe_resp (ctx->req, ret, 0,
- NULL,
ctx->hostname);
glusterd_friend_sm ();
glusterd_op_sm ();
@@ -421,9 +426,9 @@ glusterd_ac_send_friend_remove_req (glusterd_friend_sm_event_t *event,
goto out;
}
- if (!peerinfo->peer)
+ if (!peerinfo->mgmt)
goto out;
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_REMOVE];
+ proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_FRIEND_REMOVE];
if (proc->fn) {
frame = create_frame (this, this->ctx->pool);
if (!frame) {
@@ -439,36 +444,22 @@ out:
return ret;
}
-static gf_boolean_t
-glusterd_should_update_peer (glusterd_peerinfo_t *peerinfo,
- glusterd_peerinfo_t *cur_peerinfo)
-{
- gf_boolean_t is_valid = _gf_false;
-
- if ((peerinfo == cur_peerinfo) ||
- (peerinfo->state.state == GD_FRIEND_STATE_BEFRIENDED))
- is_valid = _gf_true;
-
- return is_valid;
-}
-
static int
glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
{
- int ret = 0;
- glusterd_peerinfo_t *cur_peerinfo = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- xlator_t *this = NULL;
- glusterd_friend_update_ctx_t ev_ctx = {{0}};
- glusterd_conf_t *priv = NULL;
- dict_t *friends = NULL;
- char key[100] = {0,};
- char *dup_buf = NULL;
- int32_t count = 0;
+ int ret = 0;
+ glusterd_peerinfo_t *peerinfo = NULL;
+ rpc_clnt_procedure_t *proc = NULL;
+ xlator_t *this = NULL;
+ glusterd_friend_update_ctx_t ev_ctx = {{0}};
+ glusterd_conf_t *priv = NULL;
+ dict_t *friends = NULL;
+ char key[100] = {0,};
+ char *dup_buf = NULL;
+ int32_t count = 0;
GF_ASSERT (event);
- cur_peerinfo = event->peerinfo;
+ peerinfo = event->peerinfo;
this = THIS;
priv = this->private;
@@ -487,9 +478,6 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!glusterd_should_update_peer (peerinfo, cur_peerinfo))
- continue;
-
count++;
snprintf (key, sizeof (key), "friend%d.uuid", count);
dup_buf = gf_strdup (uuid_utoa (peerinfo->uuid));
@@ -509,10 +497,7 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
- if (!peerinfo->connected || !peerinfo->peer)
- continue;
-
- if (!glusterd_should_update_peer (peerinfo, cur_peerinfo))
+ if (!peerinfo->connected || !peerinfo->mgmt)
continue;
ret = dict_set_static_ptr (friends, "peerinfo", peerinfo);
@@ -521,7 +506,7 @@ glusterd_ac_send_friend_update (glusterd_friend_sm_event_t *event, void *ctx)
goto out;
}
- proc = &peerinfo->peer->proctable[GLUSTERD_FRIEND_UPDATE];
+ proc = &peerinfo->mgmt->proctable[GLUSTERD_MGMT_FRIEND_UPDATE];
if (proc->fn) {
ret = proc->fn (NULL, this, friends);
}
@@ -536,34 +521,6 @@ out:
return ret;
}
-static int
-glusterd_peer_detach_cleanup (glusterd_conf_t *priv)
-{
- int ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmp_volinfo = NULL;
-
- GF_ASSERT (priv);
-
- list_for_each_entry_safe (volinfo,tmp_volinfo,
- &priv->volumes, vol_list) {
- if (!glusterd_friend_contains_vol_bricks (volinfo,
- MY_UUID)) {
- gf_log (THIS->name, GF_LOG_INFO,
- "Deleting stale volume %s", volinfo->volname);
- ret = glusterd_delete_volume (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error deleting stale volume");
- goto out;
- }
- }
- }
- ret = 0;
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
static int
glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event,
@@ -599,14 +556,9 @@ glusterd_ac_handle_friend_remove_req (glusterd_friend_sm_event_t *event,
if (ret)
goto out;
}
- ret = glusterd_peer_detach_cleanup (priv);
- if (ret) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "Peer detach cleanup was not successful");
- ret = 0;
- }
+
out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
@@ -616,13 +568,10 @@ glusterd_ac_friend_remove (glusterd_friend_sm_event_t *event, void *ctx)
{
int ret = -1;
- ret = glusterd_friend_remove_cleanup_vols (event->peerinfo->uuid);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "Volumes cleanup failed");
-
ret = glusterd_friend_cleanup (event->peerinfo);
+
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Cleanup returned: %d", ret);
+ gf_log ("", GF_LOG_ERROR, "Cleanup returned: %d", ret);
}
return 0;
@@ -940,7 +889,7 @@ int
glusterd_friend_sm_inject_event (glusterd_friend_sm_event_t *event)
{
GF_ASSERT (event);
- gf_log ("glusterd", GF_LOG_DEBUG, "Enqueue event: '%s'",
+ gf_log ("glusterd", GF_LOG_DEBUG, "Enqueuing event: '%s'",
glusterd_friend_sm_event_name_get (event->event));
list_add_tail (&event->list, &gd_friend_sm_queue);
diff --git a/xlators/mgmt/glusterd/src/glusterd-sm.h b/xlators/mgmt/glusterd/src/glusterd-sm.h
index e8a545c27..f607b33d8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-sm.h
+++ b/xlators/mgmt/glusterd/src/glusterd-sm.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -97,7 +97,6 @@ struct glusterd_peerinfo_ {
struct list_head op_peers_list;
struct rpc_clnt *rpc;
rpc_clnt_prog_t *mgmt;
- rpc_clnt_prog_t *peer;
int connected;
glusterd_store_handle_t *shandle;
glusterd_sm_tr_log_t sm_log;
@@ -119,7 +118,6 @@ typedef struct glusterd_peer_ctx_args_ {
typedef struct glusterd_peer_ctx_ {
glusterd_peerctx_args_t args;
glusterd_peerinfo_t *peerinfo;
- char *errstr;
} glusterd_peerctx_t;
typedef enum glusterd_friend_sm_event_type_ {
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c
index 07c29b9d3..4f296c52a 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.c
+++ b/xlators/mgmt/glusterd/src/glusterd-store.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -42,9 +42,10 @@
#include "glusterd-sm.h"
#include "glusterd-op-sm.h"
#include "glusterd-utils.h"
-#include "glusterd-hooks.h"
#include "glusterd-store.h"
+#include "glusterd1.h"
+#include "cli1.h"
#include "rpc-clnt.h"
#include "common-utils.h"
@@ -97,7 +98,7 @@ glusterd_store_mkstemp (glusterd_store_handle_t *shandle)
GF_ASSERT (shandle->path);
snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
- fd = open (tmppath, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0600);
+ fd = open (tmppath, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd <= 0) {
gf_log ("glusterd", GF_LOG_ERROR, "Failed to open %s, "
"error: %s", tmppath, strerror (errno));
@@ -106,52 +107,6 @@ glusterd_store_mkstemp (glusterd_store_handle_t *shandle)
return fd;
}
-int
-glusterd_store_sync_direntry (char *path)
-{
- int ret = -1;
- int dirfd = -1;
- char *dir = NULL;
- char *pdir = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- dir = gf_strdup (path);
- if (!dir)
- goto out;
-
- pdir = dirname (dir);
- dirfd = open (pdir, O_RDONLY);
- if (dirfd == -1) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to open directory "
- "%s, due to %s", pdir, strerror (errno));
- goto out;
- }
-
- ret = fsync (dirfd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to fsync %s, due to "
- "%s", pdir, strerror (errno));
- goto out;
- }
-
- ret = 0;
-out:
- if (dirfd >= 0) {
- ret = close (dirfd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Failed to close "
- "%s, due to %s", pdir, strerror (errno));
- }
- }
-
- if (dir)
- GF_FREE (dir);
-
- return ret;
-}
-
int32_t
glusterd_store_rename_tmppath (glusterd_store_handle_t *shandle)
{
@@ -164,13 +119,10 @@ glusterd_store_rename_tmppath (glusterd_store_handle_t *shandle)
snprintf (tmppath, sizeof (tmppath), "%s.tmp", shandle->path);
ret = rename (tmppath, shandle->path);
if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to rename %s to %s, "
+ gf_log ("glusterd", GF_LOG_ERROR, "Failed to mv %s to %s, "
"error: %s", tmppath, shandle->path, strerror (errno));
- goto out;
}
- ret = glusterd_store_sync_direntry (tmppath);
-out:
return ret;
}
@@ -275,47 +227,6 @@ glusterd_store_brickinfopath_set (glusterd_volinfo_t *volinfo,
snprintf (brickpath, len, "%s/%s", brickdirpath, brickfname);
}
-gf_boolean_t
-glusterd_store_is_valid_brickpath (char *volname, char *brick)
-{
- char brickpath[PATH_MAX] = {0};
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int32_t ret = 0;
- size_t volname_len = strlen (volname);
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "brick path validation failed");
- ret = 0;
- goto out;
- }
- ret = glusterd_volinfo_new (&volinfo);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "brick path validation failed");
- ret = 0;
- goto out;
- }
- if (volname_len >= sizeof (volinfo->volname)) {
- gf_log ("", GF_LOG_WARNING, "volume name too long");
- ret = 0;
- goto out;
- }
- memcpy (volinfo->volname, volname, volname_len+1);
- glusterd_store_brickinfopath_set (volinfo, brickinfo, brickpath,
- sizeof (brickpath));
-
- ret = (strlen (brickpath) < _POSIX_PATH_MAX);
-
-out:
- if (brickinfo)
- glusterd_brickinfo_delete (brickinfo);
- if (volinfo)
- glusterd_volinfo_delete (volinfo);
-
- return ret;
-}
-
int32_t
glusterd_store_volinfo_brick_fname_write (int vol_fd,
glusterd_brickinfo_t *brickinfo,
@@ -330,10 +241,6 @@ glusterd_store_volinfo_brick_fname_write (int vol_fd,
glusterd_store_brickinfofname_set (brickinfo, brickfname,
sizeof (brickfname));
ret = glusterd_store_save_value (vol_fd, key, brickfname);
- if (ret)
- goto out;
-
-out:
return ret;
}
@@ -377,16 +284,6 @@ glusterd_store_brickinfo_write (int fd, glusterd_brickinfo_t *brickinfo)
ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_PORT,
value);
- snprintf (value, sizeof(value), "%d", brickinfo->rdma_port);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_RDMA_PORT,
- value);
-
- snprintf (value, sizeof(value), "%d", brickinfo->decommissioned);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED,
- value);
- if (ret)
- goto out;
-
out:
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
@@ -409,6 +306,7 @@ glusterd_store_perform_brick_store (glusterd_brickinfo_t *brickinfo)
if (ret)
goto out;
+ ret = glusterd_store_rename_tmppath (brickinfo->shandle);
out:
if (ret && (fd > 0))
glusterd_store_unlink_tmppath (brickinfo->shandle);
@@ -606,17 +504,10 @@ void _storeopts (dict_t *this, char *key, data_t *value, void *data)
if (!value || !value->data)
return;
- if (is_key_glusterd_hooks_friendly (key)) {
- exists = 1;
-
- } else {
- exists = glusterd_check_option_exists (key, NULL);
- }
-
+ exists = glusterd_check_option_exists (key, NULL);
if (1 == exists) {
gf_log ("", GF_LOG_DEBUG, "Storing in volinfo:key= %s, val=%s",
key, value->data);
-
} else {
gf_log ("", GF_LOG_DEBUG, "Discarding:key= %s, val=%s",
key, value->data);
@@ -634,13 +525,11 @@ void _storeopts (dict_t *this, char *key, data_t *value, void *data)
int32_t
glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo)
{
- char *str = NULL;
-
GF_ASSERT (fd > 0);
GF_ASSERT (volinfo);
- char buf[PATH_MAX] = {0,};
- int32_t ret = -1;
+ char buf[4096] = {0,};
+ int32_t ret = -1;
snprintf (buf, sizeof (buf), "%d", volinfo->type);
ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_TYPE, buf);
@@ -663,18 +552,6 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo)
if (ret)
goto out;
- snprintf (buf, sizeof (buf), "%d", volinfo->stripe_count);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_STRIPE_CNT,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%d", volinfo->replica_count);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_REPLICA_CNT,
- buf);
- if (ret)
- goto out;
-
snprintf (buf, sizeof (buf), "%d", volinfo->version);
ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_VERSION,
buf);
@@ -692,23 +569,6 @@ glusterd_volume_exclude_options_write (int fd, glusterd_volinfo_t *volinfo)
if (ret)
goto out;
- str = glusterd_auth_get_username (volinfo);
- if (str) {
- ret = glusterd_store_save_value (fd,
- GLUSTERD_STORE_KEY_USERNAME,
- str);
- if (ret)
- goto out;
- }
-
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = glusterd_store_save_value (fd,
- GLUSTERD_STORE_KEY_PASSWORD,
- str);
- if (ret)
- goto out;
- }
out:
if (ret)
gf_log ("", GF_LOG_ERROR, "Unable to write volume values"
@@ -770,63 +630,19 @@ out:
}
static void
-glusterd_store_rbstatepath_set (glusterd_volinfo_t *volinfo, char *rbstatepath,
- size_t len)
-{
- char voldirpath[PATH_MAX] = {0,};
- GF_ASSERT (volinfo);
- GF_ASSERT (rbstatepath);
- GF_ASSERT (len <= PATH_MAX);
-
- glusterd_store_voldirpath_set (volinfo, voldirpath,
- sizeof (voldirpath));
- snprintf (rbstatepath, len, "%s/%s", voldirpath,
- GLUSTERD_VOLUME_RBSTATE_FILE);
-}
-
-static void
glusterd_store_volfpath_set (glusterd_volinfo_t *volinfo, char *volfpath,
size_t len)
{
char voldirpath[PATH_MAX] = {0,};
GF_ASSERT (volinfo);
GF_ASSERT (volfpath);
- GF_ASSERT (len <= PATH_MAX);
+ GF_ASSERT (len >= PATH_MAX);
glusterd_store_voldirpath_set (volinfo, voldirpath,
sizeof (voldirpath));
snprintf (volfpath, len, "%s/%s", voldirpath, GLUSTERD_VOLUME_INFO_FILE);
}
-static void
-glusterd_store_node_state_path_set (glusterd_volinfo_t *volinfo,
- char *node_statepath, size_t len)
-{
- char voldirpath[PATH_MAX] = {0,};
- GF_ASSERT (volinfo);
- GF_ASSERT (node_statepath);
- GF_ASSERT (len <= PATH_MAX);
-
- glusterd_store_voldirpath_set (volinfo, voldirpath,
- sizeof (voldirpath));
- snprintf (node_statepath, len, "%s/%s", voldirpath,
- GLUSTERD_NODE_STATE_FILE);
-}
-
-int32_t
-glusterd_store_create_rbstate_shandle_on_absence (glusterd_volinfo_t *volinfo)
-{
- char rbstatepath[PATH_MAX] = {0};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- glusterd_store_rbstatepath_set (volinfo, rbstatepath, sizeof (rbstatepath));
- ret = glusterd_store_handle_create_on_absence (&volinfo->rb_shandle,
- rbstatepath);
- return ret;
-}
-
int32_t
glusterd_store_create_vol_shandle_on_absence (glusterd_volinfo_t *volinfo)
{
@@ -842,23 +658,6 @@ glusterd_store_create_vol_shandle_on_absence (glusterd_volinfo_t *volinfo)
}
int32_t
-glusterd_store_create_nodestate_sh_on_absence (glusterd_volinfo_t *volinfo)
-{
- char node_state_path[PATH_MAX] = {0};
- int32_t ret = 0;
-
- GF_ASSERT (volinfo);
-
- glusterd_store_node_state_path_set (volinfo, node_state_path,
- sizeof (node_state_path));
- ret =
- glusterd_store_handle_create_on_absence (&volinfo->node_state_shandle,
- node_state_path);
-
- return ret;
-}
-
-int32_t
glusterd_store_brickinfos (glusterd_volinfo_t *volinfo, int vol_fd)
{
int32_t ret = 0;
@@ -880,130 +679,6 @@ out:
}
int32_t
-glusterd_store_rbstate_write (int fd, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- char buf[PATH_MAX] = {0, };
-
- GF_ASSERT (fd > 0);
- GF_ASSERT (volinfo);
-
- snprintf (buf, sizeof (buf), "%d", volinfo->rb_status);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_RB_STATUS,
- buf);
- if (ret)
- goto out;
-
- if (volinfo->rb_status > GF_RB_STATUS_NONE) {
-
- snprintf (buf, sizeof (buf), "%s:%s",
- volinfo->src_brick->hostname,
- volinfo->src_brick->path);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- buf);
- if (ret)
- goto out;
-
- snprintf (buf, sizeof (buf), "%s:%s",
- volinfo->dst_brick->hostname,
- volinfo->dst_brick->path);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_RB_DST_BRICK,
- buf);
- if (ret)
- goto out;
- }
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_rbstate_store (glusterd_volinfo_t *volinfo)
-{
- int fd = -1;
- int32_t ret = -1;
- GF_ASSERT (volinfo);
-
- fd = glusterd_store_mkstemp (volinfo->rb_shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_rbstate_write (fd, volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_rename_tmppath (volinfo->rb_shandle);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- glusterd_store_unlink_tmppath (volinfo->rb_shandle);
- if (fd > 0)
- close (fd);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_node_state_write (int fd, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- char buf[PATH_MAX] = {0, };
-
- GF_ASSERT (fd > 0);
- GF_ASSERT (volinfo);
-
- if (volinfo->defrag_cmd == GF_DEFRAG_CMD_STATUS) {
- ret = 0;
- goto out;
- }
-
- snprintf (buf, sizeof (buf), "%d", volinfo->defrag_cmd);
- ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_VOL_DEFRAG,
- buf);
- if (ret)
- goto out;
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
-glusterd_store_perform_node_state_store (glusterd_volinfo_t *volinfo)
-{
- int fd = -1;
- int32_t ret = -1;
- GF_ASSERT (volinfo);
-
- fd = glusterd_store_mkstemp (volinfo->node_state_shandle);
- if (fd <= 0) {
- ret = -1;
- goto out;
- }
-
- ret = glusterd_store_node_state_write (fd, volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_rename_tmppath (volinfo->node_state_shandle);
- if (ret)
- goto out;
-
-out:
- if (ret && (fd > 0))
- glusterd_store_unlink_tmppath (volinfo->node_state_shandle);
- if (fd > 0)
- close (fd);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int32_t
glusterd_store_perform_volume_store (glusterd_volinfo_t *volinfo)
{
int fd = -1;
@@ -1024,6 +699,7 @@ glusterd_store_perform_volume_store (glusterd_volinfo_t *volinfo)
if (ret)
goto out;
+ ret = glusterd_store_rename_tmppath (volinfo->shandle);
out:
if (ret && (fd > 0))
glusterd_store_unlink_tmppath (volinfo->shandle);
@@ -1045,88 +721,9 @@ glusterd_perform_volinfo_version_action (glusterd_volinfo_t *volinfo,
case GLUSTERD_VOLINFO_VER_AC_INCREMENT:
volinfo->version++;
break;
- case GLUSTERD_VOLINFO_VER_AC_DECREMENT:
- volinfo->version--;
- break;
- }
-}
-
-void
-glusterd_store_bricks_cleanup_tmp (glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- glusterd_store_unlink_tmppath (brickinfo->shandle);
}
}
-void
-glusterd_store_volume_cleanup_tmp (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
-
- glusterd_store_bricks_cleanup_tmp (volinfo);
-
- glusterd_store_unlink_tmppath (volinfo->shandle);
-
- glusterd_store_unlink_tmppath (volinfo->rb_shandle);
-
- glusterd_store_unlink_tmppath (volinfo->node_state_shandle);
-}
-
-int32_t
-glusterd_store_brickinfos_atomic_update (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_store_rename_tmppath (brickinfo->shandle);
- if (ret)
- goto out;
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_store_volinfo_atomic_update (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- GF_ASSERT (volinfo);
-
- ret = glusterd_store_rename_tmppath (volinfo->shandle);
- if (ret)
- goto out;
-
-out:
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't rename "
- "temporary file(s): Reason %s", strerror (errno));
- return ret;
-}
-
-int32_t
-glusterd_store_volume_atomic_update (glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- GF_ASSERT (volinfo);
-
- ret = glusterd_store_brickinfos_atomic_update (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_volinfo_atomic_update (volinfo);
-
-out:
- return ret;
-}
-
int32_t
glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t ac)
{
@@ -1143,42 +740,14 @@ glusterd_store_volinfo (glusterd_volinfo_t *volinfo, glusterd_volinfo_ver_ac_t a
if (ret)
goto out;
- ret = glusterd_store_create_rbstate_shandle_on_absence (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_create_nodestate_sh_on_absence (volinfo);
- if (ret)
- goto out;
-
ret = glusterd_store_perform_volume_store (volinfo);
if (ret)
goto out;
-
- ret = glusterd_store_volume_atomic_update (volinfo);
- if (ret) {
- glusterd_perform_volinfo_version_action (volinfo,
- GLUSTERD_VOLINFO_VER_AC_DECREMENT);
- goto out;
- }
-
- ret = glusterd_store_perform_rbstate_store (volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_store_perform_node_state_store (volinfo);
- if (ret)
- goto out;
-
//checksum should be computed at the end
ret = glusterd_volume_compute_cksum (volinfo);
if (ret)
goto out;
-
out:
- if (ret)
- glusterd_store_volume_cleanup_tmp (volinfo);
-
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
@@ -1265,121 +834,68 @@ out:
}
-int
-glusterd_store_read_and_tokenize (FILE *file, char *str,
- char **iter_key, char **iter_val,
- glusterd_store_op_errno_t *store_errno)
-{
- int32_t ret = -1;
- char *savetok = NULL;
-
- GF_ASSERT (file);
- GF_ASSERT (str);
- GF_ASSERT (iter_key);
- GF_ASSERT (iter_val);
- GF_ASSERT (store_errno);
-
- ret = fscanf (file, "%s", str);
- if (ret <= 0 || feof (file)) {
- ret = -1;
- *store_errno = GD_STORE_EOF;
- goto out;
- }
-
- *iter_key = strtok_r (str, "=", &savetok);
- if (*iter_key == NULL) {
- ret = -1;
- *store_errno = GD_STORE_KEY_NULL;
- goto out;
- }
-
- *iter_val = strtok_r (NULL, "=", &savetok);
- if (*iter_key == NULL) {
- ret = -1;
- *store_errno = GD_STORE_VALUE_NULL;
- goto out;
- }
-
- *store_errno = GD_STORE_SUCCESS;
- ret = 0;
-out:
- return ret;
-}
int32_t
glusterd_store_retrieve_value (glusterd_store_handle_t *handle,
char *key, char **value)
{
int32_t ret = -1;
- char *scan_str = NULL;
+ char scan_str[4096] = {0,};
char *iter_key = NULL;
char *iter_val = NULL;
+ char *str = NULL;
char *free_str = NULL;
- struct stat st = {0,};
- glusterd_store_op_errno_t store_errno = GD_STORE_SUCCESS;
GF_ASSERT (handle);
handle->fd = open (handle->path, O_RDWR);
- if (handle->fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s",
- handle->path, strerror (errno));
- goto out;
- }
if (!handle->read)
handle->read = fdopen (handle->fd, "r");
if (!handle->read) {
- gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %s",
- handle->path, strerror (errno));
- goto out;
- }
-
- ret = fstat (handle->fd, &st);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "stat on file failed");
- ret = -1;
- store_errno = GD_STORE_STAT_FAILED;
- goto out;
- }
-
- scan_str = GF_CALLOC (1, st.st_size,
- gf_gld_mt_char);
- if (scan_str == NULL) {
- ret = -1;
- store_errno = GD_STORE_ENOMEM;
+ gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %d",
+ handle->path, errno);
goto out;
}
- free_str = scan_str;
+ ret = fscanf (handle->read, "%s", scan_str);
- do {
- ret = glusterd_store_read_and_tokenize (handle->read, scan_str,
- &iter_key, &iter_val,
- &store_errno);
- if (ret < 0) {
- goto out;
+ while (ret != EOF) {
+ if (free_str) {
+ GF_FREE (free_str);
+ free_str = NULL;
}
-
+ str = gf_strdup (scan_str);
+ if (!str)
+ goto out;
+ else
+ free_str = str;
+ iter_key = strtok (str, "=");
gf_log ("", GF_LOG_DEBUG, "key %s read", iter_key);
if (!strcmp (key, iter_key)) {
gf_log ("", GF_LOG_DEBUG, "key %s found", key);
+ iter_val = strtok (NULL, "=");
ret = 0;
if (iter_val)
*value = gf_strdup (iter_val);
goto out;
}
- } while (1);
+
+ ret = fscanf (handle->read, "%s", scan_str);
+ }
+
+ if (EOF == ret)
+ ret = -1;
out:
if (handle->fd > 0) {
close (handle->fd);
handle->read = NULL;
}
- GF_FREE (free_str);
+ if (free_str)
+ GF_FREE (free_str);
return ret;
}
@@ -1388,38 +904,25 @@ int32_t
glusterd_store_save_value (int fd, char *key, char *value)
{
int32_t ret = -1;
- FILE *fp = NULL;
+ char buf[4096] = {0,};
GF_ASSERT (fd > 0);
GF_ASSERT (key);
GF_ASSERT (value);
- fp = fdopen (fd, "a+");
- if (fp == NULL) {
- gf_log ("", GF_LOG_WARNING, "fdopen failed.");
- ret = -1;
- goto out;
- }
+ snprintf (buf, sizeof (buf), "%s=%s\n", key, value);
+ ret = write (fd, buf, strlen (buf));
- ret = fprintf (fp, "%s=%s\n", key, value);
if (ret < 0) {
- gf_log ("", GF_LOG_WARNING, "Unable to store key: %s,"
+ gf_log ("", GF_LOG_CRITICAL, "Unable to store key: %s,"
"value: %s, error: %s", key, value,
strerror (errno));
ret = -1;
goto out;
}
- ret = fflush (fp);
- if (feof (fp)) {
- gf_log ("", GF_LOG_WARNING,
- "fflush failed, error: %s",
- strerror (errno));
- ret = -1;
- goto out;
- }
-
ret = 0;
+
out:
gf_log ("", GF_LOG_DEBUG, "returning: %d", ret);
@@ -1443,28 +946,28 @@ glusterd_store_handle_new (char *path, glusterd_store_handle_t **handle)
if (!spath)
goto out;
- fd = open (path, O_RDWR | O_CREAT | O_APPEND, 0600);
+ fd = open (path, O_RDWR | O_CREAT | O_APPEND, 0644);
if (fd <= 0) {
gf_log ("glusterd", GF_LOG_ERROR, "Failed to open file: %s, "
"error: %s", path, strerror (errno));
goto out;
}
- ret = glusterd_store_sync_direntry (spath);
- if (ret)
- goto out;
-
shandle->path = spath;
*handle = shandle;
ret = 0;
+
out:
if (fd > 0)
close (fd);
if (ret == -1) {
- GF_FREE (spath);
- GF_FREE (shandle);
+ if (spath)
+ GF_FREE (spath);
+ if (shandle) {
+ GF_FREE (shandle);
+ }
}
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
@@ -1518,10 +1021,8 @@ glusterd_store_uuid ()
char path[PATH_MAX] = {0,};
int32_t ret = -1;
glusterd_store_handle_t *handle = NULL;
- xlator_t *this = NULL;
- this = THIS;
- priv = this->private;
+ priv = THIS->private;
snprintf (path, PATH_MAX, "%s/%s", priv->workdir,
GLUSTERD_INFO_FILE);
@@ -1530,8 +1031,8 @@ glusterd_store_uuid ()
ret = glusterd_store_handle_new (path, &handle);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get store handle!");
+ gf_log ("", GF_LOG_ERROR, "Unable to get store"
+ " handle!");
goto out;
}
@@ -1540,25 +1041,17 @@ glusterd_store_uuid ()
handle = priv->handle;
}
- /* make glusterd's uuid available for users */
- ret = chmod (handle->path, 0644);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "chmod error for %s: %s",
- GLUSTERD_INFO_FILE, strerror (errno));
- goto out;
- }
-
handle->fd = open (handle->path, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (handle->fd <= 0) {
ret = -1;
goto out;
}
ret = glusterd_store_save_value (handle->fd, GLUSTERD_STORE_UUID_KEY,
- uuid_utoa (MY_UUID));
+ uuid_utoa (priv->uuid));
if (ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Storing uuid failed ret = %d", ret);
+ gf_log ("", GF_LOG_CRITICAL, "Storing uuid failed"
+ "ret = %d", ret);
goto out;
}
@@ -1568,7 +1061,7 @@ out:
close (handle->fd);
handle->fd = 0;
}
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -1610,7 +1103,8 @@ glusterd_retrieve_uuid ()
uuid_parse (uuid_str, priv->uuid);
out:
- GF_FREE (uuid_str);
+ if (uuid_str)
+ GF_FREE (uuid_str);
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -1653,7 +1147,6 @@ glusterd_store_iter_new (glusterd_store_handle_t *shandle,
}
strncpy (tmp_iter->filepath, shandle->path, sizeof (tmp_iter->filepath));
- tmp_iter->filepath[sizeof (tmp_iter->filepath) - 1] = 0;
*iter = tmp_iter;
ret = 0;
@@ -1702,11 +1195,11 @@ glusterd_store_iter_get_next (glusterd_store_iter_t *iter,
glusterd_store_op_errno_t *op_errno)
{
int32_t ret = -1;
- char *scan_str = NULL;
+ char scan_str[4096] = {0,};
+ char *str = NULL;
char *free_str = NULL;
char *iter_key = NULL;
char *iter_val = NULL;
- struct stat st = {0,};
glusterd_store_op_errno_t store_errno = GD_STORE_SUCCESS;
GF_ASSERT (iter);
@@ -1714,35 +1207,28 @@ glusterd_store_iter_get_next (glusterd_store_iter_t *iter,
GF_ASSERT (key);
GF_ASSERT (value);
- ret = fstat (iter->fd, &st);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_WARNING,
- "stat on file failed");
+ *key = NULL;
+ *value = NULL;
+
+ ret = fscanf (iter->file, "%s", scan_str);
+
+ if (ret <= 0) {
ret = -1;
- store_errno = GD_STORE_STAT_FAILED;
+ store_errno = GD_STORE_EOF;
goto out;
}
- scan_str = GF_CALLOC (1, st.st_size,
- gf_gld_mt_char);
- if (scan_str == NULL) {
+ str = gf_strdup (scan_str);
+ if (!str) {
ret = -1;
store_errno = GD_STORE_ENOMEM;
goto out;
+ } else {
+ free_str = str;
}
- *key = NULL;
- *value = NULL;
-
- free_str = scan_str;
-
- ret = glusterd_store_read_and_tokenize (iter->file, scan_str,
- &iter_key, &iter_val,
- &store_errno);
- if (ret < 0) {
- goto out;
- }
-
+ iter_key = strtok (str, "=");
+ iter_val = strtok (NULL, "=");
ret = glusterd_store_validate_key_value (iter->filepath, iter_key,
iter_val, &store_errno);
@@ -1771,7 +1257,8 @@ out:
*value = NULL;
}
}
- GF_FREE (free_str);
+ if (free_str)
+ GF_FREE (free_str);
if (op_errno)
*op_errno = store_errno;
@@ -1921,41 +1408,11 @@ glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo)
} else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_PORT,
strlen (GLUSTERD_STORE_KEY_BRICK_PORT))) {
gf_string2int (value, &brickinfo->port);
-
- if (brickinfo->port < GF_IANA_PRIV_PORTS_START){
- /* This is required to adhere to the
- IANA standards */
- brickinfo->port = 0;
- } else {
- /* This is required to have proper ports
- assigned to bricks after restart */
- pmap = pmap_registry_get (THIS);
- if (pmap->last_alloc <= brickinfo->port)
- pmap->last_alloc =
- brickinfo->port + 1;
- }
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_RDMA_PORT,
- strlen (GLUSTERD_STORE_KEY_BRICK_RDMA_PORT))) {
- gf_string2int (value, &brickinfo->rdma_port);
-
- if (brickinfo->rdma_port <
- GF_IANA_PRIV_PORTS_START){
- /* This is required to adhere to the
- IANA standards */
- brickinfo->rdma_port = 0;
- } else {
- /* This is required to have proper ports
- assigned to bricks after restart */
- pmap = pmap_registry_get (THIS);
- if (pmap->last_alloc <=
- brickinfo->rdma_port)
- pmap->last_alloc =
- brickinfo->rdma_port +1;
- }
-
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED,
- strlen (GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED))) {
- gf_string2int (value, &brickinfo->decommissioned);
+ /* This is required to have proper ports
+ assigned to bricks after restart */
+ pmap = pmap_registry_get (THIS);
+ if (pmap->last_alloc <= brickinfo->port)
+ pmap->last_alloc = brickinfo->port + 1;
} else {
gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
key);
@@ -1992,165 +1449,18 @@ out:
int32_t
-glusterd_store_retrieve_rbstate (char *volname)
-{
- int32_t ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- char volpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- char path[PATH_MAX] = {0,};
- glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- priv = THIS->private;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get"
- "volinfo for %s.", volname);
- goto out;
- }
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_VOLUME_RBSTATE_FILE);
-
- ret = glusterd_store_handle_retrieve (path, &volinfo->rb_shandle);
-
- if (ret)
- goto out;
-
- ret = glusterd_store_iter_new (volinfo->rb_shandle, &iter);
-
- if (ret)
- goto out;
-
- ret = glusterd_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret)
- goto out;
-
- while (!ret) {
- if (!strncmp (key, GLUSTERD_STORE_KEY_RB_STATUS,
- strlen (GLUSTERD_STORE_KEY_RB_STATUS))) {
- volinfo->rb_status = atoi (value);
- }
-
- if (volinfo->rb_status > GF_RB_STATUS_NONE) {
- if (!strncmp (key, GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- strlen (GLUSTERD_STORE_KEY_RB_SRC_BRICK))) {
- ret = glusterd_brickinfo_new_from_brick (value,
- &volinfo->src_brick);
- if (ret)
- goto out;
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_RB_DST_BRICK,
- strlen (GLUSTERD_STORE_KEY_RB_DST_BRICK))) {
- ret = glusterd_brickinfo_new_from_brick (value,
- &volinfo->dst_brick);
- if (ret)
- goto out;
- }
- }
-
- GF_FREE (key);
- GF_FREE (value);
- key = NULL;
- value = NULL;
-
- ret = glusterd_store_iter_get_next (iter, &key, &value,
- &op_errno);
- }
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = glusterd_store_iter_destroy (iter);
-
- if (ret)
- goto out;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-int32_t
-glusterd_store_retrieve_node_state (char *volname)
-{
- int32_t ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- char volpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- char path[PATH_MAX] = {0,};
- glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS;
-
- priv = THIS->private;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Couldn't get"
- "volinfo for %s.", volname);
- goto out;
- }
-
- GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv);
- snprintf (path, sizeof (path), "%s/%s", volpath,
- GLUSTERD_NODE_STATE_FILE);
-
- ret = glusterd_store_handle_retrieve (path,
- &volinfo->node_state_shandle);
-
- if (ret)
- goto out;
-
- ret = glusterd_store_iter_new (volinfo->node_state_shandle, &iter);
-
- if (ret)
- goto out;
-
- ret = glusterd_store_iter_get_next (iter, &key, &value, &op_errno);
- if (ret)
- goto out;
- if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_DEFRAG,
- strlen (GLUSTERD_STORE_KEY_VOL_DEFRAG))) {
- volinfo->defrag_cmd = atoi (value);
- }
-
- GF_FREE (key);
- GF_FREE (value);
-
- if (op_errno != GD_STORE_EOF)
- goto out;
-
- ret = glusterd_store_iter_destroy (iter);
-
- if (ret)
- goto out;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
-
- return ret;
-}
-
-int32_t
glusterd_store_retrieve_volume (char *volname)
{
- int32_t ret = -1;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_store_iter_t *iter = NULL;
- char *key = NULL;
- char *value = NULL;
- char volpath[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- char path[PATH_MAX] = {0,};
- int exists = 0;
- glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS;
+ int32_t ret = -1;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_store_iter_t *iter = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char volpath[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+ char path[PATH_MAX] = {0,};
+ int exists = 0;
+ glusterd_store_op_errno_t op_errno = GD_STORE_SUCCESS;
ret = glusterd_volinfo_new (&volinfo);
@@ -2184,50 +1494,29 @@ glusterd_store_retrieve_volume (char *volname)
strlen (GLUSTERD_STORE_KEY_VOL_TYPE))) {
volinfo->type = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_COUNT,
- strlen (GLUSTERD_STORE_KEY_VOL_COUNT))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_COUNT))) {
volinfo->brick_count = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_STATUS,
- strlen (GLUSTERD_STORE_KEY_VOL_STATUS))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_STATUS))) {
volinfo->status = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_VERSION,
- strlen (GLUSTERD_STORE_KEY_VOL_VERSION))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_VERSION))) {
volinfo->version = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_PORT,
- strlen (GLUSTERD_STORE_KEY_VOL_PORT))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_PORT))) {
volinfo->port = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_SUB_COUNT,
- strlen (GLUSTERD_STORE_KEY_VOL_SUB_COUNT))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_SUB_COUNT))) {
volinfo->sub_count = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_STRIPE_CNT,
- strlen (GLUSTERD_STORE_KEY_VOL_STRIPE_CNT))) {
- volinfo->stripe_count = atoi (value);
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_REPLICA_CNT,
- strlen (GLUSTERD_STORE_KEY_VOL_REPLICA_CNT))) {
- volinfo->replica_count = atoi (value);
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_TRANSPORT,
- strlen (GLUSTERD_STORE_KEY_VOL_TRANSPORT))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_TRANSPORT))) {
volinfo->transport_type = atoi (value);
- volinfo->nfs_transport_type = volinfo->transport_type;
- if (volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
- volinfo->nfs_transport_type = GF_DEFAULT_NFS_TRANSPORT;
- }
} else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_ID,
- strlen (GLUSTERD_STORE_KEY_VOL_ID))) {
+ strlen (GLUSTERD_STORE_KEY_VOL_ID))) {
ret = uuid_parse (value, volinfo->volume_id);
if (ret)
gf_log ("", GF_LOG_WARNING,
"failed to parse uuid");
-
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_USERNAME,
- strlen (GLUSTERD_STORE_KEY_USERNAME))) {
-
- glusterd_auth_set_username (volinfo, value);
-
- } else if (!strncmp (key, GLUSTERD_STORE_KEY_PASSWORD,
- strlen (GLUSTERD_STORE_KEY_PASSWORD))) {
-
- glusterd_auth_set_password (volinfo, value);
-
} else if (strstr (key, "slave")) {
ret = dict_set_dynstr (volinfo->gsync_slaves, key,
gf_strdup (value));
@@ -2238,39 +1527,28 @@ glusterd_store_retrieve_volume (char *volname)
}
gf_log ("", GF_LOG_DEBUG, "Parsed as "GEOREP" "
" slave:key=%s,value:%s", key, value);
-
- } else {
-
- if (is_key_glusterd_hooks_friendly (key)) {
- exists = 1;
-
- } else {
- exists = glusterd_check_option_exists (key,
- NULL);
- }
-
- switch (exists) {
- case -1:
+ }
+ else {
+ exists = glusterd_check_option_exists (key, NULL);
+ if (exists == -1) {
ret = -1;
goto out;
-
- case 0:
- gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
- key);
- break;
-
- case 1:
+ }
+ if (exists) {
ret = dict_set_str(volinfo->dict, key,
- gf_strdup (value));
+ gf_strdup (value));
if (ret) {
gf_log ("",GF_LOG_ERROR, "Error in "
- "dict_set_str");
+ "dict_set_str");
goto out;
}
gf_log ("", GF_LOG_DEBUG, "Parsed as Volume-"
- "set:key=%s,value:%s", key, value);
- break;
+ "set:key=%s,value:%s",
+ key, value);
}
+ else
+ gf_log ("", GF_LOG_ERROR, "Unknown key: %s",
+ key);
}
GF_FREE (key);
@@ -2281,42 +1559,6 @@ glusterd_store_retrieve_volume (char *volname)
ret = glusterd_store_iter_get_next (iter, &key, &value,
&op_errno);
}
-
- /* backward compatibility */
- {
-
- switch (volinfo->type) {
-
- case GF_CLUSTER_TYPE_NONE:
- volinfo->stripe_count = 1;
- volinfo->replica_count = 1;
- break;
-
- case GF_CLUSTER_TYPE_STRIPE:
- volinfo->stripe_count = volinfo->sub_count;
- volinfo->replica_count = 1;
- break;
-
- case GF_CLUSTER_TYPE_REPLICATE:
- volinfo->stripe_count = 1;
- volinfo->replica_count = volinfo->sub_count;
- break;
-
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- /* Introduced in 3.3 */
- GF_ASSERT (volinfo->stripe_count > 0);
- GF_ASSERT (volinfo->replica_count > 0);
- break;
-
- default:
- GF_ASSERT (0);
- break;
- }
-
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
- }
-
if (op_errno != GD_STORE_EOF)
goto out;
@@ -2345,12 +1587,11 @@ out:
int32_t
glusterd_store_retrieve_volumes (xlator_t *this)
{
- int32_t ret = 0;
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
- DIR *dir = NULL;
- struct dirent *entry = NULL;
- glusterd_volinfo_t *volinfo = NULL;
+ int32_t ret = 0;
+ char path[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+ DIR *dir = NULL;
+ struct dirent *entry = NULL;
GF_ASSERT (this);
priv = this->private;
@@ -2377,28 +1618,6 @@ glusterd_store_retrieve_volumes (xlator_t *this)
"volume: %s", entry->d_name);
goto out;
}
-
- ret = glusterd_store_retrieve_rbstate (entry->d_name);
- if (ret) {
- /* Backward compatibility */
- gf_log ("", GF_LOG_INFO, "Creating a new rbstate "
- "for volume: %s.", entry->d_name);
- ret = glusterd_volinfo_find (entry->d_name, &volinfo);
- ret = glusterd_store_create_rbstate_shandle_on_absence (volinfo);
- ret = glusterd_store_perform_rbstate_store (volinfo);
- }
-
- ret = glusterd_store_retrieve_node_state (entry->d_name);
- if (ret) {
- /* Backward compatibility */
- gf_log ("", GF_LOG_INFO, "Creating a new node_state "
- "for volume: %s.", entry->d_name);
- ret = glusterd_volinfo_find (entry->d_name, &volinfo);
- ret =
- glusterd_store_create_nodestate_sh_on_absence (volinfo);
- ret = glusterd_store_perform_node_state_store (volinfo);
-
- }
glusterd_for_each_entry (entry, dir);
}
@@ -2599,9 +1818,6 @@ glusterd_store_peer_write (int fd, glusterd_peerinfo_t *peerinfo)
ret = glusterd_store_save_value (fd, GLUSTERD_STORE_KEY_PEER_HOSTNAME "1",
peerinfo->hostname);
- if (ret)
- goto out;
-
out:
gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
@@ -2743,7 +1959,7 @@ glusterd_store_retrieve_peers (xlator_t *this)
args.mode = GD_MODE_SWITCH_ON;
ret = glusterd_friend_add (hostname, 0, state, &uuid,
- &peerinfo, 1, &args);
+ NULL, &peerinfo, 1, &args);
GF_FREE (hostname);
if (ret)
diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h
index af395bc64..0403c10f9 100644
--- a/xlators/mgmt/glusterd/src/glusterd-store.h
+++ b/xlators/mgmt/glusterd/src/glusterd-store.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -30,7 +30,6 @@
#include "glusterfs.h"
#include "xlator.h"
-#include "run.h"
#include "logging.h"
#include "call-stub.h"
#include "fd.h"
@@ -41,7 +40,6 @@
typedef enum glusterd_store_ver_ac_{
GLUSTERD_VOLINFO_VER_AC_NONE = 0,
GLUSTERD_VOLINFO_VER_AC_INCREMENT = 1,
- GLUSTERD_VOLINFO_VER_AC_DECREMENT = 2,
} glusterd_volinfo_ver_ac_t;
@@ -52,24 +50,14 @@ typedef enum glusterd_store_ver_ac_{
#define GLUSTERD_STORE_KEY_VOL_STATUS "status"
#define GLUSTERD_STORE_KEY_VOL_PORT "port"
#define GLUSTERD_STORE_KEY_VOL_SUB_COUNT "sub_count"
-#define GLUSTERD_STORE_KEY_VOL_STRIPE_CNT "stripe_count"
-#define GLUSTERD_STORE_KEY_VOL_REPLICA_CNT "replica_count"
#define GLUSTERD_STORE_KEY_VOL_BRICK "brick"
#define GLUSTERD_STORE_KEY_VOL_VERSION "version"
#define GLUSTERD_STORE_KEY_VOL_TRANSPORT "transport-type"
#define GLUSTERD_STORE_KEY_VOL_ID "volume-id"
-#define GLUSTERD_STORE_KEY_RB_STATUS "rb_status"
-#define GLUSTERD_STORE_KEY_RB_SRC_BRICK "rb_src"
-#define GLUSTERD_STORE_KEY_RB_DST_BRICK "rb_dst"
-#define GLUSTERD_STORE_KEY_VOL_DEFRAG "rebalance_status"
-#define GLUSTERD_STORE_KEY_USERNAME "username"
-#define GLUSTERD_STORE_KEY_PASSWORD "password"
#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname"
#define GLUSTERD_STORE_KEY_BRICK_PATH "path"
#define GLUSTERD_STORE_KEY_BRICK_PORT "listen-port"
-#define GLUSTERD_STORE_KEY_BRICK_RDMA_PORT "rdma.listen-port"
-#define GLUSTERD_STORE_KEY_BRICK_DECOMMISSIONED "decommissioned"
#define GLUSTERD_STORE_KEY_PEER_UUID "uuid"
#define GLUSTERD_STORE_KEY_PEER_HOSTNAME "hostname"
@@ -87,15 +75,13 @@ typedef enum glusterd_store_ver_ac_{
}\
} while (0); \
-
typedef enum {
GD_STORE_SUCCESS,
GD_STORE_KEY_NULL,
GD_STORE_VALUE_NULL,
GD_STORE_KEY_VALUE_NULL,
GD_STORE_EOF,
- GD_STORE_ENOMEM,
- GD_STORE_STAT_FAILED
+ GD_STORE_ENOMEM
} glusterd_store_op_errno_t;
int32_t
@@ -139,9 +125,4 @@ glusterd_restore ();
void
glusterd_perform_volinfo_version_action (glusterd_volinfo_t *volinfo,
glusterd_volinfo_ver_ac_t ac);
-gf_boolean_t
-glusterd_store_is_valid_brickpath (char *volname, char *brick);
-
-int32_t
-glusterd_store_perform_node_state_store (glusterd_volinfo_t *volinfo);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
deleted file mode 100644
index bc265de67..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-/* rpc related syncops */
-#include "syncop.h"
-#include "rpc-clnt.h"
-#include "protocol-common.h"
-#include "xdr-generic.h"
-#include "glusterd1-xdr.h"
-#include "glusterd-syncop.h"
-
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-
-int
-gd_syncop_submit_request (struct rpc_clnt *rpc, void *req,
- void *cookie, rpc_clnt_prog_t *prog,
- int procnum, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
-{
- int ret = -1;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- int count = 0;
- struct iovec iov = {0, };
- ssize_t req_size = 0;
- call_frame_t *frame = NULL;
-
- GF_ASSERT (rpc);
- if (!req)
- goto out;
-
- req_size = xdr_sizeof (xdrproc, req);
- iobuf = iobuf_get2 (rpc->ctx->iobuf_pool, req_size);
- if (!iobuf)
- goto out;
-
- iobref = iobref_new ();
- if (!iobref)
- goto out;
-
- frame = create_frame (THIS, THIS->ctx->pool);
- if (!frame)
- goto out;
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_pagesize (iobuf);
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1)
- goto out;
-
- iov.iov_len = ret;
- count = 1;
-
- frame->local = cookie;
-
- /* Send the msg */
- ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn,
- &iov, count, NULL, 0, iobref,
- frame, NULL, 0, NULL, 0, NULL);
-
- /* TODO: do we need to start ping also? */
-
-out:
- iobref_unref (iobref);
- iobuf_unref (iobuf);
-
- return ret;
-}
-
-/* Defined in glusterd-rpc-ops.c */
-extern struct rpc_clnt_program gd_mgmt_prog;
-
-int32_t
-gd_syncop_mgmt_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- struct syncargs *args = NULL;
- gd1_mgmt_cluster_lock_rsp rsp = {{0},};
- int ret = -1;
- call_frame_t *frame = NULL;
-
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- /* initialize */
- args->op_ret = -1;
- args->op_errno = EINVAL;
-
- if (-1 == req->rpc_status) {
- args->op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_lock_rsp);
- if (ret < 0) {
- goto out;
- }
-
- args->op_ret = rsp.op_ret;
- args->op_errno = rsp.op_errno;
-
- uuid_copy (args->uuid, rsp.uuid);
-
-out:
- STACK_DESTROY (frame->root);
-
- __wake (args);
-
- return 0;
-}
-
-
-int
-gd_syncop_mgmt_lock (struct rpc_clnt *rpc, uuid_t my_uuid, uuid_t recv_uuid)
-{
- struct syncargs args = {0, };
- gd1_mgmt_cluster_lock_req req = {{0},};
-
- uuid_copy (req.uuid, my_uuid);
-
- args.op_ret = -1;
- args.op_errno = ENOTCONN;
-
- GD_SYNCOP (rpc, (&args), gd_syncop_mgmt_lock_cbk,
- &req, &gd_mgmt_prog, GLUSTERD_MGMT_CLUSTER_LOCK,
- xdr_gd1_mgmt_cluster_lock_req);
-
- if (!args.op_ret)
- uuid_copy (recv_uuid, args.uuid);
-
- errno = args.op_errno;
- return args.op_ret;
-
-}
-
-int32_t
-gd_syncop_mgmt_unlock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- struct syncargs *args = NULL;
- gd1_mgmt_cluster_unlock_rsp rsp = {{0},};
- int ret = -1;
- call_frame_t *frame = NULL;
-
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- /* initialize */
- args->op_ret = -1;
- args->op_errno = EINVAL;
-
- if (-1 == req->rpc_status) {
- args->op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_cluster_unlock_rsp);
- if (ret < 0) {
- goto out;
- }
-
- args->op_ret = rsp.op_ret;
- args->op_errno = rsp.op_errno;
-
- uuid_copy (args->uuid, rsp.uuid);
-
-out:
- STACK_DESTROY (frame->root);
-
- __wake (args);
-
- return 0;
-}
-
-
-int
-gd_syncop_mgmt_unlock (struct rpc_clnt *rpc, uuid_t my_uuid, uuid_t recv_uuid)
-{
- struct syncargs args = {0, };
- gd1_mgmt_cluster_unlock_req req = {{0},};
-
- uuid_copy (req.uuid, my_uuid);
-
- args.op_ret = -1;
- args.op_errno = ENOTCONN;
-
- GD_SYNCOP (rpc, (&args), gd_syncop_mgmt_unlock_cbk,
- &req, &gd_mgmt_prog, GLUSTERD_MGMT_CLUSTER_UNLOCK,
- xdr_gd1_mgmt_cluster_unlock_req);
-
- if (!args.op_ret)
- uuid_copy (recv_uuid, args.uuid);
-
- errno = args.op_errno;
- return args.op_ret;
-
-}
-
-int32_t
-gd_syncop_stage_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- struct syncargs *args = NULL;
- gd1_mgmt_stage_op_rsp rsp = {{0},};
- int ret = -1;
- call_frame_t *frame = NULL;
-
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- /* initialize */
- args->op_ret = -1;
- args->op_errno = EINVAL;
-
- if (-1 == req->rpc_status) {
- args->op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_stage_op_rsp);
- if (ret < 0) {
- goto out;
- }
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- args->dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &args->dict);
- if (ret < 0) {
- GF_FREE (rsp.dict.dict_val);
- goto out;
- } else {
- args->dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- args->op_ret = rsp.op_ret;
- args->op_errno = rsp.op_errno;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- args->errstr = gf_strdup (rsp.op_errstr);
-
-out:
- STACK_DESTROY (frame->root);
-
- __wake (args);
-
- return 0;
-}
-
-
-int
-gd_syncop_mgmt_stage_op (struct rpc_clnt *rpc, uuid_t my_uuid, uuid_t recv_uuid,
- int op, dict_t *dict_out, dict_t **dict_in,
- char **errstr)
-{
- struct syncargs args = {0, };
- gd1_mgmt_stage_op_req req = {{0},};
- int ret = 0;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
-
- args.op_ret = -1;
- args.op_errno = ENOTCONN;
-
- ret = dict_allocate_and_serialize (dict_out,
- &req.buf.buf_val, &req.buf.buf_len);
- if (ret)
- goto out;
-
- GD_SYNCOP (rpc, (&args), gd_syncop_stage_op_cbk,
- &req, &gd_mgmt_prog, GLUSTERD_MGMT_STAGE_OP,
- xdr_gd1_mgmt_stage_op_req);
-
- if (args.errstr && errstr)
- *errstr = args.errstr;
- else GF_FREE (args.errstr);
-
- if (args.dict && dict_in)
- *dict_in = args.dict;
- else if (args.dict)
- dict_unref (args.dict);
-
- uuid_copy (recv_uuid, args.uuid);
-out:
- errno = args.op_errno;
- return args.op_ret;
-
-}
-
-int32_t
-gd_syncop_commit_op_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- struct syncargs *args = NULL;
- gd1_mgmt_commit_op_rsp rsp = {{0},};
- int ret = -1;
- call_frame_t *frame = NULL;
-
- frame = myframe;
- args = frame->local;
- frame->local = NULL;
-
- /* initialize */
- args->op_ret = -1;
- args->op_errno = EINVAL;
-
- if (-1 == req->rpc_status) {
- args->op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp,
- (xdrproc_t)xdr_gd1_mgmt_commit_op_rsp);
- if (ret < 0) {
- goto out;
- }
-
- if (rsp.dict.dict_len) {
- /* Unserialize the dictionary */
- args->dict = dict_new ();
-
- ret = dict_unserialize (rsp.dict.dict_val,
- rsp.dict.dict_len,
- &args->dict);
- if (ret < 0) {
- GF_FREE (rsp.dict.dict_val);
- goto out;
- } else {
- args->dict->extra_stdfree = rsp.dict.dict_val;
- }
- }
-
- args->op_ret = rsp.op_ret;
- args->op_errno = rsp.op_errno;
-
- uuid_copy (args->uuid, rsp.uuid);
-
- args->errstr = gf_strdup (rsp.op_errstr);
-
-out:
- STACK_DESTROY (frame->root);
-
- __wake (args);
-
- return 0;
-}
-
-
-int
-gd_syncop_mgmt_commit_op (struct rpc_clnt *rpc, uuid_t my_uuid, uuid_t recv_uuid,
- int op, dict_t *dict_out, dict_t **dict_in,
- char **errstr)
-{
- struct syncargs args = {0, };
- gd1_mgmt_commit_op_req req = {{0},};
- int ret = 0;
-
- uuid_copy (req.uuid, my_uuid);
- req.op = op;
-
- args.op_ret = -1;
- args.op_errno = ENOTCONN;
-
- ret = dict_allocate_and_serialize (dict_out,
- &req.buf.buf_val, &req.buf.buf_len);
- if (ret)
- goto out;
-
- GD_SYNCOP (rpc, (&args), gd_syncop_commit_op_cbk,
- &req, &gd_mgmt_prog, GLUSTERD_MGMT_COMMIT_OP,
- xdr_gd1_mgmt_commit_op_req);
-
- if (args.errstr && errstr)
- *errstr = args.errstr;
- else GF_FREE (args.errstr);
-
- if (args.dict && dict_in)
- *dict_in = args.dict;
- else if (args.dict)
- dict_unref (args.dict);
-
- uuid_copy (recv_uuid, args.uuid);
-
-out:
- errno = args.op_errno;
- return args.op_ret;
-
-}
-
-
-int
-gd_sync_task_begin (void *data)
-{
- int ret = -1;
- dict_t *dict = NULL;
- dict_t *rsp_dict = NULL;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *conf = NULL;
- uuid_t tmp_uuid = {0,};
- char *errstr = NULL;
- glusterd_op_t op = 0;
- int32_t tmp_op = 0;
- gf_boolean_t local_locked = _gf_false;
-
- conf = THIS->private;
-
- dict = data;
-
- ret = dict_get_int32 (dict, GD_SYNC_OPCODE_KEY, &tmp_op);
- if (ret)
- goto out;
-
- op = tmp_op;
-
- ret = -1;
- rsp_dict = dict_new ();
- if (!rsp_dict)
- goto out;
-
- /* Lock everything */
- ret = glusterd_lock (conf->uuid);
- if (ret)
- goto out;
- /* successful lock in local node */
- local_locked = _gf_true;
-
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- ret = gd_syncop_mgmt_lock (peerinfo->rpc,
- conf->uuid, tmp_uuid);
- if (ret)
- goto out;
- /* TODO: Only on lock successful nodes it should unlock */
- }
-
- /* stage op */
- ret = glusterd_op_stage_validate (op, dict, &errstr, rsp_dict);
- if (ret)
- goto out;
-
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- ret = gd_syncop_mgmt_stage_op (peerinfo->rpc,
- conf->uuid, tmp_uuid,
- op, dict, &rsp_dict, &errstr);
- if (ret) {
- if (errstr)
- ret = dict_set_dynstr (dict, "error", errstr);
-
- ret = -1;
- goto out;
- }
- }
-
- /* commit op */
- ret = glusterd_op_commit_perform (op, dict, &errstr, rsp_dict);
- if (ret)
- goto out;
-
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- ret = gd_syncop_mgmt_commit_op (peerinfo->rpc,
- conf->uuid, tmp_uuid,
- op, dict, &rsp_dict, &errstr);
- if (ret) {
- if (errstr)
- ret = dict_set_dynstr (dict, "error", errstr);
-
- ret = -1;
- goto out;
- }
- }
-
- ret = 0;
-out:
- if (local_locked) {
- /* unlock everything as we help successful local lock */
- list_for_each_entry (peerinfo, &conf->peers, uuid_list) {
- /* No need to check the error code, as it is possible
- that if 'lock' on few nodes failed, it would come
- here, and unlock would fail on nodes where lock
- never was sent */
- gd_syncop_mgmt_unlock (peerinfo->rpc,
- conf->uuid, tmp_uuid);
- }
-
- /* Local node should be the one to be locked first,
- unlocked last to prevent races */
- glusterd_unlock (conf->uuid);
- }
-
- if (rsp_dict)
- dict_unref (rsp_dict);
-
- return ret;
-}
-
-int
-gd_sync_task_completion (int op_ret, call_frame_t *sync_frame, void *data)
-{
- int ret = 0;
- dict_t *dict = NULL;
- rpcsvc_request_t *req = NULL;
- int32_t tmp_op = 0;
- glusterd_op_t op = 0;
-
- dict = data;
-
- req = sync_frame->local;
- sync_frame->local = NULL;
-
- ret = dict_get_int32 (dict, GD_SYNC_OPCODE_KEY, &tmp_op);
- if (ret)
- goto out;
- op = tmp_op;
-
- ret = glusterd_op_send_cli_response (op, op_ret, 0, req, NULL,
- "operation failed");
-
-out:
- if (dict)
- dict_unref (dict);
-
- STACK_DESTROY (sync_frame->root);
-
- return ret;
-}
-
-
-int32_t
-glusterd_op_begin_synctask (rpcsvc_request_t *req, glusterd_op_t op,
- void *dict)
-{
- int ret = 0;
- call_frame_t *dummy_frame = NULL;
- glusterfs_ctx_t *ctx = NULL;
-
- dummy_frame = create_frame (THIS, THIS->ctx->pool);
- if (!dummy_frame)
- goto out;
-
- dummy_frame->local = req;
-
- ret = dict_set_int32 (dict, GD_SYNC_OPCODE_KEY, op);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "dict set failed for setting operations");
- goto out;
- }
-
- ctx = THIS->ctx;
-
- ret = synctask_new (ctx->env, gd_sync_task_begin,
- gd_sync_task_completion,
- dummy_frame, dict);
-out:
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.h b/xlators/mgmt/glusterd/src/glusterd-syncop.h
deleted file mode 100644
index a3cc0ab47..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (c) 2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __RPC_SYNCOP_H
-#define __RPC_SYNCOP_H
-
-#include "syncop.h"
-
-
-#define GD_SYNC_OPCODE_KEY "sync-mgmt-operation"
-
-/* gd_syncop_* */
-#define GD_SYNCOP(rpc, stb, cbk, req, prog, procnum, xdrproc) do { \
- int ret = 0; \
- struct synctask *task = NULL; \
- task = synctask_get (); \
- stb->task = task; \
- \
- ret = gd_syncop_submit_request (rpc, req, stb, \
- prog, procnum, cbk, \
- (xdrproc_t)xdrproc); \
- if (!ret) \
- synctask_yield (stb->task); \
- } while (0)
-
-
-int gd_syncop_submit_request (struct rpc_clnt *rpc, void *req,
- void *cookie, rpc_clnt_prog_t *prog,
- int procnum, fop_cbk_fn_t cbkfn,
- xdrproc_t xdrproc);
-
-
-int gd_syncop_mgmt_lock (struct rpc_clnt *rpc, uuid_t my_uuid,
- uuid_t recv_uuid);
-int gd_syncop_mgmt_unlock (struct rpc_clnt *rpc, uuid_t my_uuid,
- uuid_t recv_uuid);
-int gd_syncop_mgmt_stage_op (struct rpc_clnt *rpc, uuid_t my_uuid,
- uuid_t recv_uuid, int op, dict_t *dict_out,
- dict_t **dict_in, char **errstr);
-int gd_syncop_mgmt_commit_op (struct rpc_clnt *rpc, uuid_t my_uuid,
- uuid_t recv_uuid, int op, dict_t *dict_out,
- dict_t **dict_in, char **errstr);
-
-#endif /* __RPC_SYNCOP_H */
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 987615a57..ad2b7dde8 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -21,7 +21,6 @@
#define _CONFIG_H
#include "config.h"
#endif
-#include <openssl/md5.h>
#include <inttypes.h>
#include "globals.h"
@@ -33,10 +32,9 @@
#include "timer.h"
#include "defaults.h"
#include "compat.h"
-#include "run.h"
+#include "md5.h"
#include "compat-errno.h"
#include "statedump.h"
-#include "syscall.h"
#include "glusterd-mem-types.h"
#include "glusterd.h"
#include "glusterd-op-sm.h"
@@ -46,8 +44,6 @@
#include "glusterd-volgen.h"
#include "glusterd-pmap.h"
-#include "xdr-generic.h"
-
#include <sys/resource.h>
#include <inttypes.h>
#include <signal.h>
@@ -56,44 +52,21 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <rpc/pmap_clnt.h>
-#include <unistd.h>
-#include <fnmatch.h>
-#include <sys/statvfs.h>
-
-#ifdef GF_LINUX_HOST_OS
-#include <mntent.h>
-#endif
#ifdef GF_SOLARIS_HOST_OS
#include <sys/sockio.h>
#endif
-#define NFS_PROGRAM 100003
-#define NFSV3_VERSION 3
-
-#define MOUNT_PROGRAM 100005
-#define MOUNTV3_VERSION 3
-#define MOUNTV1_VERSION 1
-
-#define NLM_PROGRAM 100021
-#define NLMV4_VERSION 4
-#define NLMV1_VERSION 1
+#define MOUNT_PROGRAM 100005
+#define NFS_PROGRAM 100003
+#define NFSV3_VERSION 3
+#define MOUNTV3_VERSION 3
+#define MOUNTV1_VERSION 1
char *glusterd_sock_dir = "/tmp";
static glusterd_lock_t lock;
-static void
-md5_wrapper(const unsigned char *data, size_t len, char *md5)
-{
- unsigned short i = 0;
- unsigned short lim = MD5_DIGEST_LENGTH*2+1;
- unsigned char scratch[MD5_DIGEST_LENGTH] = {0,};
- MD5(data, len, scratch);
- for (; i < MD5_DIGEST_LENGTH; i++)
- snprintf(md5 + i * 2, lim-i*2, "%02x", scratch[i]);
-}
-
-int32_t
+static int32_t
glusterd_get_lock_owner (uuid_t *uuid)
{
uuid_copy (*uuid, lock.owner) ;
@@ -117,20 +90,6 @@ glusterd_unset_lock_owner (uuid_t owner)
}
gf_boolean_t
-glusterd_is_fuse_available ()
-{
-
- int fd = 0;
-
- fd = open ("/dev/fuse", O_RDWR);
-
- if (fd > -1 && !close (fd))
- return _gf_true;
- else
- return _gf_false;
-}
-
-gf_boolean_t
glusterd_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
{
GF_ASSERT (sa);
@@ -167,42 +126,6 @@ glusterd_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
return is_local;
}
-char *
-get_ip_from_addrinfo (struct addrinfo *addr, char **ip)
-{
- char buf[64];
- void *in_addr = NULL;
- struct sockaddr_in *s4 = NULL;
- struct sockaddr_in6 *s6 = NULL;
-
- switch (addr->ai_family)
- {
- case AF_INET:
- s4 = (struct sockaddr_in *)addr->ai_addr;
- in_addr = &s4->sin_addr;
- break;
-
- case AF_INET6:
- s6 = (struct sockaddr_in6 *)addr->ai_addr;
- in_addr = &s6->sin6_addr;
- break;
-
- default:
- gf_log ("glusterd", GF_LOG_ERROR, "Invalid family");
- return NULL;
- }
-
- if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
- gf_log ("glusterd", GF_LOG_ERROR, "String conversion failed");
- return NULL;
- }
-
- *ip = strdup (buf);
- return *ip;
-}
-
-/*TODO:FIXME: The function is expected to return a "yes/no" result.
- change return type to bool.*/
int32_t
glusterd_is_local_addr (char *hostname)
{
@@ -210,15 +133,18 @@ glusterd_is_local_addr (char *hostname)
struct addrinfo *result = NULL;
struct addrinfo *res = NULL;
int32_t found = 0;
+ struct ifconf buf = {0,};
int sd = -1;
- char *ip = NULL;
- xlator_t *this = NULL;
+ struct ifreq *ifr = NULL;
+ struct ifreq *ifr_end = NULL;
+ int32_t size = 0;
+ char buff[1024] = {0,};
+ gf_boolean_t need_free = _gf_false;
- this = THIS;
ret = getaddrinfo (hostname, NULL, NULL, &result);
if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR, "error in getaddrinfo: %s\n",
+ gf_log ("", GF_LOG_ERROR, "error in getaddrinfo: %s\n",
gai_strerror(ret));
goto out;
}
@@ -229,30 +155,62 @@ glusterd_is_local_addr (char *hostname)
goto out;
}
- for (res = result; res != NULL; res = res->ai_next) {
- gf_log (this->name, GF_LOG_DEBUG, "%s ",
- get_ip_from_addrinfo (res, &ip));
- sd = socket (res->ai_family, SOCK_DGRAM, 0);
- if (sd == -1)
+
+ sd = socket (AF_INET, SOCK_DGRAM, 0);
+ if (sd == -1)
+ goto out;
+
+ buf.ifc_len = sizeof (buff);
+ buf.ifc_buf = buff;
+ size = buf.ifc_len;
+
+ ret = ioctl (sd, SIOCGIFCONF, &buf);
+ if (ret) {
+ goto out;
+ }
+
+ while (size <= buf.ifc_len) {
+ size += sizeof (struct ifreq);
+ buf.ifc_len = size;
+ if (need_free)
+ GF_FREE (buf.ifc_req);
+ buf.ifc_req = GF_CALLOC (1, size, gf_gld_mt_ifreq);
+ need_free = 1;
+ ret = ioctl (sd, SIOCGIFCONF, &buf);
+ if (ret) {
goto out;
- /*If bind succeeds then its a local address*/
- ret = bind (sd, res->ai_addr, res->ai_addrlen);
- if (ret == 0) {
- found = _gf_true;
- gf_log (this->name, GF_LOG_DEBUG, "%s is local",
- get_ip_from_addrinfo (res, &ip));
- close (sd);
- break;
}
- close (sd);
+ }
+
+ ifr_end = (struct ifreq *)&buf.ifc_buf[buf.ifc_len];
+
+ for (res = result; res != NULL; res = res->ai_next) {
+ ifr = buf.ifc_req;
+ while (ifr < ifr_end) {
+ if ((ifr->ifr_addr.sa_family == res->ai_addr->sa_family)
+ && (memcmp (&ifr->ifr_addr, res->ai_addr,
+ res->ai_addrlen) == 0)) {
+ found = 1;
+ goto out;
+ }
+ ifr++;
+ }
}
out:
+ if (sd >= 0)
+ close (sd);
+
if (result)
freeaddrinfo (result);
- if (!found)
- gf_log (this->name, GF_LOG_DEBUG, "%s is not local", hostname);
+ if (need_free)
+ GF_FREE (buf.ifc_req);
+
+ if (found)
+ gf_log ("glusterd", GF_LOG_DEBUG, "%s is local", hostname);
+ else
+ gf_log ("glusterd", GF_LOG_DEBUG, "%s is not local", hostname);
return !found;
}
@@ -302,7 +260,7 @@ glusterd_unlock (uuid_t uuid)
glusterd_get_lock_owner (&owner);
- if (uuid_is_null (owner)) {
+ if (NULL == owner) {
gf_log ("glusterd", GF_LOG_ERROR, "Cluster lock not held!");
goto out;
}
@@ -340,7 +298,7 @@ glusterd_get_uuid (uuid_t *uuid)
GF_ASSERT (priv);
- uuid_copy (*uuid, MY_UUID);
+ uuid_copy (*uuid, priv->uuid);
return 0;
}
@@ -349,48 +307,46 @@ int
glusterd_submit_request (struct rpc_clnt *rpc, void *req,
call_frame_t *frame, rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc)
+ gd_serialize_t sfunc, xlator_t *this,
+ fop_cbk_fn_t cbkfn)
{
int ret = -1;
struct iobuf *iobuf = NULL;
int count = 0;
char new_iobref = 0, start_ping = 0;
struct iovec iov = {0, };
- ssize_t req_size = 0;
GF_ASSERT (rpc);
GF_ASSERT (this);
- if (req) {
- req_size = xdr_sizeof (xdrproc, req);
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, req_size);
- if (!iobuf) {
- goto out;
- };
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ goto out;
+ };
+ if (!iobref) {
+ iobref = iobref_new ();
if (!iobref) {
- iobref = iobref_new ();
- if (!iobref) {
- goto out;
- }
-
- new_iobref = 1;
+ goto out;
}
- iobref_add (iobref, iobuf);
+ new_iobref = 1;
+ }
+
+ iobref_add (iobref, iobuf);
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_pagesize (iobuf);
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = 128 * GF_UNIT_KB;
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
+ /* Create the xdr payload */
+ if (req && sfunc) {
+ ret = sfunc (iov, req);
if (ret == -1) {
goto out;
}
iov.iov_len = ret;
count = 1;
}
-
/* Send the msg */
ret = rpc_clnt_submit (rpc, prog, procnum, cbkfn,
&iov, count,
@@ -422,17 +378,15 @@ out:
struct iobuf *
glusterd_serialize_reply (rpcsvc_request_t *req, void *arg,
- struct iovec *outmsg, xdrproc_t xdrproc)
+ gd_serialize_t sfunc, struct iovec *outmsg)
{
struct iobuf *iob = NULL;
ssize_t retlen = -1;
- ssize_t rsp_size = 0;
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
- rsp_size = xdr_sizeof (xdrproc, arg);
- iob = iobuf_get2 (req->svc->ctx->iobuf_pool, rsp_size);
+ iob = iobuf_get (req->svc->ctx->iobuf_pool);
if (!iob) {
gf_log ("", GF_LOG_ERROR, "Failed to get iobuf");
goto ret;
@@ -445,7 +399,7 @@ glusterd_serialize_reply (rpcsvc_request_t *req, void *arg,
/* retlen is used to received the error since size_t is unsigned and we
* need -1 for error notification during encoding.
*/
- retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
+ retlen = sfunc (*outmsg, arg);
if (retlen == -1) {
gf_log ("", GF_LOG_ERROR, "Failed to encode message");
goto ret;
@@ -464,7 +418,7 @@ ret:
int
glusterd_submit_reply (rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc)
+ struct iobref *iobref, gd_serialize_t sfunc)
{
struct iobuf *iob = NULL;
int ret = -1;
@@ -476,6 +430,7 @@ glusterd_submit_reply (rpcsvc_request_t *req, void *arg,
goto out;
}
+
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
@@ -486,7 +441,7 @@ glusterd_submit_reply (rpcsvc_request_t *req, void *arg,
new_iobref = 1;
}
- iob = glusterd_serialize_reply (req, arg, &rsp, xdrproc);
+ iob = glusterd_serialize_reply (req, arg, sfunc, &rsp);
if (!iob) {
gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
} else {
@@ -561,20 +516,20 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo)
new_volinfo->dict = dict_new ();
if (!new_volinfo->dict) {
- GF_FREE (new_volinfo);
+ if (new_volinfo)
+ GF_FREE (new_volinfo);
goto out;
}
new_volinfo->gsync_slaves = dict_new ();
if (!new_volinfo->gsync_slaves) {
- GF_FREE (new_volinfo);
+ if (new_volinfo)
+ GF_FREE (new_volinfo);
goto out;
}
- new_volinfo->xl = THIS;
-
*volinfo = new_volinfo;
ret = 0;
@@ -584,52 +539,6 @@ out:
return ret;
}
-void
-glusterd_auth_cleanup (glusterd_volinfo_t *volinfo) {
-
- GF_ASSERT (volinfo);
-
- GF_FREE (volinfo->auth.username);
-
- GF_FREE (volinfo->auth.password);
-}
-
-char *
-glusterd_auth_get_username (glusterd_volinfo_t *volinfo) {
-
- GF_ASSERT (volinfo);
-
- return volinfo->auth.username;
-}
-
-char *
-glusterd_auth_get_password (glusterd_volinfo_t *volinfo) {
-
- GF_ASSERT (volinfo);
-
- return volinfo->auth.password;
-}
-
-int32_t
-glusterd_auth_set_username (glusterd_volinfo_t *volinfo, char *username) {
-
- GF_ASSERT (volinfo);
- GF_ASSERT (username);
-
- volinfo->auth.username = gf_strdup (username);
- return 0;
-}
-
-int32_t
-glusterd_auth_set_password (glusterd_volinfo_t *volinfo, char *password) {
-
- GF_ASSERT (volinfo);
- GF_ASSERT (password);
-
- volinfo->auth.password = gf_strdup (password);
- return 0;
-}
-
int32_t
glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo)
{
@@ -639,7 +548,8 @@ glusterd_brickinfo_delete (glusterd_brickinfo_t *brickinfo)
list_del_init (&brickinfo->brick_list);
- GF_FREE (brickinfo->logfile);
+ if (brickinfo->logfile)
+ GF_FREE (brickinfo->logfile);
GF_FREE (brickinfo);
ret = 0;
@@ -684,9 +594,8 @@ glusterd_volinfo_delete (glusterd_volinfo_t *volinfo)
dict_unref (volinfo->dict);
if (volinfo->gsync_slaves)
dict_unref (volinfo->gsync_slaves);
- GF_FREE (volinfo->logdir);
-
- glusterd_auth_cleanup (volinfo);
+ if (volinfo->logdir)
+ GF_FREE (volinfo->logdir);
GF_FREE (volinfo);
ret = 0;
@@ -735,34 +644,34 @@ glusterd_resolve_brick (glusterd_brickinfo_t *brickinfo)
}
int32_t
-glusterd_brickinfo_new_from_brick (char *brick,
- glusterd_brickinfo_t **brickinfo)
+glusterd_brickinfo_from_brick (char *brick,
+ glusterd_brickinfo_t **brickinfo)
{
int32_t ret = -1;
glusterd_brickinfo_t *new_brickinfo = NULL;
char *hostname = NULL;
char *path = NULL;
- char *tmp_host = NULL;
- char *tmp_path = NULL;
+ char *tmp = NULL;
+ char *tmpstr = NULL;
GF_ASSERT (brick);
GF_ASSERT (brickinfo);
- tmp_host = gf_strdup (brick);
- if (tmp_host && !get_host_name (tmp_host, &hostname))
- goto out;
- tmp_path = gf_strdup (brick);
- if (tmp_path && !get_path_name (tmp_path, &path))
+ tmp = gf_strdup (brick);
+ if (!tmp) {
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "Out of memory");
goto out;
+ }
+
+ hostname = strtok_r (tmp, ":", &tmpstr);
+ path = strtok_r (NULL, ":", &tmpstr);
GF_ASSERT (hostname);
GF_ASSERT (path);
ret = glusterd_brickinfo_new (&new_brickinfo);
- if (ret)
- goto out;
- ret = gf_canonicalize_path (path);
if (ret)
goto out;
@@ -773,72 +682,12 @@ glusterd_brickinfo_new_from_brick (char *brick,
ret = 0;
out:
- GF_FREE (tmp_host);
- if (tmp_host)
- GF_FREE (tmp_path);
+ if (tmp)
+ GF_FREE (tmp);
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-static gf_boolean_t
-_is_prefix (char *str1, char *str2)
-{
- GF_ASSERT (str1);
- GF_ASSERT (str2);
-
- int i = 0;
- int small_len = 0;
- gf_boolean_t prefix = _gf_true;
-
- small_len = min (strlen (str1), strlen (str2));
- for (i = 0; i < small_len; i++) {
- if (str1[i] != str2[i]) {
- prefix = _gf_false;
- break;
- }
-
- }
-
- return prefix;
-}
-
-/* Checks if @path is available in the peer identified by @uuid
- * 'availability' is determined by querying current state of volumes
- * in the cluster. */
-gf_boolean_t
-glusterd_is_brickpath_available (uuid_t uuid, char *path)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_conf_t *priv = NULL;
- gf_boolean_t available = _gf_false;
- char tmp_path[PATH_MAX+1] = {0};
- char tmp_brickpath[PATH_MAX+1] = {0};
-
- priv = THIS->private;
-
- strncpy (tmp_path, path, PATH_MAX);
- /* path may not yet exist */
- if (!realpath (path, tmp_path) && (errno != ENOENT))
- goto out;
-
- list_for_each_entry (volinfo, &priv->volumes, vol_list) {
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (uuid, brickinfo->uuid))
- continue;
-
- if (!realpath (brickinfo->path, tmp_brickpath))
- goto out;
-
- if (_is_prefix (tmp_brickpath, tmp_path))
- goto out;
- }
- }
- available = _gf_true;
-out:
- return available;
-}
-
int32_t
glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
glusterd_volinfo_t *volinfo,
@@ -847,6 +696,10 @@ glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
glusterd_brickinfo_t *brickiter = NULL;
uuid_t peer_uuid = {0};
int32_t ret = -1;
+ int32_t brick_path_len = 0;
+ int32_t path_len = 0;
+ int32_t smaller_path = 0;
+ gf_boolean_t is_path_smaller = _gf_true;
if (uuid) {
uuid_copy (peer_uuid, uuid);
@@ -856,20 +709,48 @@ glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
goto out;
}
ret = -1;
+ path_len = strlen (path);
list_for_each_entry (brickiter, &volinfo->bricks, brick_list) {
- if ((uuid_is_null (brickiter->uuid)) &&
- (glusterd_resolve_brick (brickiter) != 0))
- goto out;
- if (uuid_compare (peer_uuid, brickiter->uuid))
- continue;
-
- if (strcmp (brickiter->path, path) == 0) {
- gf_log (THIS->name, GF_LOG_INFO, "Found brick");
+ if (uuid_is_null (brickiter->uuid)) {
+ ret = glusterd_resolve_brick (brickiter);
+ if (ret)
+ goto out;
+ }
+ brick_path_len = strlen (brickiter->path);
+ smaller_path = min (brick_path_len, path_len);
+ if (smaller_path != path_len)
+ is_path_smaller = _gf_false;
+ if ((!uuid_compare (peer_uuid, brickiter->uuid)) &&
+ !strcmp (brickiter->path, path)) {
+ gf_log ("", GF_LOG_INFO, "Found brick");
ret = 0;
if (brickinfo)
*brickinfo = brickiter;
break;
+ } else {
+ if ((!uuid_compare (peer_uuid, brickiter->uuid)) &&
+ !strncmp (brickiter->path, path, smaller_path)) {
+ if (is_path_smaller == _gf_true) {
+ if (brickiter->path[smaller_path] == '/') {
+ ret = 0;
+ gf_log ("", GF_LOG_INFO,
+ "given path %s lies"
+ " within %s", path,
+ brickiter->path);
+ break;
+ }
+ } else
+ if (path[smaller_path] == '/') {
+ gf_log ("", GF_LOG_INFO,
+ "brick %s is a part of"
+ " %s", brickiter->path,
+ path);
+ ret = 0;
+ break;
+ }
+ }
+ ret = -1;
}
}
@@ -884,59 +765,60 @@ glusterd_volume_brickinfo_get_by_brick (char *brick,
glusterd_brickinfo_t **brickinfo)
{
int32_t ret = -1;
- glusterd_brickinfo_t *tmp_brickinfo = NULL;
+ char *hostname = NULL;
+ char *path = NULL;
+ char *dup_brick = NULL;
+ char *free_ptr = NULL;
GF_ASSERT (brick);
GF_ASSERT (volinfo);
- ret = glusterd_brickinfo_new_from_brick (brick, &tmp_brickinfo);
- if (ret)
+ gf_log ("", GF_LOG_INFO, "brick: %s", brick);
+
+ dup_brick = gf_strdup (brick);
+ if (!dup_brick) {
+ gf_log ("", GF_LOG_ERROR,
+ "Out of memory");
+ ret = -1;
+ goto out;
+ } else {
+ free_ptr = dup_brick;
+ }
+
+ hostname = strtok (dup_brick, ":");
+ path = strtok (NULL, ":");
+
+ if (!hostname || !path) {
+ gf_log ("", GF_LOG_ERROR,
+ "brick %s is not of form <HOSTNAME>:<export-dir>",
+ brick);
+ ret = -1;
goto out;
+ }
- ret = glusterd_volume_brickinfo_get (NULL, tmp_brickinfo->hostname,
- tmp_brickinfo->path, volinfo,
+ ret = glusterd_volume_brickinfo_get (NULL, hostname, path, volinfo,
brickinfo);
- (void) glusterd_brickinfo_delete (tmp_brickinfo);
out:
+ if (free_ptr)
+ GF_FREE (free_ptr);
+
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-gf_boolean_t
-glusterd_is_brick_decommissioned (glusterd_volinfo_t *volinfo, char *hostname,
- char *path)
-{
- gf_boolean_t decommissioned = _gf_false;
- glusterd_brickinfo_t *brickinfo = NULL;
- int ret = -1;
-
- ret = glusterd_volume_brickinfo_get (NULL, hostname, path, volinfo,
- &brickinfo);
- if (ret)
- goto out;
- decommissioned = brickinfo->decommissioned;
-out:
- return decommissioned;
-}
-
int32_t
glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo)
{
GF_ASSERT (peerinfo);
- glusterd_peerctx_t *peerctx = NULL;
+ glusterd_peerctx_t *peerctx = NULL;
if (peerinfo->rpc) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&peerinfo->rpc->conn);
-
peerctx = peerinfo->rpc->mydata;
peerinfo->rpc->mydata = NULL;
peerinfo->rpc = rpc_clnt_unref (peerinfo->rpc);
peerinfo->rpc = NULL;
- if (peerctx) {
- GF_FREE (peerctx->errstr);
+ if (peerctx)
GF_FREE (peerctx);
- }
}
glusterd_peer_destroy (peerinfo);
@@ -1003,9 +885,6 @@ glusterd_service_stop (const char *service, char *pidfile, int sig,
if (ret && (ENOENT != errno)) {
gf_log ("", GF_LOG_ERROR, "Unable to "
"unlink stale pidfile: %s", pidfile);
- } else if (ret && (ENOENT == errno)){
- ret = 0;
- gf_log ("", GF_LOG_INFO, "Brick already stopped");
}
goto out;
}
@@ -1066,28 +945,20 @@ out:
}
void
-glusterd_set_socket_filepath (char *sock_filepath, char *sockpath, size_t len)
-{
- char md5_sum[MD5_DIGEST_LENGTH*2+1] = {0,};
-
- md5_wrapper ((unsigned char *) sock_filepath, strlen(sock_filepath), md5_sum);
- snprintf (sockpath, len, "%s/%s.socket", glusterd_sock_dir, md5_sum);
-}
-
-void
glusterd_set_brick_socket_filepath (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
char *sockpath, size_t len)
{
char export_path[PATH_MAX] = {0,};
char sock_filepath[PATH_MAX] = {0,};
+ char md5_sum[MD5_DIGEST_LEN*2+1] = {0,};
char volume_dir[PATH_MAX] = {0,};
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int expected_file_len = 0;
expected_file_len = strlen (glusterd_sock_dir) + strlen ("/") +
- MD5_DIGEST_LENGTH*2 + strlen (".socket") + 1;
+ MD5_DIGEST_LEN*2 + strlen (".socket") + 1;
GF_ASSERT (len >= expected_file_len);
this = THIS;
GF_ASSERT (this);
@@ -1098,8 +969,10 @@ glusterd_set_brick_socket_filepath (glusterd_volinfo_t *volinfo,
GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, export_path);
snprintf (sock_filepath, PATH_MAX, "%s/run/%s-%s",
volume_dir, brickinfo->hostname, export_path);
+ _get_md5_str (md5_sum, sizeof (md5_sum),
+ (uint8_t*)sock_filepath, strlen (sock_filepath));
- glusterd_set_socket_filepath (sock_filepath, sockpath, len);
+ snprintf (sockpath, len, "%s/%s.socket", glusterd_sock_dir, md5_sum);
}
/* connection happens only if it is not aleady connected,
@@ -1146,19 +1019,15 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
char pidfile[PATH_MAX] = {0,};
char volfile[PATH_MAX] = {0,};
char path[PATH_MAX] = {0,};
- runner_t runner = {0,};
+ char cmd_str[8192] = {0,};
char rundir[PATH_MAX] = {0,};
char exp_path[PATH_MAX] = {0,};
char logfile[PATH_MAX] = {0,};
int port = 0;
- int rdma_port = 0;
FILE *file = NULL;
gf_boolean_t is_locked = _gf_false;
char socketpath[PATH_MAX] = {0};
- char glusterd_uuid[1024] = {0,};
-#ifdef DEBUG
- char valgrind_logfile[PATH_MAX] = {0};
-#endif
+
GF_ASSERT (volinfo);
GF_ASSERT (brickinfo);
@@ -1238,64 +1107,20 @@ glusterd_volume_start_glusterfs (glusterd_volinfo_t *volinfo,
if (!port)
port = pmap_registry_alloc (THIS);
- runinit (&runner);
-
-#ifdef DEBUG
- if (priv->valgrind) {
- if (volinfo->logdir) {
- snprintf (valgrind_logfile, PATH_MAX,
- "%s/valgrind-%s-%s.log", volinfo->logdir,
- volinfo->volname, exp_path);
- } else {
- snprintf (valgrind_logfile, PATH_MAX,
- "%s/bricks/valgrind-%s-%s.log",
- DEFAULT_LOG_FILE_DIRECTORY,
- volinfo->volname, exp_path);
- }
- /* Run bricks with valgrind */
- runner_add_args (&runner, "valgrind", "--leak-check=full",
- "--trace-children=yes", NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-#endif
- (void) snprintf (glusterd_uuid, 1024, "*-posix.glusterd-uuid=%s",
- uuid_utoa (MY_UUID));
- runner_add_args (&runner, SBIN_DIR"/glusterfsd",
- "-s", "localhost", "--volfile-id", volfile,
- "-p", pidfile, "-S", socketpath,
- "--brick-name", brickinfo->path,
- "-l", brickinfo->logfile,
- "--xlator-option", glusterd_uuid,
- NULL);
-
- runner_add_arg (&runner, "--brick-port");
- if (volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) {
- runner_argprintf (&runner, "%d", port);
- } else {
- rdma_port = brickinfo->rdma_port;
- if (!rdma_port)
- rdma_port = pmap_registry_alloc (THIS);
- runner_argprintf (&runner, "%d,%d", port, rdma_port);
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "%s-server.transport.rdma.listen-port=%d",
- volinfo->volname, rdma_port);
- }
-
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "%s-server.listen-port=%d",
- volinfo->volname, port);
-
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
+ snprintf (cmd_str, 8192,
+ "%s/sbin/glusterfsd --xlator-option %s-server.listen-port=%d "
+ "-s localhost --volfile-id %s -p %s -S %s --brick-name %s "
+ "--brick-port %d -l %s", GFS_PREFIX, volinfo->volname,
+ port, volfile, pidfile, socketpath, brickinfo->path, port,
+ brickinfo->logfile);
- runner_log (&runner, "", GF_LOG_DEBUG, "Starting GlusterFS");
- ret = runner_run (&runner);
- if (ret)
- goto out;
+ gf_log ("",GF_LOG_DEBUG,"Starting GlusterFS Command Executed: \n %s \n", cmd_str);
+ ret = gf_system (cmd_str);
- //pmap_registry_bind (THIS, port, brickinfo->path);
- brickinfo->port = port;
- brickinfo->rdma_port = rdma_port;
+ if (ret == 0) {
+ //pmap_registry_bind (THIS, port, brickinfo->path);
+ brickinfo->port = port;
+ }
connect:
ret = glusterd_brick_connect (volinfo, brickinfo);
@@ -1348,9 +1173,6 @@ glusterd_brick_disconnect (glusterd_brickinfo_t *brickinfo)
GF_ASSERT (brickinfo);
if (brickinfo->rpc) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&brickinfo->rpc->conn);
-
rpc_clnt_unref (brickinfo->rpc);
brickinfo->rpc = NULL;
}
@@ -1383,7 +1205,7 @@ glusterd_volume_stop_glusterfs (glusterd_volinfo_t *volinfo,
ret = glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_false);
if (ret == 0) {
glusterd_set_brick_status (brickinfo, GF_BRICK_STOPPED);
- (void) glusterd_brick_unlink_socket_file (volinfo, brickinfo);
+ ret = glusterd_brick_unlink_socket_file (volinfo, brickinfo);
}
return ret;
}
@@ -1414,95 +1236,6 @@ out:
return ret;
}
-char **
-glusterd_readin_file (const char *filepath, int *line_count)
-{
- int ret = -1;
- int n = 8;
- int counter = 0;
- char buffer[PATH_MAX + 256] = {0};
- char **lines = NULL;
- FILE *fp = NULL;
-
- fp = fopen (filepath, "r");
- if (!fp)
- goto out;
-
- lines = GF_CALLOC (1, n * sizeof (*lines), gf_gld_mt_charptr);
- if (!lines)
- goto out;
-
- for (counter = 0; fgets (buffer, sizeof (buffer), fp); counter++) {
-
- if (counter == n-1) {
- n *= 2;
- lines = GF_REALLOC (lines, n * sizeof (char *));
- if (!lines)
- goto out;
- }
-
- lines[counter] = gf_strdup (buffer);
- memset (buffer, 0, sizeof (buffer));
- }
-
- lines[counter] = NULL;
- lines = GF_REALLOC (lines, (counter + 1) * sizeof (char *));
- if (!lines)
- goto out;
-
- *line_count = counter;
- ret = 0;
-
- out:
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "%s", strerror (errno));
- if (fp)
- fclose (fp);
-
- return lines;
-}
-
-int
-glusterd_compare_lines (const void *a, const void *b) {
-
- return strcmp(* (char * const *) a, * (char * const *) b);
-}
-
-int
-glusterd_sort_and_redirect (const char *src_filepath, int dest_fd)
-{
- int ret = -1;
- int line_count = 0;
- int counter = 0;
- char **lines = NULL;
-
-
- if (!src_filepath || dest_fd < 0)
- goto out;
-
- lines = glusterd_readin_file (src_filepath, &line_count);
- if (!lines)
- goto out;
-
- qsort (lines, line_count, sizeof (*lines), glusterd_compare_lines);
-
- for (counter = 0; lines[counter]; counter++) {
-
- ret = write (dest_fd, lines[counter],
- strlen (lines[counter]));
- if (ret < 0)
- goto out;
-
- GF_FREE (lines[counter]);
- }
-
- ret = 0;
- out:
- GF_FREE (lines);
-
- return ret;
-}
-
int
glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
{
@@ -1516,11 +1249,11 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
char buf[4096] = {0,};
char sort_filepath[PATH_MAX] = {0};
gf_boolean_t unlink_sortfile = _gf_false;
+ char sort_cmd[2*PATH_MAX + 32];
int sort_fd = 0;
- xlator_t *this = NULL;
GF_ASSERT (volinfo);
- this = THIS;
+
priv = THIS->private;
GF_ASSERT (priv);
@@ -1529,10 +1262,10 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
snprintf (cksum_path, sizeof (cksum_path), "%s/%s",
path, GLUSTERD_CKSUM_FILE);
- fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT| O_TRUNC, 0600);
+ fd = open (cksum_path, O_RDWR | O_APPEND | O_CREAT| O_TRUNC, 0644);
if (-1 == fd) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
cksum_path, errno);
ret = -1;
goto out;
@@ -1542,10 +1275,9 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
GLUSTERD_VOLUME_INFO_FILE);
snprintf (sort_filepath, sizeof (sort_filepath), "/tmp/%s.XXXXXX",
volinfo->volname);
-
sort_fd = mkstemp (sort_filepath);
if (sort_fd < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Could not generate temp file, "
+ gf_log ("", GF_LOG_ERROR, "Could not generate temp file, "
"reason: %s for volume: %s", strerror (errno),
volinfo->volname);
goto out;
@@ -1553,22 +1285,18 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
unlink_sortfile = _gf_true;
}
- /* sort the info file, result in sort_filepath */
-
- ret = glusterd_sort_and_redirect (filepath, sort_fd);
+ snprintf (sort_cmd, sizeof (sort_cmd), "sort %s -o %s",
+ filepath, sort_filepath);
+ ret = system (sort_cmd);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "sorting info file failed");
+ gf_log ("", GF_LOG_ERROR, "failed to sort file %s to %s",
+ filepath, sort_filepath);
goto out;
}
-
- ret = close (sort_fd);
- if (ret)
- goto out;
-
ret = get_checksum_for_path (sort_filepath, &cksum);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get checksum"
+ gf_log ("", GF_LOG_ERROR, "Unable to get checksum"
" for path: %s", sort_filepath);
goto out;
}
@@ -1591,9 +1319,11 @@ glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo)
out:
if (fd > 0)
close (fd);
+ if (sort_fd > 0)
+ close (sort_fd);
if (unlink_sortfile)
unlink (sort_filepath);
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret);
return ret;
}
@@ -1624,45 +1354,15 @@ _add_volinfo_dict_to_prdict (dict_t *this, char *key, data_t *value, void *data)
}
int32_t
-glusterd_add_bricks_hname_path_to_dict (dict_t *dict,
- glusterd_volinfo_t *volinfo)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- int ret = 0;
- char key[256] = {0};
- int index = 0;
-
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- snprintf (key, sizeof (key), "%d-hostname", index);
- ret = dict_set_str (dict, key, brickinfo->hostname);
- if (ret)
- goto out;
-
- snprintf (key, sizeof (key), "%d-path", index);
- ret = dict_set_str (dict, key, brickinfo->path);
- if (ret)
- goto out;
-
- index++;
- }
-out:
- return ret;
-}
-
-int32_t
glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
dict_t *dict, int32_t count)
{
- int32_t ret = -1;
- char key[512] = {0,};
- glusterd_brickinfo_t *brickinfo = NULL;
- int32_t i = 1;
- char *volume_id_str = NULL;
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *str = NULL;
- glusterd_voldict_ctx_t ctx = {0};
+ int32_t ret = -1;
+ char key[512] = {0,};
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int32_t i = 1;
+ char *volume_id_str = NULL;
+ glusterd_voldict_ctx_t ctx = {0};
GF_ASSERT (dict);
GF_ASSERT (volinfo);
@@ -1703,24 +1403,6 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
goto out;
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.stripe_count", count);
- ret = dict_set_int32 (dict, key, volinfo->stripe_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.replica_count", count);
- ret = dict_set_int32 (dict, key, volinfo->replica_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.dist_count", count);
- ret = dict_set_int32 (dict, key, volinfo->dist_leaf_count);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.ckusm", count);
ret = dict_set_int64 (dict, key, volinfo->cksum);
if (ret)
@@ -1742,58 +1424,6 @@ glusterd_add_volume_to_dict (glusterd_volinfo_t *volinfo,
if (ret)
goto out;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.username", count);
- str = glusterd_auth_get_username (volinfo);
- if (str) {
- ret = dict_set_dynstr (dict, key, gf_strdup (str));
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.password", count);
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = dict_set_dynstr (dict, key, gf_strdup (str));
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count);
- ret = dict_set_int32 (dict, key, volinfo->rb_status);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d.rebalance", count);
- ret = dict_set_int32 (dict, key, volinfo->defrag_cmd);
- if (ret)
- goto out;
- if (volinfo->rb_status > GF_RB_STATUS_NONE) {
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- count);
- gf_asprintf (&src_brick, "%s:%s",
- volinfo->src_brick->hostname,
- volinfo->src_brick->path);
- ret = dict_set_dynstr (dict, key, src_brick);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- count);
- gf_asprintf (&dst_brick, "%s:%s",
- volinfo->dst_brick->hostname,
- volinfo->dst_brick->path);
- ret = dict_set_dynstr (dict, key, dst_brick);
- if (ret)
- goto out;
- }
-
ctx.dict = dict;
ctx.count = count;
ctx.opt_count = 1;
@@ -2144,16 +1774,12 @@ int32_t
glusterd_import_volinfo (dict_t *vols, int count,
glusterd_volinfo_t **volinfo)
{
- int ret = -1;
- char key[256] = {0};
- char *volname = NULL;
- glusterd_volinfo_t *new_volinfo = NULL;
- char *volume_id_str = NULL;
- char msg[2048] = {0};
- char *src_brick = NULL;
- char *dst_brick = NULL;
- char *str = NULL;
- int rb_status = 0;
+ int ret = -1;
+ char key[256] = {0};
+ char *volname = NULL;
+ glusterd_volinfo_t *new_volinfo = NULL;
+ char *volume_id_str = NULL;
+ char msg[2048] = {0};
GF_ASSERT (vols);
GF_ASSERT (volinfo);
@@ -2216,33 +1842,6 @@ glusterd_import_volinfo (dict_t *vols, int count,
goto out;
}
- /* not having a 'stripe_count' key is not a error
- (as peer may be of old version) */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.stripe_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->stripe_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
-
- /* not having a 'replica_count' key is not a error
- (as peer may be of old version) */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.replica_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->replica_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
-
- /* not having a 'dist_count' key is not a error
- (as peer may be of old version) */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.dist_count", count);
- ret = dict_get_int32 (vols, key, &new_volinfo->dist_leaf_count);
- if (ret)
- gf_log (THIS->name, GF_LOG_INFO,
- "peer is possibly old version");
-
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.ckusm", count);
ret = dict_get_uint32 (vols, key, &new_volinfo->cksum);
@@ -2262,24 +1861,6 @@ glusterd_import_volinfo (dict_t *vols, int count,
}
memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.username", count);
- ret = dict_get_str (vols, key, &str);
- if (!ret) {
- ret = glusterd_auth_set_username (new_volinfo, str);
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.password", count);
- ret = dict_get_str (vols, key, &str);
- if (!ret) {
- ret = glusterd_auth_set_password (new_volinfo, str);
- if (ret)
- goto out;
- }
-
- memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "volume%d.transport_type", count);
ret = dict_get_uint32 (vols, key, &new_volinfo->transport_type);
if (ret) {
@@ -2288,58 +1869,8 @@ glusterd_import_volinfo (dict_t *vols, int count,
goto out;
}
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "volume%d.rebalance", count);
- ret = dict_get_uint32 (vols, key, &new_volinfo->defrag_cmd);
- if (ret) {
- snprintf (msg, sizeof (msg), "%s missing in payload for %s",
- key, volname);
- goto out;
- }
-
uuid_parse (volume_id_str, new_volinfo->volume_id);
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_STATUS, count);
- ret = dict_get_int32 (vols, key, &rb_status);
- if (ret)
- goto out;
- new_volinfo->rb_status = rb_status;
-
- if (new_volinfo->rb_status > GF_RB_STATUS_NONE) {
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_SRC_BRICK,
- count);
- ret = dict_get_str (vols, key, &src_brick);
- if (ret)
- goto out;
-
- ret = glusterd_brickinfo_new_from_brick (src_brick,
- &new_volinfo->src_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create"
- " src brickinfo");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, 256, "volume%d."GLUSTERD_STORE_KEY_RB_DST_BRICK,
- count);
- ret = dict_get_str (vols, key, &dst_brick);
- if (ret)
- goto out;
-
- ret = glusterd_brickinfo_new_from_brick (dst_brick,
- &new_volinfo->dst_brick);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to create"
- " dst brickinfo");
- goto out;
- }
- }
-
-
ret = glusterd_import_friend_volume_opts (vols, count, new_volinfo);
if (ret)
goto out;
@@ -2445,8 +1976,7 @@ glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo,
* stop stale bricks. Stale volume information is going to be deleted.
* Which deletes the valid brick information inside stale volinfo.
* We dont want brick_rpc_notify to access already deleted brickinfo.
- * Disconnect all bricks from stale_volinfo (unconditionally), since
- * they are being deleted subsequently.
+ * Disconnect valid bricks.
*/
if (glusterd_is_volume_started (stale_volinfo)) {
if (glusterd_is_volume_started (valid_volinfo)) {
@@ -2455,12 +1985,10 @@ glusterd_delete_stale_volume (glusterd_volinfo_t *stale_volinfo,
//Only valid bricks will be running now.
(void) glusterd_volinfo_copy_brick_portinfo (valid_volinfo,
stale_volinfo);
-
+ (void) glusterd_volume_disconnect_all_bricks (stale_volinfo);
} else {
(void) glusterd_stop_bricks (stale_volinfo);
}
-
- (void) glusterd_volume_disconnect_all_bricks (stale_volinfo);
}
/* Delete all the bricks and stores and vol files. They will be created
* again by the valid_volinfo. Volume store delete should not be
@@ -2550,7 +2078,6 @@ glusterd_compare_friend_data (dict_t *vols, int32_t *status)
int i = 1;
gf_boolean_t update = _gf_false;
gf_boolean_t stale_nfs = _gf_false;
- gf_boolean_t stale_shd = _gf_false;
GF_ASSERT (vols);
GF_ASSERT (status);
@@ -2575,20 +2102,16 @@ glusterd_compare_friend_data (dict_t *vols, int32_t *status)
}
if (update) {
- if (glusterd_is_nodesvc_running ("nfs"))
+ if (glusterd_is_nfs_started ())
stale_nfs = _gf_true;
- if (glusterd_is_nodesvc_running ("glustershd"))
- stale_shd = _gf_true;
ret = glusterd_import_friend_volumes (vols);
if (ret)
goto out;
if (_gf_false == glusterd_are_all_volumes_stopped ()) {
- ret = glusterd_nodesvcs_handle_graph_change (NULL);
+ ret = glusterd_check_generate_start_nfs ();
} else {
if (stale_nfs)
glusterd_nfs_server_stop ();
- if (stale_shd)
- glusterd_shd_stop ();
}
}
@@ -2599,275 +2122,48 @@ out:
return ret;
}
-/* Valid only in if service is 'local' to glusterd.
- * pid can be -1, if reading pidfile failed */
-gf_boolean_t
-glusterd_is_service_running (char *pidfile, int *pid)
-{
- FILE *file = NULL;
- gf_boolean_t running = _gf_false;
- int ret = 0;
- int fno = 0;
-
- file = fopen (pidfile, "r+");
- if (!file)
- goto out;
-
- fno = fileno (file);
- ret = lockf (fno, F_TEST, 0);
- if (ret == -1)
- running = _gf_true;
- if (!pid)
- goto out;
-
- ret = fscanf (file, "%d", pid);
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to read pidfile: %s, %s",
- pidfile, strerror (errno));
- *pid = -1;
- }
-
-out:
- if (file)
- fclose (file);
- return running;
-}
-
-void
-glusterd_get_nodesvc_dir (char *server, char *workdir,
- char *path, size_t len)
-{
- GF_ASSERT (len == PATH_MAX);
- snprintf (path, len, "%s/%s", workdir, server);
-}
-
-void
-glusterd_get_nodesvc_rundir (char *server, char *workdir,
- char *path, size_t len)
-{
- char dir[PATH_MAX] = {0};
- GF_ASSERT (len == PATH_MAX);
-
- glusterd_get_nodesvc_dir (server, workdir, dir, sizeof (dir));
- snprintf (path, len, "%s/run", dir);
-}
-
-void
-glusterd_get_nodesvc_pidfile (char *server, char *workdir,
- char *path, size_t len)
-{
- char dir[PATH_MAX] = {0};
- GF_ASSERT (len == PATH_MAX);
-
- glusterd_get_nodesvc_rundir (server, workdir, dir, sizeof (dir));
- snprintf (path, len, "%s/%s.pid", dir, server);
-}
-
-void
-glusterd_get_nodesvc_volfile (char *server, char *workdir,
- char *volfile, size_t len)
-{
- char dir[PATH_MAX] = {0,};
- GF_ASSERT (len == PATH_MAX);
-
- glusterd_get_nodesvc_dir (server, workdir, dir, sizeof (dir));
- snprintf (volfile, len, "%s/%s-server.vol", dir, server);
-}
-
-void
-glusterd_nodesvc_set_running (char *server, gf_boolean_t status)
-{
- glusterd_conf_t *priv = NULL;
-
- GF_ASSERT (server);
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (priv->shd);
- GF_ASSERT (priv->nfs);
-
- if (!strcmp("glustershd", server))
- priv->shd->running = status;
- else if (!strcmp ("nfs", server))
- priv->nfs->running = status;
-}
-
gf_boolean_t
-glusterd_nodesvc_is_running (char *server)
-{
- glusterd_conf_t *conf = NULL;
- gf_boolean_t running = _gf_false;
-
- GF_ASSERT (server);
- conf = THIS->private;
- GF_ASSERT (conf);
- GF_ASSERT (conf->shd);
- GF_ASSERT (conf->nfs);
-
- if (!strcmp (server, "glustershd"))
- running = conf->shd->running;
- else if (!strcmp (server, "nfs"))
- running = conf->nfs->running;
-
- return running;
-}
-
-int32_t
-glusterd_nodesvc_set_socket_filepath (char *rundir, uuid_t uuid,
- char *socketpath, int len)
-{
- char sockfilepath[PATH_MAX] = {0,};
-
- snprintf (sockfilepath, sizeof (sockfilepath), "%s/run-%s",
- rundir, uuid_utoa (uuid));
-
- glusterd_set_socket_filepath (sockfilepath, socketpath, len);
- return 0;
-}
-
-struct rpc_clnt*
-glusterd_pending_node_get_rpc (glusterd_pending_node_t *pending_node)
-{
- struct rpc_clnt *rpc = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- nodesrv_t *shd = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- nodesrv_t *nfs = NULL;
-
- GF_VALIDATE_OR_GOTO (THIS->name, pending_node, out);
- GF_VALIDATE_OR_GOTO (THIS->name, pending_node->node, out);
-
- if (pending_node->type == GD_NODE_BRICK) {
- brickinfo = pending_node->node;
- rpc = brickinfo->rpc;
-
- } else if (pending_node->type == GD_NODE_SHD) {
- shd = pending_node->node;
- rpc = shd->rpc;
-
- } else if (pending_node->type == GD_NODE_REBALANCE) {
- volinfo = pending_node->node;
- if (volinfo->defrag)
- rpc = volinfo->defrag->rpc;
-
- } else if (pending_node->type == GD_NODE_NFS) {
- nfs = pending_node->node;
- rpc = nfs->rpc;
-
- } else {
- GF_ASSERT (0);
- }
-
-out:
- return rpc;
-}
-
-struct rpc_clnt*
-glusterd_nodesvc_get_rpc (char *server)
+glusterd_is_nfs_started ()
{
- glusterd_conf_t *priv = NULL;
- struct rpc_clnt *rpc = NULL;
-
- GF_ASSERT (server);
- priv = THIS->private;
- GF_ASSERT (priv);
- GF_ASSERT (priv->shd);
- GF_ASSERT (priv->nfs);
-
- if (!strcmp (server, "glustershd"))
- rpc = priv->shd->rpc;
- else if (!strcmp (server, "nfs"))
- rpc = priv->nfs->rpc;
-
- return rpc;
-}
-
-int32_t
-glusterd_nodesvc_set_rpc (char *server, struct rpc_clnt *rpc)
-{
- int ret = 0;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char pidfile[PATH_MAX] = {0,};
this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
- GF_ASSERT (priv->shd);
- GF_ASSERT (priv->nfs);
-
- if (!strcmp ("glustershd", server))
- priv->shd->rpc = rpc;
- else if (!strcmp ("nfs", server))
- priv->nfs->rpc = rpc;
-
- return ret;
-}
-
-int32_t
-glusterd_nodesvc_connect (char *server, char *socketpath) {
- int ret = 0;
- dict_t *options = NULL;
- struct rpc_clnt *rpc = NULL;
-
- rpc = glusterd_nodesvc_get_rpc (server);
-
- if (rpc == NULL) {
- ret = rpc_clnt_transport_unix_options_build (&options,
- socketpath);
- if (ret)
- goto out;
- ret = glusterd_rpc_create (&rpc, options,
- glusterd_nodesvc_rpc_notify,
- server);
- if (ret)
- goto out;
- (void) glusterd_nodesvc_set_rpc (server, rpc);
- }
-out:
- return ret;
-}
-
-int32_t
-glusterd_nodesvc_disconnect (char *server)
-{
- struct rpc_clnt *rpc = NULL;
+ GF_ASSERT(this);
- rpc = glusterd_nodesvc_get_rpc (server);
+ priv = this->private;
- if (rpc) {
- rpc_clnt_connection_cleanup (&rpc->conn);
- rpc_clnt_unref (rpc);
- (void)glusterd_nodesvc_set_rpc (server, NULL);
- }
+ GLUSTERD_GET_NFS_PIDFILE(pidfile);
+ ret = access (pidfile, F_OK);
- return 0;
+ if (ret == 0)
+ return _gf_true;
+ else
+ return _gf_false;
}
int32_t
-glusterd_nodesvc_start (char *server)
+glusterd_nfs_server_start ()
{
- int32_t ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- char pidfile[PATH_MAX] = {0,};
- char logfile[PATH_MAX] = {0,};
- char volfile[PATH_MAX] = {0,};
- char rundir[PATH_MAX] = {0,};
- char sockfpath[PATH_MAX] = {0,};
- char volfileid[256] = {0};
- char glusterd_uuid_option[1024] = {0};
-#ifdef DEBUG
- char valgrind_logfile[PATH_MAX] = {0};
-#endif
+ int32_t ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char pidfile[PATH_MAX] = {0,};
+ char logfile[PATH_MAX] = {0,};
+ char volfile[PATH_MAX] = {0,};
+ char path[PATH_MAX] = {0,};
+ char cmd_str[8192] = {0,};
+ char rundir[PATH_MAX] = {0,};
this = THIS;
GF_ASSERT(this);
priv = this->private;
- glusterd_get_nodesvc_rundir (server, priv->workdir,
- rundir, sizeof (rundir));
+ GLUSTERD_GET_NFS_DIR(path, priv);
+ snprintf (rundir, PATH_MAX, "%s/run", path);
ret = mkdir (rundir, 0777);
if ((ret == -1) && (EEXIST != errno)) {
@@ -2876,131 +2172,23 @@ glusterd_nodesvc_start (char *server)
goto out;
}
- glusterd_get_nodesvc_pidfile (server, priv->workdir,
- pidfile, sizeof (pidfile));
- glusterd_get_nodesvc_volfile (server, priv->workdir,
- volfile, sizeof (volfile));
+ GLUSTERD_GET_NFS_PIDFILE(pidfile);
+ glusterd_get_nfs_filepath (volfile);
+
ret = access (volfile, F_OK);
if (ret) {
- gf_log ("", GF_LOG_ERROR, "%s Volfile %s is not present",
- server, volfile);
+ gf_log ("", GF_LOG_ERROR, "Nfs Volfile %s is not present",
+ volfile);
goto out;
}
- snprintf (logfile, PATH_MAX, "%s/%s.log", DEFAULT_LOG_FILE_DIRECTORY,
- server);
- snprintf (volfileid, sizeof (volfileid), "gluster/%s", server);
-
- glusterd_nodesvc_set_socket_filepath (rundir, MY_UUID,
- sockfpath, sizeof (sockfpath));
-
- runinit (&runner);
-
-#ifdef DEBUG
- if (priv->valgrind) {
- snprintf (valgrind_logfile, PATH_MAX,
- "%s/valgrind-%s.log",
- DEFAULT_LOG_FILE_DIRECTORY,
- server);
-
- runner_add_args (&runner, "valgrind", "--leak-check=full",
- "--trace-children=yes", NULL);
- runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
- }
-#endif
-
- runner_add_args (&runner, SBIN_DIR"/glusterfs",
- "-s", "localhost",
- "--volfile-id", volfileid,
- "-p", pidfile,
- "-l", logfile,
- "-S", sockfpath, NULL);
-
- if (!strcmp (server, "glustershd")) {
- snprintf (glusterd_uuid_option, sizeof (glusterd_uuid_option),
- "*replicate*.node-uuid=%s", uuid_utoa (MY_UUID));
- runner_add_args (&runner, "--xlator-option",
- glusterd_uuid_option, NULL);
- }
- runner_log (&runner, "", GF_LOG_DEBUG,
- "Starting the nfs/glustershd services");
-
- ret = runner_run (&runner);
- if (ret == 0) {
- glusterd_nodesvc_connect (server, sockfpath);
- }
-out:
- return ret;
-}
-
-int
-glusterd_nfs_server_start ()
-{
- return glusterd_nodesvc_start ("nfs");
-}
-
-int
-glusterd_shd_start ()
-{
- return glusterd_nodesvc_start ("glustershd");
-}
-
-gf_boolean_t
-glusterd_is_nodesvc_running (char *server)
-{
- char pidfile[PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
-
- glusterd_get_nodesvc_pidfile (server, priv->workdir,
- pidfile, sizeof (pidfile));
- return glusterd_is_service_running (pidfile, NULL);
-}
-
-int32_t
-glusterd_nodesvc_unlink_socket_file (char *server)
-{
- int ret = 0;
- char sockfpath[PATH_MAX] = {0,};
- char rundir[PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
-
- glusterd_get_nodesvc_rundir (server, priv->workdir,
- rundir, sizeof (rundir));
-
- glusterd_nodesvc_set_socket_filepath (rundir, MY_UUID,
- sockfpath, sizeof (sockfpath));
-
- ret = unlink (sockfpath);
- if (ret && (ENOENT == errno)) {
- ret = 0;
- } else {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to remove %s"
- " error: %s", sockfpath, strerror (errno));
- }
-
- return ret;
-}
-
-int32_t
-glusterd_nodesvc_stop (char *server, int sig)
-{
- char pidfile[PATH_MAX] = {0,};
- glusterd_conf_t *priv = THIS->private;
- int ret = 0;
-
- if (!glusterd_is_nodesvc_running (server))
- goto out;
-
- (void)glusterd_nodesvc_disconnect (server);
+ snprintf (logfile, PATH_MAX, "%s/nfs.log", DEFAULT_LOG_FILE_DIRECTORY);
- glusterd_get_nodesvc_pidfile (server, priv->workdir,
- pidfile, sizeof (pidfile));
- ret = glusterd_service_stop (server, pidfile, sig, _gf_true);
+ snprintf (cmd_str, 8192,
+ "%s/sbin/glusterfs -f %s -p %s -l %s",
+ GFS_PREFIX, volfile, pidfile, logfile);
+ ret = gf_system (cmd_str);
- if (ret == 0) {
- glusterd_nodesvc_set_running (server, _gf_false);
- (void)glusterd_nodesvc_unlink_socket_file (server);
- }
out:
return ret;
}
@@ -3023,114 +2211,28 @@ glusterd_nfs_pmap_deregister ()
else
gf_log ("", GF_LOG_ERROR, "De-register NFSV3 is unsuccessful");
- if (pmap_unset (NLM_PROGRAM, NLMV4_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered NLM v4 successfully");
- else
- gf_log ("", GF_LOG_ERROR, "De-registration of NLM v4 failed");
-
- if (pmap_unset (NLM_PROGRAM, NLMV1_VERSION))
- gf_log ("", GF_LOG_INFO, "De-registered NLM v1 successfully");
- else
- gf_log ("", GF_LOG_ERROR, "De-registration of NLM v1 failed");
-
}
-int
+int32_t
glusterd_nfs_server_stop ()
{
- int ret = 0;
- gf_boolean_t deregister = _gf_false;
-
- if (glusterd_is_nodesvc_running ("nfs"))
- deregister = _gf_true;
- ret = glusterd_nodesvc_stop ("nfs", SIGKILL);
- if (ret)
- goto out;
- if (deregister)
- glusterd_nfs_pmap_deregister ();
-out:
- return ret;
-}
-
-int
-glusterd_shd_stop ()
-{
- return glusterd_nodesvc_stop ("glustershd", SIGTERM);
-}
-
-int
-glusterd_add_node_to_dict (char *server, dict_t *dict, int count,
- dict_t *vol_opts)
-{
- int ret = -1;
- glusterd_conf_t *priv = THIS->private;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
char pidfile[PATH_MAX] = {0,};
- gf_boolean_t running = _gf_false;
- int pid = -1;
- int port = 0;
- char key[1024] = {0,};
-
- glusterd_get_nodesvc_pidfile (server, priv->workdir, pidfile,
- sizeof (pidfile));
- running = glusterd_is_service_running (pidfile, &pid);
-
- /* For nfs-servers/self-heal-daemon setting
- * brick<n>.hostname = "NFS Server" / "Self-heal Daemon"
- * brick<n>.path = uuid
- * brick<n>.port = 0
- *
- * This might be confusing, but cli displays the name of
- * the brick as hostname+path, so this will make more sense
- * when output.
- */
- snprintf (key, sizeof (key), "brick%d.hostname", count);
- if (!strcmp (server, "nfs"))
- ret = dict_set_str (dict, key, "NFS Server");
- else if (!strcmp (server, "glustershd"))
- ret = dict_set_str (dict, key, "Self-heal Daemon");
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.path", count);
- ret = dict_set_dynstr (dict, key, gf_strdup (uuid_utoa (MY_UUID)));
- if (ret)
- goto out;
+ char path[PATH_MAX] = {0,};
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.port", count);
- /* Port is available only for the NFS server.
- * Self-heal daemon doesn't provide any port for access
- * by entities other than gluster.
- */
- if (!strcmp (server, "nfs")) {
- if (dict_get (vol_opts, "nfs.port")) {
- ret = dict_get_int32 (vol_opts, "nfs.port", &port);
- if (ret)
- goto out;
- } else
- port = GF_NFS3_PORT;
- }
- ret = dict_set_int32 (dict, key, port);
- if (ret)
- goto out;
+ this = THIS;
+ GF_ASSERT(this);
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.pid", count);
- ret = dict_set_int32 (dict, key, pid);
- if (ret)
- goto out;
+ priv = this->private;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.status", count);
- ret = dict_set_int32 (dict, key, running);
- if (ret)
- goto out;
+ GLUSTERD_GET_NFS_DIR(path, priv);
+ GLUSTERD_GET_NFS_PIDFILE(pidfile);
+ glusterd_service_stop ("nfsd", pidfile, SIGKILL, _gf_true);
+ glusterd_nfs_pmap_deregister ();
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ return 0;
}
int
@@ -3141,221 +2243,44 @@ glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
GF_ASSERT (req->trans);
char *name = NULL;
- char *hostname = NULL;
- char *tmp_host = NULL;
- int ret = 0;
+ char *delimiter = NULL;
name = req->trans->peerinfo.identifier;
- tmp_host = gf_strdup (name);
- if (tmp_host)
- get_host_name (tmp_host, &hostname);
+ strncpy (remote_host, name, len);
+ delimiter = strchr (remote_host, ':');
- GF_ASSERT (hostname);
- if (!hostname) {
+ GF_ASSERT (delimiter);
+ if (!delimiter) {
memset (remote_host, 0, len);
- ret = -1;
- goto out;
+ return -1;
}
- strncpy (remote_host, hostname, strlen (hostname));
-
-
-out:
- GF_FREE (tmp_host);
- return ret;
-}
-
-int
-glusterd_check_generate_start_service (int (*create_volfile) (),
- int (*stop) (), int (*start) ())
-{
- int ret = -1;
-
- ret = create_volfile ();
- if (ret)
- goto out;
-
- ret = stop ();
- if (ret)
- goto out;
+ *delimiter = '\0';
- ret = start ();
-out:
- return ret;
+ return 0;
}
int
-glusterd_reconfigure_nodesvc (int (*create_volfile) ())
+glusterd_check_generate_start_nfs ()
{
int ret = -1;
- ret = create_volfile ();
- if (ret)
- goto out;
-
- ret = glusterd_fetchspec_notify (THIS);
-out:
- return ret;
-}
-
-int
-glusterd_reconfigure_shd ()
-{
- int (*create_volfile) () = glusterd_create_shd_volfile;
- return glusterd_reconfigure_nodesvc (create_volfile);
-}
-
-int
-glusterd_reconfigure_nfs ()
-{
- int ret = -1;
- gf_boolean_t identical = _gf_false;
-
- ret = glusterd_check_nfs_volfile_identical (&identical);
+ ret = glusterd_create_nfs_volfile ();
if (ret)
goto out;
- if (identical) {
- ret = 0;
- goto out;
+ if (glusterd_is_nfs_started ()) {
+ ret = glusterd_nfs_server_stop ();
+ if (ret)
+ goto out;
}
- ret = glusterd_check_generate_start_nfs ();
-
-out:
- return ret;
-}
-
-
-int
-glusterd_check_generate_start_nfs ()
-{
- int ret = 0;
-
- ret = glusterd_check_generate_start_service (glusterd_create_nfs_volfile,
- glusterd_nfs_server_stop,
- glusterd_nfs_server_start);
- return ret;
-}
-
-int
-glusterd_check_generate_start_shd ()
-{
- int ret = 0;
-
- ret = glusterd_check_generate_start_service (glusterd_create_shd_volfile,
- glusterd_shd_stop,
- glusterd_shd_start);
- if (ret == -EINVAL)
- ret = 0;
- return ret;
-}
-
-int
-glusterd_nodesvcs_batch_op (glusterd_volinfo_t *volinfo,
- int (*nfs_op) (), int (*shd_op) ())
-{
- int ret = 0;
-
- ret = nfs_op ();
- if (ret)
- goto out;
-
- if (volinfo && !glusterd_is_volume_replicate (volinfo))
- goto out;
-
- ret = shd_op ();
- if (ret)
- goto out;
+ ret = glusterd_nfs_server_start ();
out:
return ret;
}
int
-glusterd_nodesvcs_start (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_nfs_server_start,
- glusterd_shd_start);
-}
-
-int
-glusterd_nodesvcs_stop (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_nfs_server_stop,
- glusterd_shd_stop);
-}
-
-gf_boolean_t
-glusterd_are_all_volumes_stopped ()
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *voliter = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (voliter->status == GLUSTERD_STATUS_STARTED)
- return _gf_false;
- }
-
- return _gf_true;
-
-}
-
-gf_boolean_t
-glusterd_all_replicate_volumes_stopped ()
-{
- glusterd_conf_t *priv = NULL;
- xlator_t *this = NULL;
- glusterd_volinfo_t *voliter = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (!glusterd_is_volume_replicate (voliter))
- continue;
- if (voliter->status == GLUSTERD_STATUS_STARTED)
- return _gf_false;
- }
-
- return _gf_true;
-}
-
-int
-glusterd_nodesvcs_handle_graph_change (glusterd_volinfo_t *volinfo)
-{
- int (*shd_op) () = NULL;
- int (*nfs_op) () = NULL;
-
- shd_op = glusterd_check_generate_start_shd;
- nfs_op = glusterd_check_generate_start_nfs;
- if (glusterd_are_all_volumes_stopped ()) {
- shd_op = glusterd_shd_stop;
- nfs_op = glusterd_nfs_server_stop;
- } else if (glusterd_all_replicate_volumes_stopped()) {
- shd_op = glusterd_shd_stop;
- }
- return glusterd_nodesvcs_batch_op (volinfo, nfs_op, shd_op);
-}
-
-int
-glusterd_nodesvcs_handle_reconfigure (glusterd_volinfo_t *volinfo)
-{
- return glusterd_nodesvcs_batch_op (volinfo,
- glusterd_reconfigure_nfs,
- glusterd_reconfigure_shd);
-}
-
-int
glusterd_volume_count_get (void)
{
glusterd_volinfo_t *tmp_volinfo = NULL;
@@ -3397,9 +2322,9 @@ glusterd_brickinfo_get (uuid_t uuid, char *hostname, char *path,
list_for_each_entry (volinfo, &priv->volumes, vol_list) {
ret = glusterd_volume_brickinfo_get (uuid, hostname, path,
- volinfo, brickinfo);
- if (ret == 0)
- /*Found*/
+ volinfo,
+ brickinfo);
+ if (!ret)
goto out;
}
out:
@@ -3451,25 +2376,22 @@ out:
int
glusterd_restart_bricks (glusterd_conf_t *conf)
{
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- gf_boolean_t start_nodesvcs = _gf_false;
- int ret = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_brickinfo_t *brickinfo = NULL;
+ int ret = 0;
+
+ GF_ASSERT (conf);
list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- /* If volume status is not started, do not proceed */
+ //If volume status is not started, do not proceed
if (volinfo->status == GLUSTERD_STATUS_STARTED) {
list_for_each_entry (brickinfo, &volinfo->bricks,
brick_list) {
glusterd_brick_start (volinfo, brickinfo);
}
- start_nodesvcs = _gf_true;
+ glusterd_check_generate_start_nfs ();
}
}
-
- if (start_nodesvcs)
- glusterd_nodesvcs_handle_graph_change (NULL);
-
return ret;
}
@@ -3490,8 +2412,9 @@ _local_gsyncd_start (dict_t *this, char *key, data_t *value, void *data)
return;
uuid_len = (slave - value->data - 1);
+
strncpy (uuid_str, (char*)value->data, uuid_len);
- glusterd_start_gsync (volinfo, slave, uuid_str, NULL);
+ glusterd_start_gsync (volinfo->volname, slave, uuid_str, NULL);
}
int
@@ -3543,23 +2466,9 @@ glusterd_get_brickinfo (xlator_t *this, const char *brickname, int port,
return ret;
}
-glusterd_brickinfo_t*
-glusterd_get_brickinfo_by_position (glusterd_volinfo_t *volinfo, uint32_t pos)
-{
- glusterd_brickinfo_t *tmpbrkinfo = NULL;
-
- list_for_each_entry (tmpbrkinfo, &volinfo->bricks,
- brick_list) {
- if (pos == 0)
- return tmpbrkinfo;
- pos--;
- }
- return NULL;
-}
-
void
glusterd_set_brick_status (glusterd_brickinfo_t *brickinfo,
- gf_brick_status_t status)
+ gf_brick_status_t status)
{
GF_ASSERT (brickinfo);
brickinfo->status = status;
@@ -3602,423 +2511,6 @@ out:
return -1;
}
-#ifdef GF_LINUX_HOST_OS
-static int
-glusterd_get_brick_root (char *path, char **mount_point)
-{
- char *ptr = NULL;
- struct stat brickstat = {0};
- struct stat buf = {0};
-
- if (!path)
- goto err;
- *mount_point = gf_strdup (path);
- if (!*mount_point)
- goto err;
- if (stat (*mount_point, &brickstat))
- goto err;
-
- while ((ptr = strrchr (*mount_point, '/')) &&
- ptr != *mount_point) {
-
- *ptr = '\0';
- if (stat (*mount_point, &buf)) {
- gf_log (THIS->name, GF_LOG_ERROR, "error in "
- "stat: %s", strerror (errno));
- goto err;
- }
-
- if (brickstat.st_dev != buf.st_dev) {
- *ptr = '/';
- break;
- }
- }
-
- if (ptr == *mount_point) {
- if (stat ("/", &buf)) {
- gf_log (THIS->name, GF_LOG_ERROR, "error in "
- "stat: %s", strerror (errno));
- goto err;
- }
- if (brickstat.st_dev == buf.st_dev)
- strcpy (*mount_point, "/");
- }
-
- return 0;
-
- err:
- GF_FREE (*mount_point);
- return -1;
-}
-
-static char*
-glusterd_parse_inode_size (char *stream, char *pattern)
-{
- char *needle = NULL;
- char *trail = NULL;
-
- needle = strstr (stream, pattern);
- if (!needle)
- goto out;
-
- needle = nwstrtail (needle, pattern);
-
- trail = needle;
- while (trail && isdigit (*trail)) trail++;
- if (trail)
- *trail = '\0';
-
-out:
- return needle;
-}
-
-static int
-glusterd_add_inode_size_to_dict (dict_t *dict, int count)
-{
- int ret = -1;
- char key[1024] = {0};
- char buffer[4096] = {0};
- char *inode_size = NULL;
- char *device = NULL;
- char *fs_name = NULL;
- char *cur_word = NULL;
- char *pattern = NULL;
- char *trail = NULL;
- runner_t runner = {0, };
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.device", count);
- ret = dict_get_str (dict, key, &device);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.fs_name", count);
- ret = dict_get_str (dict, key, &fs_name);
- if (ret)
- goto out;
-
- runinit (&runner);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- /* get inode size for xfs or ext2/3/4 */
- if (!strcmp (fs_name, "xfs")) {
-
- runner_add_args (&runner, "xfs_info", device, NULL);
- pattern = "isize=";
-
- } else if (IS_EXT_FS(fs_name)) {
-
- runner_add_args (&runner, "tune2fs", "-l", device, NULL);
- pattern = "Inode size:";
-
- } else {
- ret = 0;
- gf_log (THIS->name, GF_LOG_INFO, "Skipped fetching "
- "inode size for %s: FS type not recommended",
- fs_name);
- goto out;
- }
-
- ret = runner_start (&runner);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "could not get inode "
- "size for %s : %s package missing", fs_name,
- ((strcmp (fs_name, "xfs")) ?
- "e2fsprogs" : "xfsprogs"));
- goto out;
- }
-
- for (;;) {
- if (fgets (buffer, sizeof (buffer),
- runner_chio (&runner, STDOUT_FILENO)) == NULL)
- break;
- trail = strrchr (buffer, '\n');
- if (trail)
- *trail = '\0';
-
- cur_word = glusterd_parse_inode_size (buffer, pattern);
- if (cur_word)
- break;
- }
-
- ret = runner_end (&runner);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "%s exited with non-zero "
- "exit status", ((!strcmp (fs_name, "xfs")) ?
- "xfs_info" : "tune2fs"));
- goto out;
- }
- if (!cur_word) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR, "Unable to retrieve inode "
- "size using %s",
- (!strcmp (fs_name, "xfs")? "xfs_info": "tune2fs"));
- goto out;
- }
-
- inode_size = gf_strdup (cur_word);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "brick%d.inode_size", count);
-
- ret = dict_set_dynstr (dict, key, inode_size);
-
- out:
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get inode size");
- return ret;
-}
-
-static int
-glusterd_add_brick_mount_details (glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int count)
-{
- int ret = -1;
- char key[1024] = {0};
- char base_key[1024] = {0};
- char *mnt_pt = NULL;
- char *fs_name = NULL;
- char *mnt_options = NULL;
- char *device = NULL;
- FILE *mtab = NULL;
- struct mntent *entry = NULL;
-
- snprintf (base_key, sizeof (base_key), "brick%d", count);
-
- ret = glusterd_get_brick_root (brickinfo->path, &mnt_pt);
- if (ret)
- goto out;
-
- mtab = setmntent (_PATH_MOUNTED, "r");
- entry = getmntent (mtab);
-
- while (1) {
- if (!entry) {
- ret = -1;
- goto out;
- }
- if (!strcmp (entry->mnt_dir, mnt_pt) &&
- strcmp (entry->mnt_type, "rootfs"))
- break;
- entry = getmntent (mtab);
- }
-
- /* get device file */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.device", base_key);
-
- device = gf_strdup (entry->mnt_fsname);
- ret = dict_set_dynstr (dict, key, device);
- if (ret)
- goto out;
-
- /* fs type */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.fs_name", base_key);
-
- fs_name = gf_strdup (entry->mnt_type);
- ret = dict_set_dynstr (dict, key, fs_name);
- if (ret)
- goto out;
-
- /* mount options */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.mnt_options", base_key);
-
- mnt_options = gf_strdup (entry->mnt_opts);
- ret = dict_set_dynstr (dict, key, mnt_options);
-
- out:
- GF_FREE (mnt_pt);
- return ret;
-}
-#endif
-
-int
-glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int count)
-{
- int ret = -1;
- uint64_t memtotal = 0;
- uint64_t memfree = 0;
- uint64_t inodes_total = 0;
- uint64_t inodes_free = 0;
- uint64_t block_size = 0;
- char key[1024] = {0};
- char base_key[1024] = {0};
- struct statvfs brickstat = {0};
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
- GF_ASSERT (dict);
-
- snprintf (base_key, sizeof (base_key), "brick%d", count);
-
- ret = statvfs (brickinfo->path, &brickstat);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "statfs error: %s ",
- strerror (errno));
- goto out;
- }
-
- /* file system block size */
- block_size = brickstat.f_bsize;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.block_size", base_key);
- ret = dict_set_uint64 (dict, key, block_size);
- if (ret)
- goto out;
-
- /* free space in brick */
- memfree = brickstat.f_bfree * brickstat.f_bsize;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.free", base_key);
- ret = dict_set_uint64 (dict, key, memfree);
- if (ret)
- goto out;
-
- /* total space of brick */
- memtotal = brickstat.f_blocks * brickstat.f_bsize;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.total", base_key);
- ret = dict_set_uint64 (dict, key, memtotal);
- if (ret)
- goto out;
-
- /* inodes: total and free counts only for ext2/3/4 and xfs */
- inodes_total = brickstat.f_files;
- if (inodes_total) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.total_inodes", base_key);
- ret = dict_set_uint64 (dict, key, inodes_total);
- if (ret)
- goto out;
- }
-
- inodes_free = brickstat.f_ffree;
- if (inodes_free) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.free_inodes", base_key);
- ret = dict_set_uint64 (dict, key, inodes_free);
- if (ret)
- goto out;
- }
-#ifdef GF_LINUX_HOST_OS
- ret = glusterd_add_brick_mount_details (brickinfo, dict, count);
- if (ret)
- goto out;
-
- ret = glusterd_add_inode_size_to_dict (dict, count);
-#endif
- out:
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "Error adding brick"
- " detail to dict: %s", strerror (errno));
- return ret;
-}
-
-int32_t
-glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int32_t count)
-{
-
- int ret = -1;
- int32_t pid = -1;
- int32_t brick_online = -1;
- char key[1024] = {0};
- char base_key[1024] = {0};
- char pidfile[PATH_MAX] = {0};
- char path[PATH_MAX] = {0};
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
-
-
- GF_ASSERT (volinfo);
- GF_ASSERT (brickinfo);
- GF_ASSERT (dict);
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
-
- snprintf (base_key, sizeof (base_key), "brick%d", count);
- snprintf (key, sizeof (key), "%s.hostname", base_key);
-
- ret = dict_set_str (dict, key, brickinfo->hostname);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.path", base_key);
- ret = dict_set_str (dict, key, brickinfo->path);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.port", base_key);
- ret = dict_set_int32 (dict, key, brickinfo->port);
- if (ret)
- goto out;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
- GLUSTERD_GET_BRICK_PIDFILE (pidfile, path, brickinfo->hostname,
- brickinfo->path);
-
- brick_online = glusterd_is_service_running (pidfile, &pid);
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.pid", base_key);
- ret = dict_set_int32 (dict, key, pid);
- if (ret)
- goto out;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "%s.status", base_key);
- ret = dict_set_int32 (dict, key, brick_online);
-
-out:
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int32_t
-glusterd_get_all_volnames (dict_t *dict)
-{
- int ret = -1;
- int32_t vol_count = 0;
- char key[256] = {0};
- glusterd_volinfo_t *entry = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (entry, &priv->volumes, vol_list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "vol%d", vol_count);
- ret = dict_set_str (dict, key, entry->volname);
- if (ret)
- goto out;
-
- vol_count++;
- }
-
- ret = dict_set_int32 (dict, "vol_count", vol_count);
-
- out:
- if (ret)
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get all "
- "volume names for status");
- return ret;
-}
-
int
glusterd_all_volume_cond_check (glusterd_condition_func func, int status,
void *ctx)
@@ -4097,23 +2589,20 @@ glusterd_friend_find_by_hostname (const char *hoststr,
struct sockaddr_in *s4 = NULL;
struct in_addr *in_addr = NULL;
char hname[1024] = {0,};
- xlator_t *this = NULL;
-
- this = THIS;
GF_ASSERT (hoststr);
GF_ASSERT (peerinfo);
*peerinfo = NULL;
- priv = this->private;
+ priv = THIS->private;
GF_ASSERT (priv);
list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!strncasecmp (entry->hostname, hoststr,
- 1024)) {
+ if (!strncmp (entry->hostname, hoststr,
+ 1024)) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log ("glusterd", GF_LOG_DEBUG,
"Friend %s found.. state: %d", hoststr,
entry->state.state);
*peerinfo = entry;
@@ -4121,10 +2610,9 @@ glusterd_friend_find_by_hostname (const char *hoststr,
}
}
- ret = getaddrinfo (hoststr, NULL, NULL, &addr);
+ ret = getaddrinfo(hoststr, NULL, NULL, &addr);
if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "error in getaddrinfo: %s\n",
+ gf_log ("", GF_LOG_ERROR, "error in getaddrinfo: %s\n",
gai_strerror(ret));
goto out;
}
@@ -4150,10 +2638,10 @@ glusterd_friend_find_by_hostname (const char *hoststr,
goto out;
list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!strncasecmp (entry->hostname, host,
- 1024) || !strncasecmp (entry->hostname,hname,
+ if (!strncmp (entry->hostname, host,
+ 1024) || !strncmp (entry->hostname,hname,
1024)) {
- gf_log (this->name, GF_LOG_DEBUG,
+ gf_log ("glusterd", GF_LOG_DEBUG,
"Friend %s found.. state: %d",
hoststr, entry->state.state);
*peerinfo = entry;
@@ -4164,7 +2652,7 @@ glusterd_friend_find_by_hostname (const char *hoststr,
}
out:
- gf_log (this->name, GF_LOG_DEBUG, "Unable to find friend: %s", hoststr);
+ gf_log ("glusterd", GF_LOG_DEBUG, "Unable to find friend: %s", hoststr);
if (addr)
freeaddrinfo (addr);
return -1;
@@ -4192,7 +2680,7 @@ glusterd_hostname_to_uuid (char *hostname, uuid_t uuid)
if (ret)
goto out;
else
- uuid_copy (uuid, MY_UUID);
+ uuid_copy (uuid, priv->uuid);
} else {
uuid_copy (uuid, peerinfo->uuid);
}
@@ -4252,20 +2740,44 @@ out:
int
glusterd_is_defrag_on (glusterd_volinfo_t *volinfo)
{
- return (volinfo->defrag != NULL);
+ return ((volinfo->defrag_status == GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED) ||
+ (volinfo->defrag_status == GF_DEFRAG_STATUS_MIGRATE_DATA_STARTED));
}
-gf_boolean_t
-glusterd_is_rb_ongoing (glusterd_volinfo_t *volinfo)
+int
+glusterd_is_replace_running (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo)
{
- gf_boolean_t ret = _gf_false;
+ int ret = 0;
+ char *src_hostname = NULL;
+ char *brick_hostname = NULL;
- GF_ASSERT (volinfo);
+ if (volinfo->src_brick) {
+ src_hostname = gf_strdup (volinfo->src_brick->hostname);
+ if (!src_hostname) {
+ ret = -1;
+ goto out;
+ }
+ } else {
+ gf_log ("glusterd", GF_LOG_DEBUG,
+ "replace brick is not running");
+ goto out;
+ }
- if (glusterd_is_rb_started (volinfo) ||
- glusterd_is_rb_paused (volinfo))
- ret = _gf_true;
+ brick_hostname = gf_strdup (brickinfo->hostname);
+ if (!brick_hostname) {
+ ret = -1;
+ goto out;
+ }
+ if (!glusterd_is_local_addr (src_hostname) && !glusterd_is_local_addr (brick_hostname)) {
+ if (glusterd_is_rb_started (volinfo) || glusterd_is_rb_paused (volinfo))
+ ret = -1;
+ }
+out:
+ if (src_hostname)
+ GF_FREE (src_hostname);
+ if (brick_hostname)
+ GF_FREE (brick_hostname);
return ret;
}
@@ -4274,6 +2786,7 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
char *op_errstr, size_t len)
{
glusterd_brickinfo_t *newbrickinfo = NULL;
+ glusterd_brickinfo_t *tmpbrkinfo = NULL;
int ret = -1;
gf_boolean_t is_allocated = _gf_false;
glusterd_peerinfo_t *peerinfo = NULL;
@@ -4290,7 +2803,7 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
GF_ASSERT (op_errstr);
if (!brickinfo) {
- ret = glusterd_brickinfo_new_from_brick (brick, &newbrickinfo);
+ ret = glusterd_brickinfo_from_brick (brick, &newbrickinfo);
if (ret)
goto out;
is_allocated = _gf_true;
@@ -4302,11 +2815,11 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
if (ret) {
snprintf (op_errstr, len, "Host %s not a friend",
newbrickinfo->hostname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", op_errstr);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", op_errstr);
goto out;
}
- if (!uuid_compare (MY_UUID, newbrickinfo->uuid))
+ if (!uuid_compare (priv->uuid, newbrickinfo->uuid))
goto brick_validation;
ret = glusterd_friend_find_by_uuid (newbrickinfo->uuid, &peerinfo);
if (ret)
@@ -4315,17 +2828,18 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
(peerinfo->state.state != GD_FRIEND_STATE_BEFRIENDED)) {
snprintf(op_errstr, len, "Host %s not connected",
newbrickinfo->hostname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", op_errstr);
+ gf_log ("glusterd", GF_LOG_ERROR, "%s", op_errstr);
ret = -1;
goto out;
}
brick_validation:
- if (!glusterd_is_brickpath_available (newbrickinfo->uuid,
- newbrickinfo->path)) {
- snprintf(op_errstr, len, "Brick: %s not available. Brick may "
- "be containing or be contained by an existing brick",
+ ret = glusterd_brickinfo_get (newbrickinfo->uuid,
+ newbrickinfo->hostname,
+ newbrickinfo->path, &tmpbrkinfo);
+ if (!ret) {
+ snprintf(op_errstr, len, "Brick: %s already in use",
brick);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", op_errstr);
+ gf_log ("", GF_LOG_ERROR, "%s", op_errstr);
ret = -1;
goto out;
} else {
@@ -4334,7 +2848,7 @@ brick_validation:
out:
if (is_allocated && newbrickinfo)
glusterd_brickinfo_delete (newbrickinfo);
- gf_log (THIS->name, GF_LOG_DEBUG, "returning %d ", ret);
+ gf_log ("", GF_LOG_DEBUG, "returning %d ", ret);
return ret;
}
@@ -4388,165 +2902,40 @@ glusterd_rb_check_bricks (glusterd_volinfo_t *volinfo,
return 0;
}
-/*path needs to be absolute; works only on gfid, volume-id*/
-static int
-glusterd_is_uuid_present (char *path, char *xattr, gf_boolean_t *present)
-{
- GF_ASSERT (path);
- GF_ASSERT (xattr);
- GF_ASSERT (present);
-
- int ret = -1;
- uuid_t uid = {0,};
-
- if (!path || !xattr || !present)
- goto out;
-
- ret = sys_lgetxattr (path, xattr, &uid, 16);
-
- if (ret >= 0) {
- *present = _gf_true;
- ret = 0;
- goto out;
- }
-
- switch (errno) {
-#if defined(ENODATA)
- case ENODATA: /* FALLTHROUGH */
-#endif
-#if defined(ENOATTR) && (ENOATTR != ENODATA)
- case ENOATTR: /* FALLTHROUGH */
-#endif
- case ENOTSUP:
- *present = _gf_false;
- ret = 0;
- break;
- default:
- break;
- }
-out:
- return ret;
-}
-
-/*path needs to be absolute*/
-static int
-glusterd_is_path_in_use (char *path, gf_boolean_t *in_use, char **op_errstr)
-{
- int i = 0;
- int ret = -1;
- gf_boolean_t used = _gf_false;
- char dir[PATH_MAX] = {0,};
- char *curdir = NULL;
- char msg[2048] = {0};
- char *keys[3] = {GFID_XATTR_KEY,
- GF_XATTR_VOL_ID_KEY,
- NULL};
-
- GF_ASSERT (path);
- if (!path)
- goto out;
-
- strcpy (dir, path);
- curdir = dir;
- do {
- for (i = 0; !used && keys[i]; i++) {
- ret = glusterd_is_uuid_present (curdir, keys[i], &used);
- if (ret)
- goto out;
- }
-
- if (used)
- break;
-
- curdir = dirname (curdir);
- if (!strcmp (curdir, "."))
- goto out;
-
-
- } while (strcmp (curdir, "/"));
-
- if (!strcmp (curdir, "/")) {
- for (i = 0; !used && keys[i]; i++) {
- ret = glusterd_is_uuid_present (curdir, keys[i], &used);
- if (ret)
- goto out;
- }
- }
-
- ret = 0;
- *in_use = used;
-out:
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to get extended "
- "attribute %s, reason: %s", keys[i],
- strerror (errno));
- }
-
- if (*in_use) {
- snprintf (msg, sizeof (msg), "%s or a prefix of it is "
- "already part of a volume", path);
- }
-
- if (strlen (msg)) {
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- }
-
- return ret;
-}
-
int
-glusterd_brick_create_path (char *host, char *path, uuid_t uuid,
+glusterd_brick_create_path (char *host, char *path, mode_t mode,
char **op_errstr)
{
- int ret = -1;
- char msg[2048] = {0,};
- gf_boolean_t in_use = _gf_false;
-
- ret = mkdir_p (path, 0777, _gf_true);
- if (ret)
- goto out;
-
- /* Check for xattr support in backend fs */
- ret = sys_lsetxattr (path, "trusted.glusterfs.test",
- "working", 8, 0);
- if (ret) {
- snprintf (msg, sizeof (msg), "Glusterfs is not"
- " supported on brick: %s:%s.\nSetting"
- " extended attributes failed, reason:"
- " %s.", host, path, strerror(errno));
- goto out;
-
- } else {
- sys_lremovexattr (path, "trusted.glusterfs.test");
-
- }
-
- ret = glusterd_is_path_in_use (path, &in_use, op_errstr);
- if (ret)
- goto out;
-
- if (in_use) {
+ int ret = -1;
+ char msg[2048] = {0};
+ struct stat st_buf = {0};
+
+ ret = stat (path, &st_buf);
+ if ((!ret) && (!S_ISDIR (st_buf.st_mode))) {
+ snprintf (msg, sizeof (msg), "brick %s:%s, "
+ "path %s is not a directory", host, path, path);
+ gf_log ("", GF_LOG_ERROR, "%s", msg);
+ *op_errstr = gf_strdup (msg);
ret = -1;
goto out;
- }
-
- ret = sys_lsetxattr (path, GF_XATTR_VOL_ID_KEY, uuid, 16,
- XATTR_CREATE);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to set extended "
- "attributes %s, reason: %s",
- GF_XATTR_VOL_ID_KEY, strerror (errno));
+ } else if (!ret) {
goto out;
}
- ret = 0;
-out:
- if (strlen (msg))
+ ret = mkdir (path, mode);
+ if ((ret == -1) && (EEXIST != errno)) {
+ snprintf (msg, sizeof (msg), "brick: %s:%s, path "
+ "creation failed, reason: %s",
+ host, path, strerror(errno));
+ gf_log ("glusterd",GF_LOG_ERROR, "%s", msg);
*op_errstr = gf_strdup (msg);
+ } else {
+ ret = 0;
+ }
+out:
+ gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
return ret;
-
}
int
@@ -4556,8 +2945,9 @@ glusterd_sm_tr_log_transition_add_to_dict (dict_t *dict,
{
int ret = -1;
char key[512] = {0};
- char timestr[64] = {0,};
+ char timestr[256] = {0,};
char *str = NULL;
+ struct tm tm = {0};
GF_ASSERT (dict);
GF_ASSERT (log);
@@ -4586,8 +2976,9 @@ glusterd_sm_tr_log_transition_add_to_dict (dict_t *dict,
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "log%d-time", count);
- gf_time_fmt (timestr, sizeof timestr, log->transitions[i].time,
- gf_timefmt_FT);
+ localtime_r ((const time_t*)&log->transitions[i].time, &tm);
+ memset (timestr, 0, sizeof (timestr));
+ strftime (timestr, 256, "%Y-%m-%d %H:%M:%S", &tm);
str = gf_strdup (timestr);
ret = dict_set_dynstr (dict, key, str);
if (ret)
@@ -4675,7 +3066,8 @@ glusterd_sm_tr_log_delete (glusterd_sm_tr_log_t *log)
{
if (!log)
return;
- GF_FREE (log->transitions);
+ if (log->transitions)
+ GF_FREE (log->transitions);
return;
}
@@ -4773,7 +3165,8 @@ glusterd_peer_destroy (glusterd_peerinfo_t *peerinfo)
}
list_del_init (&peerinfo->uuid_list);
- GF_FREE (peerinfo->hostname);
+ if (peerinfo->hostname)
+ GF_FREE (peerinfo->hostname);
glusterd_sm_tr_log_delete (&peerinfo->sm_log);
GF_FREE (peerinfo);
peerinfo = NULL;
@@ -4789,7 +3182,7 @@ glusterd_remove_pending_entry (struct list_head *list, void *elem)
{
glusterd_pending_node_t *pending_node = NULL;
glusterd_pending_node_t *tmp = NULL;
- int ret = 0;
+ int ret = -1;
list_for_each_entry_safe (pending_node, tmp, list, list) {
if (elem == pending_node->node) {
@@ -4857,8 +3250,7 @@ glusterd_delete_brick (glusterd_volinfo_t* volinfo,
#ifdef DEBUG
ret = glusterd_volume_brickinfo_get (brickinfo->uuid,
brickinfo->hostname,
- brickinfo->path, volinfo,
- NULL);
+ brickinfo->path, volinfo, NULL);
GF_ASSERT (0 == ret);
#endif
glusterd_delete_volfile (volinfo, brickinfo);
@@ -4884,14 +3276,29 @@ glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo)
}
int
-glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
- char *glusterd_uuid_str, char **op_errstr)
+mkdir_if_missing (char *path)
+{
+ struct stat st = {0,};
+ int ret = 0;
+
+ ret = mkdir (path, 0777);
+ if (!ret || errno == EEXIST)
+ ret = stat (path, &st);
+ if (ret == -1 || !S_ISDIR (st.st_mode))
+ gf_log ("", GF_LOG_WARNING, "Failed to create the"
+ " directory %s", path);
+
+ return ret;
+}
+
+int
+glusterd_start_gsync (char *master, char *slave, char *uuid_str,
+ char **op_errstr)
{
int32_t ret = 0;
int32_t status = 0;
char buf[PATH_MAX] = {0,};
- char uuid_str [64] = {0};
- runner_t runner = {0,};
+ char local_uuid_str [64] = {0};
xlator_t *this = NULL;
glusterd_conf_t *priv = NULL;
int errcode = 0;
@@ -4901,51 +3308,41 @@ glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
priv = this->private;
GF_ASSERT (priv);
- uuid_utoa_r (MY_UUID, uuid_str);
- if (strcmp (uuid_str, glusterd_uuid_str))
+ uuid_utoa_r (priv->uuid, local_uuid_str);
+ if (strcmp (local_uuid_str, uuid_str))
goto out;
- ret = gsync_status (master_vol->volname, slave, &status);
+ ret = gsync_status (master, slave, &status);
if (status == 0)
goto out;
- snprintf (buf, PATH_MAX, "%s/"GEOREP"/%s", priv->workdir, master_vol->volname);
- ret = mkdir_p (buf, 0777, _gf_true);
+ snprintf (buf, PATH_MAX, "%s/"GEOREP"/%s", priv->workdir, master);
+ ret = mkdir_if_missing (buf);
if (ret) {
errcode = -1;
goto out;
}
snprintf (buf, PATH_MAX, DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/%s",
- master_vol->volname);
- ret = mkdir_p (buf, 0777, _gf_true);
+ master);
+ ret = mkdir_if_missing (buf);
if (ret) {
errcode = -1;
goto out;
}
- uuid_utoa_r (master_vol->volume_id, uuid_str);
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir);
- runner_argprintf (&runner, ":%s", master_vol->volname);
- runner_add_args (&runner, slave, "--config-set", "session-owner",
- uuid_str, NULL);
- ret = runner_run (&runner);
- if (ret == -1) {
+ ret = snprintf (buf, PATH_MAX, GSYNCD_PREFIX "/gsyncd --monitor -c "
+ "%s/"GSYNC_CONF" :%s %s", priv->workdir, master, slave);
+ if (ret <= 0) {
+ ret = -1;
errcode = -1;
goto out;
}
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--monitor", "-c", NULL);
- runner_argprintf (&runner, "%s/"GSYNC_CONF, priv->workdir);
- runner_argprintf (&runner, ":%s", master_vol->volname);
- runner_add_arg (&runner, slave);
- ret = runner_run (&runner);
+ ret = gf_system (buf);
if (ret == -1) {
gf_asprintf (op_errstr, GEOREP" start failed for %s %s",
- master_vol->volname, slave);
+ master, slave);
goto out;
}
@@ -4961,656 +3358,3 @@ out:
gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-
-int32_t
-glusterd_recreate_bricks (glusterd_conf_t *conf)
-{
-
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
-
- GF_ASSERT (conf);
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- ret = generate_brick_volfiles (volinfo);
- }
- return ret;
-}
-
-int32_t
-glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf)
-{
- int ret = 0;
- char *type = NULL;
- gf_boolean_t upgrade = _gf_false;
- gf_boolean_t downgrade = _gf_false;
- gf_boolean_t regenerate_brick_volfiles = _gf_false;
- gf_boolean_t terminate = _gf_false;
-
- ret = dict_get_str (options, "upgrade", &type);
- if (!ret) {
- ret = gf_string2boolean (type, &upgrade);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "upgrade option "
- "%s is not a valid boolean type", type);
- ret = -1;
- goto out;
- }
- if (_gf_true == upgrade)
- regenerate_brick_volfiles = _gf_true;
- }
-
- ret = dict_get_str (options, "downgrade", &type);
- if (!ret) {
- ret = gf_string2boolean (type, &downgrade);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "downgrade option "
- "%s is not a valid boolean type", type);
- ret = -1;
- goto out;
- }
- }
-
- if (upgrade && downgrade) {
- gf_log ("glusterd", GF_LOG_ERROR, "Both upgrade and downgrade"
- " options are set. Only one should be on");
- ret = -1;
- goto out;
- }
-
- if (!upgrade && !downgrade)
- ret = 0;
- else
- terminate = _gf_true;
- if (regenerate_brick_volfiles) {
- ret = glusterd_recreate_bricks (conf);
- }
-out:
- if (terminate && (ret == 0))
- kill (getpid(), SIGTERM);
- return ret;
-}
-
-gf_boolean_t
-glusterd_is_volume_replicate (glusterd_volinfo_t *volinfo)
-{
- gf_boolean_t replicates = _gf_false;
- if (volinfo && ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) ||
- (volinfo->type == GF_CLUSTER_TYPE_STRIPE_REPLICATE)))
- replicates = _gf_true;
- return replicates;
-}
-
-int
-glusterd_set_dump_options (char *dumpoptions_path, char *options,
- int option_cnt)
-{
- int ret = 0;
- char *dup_options = NULL;
- char *option = NULL;
- char *tmpptr = NULL;
- FILE *fp = NULL;
- int nfs_cnt = 0;
-
- if (0 == option_cnt ||
- (option_cnt == 1 && (!strcmp (options, "nfs ")))) {
- ret = 0;
- goto out;
- }
-
- fp = fopen (dumpoptions_path, "w");
- if (!fp) {
- ret = -1;
- goto out;
- }
- dup_options = gf_strdup (options);
- gf_log ("", GF_LOG_INFO, "Received following statedump options: %s",
- dup_options);
- option = strtok_r (dup_options, " ", &tmpptr);
- while (option) {
- if (!strcmp (option, "nfs")) {
- if (nfs_cnt > 0) {
- unlink (dumpoptions_path);
- ret = 0;
- goto out;
- }
- nfs_cnt++;
- option = strtok_r (NULL, " ", &tmpptr);
- continue;
- }
- fprintf (fp, "%s=yes\n", option);
- option = strtok_r (NULL, " ", &tmpptr);
- }
-
-out:
- if (fp)
- fclose (fp);
- GF_FREE (dup_options);
- return ret;
-}
-
-int
-glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- char *options, int option_cnt, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char pidfile_path[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- char dumpoptions_path[PATH_MAX] = {0,};
- FILE *pidfile = NULL;
- pid_t pid = -1;
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "Cannot resolve brick %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
- }
-
- if (uuid_compare (brickinfo->uuid, conf->uuid)) {
- ret = 0;
- goto out;
- }
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, conf);
- GLUSTERD_GET_BRICK_PIDFILE (pidfile_path, path, brickinfo->hostname,
- brickinfo->path);
-
- pidfile = fopen (pidfile_path, "r");
- if (!pidfile) {
- gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
- pidfile_path);
- ret = -1;
- goto out;
- }
-
- ret = fscanf (pidfile, "%d", &pid);
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to get pid of brick process");
- ret = -1;
- goto out;
- }
-
- snprintf (dumpoptions_path, sizeof (dumpoptions_path),
- "/tmp/glusterdump.%d.options", pid);
- ret = glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error while parsing the statedump "
- "options");
- ret = -1;
- goto out;
- }
-
- gf_log ("", GF_LOG_INFO, "Performing statedump on brick with pid %d",
- pid);
-
- kill (pid, SIGUSR1);
-
- sleep (1);
- ret = 0;
-out:
- unlink (dumpoptions_path);
- if (pidfile)
- fclose (pidfile);
- return ret;
-}
-
-int
-glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr)
-{
- int ret = -1;
- xlator_t *this = NULL;
- glusterd_conf_t *conf = NULL;
- char pidfile_path[PATH_MAX] = {0,};
- char path[PATH_MAX] = {0,};
- FILE *pidfile = NULL;
- pid_t pid = -1;
- char dumpoptions_path[PATH_MAX] = {0,};
- char *option = NULL;
- char *tmpptr = NULL;
- char *dup_options = NULL;
- char msg[256] = {0,};
-
- this = THIS;
- GF_ASSERT (this);
- conf = this->private;
- GF_ASSERT (conf);
-
- dup_options = gf_strdup (options);
- option = strtok_r (dup_options, " ", &tmpptr);
- if (strcmp (option, "nfs")) {
- snprintf (msg, sizeof (msg), "for nfs statedump, options should"
- " be after the key nfs");
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- GLUSTERD_GET_NFS_DIR (path, conf);
- GLUSTERD_GET_NFS_PIDFILE (pidfile_path, path);
-
- pidfile = fopen (pidfile_path, "r");
- if (!pidfile) {
- gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
- pidfile_path);
- ret = -1;
- goto out;
- }
-
- ret = fscanf (pidfile, "%d", &pid);
- if (ret <= 0) {
- gf_log ("", GF_LOG_ERROR, "Unable to get pid of brick process");
- ret = -1;
- goto out;
- }
-
- snprintf (dumpoptions_path, sizeof (dumpoptions_path),
- "/tmp/glusterdump.%d.options", pid);
- ret = glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
- if (ret < 0) {
- gf_log ("", GF_LOG_ERROR, "error while parsing the statedump "
- "options");
- ret = -1;
- goto out;
- }
-
- gf_log ("", GF_LOG_INFO, "Performing statedump on nfs server with "
- "pid %d", pid);
-
- kill (pid, SIGUSR1);
-
- sleep (1);
-
- ret = 0;
-out:
- if (pidfile)
- fclose (pidfile);
- unlink (dumpoptions_path);
- GF_FREE (dup_options);
- return ret;
-}
-
-/* Checks if the given peer contains all the bricks belonging to the
- * given volume. Returns true if it does else returns false
- */
-gf_boolean_t
-glusterd_friend_contains_vol_bricks (glusterd_volinfo_t *volinfo,
- uuid_t friend_uuid)
-{
- gf_boolean_t ret = _gf_true;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- GF_ASSERT (volinfo);
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- if (uuid_compare (friend_uuid, brickinfo->uuid)) {
- ret = _gf_false;
- break;
- }
- }
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* Remove all volumes which completely belong to given friend
- */
-int
-glusterd_friend_remove_cleanup_vols (uuid_t uuid)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_volinfo_t *tmp_volinfo = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- list_for_each_entry_safe (volinfo, tmp_volinfo,
- &priv->volumes, vol_list) {
- if (glusterd_friend_contains_vol_bricks (volinfo, uuid)) {
- gf_log (THIS->name, GF_LOG_INFO,
- "Deleting stale volume %s", volinfo->volname);
- ret = glusterd_delete_volume (volinfo);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Error deleting stale volume");
- goto out;
- }
- }
- }
- ret = 0;
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-/* Check if the all peers are connected and befriended, except the peer
- * specified (the peer being detached)
- */
-gf_boolean_t
-glusterd_chk_peers_connected_befriended (uuid_t skip_uuid)
-{
- gf_boolean_t ret = _gf_true;
- glusterd_peerinfo_t *peerinfo = NULL;
- glusterd_conf_t *priv = NULL;
-
- priv= THIS->private;
- GF_ASSERT (priv);
-
- list_for_each_entry (peerinfo, &priv->peers, uuid_list) {
-
- if (!uuid_is_null (skip_uuid) && !uuid_compare (skip_uuid,
- peerinfo->uuid))
- continue;
-
- if ((GD_FRIEND_STATE_BEFRIENDED != peerinfo->state.state)
- || !(peerinfo->connected)) {
- ret = _gf_false;
- break;
- }
- }
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %s",
- (ret?"TRUE":"FALSE"));
- return ret;
-}
-
-void
-glusterd_get_client_filepath (char *filepath, glusterd_volinfo_t *volinfo,
- gf_transport_type type)
-{
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
-
- if ((volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) &&
- (type == GF_TRANSPORT_RDMA))
- snprintf (filepath, PATH_MAX, "%s/%s.rdma-fuse.vol",
- path, volinfo->volname);
- else
- snprintf (filepath, PATH_MAX, "%s/%s-fuse.vol",
- path, volinfo->volname);
-}
-
-void
-glusterd_get_trusted_client_filepath (char *filepath,
- glusterd_volinfo_t *volinfo,
- gf_transport_type type)
-{
- char path[PATH_MAX] = {0,};
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
-
- if ((volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) &&
- (type == GF_TRANSPORT_RDMA))
- snprintf (filepath, PATH_MAX,
- "%s/trusted-%s.rdma-fuse.vol",
- path, volinfo->volname);
- else
- snprintf (filepath, PATH_MAX,
- "%s/trusted-%s-fuse.vol",
- path, volinfo->volname);
-}
-
-int
-glusterd_volume_defrag_restart (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, int cmd, defrag_cbk_fn_t cbk)
-{
- glusterd_conf_t *priv = NULL;
- char pidfile[PATH_MAX];
- int ret = -1;
- pid_t pid;
-
- priv = THIS->private;
- if (!priv)
- return ret;
-
- GLUSTERD_GET_DEFRAG_PID_FILE(pidfile, volinfo, priv);
-
- if (!glusterd_is_service_running (pidfile, &pid)) {
- glusterd_handle_defrag_start (volinfo, op_errstr, len, cmd,
- cbk);
- } else {
- glusterd_rebalance_rpc_create (volinfo, priv, cmd);
- }
-
- return ret;
-}
-
-int
-glusterd_restart_rebalance (glusterd_conf_t *conf)
-{
- glusterd_volinfo_t *volinfo = NULL;
- int ret = 0;
- char op_errstr[256];
-
- list_for_each_entry (volinfo, &conf->volumes, vol_list) {
- if (!volinfo->defrag_cmd)
- continue;
- glusterd_volume_defrag_restart (volinfo, op_errstr, 256,
- volinfo->defrag_cmd, NULL);
- }
- return ret;
-}
-
-
-void
-glusterd_volinfo_reset_defrag_stats (glusterd_volinfo_t *volinfo)
-{
- GF_ASSERT (volinfo);
-
- volinfo->rebalance_files = 0;
- volinfo->rebalance_data = 0;
- volinfo->lookedup_files = 0;
- volinfo->rebalance_failures = 0;
- volinfo->rebalance_time = 0;
-
-}
-
-/* Return hostname for given uuid if it exists
- * else return NULL
- */
-char *
-glusterd_uuid_to_hostname (uuid_t uuid)
-{
- char *hostname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_peerinfo_t *entry = NULL;
-
- priv = THIS->private;
- GF_ASSERT (priv);
-
- if (!uuid_compare (MY_UUID, uuid)) {
- hostname = gf_strdup ("localhost");
- }
- if (!list_empty (&priv->peers)) {
- list_for_each_entry (entry, &priv->peers, uuid_list) {
- if (!uuid_compare (entry->uuid, uuid)) {
- hostname = gf_strdup (entry->hostname);
- break;
- }
- }
- }
-
- return hostname;
-}
-
-gf_boolean_t
-glusterd_is_local_brick (xlator_t *this, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo)
-{
- gf_boolean_t local = _gf_false;
- int ret = 0;
- glusterd_conf_t *conf = NULL;
-
- if (uuid_is_null (brickinfo->uuid)) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret)
- goto out;
- }
- conf = this->private;
- local = !uuid_compare (brickinfo->uuid, conf->uuid);
-out:
- return local;
-}
-int
-glusterd_validate_volume_id (dict_t *op_dict, glusterd_volinfo_t *volinfo)
-{
- int ret = -1;
- char *volid_str = NULL;
- uuid_t vol_uid = {0, };
-
- ret = dict_get_str (op_dict, "vol-id", &volid_str);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get volume id");
- goto out;
- }
- ret = uuid_parse (volid_str, vol_uid);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to parse uuid");
- goto out;
- }
-
- if (uuid_compare (vol_uid, volinfo->volume_id)) {
- gf_log (THIS->name, GF_LOG_ERROR, "Volume ids are different. "
- "Possibly a split brain among peers.");
- ret = -1;
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_defrag_volume_status_update (glusterd_volinfo_t *volinfo,
- dict_t *rsp_dict)
-{
- int ret = 0;
- uint64_t files = 0;
- uint64_t size = 0;
- uint64_t lookup = 0;
- gf_defrag_status_t status = GF_DEFRAG_STATUS_NOT_STARTED;
- uint64_t failures = 0;
- xlator_t *this = NULL;
- double run_time = 0;
-
- this = THIS;
-
- ret = dict_get_uint64 (rsp_dict, "files", &files);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get file count");
-
- ret = dict_get_uint64 (rsp_dict, "size", &size);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get size of xfer");
-
- ret = dict_get_uint64 (rsp_dict, "lookups", &lookup);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get lookedup file count");
-
- ret = dict_get_int32 (rsp_dict, "status", (int32_t *)&status);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get status");
-
- ret = dict_get_uint64 (rsp_dict, "failures", &failures);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get failure count");
-
- ret = dict_get_double (rsp_dict, "run-time", &run_time);
- if (ret)
- gf_log (this->name, GF_LOG_TRACE,
- "failed to get run-time");
-
- if (files)
- volinfo->rebalance_files = files;
- if (size)
- volinfo->rebalance_data = size;
- if (lookup)
- volinfo->lookedup_files = lookup;
- if (status)
- volinfo->defrag_status = status;
- if (failures)
- volinfo->rebalance_failures = failures;
- if (run_time)
- volinfo->rebalance_time = run_time;
-
- return ret;
-}
-
-int
-glusterd_check_files_identical (char *filename1, char *filename2,
- gf_boolean_t *identical)
-{
- int ret = -1;
- struct stat buf1 = {0,};
- struct stat buf2 = {0,};
- uint32_t cksum1 = 0;
- uint32_t cksum2 = 0;
- xlator_t *this = NULL;
-
- GF_ASSERT (filename1);
- GF_ASSERT (filename2);
- GF_ASSERT (identical);
-
- this = THIS;
-
- ret = stat (filename1, &buf1);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "stat on file: %s failed "
- "(%s)", filename1, strerror (errno));
- goto out;
- }
-
- ret = stat (filename2, &buf2);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "stat on file: %s failed "
- "(%s)", filename2, strerror (errno));
- goto out;
- }
-
- if (buf1.st_size != buf2.st_size) {
- *identical = _gf_false;
- goto out;
- }
-
- ret = get_checksum_for_path (filename1, &cksum1);
- if (ret)
- goto out;
-
-
- ret = get_checksum_for_path (filename2, &cksum2);
- if (ret)
- goto out;
-
- if (cksum1 != cksum2)
- *identical = _gf_false;
- else
- *identical = _gf_true;
-
-out:
- gf_log (this->name, GF_LOG_DEBUG, "Returning with %d", ret);
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index c538345fd..7cf06f7ae 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -51,16 +51,11 @@ typedef struct glusterd_voldict_ctx_ {
char *val_name;
} glusterd_voldict_ctx_t;
-int
-glusterd_compare_lines (const void *a, const void *b);
-
typedef int (*glusterd_condition_func) (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
void *ctx);
-typedef struct glusterd_lock_ glusterd_lock_t;
-int32_t
-glusterd_get_lock_owner (uuid_t *cur_owner);
+typedef struct glusterd_lock_ glusterd_lock_t;
int32_t
glusterd_lock (uuid_t new_owner);
@@ -74,31 +69,17 @@ glusterd_get_uuid (uuid_t *uuid);
int
glusterd_submit_reply (rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc);
+ struct iobref *iobref, gd_serialize_t sfunc);
int
glusterd_submit_request (struct rpc_clnt *rpc, void *req,
call_frame_t *frame, rpc_clnt_prog_t *prog,
int procnum, struct iobref *iobref,
- xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc);
+ gd_serialize_t sfunc, xlator_t *this,
+ fop_cbk_fn_t cbkfn);
int32_t
glusterd_volinfo_new (glusterd_volinfo_t **volinfo);
-char *
-glusterd_auth_get_username (glusterd_volinfo_t *volinfo);
-
-char *
-glusterd_auth_get_password (glusterd_volinfo_t *volinfo);
-
-int32_t
-glusterd_auth_set_username (glusterd_volinfo_t *volinfo, char *username);
-
-int32_t
-glusterd_auth_set_password (glusterd_volinfo_t *volinfo, char *password);
-
-void
-glusterd_auth_cleanup (glusterd_volinfo_t *volinfo);
-
gf_boolean_t
glusterd_check_volume_exists (char *volname);
@@ -106,7 +87,7 @@ int32_t
glusterd_brickinfo_new (glusterd_brickinfo_t **brickinfo);
int32_t
-glusterd_brickinfo_new_from_brick (char *brick, glusterd_brickinfo_t **brickinfo);
+glusterd_brickinfo_from_brick (char *brick, glusterd_brickinfo_t **brickinfo);
int32_t
glusterd_friend_cleanup (glusterd_peerinfo_t *peerinfo);
@@ -148,7 +129,6 @@ int32_t
glusterd_volume_brickinfo_get_by_brick (char *brick,
glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t **brickinfo);
-
int32_t
glusterd_is_local_addr (char *hostname);
@@ -161,59 +141,15 @@ glusterd_compare_friend_data (dict_t *vols, int32_t *status);
int
glusterd_volume_compute_cksum (glusterd_volinfo_t *volinfo);
-void
-glusterd_get_nodesvc_volfile (char *server, char *workdir,
- char *volfile, size_t len);
-
-gf_boolean_t
-glusterd_is_service_running (char *pidfile, int *pid);
-
gf_boolean_t
-glusterd_is_nodesvc_running ();
+glusterd_is_nfs_started ();
-gf_boolean_t
-glusterd_is_nodesvc_running ();
-
-void
-glusterd_get_nodesvc_dir (char *server, char *workdir,
- char *path, size_t len);
int32_t
glusterd_nfs_server_start ();
int32_t
glusterd_nfs_server_stop ();
-int32_t
-glusterd_shd_start ();
-
-int32_t
-glusterd_shd_stop ();
-
-void
-glusterd_set_socket_filepath (char *sock_filepath, char *sockpath, size_t len);
-
-int32_t
-glusterd_nodesvc_set_socket_filepath (char *rundir, uuid_t uuid,
- char *socketpath, int len);
-
-struct rpc_clnt*
-glusterd_pending_node_get_rpc (glusterd_pending_node_t *pending_node);
-
-struct rpc_clnt*
-glusterd_nodesvc_get_rpc (char *server);
-
-int32_t
-glusterd_nodesvc_set_rpc (char *server, struct rpc_clnt *rpc);
-
-int32_t
-glusterd_nodesvc_connect (char *server, char *socketpath);
-
-void
-glusterd_nodesvc_set_running (char *server, gf_boolean_t status);
-
-gf_boolean_t
-glusterd_nodesvc_is_running (char *server);
-
int
glusterd_remote_hostname_get (rpcsvc_request_t *req,
char *remote_host, int len);
@@ -224,22 +160,6 @@ glusterd_set_volume_status (glusterd_volinfo_t *volinfo,
glusterd_volume_status status);
int
glusterd_check_generate_start_nfs (void);
-
-int
-glusterd_check_generate_start_shd (void);
-
-int
-glusterd_nodesvcs_handle_graph_change (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_nodesvcs_handle_reconfigure (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_nodesvcs_start (glusterd_volinfo_t *volinfo);
-
-int
-glusterd_nodesvcs_stop (glusterd_volinfo_t *volinfo);
-
int32_t
glusterd_volume_count_get (void);
int32_t
@@ -289,12 +209,10 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
char *op_errstr, size_t len);
int32_t
glusterd_volume_brickinfos_delete (glusterd_volinfo_t *volinfo);
-
int32_t
glusterd_volume_brickinfo_get (uuid_t uuid, char *hostname, char *path,
glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t **brickinfo);
-
int
glusterd_brickinfo_get (uuid_t uuid, char *hostname, char *path,
glusterd_brickinfo_t **brickinfo);
@@ -307,16 +225,14 @@ glusterd_is_rb_paused (glusterd_volinfo_t *volinfo);
int
glusterd_set_rb_status (glusterd_volinfo_t *volinfo, gf_rb_status_t status);
-gf_boolean_t
-glusterd_is_rb_ongoing (glusterd_volinfo_t *volinfo);
+int
+glusterd_is_replace_running (glusterd_volinfo_t *volinfo, glusterd_brickinfo_t *brickinfo);
int
glusterd_rb_check_bricks (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *src_brick,
- glusterd_brickinfo_t *dst_brick);
-
+ glusterd_brickinfo_t *src_brick, glusterd_brickinfo_t *dst_brick);
int
-glusterd_brick_create_path (char *host, char *path, uuid_t uuid,
+glusterd_brick_create_path (char *host, char *path, mode_t mode,
char **op_errstr);
int
glusterd_sm_tr_log_transition_add (glusterd_sm_tr_log_t *log,
@@ -358,87 +274,6 @@ glusterd_delete_all_bricks (glusterd_volinfo_t* volinfo);
int
glusterd_restart_gsyncds (glusterd_conf_t *conf);
int
-glusterd_start_gsync (glusterd_volinfo_t *master_vol, char *slave,
- char *glusterd_uuid_str, char **op_errstr);
-int32_t
-glusterd_recreate_bricks (glusterd_conf_t *conf);
-int32_t
-glusterd_handle_upgrade_downgrade (dict_t *options, glusterd_conf_t *conf);
-
-int
-glusterd_add_brick_detail_to_dict (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int32_t count);
-
-int32_t
-glusterd_add_brick_to_dict (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- dict_t *dict, int32_t count);
-
-int32_t
-glusterd_get_all_volnames (dict_t *dict);
-
-gf_boolean_t
-glusterd_is_fuse_available ();
-
-int
-glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo,
- char *options, int option_cnt, char **op_errstr);
-int
-glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr);
-gf_boolean_t
-glusterd_is_volume_replicate (glusterd_volinfo_t *volinfo);
-gf_boolean_t
-glusterd_is_brick_decommissioned (glusterd_volinfo_t *volinfo, char *hostname,
- char *path);
-gf_boolean_t
-glusterd_friend_contains_vol_bricks (glusterd_volinfo_t *volinfo,
- uuid_t friend_uuid);
-int
-glusterd_friend_remove_cleanup_vols (uuid_t uuid);
-
-gf_boolean_t
-glusterd_chk_peers_connected_befriended (uuid_t skip_uuid);
-
-void
-glusterd_get_client_filepath (char *filepath,
- glusterd_volinfo_t *volinfo,
- gf_transport_type type);
-void
-glusterd_get_trusted_client_filepath (char *filepath,
- glusterd_volinfo_t *volinfo,
- gf_transport_type type);
-int
-glusterd_restart_rebalance (glusterd_conf_t *conf);
-
-int32_t
-glusterd_add_bricks_hname_path_to_dict (dict_t *dict,
- glusterd_volinfo_t *volinfo);
-
-int
-glusterd_add_node_to_dict (char *server, dict_t *dict, int count,
- dict_t *vol_opts);
-
-char *
-glusterd_uuid_to_hostname (uuid_t uuid);
-
-glusterd_brickinfo_t*
-glusterd_get_brickinfo_by_position (glusterd_volinfo_t *volinfo, uint32_t pos);
-
-gf_boolean_t
-glusterd_is_local_brick (xlator_t *this, glusterd_volinfo_t *volinfo,
- glusterd_brickinfo_t *brickinfo);
-int
-glusterd_validate_volume_id (dict_t *op_dict, glusterd_volinfo_t *volinfo);
-
-int
-glusterd_defrag_volume_status_update (glusterd_volinfo_t *volinfo,
- dict_t *rsp_dict);
-
-int
-glusterd_check_files_identical (char *filename1, char *filename2,
- gf_boolean_t *identical);
-void
-glusterd_volinfo_reset_defrag_stats (glusterd_volinfo_t *volinfo);
+glusterd_start_gsync (char *master, char *slave, char *uuid_str,
+ char **op_errstr);
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
index 099f55700..f7f3ddd11 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ GlusterFS is GF_FREE software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -24,12 +24,6 @@
#endif
#include <fnmatch.h>
-#include <sys/wait.h>
-
-#if (HAVE_LIB_XML)
-#include <libxml/encoding.h>
-#include <libxml/xmlwriter.h>
-#endif
#include "xlator.h"
#include "glusterd.h"
@@ -39,18 +33,9 @@
#include "graph-utils.h"
#include "trie.h"
#include "glusterd-mem-types.h"
-#include "cli1-xdr.h"
+#include "cli1.h"
#include "glusterd-volgen.h"
#include "glusterd-op-sm.h"
-#include "glusterd-utils.h"
-#include "run.h"
-
-#define AUTH_ALLOW_MAP_KEY "auth.allow"
-#define AUTH_REJECT_MAP_KEY "auth.reject"
-#define NFS_DISABLE_MAP_KEY "nfs.disable"
-#define AUTH_ALLOW_OPT_KEY "auth.addr.*.allow"
-#define AUTH_REJECT_OPT_KEY "auth.addr.*.reject"
-#define NFS_DISABLE_OPT_KEY "nfs.*.disable"
/* dispatch table for VOLUME SET
@@ -118,130 +103,85 @@ static struct volopt_map_entry glusterd_volopt_map[] = {
{"cluster.lookup-unhashed", "cluster/distribute", NULL, NULL, NO_DOC, 0 },
{"cluster.min-free-disk", "cluster/distribute", NULL, NULL, NO_DOC, 0 },
- {"cluster.min-free-inodes", "cluster/distribute", NULL, NULL, NO_DOC, 0 },
- {"cluster.rebalance-stats", "cluster/distribute", NULL, NULL, NO_DOC, 0 },
- {"cluster.subvols-per-directory", "cluster/distribute", "directory-layout-spread", NULL, NO_DOC, 0 },
{"cluster.entry-change-log", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.read-subvolume", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
- {"cluster.read-subvolume-index", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
- {"cluster.read-hash-mode", "cluster/replicate", NULL, NULL, NO_DOC, 0},
{"cluster.background-self-heal-count", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.metadata-self-heal", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.data-self-heal", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.entry-self-heal", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
- {"cluster.self-heal-daemon", "cluster/replicate", "!self-heal-daemon" , NULL, NO_DOC, 0 },
- {"cluster.heal-timeout", "cluster/replicate", "!heal-timeout" , NULL, NO_DOC, 0 },
{"cluster.strict-readdir", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.self-heal-window-size", "cluster/replicate", "data-self-heal-window-size", NULL, DOC, 0},
{"cluster.data-change-log", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.metadata-change-log", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
{"cluster.data-self-heal-algorithm", "cluster/replicate", "data-self-heal-algorithm", NULL,DOC, 0},
- {"cluster.eager-lock", "cluster/replicate", NULL, NULL, NO_DOC, 0 },
- {"cluster.quorum-type", "cluster/replicate", "quorum-type", NULL, NO_DOC, 0},
- {"cluster.quorum-count", "cluster/replicate", "quorum-count", NULL, NO_DOC, 0},
- {"cluster.choose-local", "cluster/replicate", NULL, NULL, DOC, 0},
-
- {"cluster.stripe-block-size", "cluster/stripe", "block-size", NULL, DOC, 0},
- {"cluster.stripe-coalesce", "cluster/stripe", "coalesce", NULL, DOC, 0},
- {VKEY_DIAG_LAT_MEASUREMENT, "debug/io-stats", "latency-measurement", "off", NO_DOC, 0},
- {"diagnostics.dump-fd-stats", "debug/io-stats", NULL, NULL, NO_DOC, 0},
- {VKEY_DIAG_CNT_FOP_HITS, "debug/io-stats", "count-fop-hits", "off", NO_DOC, 0},
+ {"cluster.stripe-block-size", "cluster/stripe", "block-size", NULL, DOC, 0},
- {"diagnostics.brick-log-level", "debug/io-stats", "!brick-log-level", NULL, DOC, 0},
- {"diagnostics.client-log-level", "debug/io-stats", "!client-log-level", NULL, DOC, 0},
- {"diagnostics.brick-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0},
- {"diagnostics.client-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0},
+ {VKEY_DIAG_LAT_MEASUREMENT, "debug/io-stats", "latency-measurement", "off", NO_DOC, 0 },
+ {"diagnostics.dump-fd-stats", "debug/io-stats", NULL, NULL, NO_DOC, 0 },
+ {VKEY_DIAG_CNT_FOP_HITS, "debug/io-stats", "count-fop-hits", "off", NO_DOC, 0 },
+ {"diagnostics.brick-log-level", "debug/io-stats", "!log-level", NULL, DOC, 0},
+ {"diagnostics.client-log-level", "debug/io-stats", "!log-level", NULL, DOC, 0},
{"performance.cache-max-file-size", "performance/io-cache", "max-file-size", NULL, DOC, 0},
{"performance.cache-min-file-size", "performance/io-cache", "min-file-size", NULL, DOC, 0},
{"performance.cache-refresh-timeout", "performance/io-cache", "cache-timeout", NULL, DOC, 0},
{"performance.cache-priority", "performance/io-cache", "priority", NULL, DOC, 0},
- {"performance.cache-size", "performance/io-cache", NULL, NULL, NO_DOC, 0 },
- {"performance.cache-size", "performance/quick-read", NULL, NULL, NO_DOC, 0 },
- {"performance.flush-behind", "performance/write-behind", "flush-behind", NULL, DOC, 0},
- {"performance.md-cache-timeout", "performance/md-cache", "md-cache-timeout", NULL, DOC, 0},
-
- {"performance.io-thread-count", "performance/io-threads", "thread-count", NULL, DOC, 0},
- {"performance.high-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0},
- {"performance.normal-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0},
- {"performance.low-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0},
- {"performance.least-prio-threads", "performance/io-threads", NULL, NULL, DOC, 0},
- {"performance.enable-least-priority", "performance/io-threads", NULL, NULL, DOC, 0},
- {"performance.disk-usage-limit", "performance/quota", NULL, NULL, NO_DOC, 0},
- {"performance.min-free-disk-limit", "performance/quota", NULL, NULL, NO_DOC, 0},
+ {"performance.cache-size", "performance/io-cache", NULL, NULL, NO_DOC, 0 },
+ {"performance.cache-size", "performance/quick-read", NULL, NULL, NO_DOC, 0 },
+ {"performance.flush-behind", "performance/write-behind", "flush-behind", NULL, DOC, 0},
+
+ {"performance.io-thread-count", "performance/io-threads", "thread-count", DOC, 0},
+
+ {"performance.disk-usage-limit", "performance/quota", NULL, NULL, NO_DOC, 0 },
+ {"performance.min-free-disk-limit", "performance/quota", NULL, NULL, NO_DOC, 0 },
+
{"performance.write-behind-window-size", "performance/write-behind", "cache-size", NULL, DOC},
- {"performance.read-ahead-page-count", "performance/read-ahead", "page-count", NULL, DOC},
- {"network.frame-timeout", "protocol/client", NULL, NULL, NO_DOC, 0},
- {"network.ping-timeout", "protocol/client", NULL, NULL, NO_DOC, 0},
- {"network.tcp-window-size", "protocol/client", NULL, NULL, NO_DOC, 0},
- { "client.ssl", "protocol/client", "transport.socket.ssl-enabled", NULL, NO_DOC, 0},
+ {"network.frame-timeout", "protocol/client", NULL, NULL, NO_DOC, 0 },
+ {"network.ping-timeout", "protocol/client", NULL, NULL, NO_DOC, 0 },
+ {"network.inode-lru-limit", "protocol/server", NULL, NULL, NO_DOC, 0 },
+
+ {"auth.allow", "protocol/server", "!server-auth", "*", DOC, 0},
+ {"auth.reject", "protocol/server", "!server-auth", NULL, DOC, 0},
- {"network.tcp-window-size", "protocol/server", NULL, NULL, NO_DOC, 0},
- {"network.inode-lru-limit", "protocol/server", NULL, NULL, NO_DOC, 0},
- {AUTH_ALLOW_MAP_KEY, "protocol/server", "!server-auth", "*", DOC, 0},
- {AUTH_REJECT_MAP_KEY, "protocol/server", "!server-auth", NULL, DOC, 0},
- {"transport.keepalive", "protocol/server", "transport.socket.keepalive", NULL, NO_DOC, 0},
- {"server.allow-insecure", "protocol/server", "rpc-auth-allow-insecure", NULL, NO_DOC, 0},
- { "server.ssl", "protocol/server", "transport.socket.ssl-enabled", NULL, NO_DOC, 0},
+ {"transport.keepalive", "protocol/server", "transport.socket.keepalive", NULL, NO_DOC, 0},
+ {"server.allow-insecure", "protocol/server", "rpc-auth-allow-insecure", NULL, NO_DOC, 0},
{"performance.write-behind", "performance/write-behind", "!perf", "on", NO_DOC, 0},
{"performance.read-ahead", "performance/read-ahead", "!perf", "on", NO_DOC, 0},
{"performance.io-cache", "performance/io-cache", "!perf", "on", NO_DOC, 0},
{"performance.quick-read", "performance/quick-read", "!perf", "on", NO_DOC, 0},
- {VKEY_PERF_STAT_PREFETCH, "performance/md-cache", "!perf", "on", NO_DOC, 0},
- {"performance.client-io-threads", "performance/io-threads", "!perf", "off", NO_DOC, 0},
-
- {"performance.nfs.write-behind", "performance/write-behind", "!nfsperf", "off", NO_DOC, 0},
- {"performance.nfs.read-ahead", "performance/read-ahead", "!nfsperf", "off", NO_DOC, 0},
- {"performance.nfs.io-cache", "performance/io-cache", "!nfsperf", "off", NO_DOC, 0},
- {"performance.nfs.quick-read", "performance/quick-read", "!nfsperf", "off", NO_DOC, 0},
- {"performance.nfs.stat-prefetch", "performance/md-cache", "!nfsperf", "off", NO_DOC, 0},
- {"performance.nfs.io-threads", "performance/io-threads", "!nfsperf", "off", NO_DOC, 0},
+ {VKEY_PERF_STAT_PREFETCH, "performance/stat-prefetch", "!perf", "on", NO_DOC, 0},
{VKEY_MARKER_XTIME, "features/marker", "xtime", "off", NO_DOC, OPT_FLAG_FORCE},
{VKEY_MARKER_XTIME, "features/marker", "!xtime", "off", NO_DOC, OPT_FLAG_FORCE},
- {"debug.trace", "debug/trace", "!debug","off", NO_DOC, 0},
- {"debug.error-gen", "debug/error-gen", "!debug","off", NO_DOC, 0},
{"nfs.enable-ino32", "nfs/server", "nfs.enable-ino32", NULL, GLOBAL_DOC, 0},
{"nfs.mem-factor", "nfs/server", "nfs.mem-factor", NULL, GLOBAL_DOC, 0},
{"nfs.export-dirs", "nfs/server", "nfs3.export-dirs", NULL, GLOBAL_DOC, 0},
{"nfs.export-volumes", "nfs/server", "nfs3.export-volumes", NULL, GLOBAL_DOC, 0},
{"nfs.addr-namelookup", "nfs/server", "rpc-auth.addr.namelookup", NULL, GLOBAL_DOC, 0},
- {"nfs.dynamic-volumes", "nfs/server", "nfs.dynamic-volumes", NULL, GLOBAL_NO_DOC, 0},
+ {"nfs.dynamic-volumes", "nfs/server", "nfs.dynamic-volumes", NULL, GLOBAL_DOC, 0},
{"nfs.register-with-portmap", "nfs/server", "rpc.register-with-portmap", NULL, GLOBAL_DOC, 0},
{"nfs.port", "nfs/server", "nfs.port", NULL, GLOBAL_DOC, 0},
- {"nfs.rpc-auth-unix", "nfs/server", "!rpc-auth.auth-unix.*", NULL, DOC, 0},
- {"nfs.rpc-auth-null", "nfs/server", "!rpc-auth.auth-null.*", NULL, DOC, 0},
- {"nfs.rpc-auth-allow", "nfs/server", "!rpc-auth.addr.*.allow", NULL, DOC, 0},
- {"nfs.rpc-auth-reject", "nfs/server", "!rpc-auth.addr.*.reject", NULL, DOC, 0},
- {"nfs.ports-insecure", "nfs/server", "!rpc-auth.ports.*.insecure", NULL, DOC, 0},
- {"nfs.transport-type", "nfs/server", "!nfs.transport-type", NULL, DOC, 0},
-
- {"nfs.trusted-sync", "nfs/server", "!nfs3.*.trusted-sync", NULL, DOC, 0},
- {"nfs.trusted-write", "nfs/server", "!nfs3.*.trusted-write", NULL, DOC, 0},
- {"nfs.volume-access", "nfs/server", "!nfs3.*.volume-access", NULL, DOC, 0},
- {"nfs.export-dir", "nfs/server", "!nfs3.*.export-dir", NULL, DOC, 0},
- {NFS_DISABLE_MAP_KEY, "nfs/server", "!nfs-disable", NULL, DOC, 0},
- {"nfs.nlm", "nfs/server", "nfs.nlm", NULL, GLOBAL_DOC, 0},
- {"nfs.mount-udp", "nfs/server", "nfs.mount-udp", NULL, GLOBAL_DOC, 0},
- {"nfs.server-aux-gids", "nfs/server", "nfs.server-aux-gids", NULL, NO_DOC, 0},
+ {"nfs.rpc-auth-unix", "nfs/server", "!nfs.rpc-auth-auth-unix", NULL, DOC, 0},
+ {"nfs.rpc-auth-null", "nfs/server", "!nfs.rpc-auth-auth-null", NULL, DOC, 0},
+ {"nfs.rpc-auth-allow", "nfs/server", "!nfs.rpc-auth.addr.allow", NULL, DOC, 0},
+ {"nfs.rpc-auth-reject", "nfs/server", "!nfs.rpc-auth.addr.reject", NULL, DOC, 0},
+ {"nfs.ports-insecure", "nfs/server", "!nfs.auth.ports.insecure", NULL, DOC, 0},
+
+ {"nfs.trusted-sync", "nfs/server", "!nfs-trusted-sync", NULL, DOC, 0},
+ {"nfs.trusted-write", "nfs/server", "!nfs-trusted-write", NULL, DOC, 0},
+ {"nfs.volume-access", "nfs/server", "!nfs-volume-access", NULL, DOC, 0},
+ {"nfs.export-dir", "nfs/server", "!nfs-export-dir", NULL, DOC, 0},
+ {"nfs.disable", "nfs/server", "!nfs-disable", NULL, DOC, 0},
{VKEY_FEATURES_QUOTA, "features/marker", "quota", "off", NO_DOC, OPT_FLAG_FORCE},
{VKEY_FEATURES_LIMIT_USAGE, "features/quota", "limit-set", NULL, NO_DOC, 0},
- {"features.quota-timeout", "features/quota", "timeout", "0", DOC, 0},
- {"server.statedump-path", "protocol/server", "statedump-path", NULL, DOC, 0},
- {"features.lock-heal", "protocol/client", "lk-heal", NULL, NO_DOC, 0},
- {"features.lock-heal", "protocol/server", "lk-heal", NULL, DOC, 0},
- {"features.grace-timeout", "protocol/client", "grace-timeout", NULL, NO_DOC, 0},
- {"features.grace-timeout", "protocol/server", "grace-timeout", NULL, DOC, 0},
- {"features.read-only", "features/read-only", "!read-only", "off", DOC, 0},
- {"features.worm", "features/worm", "!worm", "off", DOC, 0},
- {"storage.linux-aio", "storage/posix", NULL, NULL, DOC, 0},
+ {"features.quota-timeout", "features/quota", "timeout", "0", NO_DOC, 0},
{NULL, }
};
@@ -300,7 +240,8 @@ xlator_instantiate_va (const char *type, const char *format, va_list arg)
error:
gf_log ("", GF_LOG_ERROR, "creating xlator of type %s failed",
type);
- GF_FREE (volname);
+ if (volname)
+ GF_FREE (volname);
if (xl)
xlator_destroy (xl);
@@ -431,13 +372,6 @@ xlator_set_option (xlator_t *xl, char *key, char *value)
return dict_set_dynstr (xl->options, key, dval);
}
-static int
-xlator_get_option (xlator_t *xl, char *key, char **value)
-{
- GF_ASSERT (xl);
- return dict_get_str (xl->options, key, value);
-}
-
static inline xlator_t *
first_of (volgen_graph_t *graph)
{
@@ -623,7 +557,8 @@ volopt_trie (char *key, char **hint)
}
out:
- GF_FREE (patt[0]);
+ if (patt[0])
+ GF_FREE (patt[0]);
if (ret)
*hint = NULL;
@@ -740,35 +675,25 @@ volgen_graph_set_options_generic (volgen_graph_t *graph, dict_t *dict,
}
static int
-no_filter_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
+basic_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
+ void *param)
{
xlator_t *trav;
int ret = 0;
+ if (vme->option[0] == '!')
+ return 0;
+
for (trav = first_of (graph); trav; trav = trav->next) {
if (strcmp (trav->type, vme->voltype) != 0)
continue;
ret = xlator_set_option (trav, vme->option, vme->value);
if (ret)
- break;
+ return -1;
}
- return ret;
-}
-
-static int
-basic_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- int ret = 0;
-
- if (vme->option[0] == '!')
- goto out;
- ret = no_filter_option_handler (graph, vme, param);
-out:
- return ret;
+ return 0;
}
static int
@@ -790,42 +715,6 @@ optget_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
return 0;
}
-int
-check_and_add_debug_xl (volgen_graph_t *graph, dict_t *set_dict, char *volname,
- char *xlname)
-{
- int ret = 0;
- xlator_t *xl = NULL;
- char *value_str = NULL;
-
- ret = dict_get_str (set_dict, "debug.trace", &value_str);
- if (!ret) {
- if (strcmp (xlname, value_str) == 0) {
- xl = volgen_graph_add (graph, "debug/trace", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
- }
-
- ret = dict_get_str (set_dict, "debug.error-gen", &value_str);
- if (!ret) {
- if (strcmp (xlname, value_str) == 0) {
- xl = volgen_graph_add (graph, "debug/error-gen", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
/* This getter considers defaults also. */
static int
volgen_dict_get (dict_t *dict, char *key, char **value)
@@ -914,7 +803,20 @@ glusterd_check_voloption_flags (char *key, int32_t flags)
struct volopt_map_entry *vmep = NULL;
int ret = 0;
- COMPLETE_OPTION(key, completion, ret);
+ if (!strchr (key, '.')) {
+ ret = option_complete (key, &completion);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ return _gf_false;
+ }
+
+ if (!completion) {
+ gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+ key);
+ return _gf_false;
+ }
+ }
+
for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
if (strcmp (vmep->key, key) == 0) {
if (vmep->flags & flags)
@@ -934,7 +836,20 @@ glusterd_check_globaloption (char *key)
struct volopt_map_entry *vmep = NULL;
int ret = 0;
- COMPLETE_OPTION(key, completion, ret);
+ if (!strchr (key, '.')) {
+ ret = option_complete (key, &completion);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ return _gf_false;
+ }
+
+ if (!completion) {
+ gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+ key);
+ return _gf_false;
+ }
+ }
+
for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
if (strcmp (vmep->key, key) == 0) {
if ((vmep->type == GLOBAL_DOC) ||
@@ -955,7 +870,20 @@ glusterd_check_localoption (char *key)
struct volopt_map_entry *vmep = NULL;
int ret = 0;
- COMPLETE_OPTION(key, completion, ret);
+ if (!strchr (key, '.')) {
+ ret = option_complete (key, &completion);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ return _gf_false;
+ }
+
+ if (!completion) {
+ gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+ key);
+ return _gf_false;
+ }
+ }
+
for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
if (strcmp (vmep->key, key) == 0) {
if ((vmep->type == DOC) ||
@@ -976,7 +904,20 @@ glusterd_check_voloption (char *key)
struct volopt_map_entry *vmep = NULL;
int ret = 0;
- COMPLETE_OPTION(key, completion, ret);
+ if (!strchr (key, '.')) {
+ ret = option_complete (key, &completion);
+ if (ret) {
+ gf_log ("", GF_LOG_ERROR, "Out of memory");
+ return _gf_false;
+ }
+
+ if (!completion) {
+ gf_log ("", GF_LOG_ERROR, "option %s does not exist",
+ key);
+ return _gf_false;
+ }
+ }
+
for (vmep = glusterd_volopt_map; vmep->key; vmep++) {
if (strcmp (vmep->key, key) == 0) {
if ((vmep->type == DOC) ||
@@ -1064,67 +1005,21 @@ glusterd_check_option_exists (char *key, char **completion)
ret = volopt_trie (key, completion);
if (ret) {
gf_log ("", GF_LOG_ERROR,
- "Some error occurred during keyword hinting");
+ "Some error occured during keyword hinting");
}
return ret;
}
-char*
-glusterd_get_trans_type_rb (gf_transport_type ttype)
-{
- char *trans_type = NULL;
-
- switch (ttype) {
- case GF_TRANSPORT_RDMA:
- gf_asprintf (&trans_type, "rdma");
- break;
- case GF_TRANSPORT_TCP:
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- gf_asprintf (&trans_type, "tcp");
- break;
- default:
- gf_log (THIS->name, GF_LOG_ERROR, "Unknown "
- "transport type");
- }
-
- return trans_type;
-}
-
static int
-_xl_link_children (xlator_t *parent, xlator_t *children, size_t child_count)
-{
- xlator_t *trav = NULL;
- size_t seek = 0;
- int ret = -1;
-
- if (child_count == 0)
- goto out;
- seek = child_count;
- for (trav = children; --seek; trav = trav->next);
- for (; child_count--; trav = trav->prev) {
- ret = volgen_xlator_link (parent, trav);
- if (ret)
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
-static int
-volgen_graph_merge_sub (volgen_graph_t *dgraph, volgen_graph_t *sgraph,
- size_t child_count)
+volgen_graph_merge_sub (volgen_graph_t *dgraph, volgen_graph_t *sgraph)
{
xlator_t *trav = NULL;
- int ret = 0;
GF_ASSERT (dgraph->graph.first);
- ret = _xl_link_children (first_of (dgraph), first_of (sgraph),
- child_count);
- if (ret)
- goto out;
+ if (volgen_xlator_link (first_of (dgraph), first_of (sgraph)) == -1)
+ return -1;
for (trav = first_of (dgraph); trav->next; trav = trav->next);
@@ -1132,72 +1027,14 @@ volgen_graph_merge_sub (volgen_graph_t *dgraph, volgen_graph_t *sgraph,
trav->next->prev = trav;
dgraph->graph.xl_count += sgraph->graph.xl_count;
-out:
- return ret;
-}
-
-static void
-volgen_apply_filters (char *orig_volfile)
-{
- DIR *filterdir = NULL;
- struct dirent entry = {0,};
- struct dirent *next = NULL;
- char *filterpath = NULL;
- struct stat statbuf = {0,};
-
- filterdir = opendir(FILTERDIR);
- if (!filterdir) {
- return;
- }
-
- while ((readdir_r(filterdir,&entry,&next) == 0) && next) {
- if (!strncmp(entry.d_name,".",sizeof(entry.d_name))) {
- continue;
- }
- if (!strncmp(entry.d_name,"..",sizeof(entry.d_name))) {
- continue;
- }
- /*
- * d_type isn't guaranteed to be present/valid on all systems,
- * so do an explicit stat instead.
- */
- if (gf_asprintf(&filterpath,"%s/%.*s",FILTERDIR,
- sizeof(entry.d_name), entry.d_name) == (-1)) {
- continue;
- }
- /* Deliberately use stat instead of lstat to allow symlinks. */
- if (stat(filterpath,&statbuf) == (-1)) {
- goto free_fp;
- }
- if (!S_ISREG(statbuf.st_mode)) {
- goto free_fp;
- }
- /*
- * We could check the mode in statbuf directly, or just skip
- * this entirely and check for EPERM after exec fails, but this
- * is cleaner.
- */
- if (access(filterpath,X_OK) != 0) {
- goto free_fp;
- }
- if (runcmd(filterpath,orig_volfile,NULL)) {
- gf_log("",GF_LOG_ERROR,"failed to run filter %.*s",
- (int)sizeof(entry.d_name), entry.d_name);
- }
-free_fp:
- GF_FREE(filterpath);
- }
+ return 0;
}
static int
volgen_write_volfile (volgen_graph_t *graph, char *filename)
{
- char *ftmp = NULL;
- FILE *f = NULL;
- int fd = 0;
- xlator_t *this = NULL;
-
- this = THIS;
+ char *ftmp = NULL;
+ FILE *f = NULL;
if (gf_asprintf (&ftmp, "%s.tmp", filename) == -1) {
ftmp = NULL;
@@ -1205,15 +1042,6 @@ volgen_write_volfile (volgen_graph_t *graph, char *filename)
goto error;
}
- fd = creat (ftmp, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- gf_log (this->name, GF_LOG_ERROR, "%s",
- strerror (errno));
- goto error;
- }
-
- close (fd);
-
f = fopen (ftmp, "w");
if (!f)
goto error;
@@ -1221,19 +1049,8 @@ volgen_write_volfile (volgen_graph_t *graph, char *filename)
if (glusterfs_graph_print_file (f, &graph->graph) == -1)
goto error;
- if (fclose (f) != 0) {
- gf_log (THIS->name, GF_LOG_ERROR, "fclose on the file %s "
- "failed (%s)", ftmp, strerror (errno));
- /*
- * Even though fclose has failed here, we have to set f to NULL.
- * Otherwise when the code path goes to error, there again we
- * try to close it which might cause undefined behavior such as
- * process crash.
- */
- f = NULL;
+ if (fclose (f) == -1)
goto error;
- }
-
f = NULL;
if (rename (ftmp, filename) == -1)
@@ -1241,18 +1058,16 @@ volgen_write_volfile (volgen_graph_t *graph, char *filename)
GF_FREE (ftmp);
- volgen_apply_filters(filename);
-
return 0;
error:
- GF_FREE (ftmp);
+ if (ftmp)
+ GF_FREE (ftmp);
if (f)
fclose (f);
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create volfile %s", filename);
+ gf_log ("", GF_LOG_ERROR, "failed to create volfile %s", filename);
return -1;
}
@@ -1288,11 +1103,10 @@ build_graph_generic (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
set_dict = dict_copy (volinfo->dict, NULL);
if (!set_dict)
return -1;
- dict_copy (mod_dict, set_dict);
- /* XXX dict_copy swallows errors */
- } else {
+ dict_copy (mod_dict, set_dict);
+ /* XXX dict_copy swallows errors */
+ } else
set_dict = volinfo->dict;
- }
ret = builder (graph, volinfo, set_dict, param);
if (!ret)
@@ -1304,24 +1118,10 @@ build_graph_generic (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
return ret;
}
-static gf_transport_type
-transport_str_to_type (char *tt)
-{
- gf_transport_type type = GF_TRANSPORT_TCP;
-
- if (!strcmp ("tcp", tt))
- type = GF_TRANSPORT_TCP;
- else if (!strcmp ("rdma", tt))
- type = GF_TRANSPORT_RDMA;
- else if (!strcmp ("tcp,rdma", tt))
- type = GF_TRANSPORT_BOTH_TCP_RDMA;
- return type;
-}
-
static void
-transport_type_to_str (gf_transport_type type, char *tt)
+get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt)
{
- switch (type) {
+ switch (volinfo->transport_type) {
case GF_TRANSPORT_RDMA:
strcpy (tt, "rdma");
break;
@@ -1334,54 +1134,6 @@ transport_type_to_str (gf_transport_type type, char *tt)
}
}
-static void
-get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt)
-{
- transport_type_to_str (volinfo->transport_type, tt);
-}
-
-static void
-get_vol_nfs_transport_type (glusterd_volinfo_t *volinfo, char *tt)
-{
- if (volinfo->nfs_transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
- gf_log ("", GF_LOG_ERROR, "%s:nfs transport cannot be both"
- " tcp and rdma", volinfo->volname);
- GF_ASSERT (0);
- }
- transport_type_to_str (volinfo->nfs_transport_type, tt);
-}
-
-/* gets the volinfo, dict, a character array for filling in
- * the transport type and a boolean option which says whether
- * the transport type is required for nfs or not. If its not
- * for nfs, then it is considered as the client transport
- * and client transport type is filled in the character array
- */
-static void
-get_transport_type (glusterd_volinfo_t *volinfo, dict_t *set_dict,
- char *transt, gf_boolean_t is_nfs)
-{
- int ret = -1;
- char *tt = NULL;
- char *key = NULL;
- typedef void (*transport_type) (glusterd_volinfo_t *volinfo, char *tt);
- transport_type get_transport;
-
- if (is_nfs == _gf_false) {
- key = "client-transport-type";
- get_transport = get_vol_transport_type;
- } else {
- key = "nfs.transport-type";
- get_transport = get_vol_nfs_transport_type;
- }
-
- ret = dict_get_str (set_dict, key, &tt);
- if (ret)
- get_transport (volinfo, transt);
- if (!ret)
- strcpy (transt, tt);
-}
-
static int
server_auth_option_handler (volgen_graph_t *graph,
struct volopt_map_entry *vme, void *param)
@@ -1421,9 +1173,8 @@ loglevel_option_handler (volgen_graph_t *graph,
char *role = param;
struct volopt_map_entry vme2 = {0,};
- if ( (strcmp (vme->option, "!client-log-level") != 0 &&
- strcmp (vme->option, "!brick-log-level") != 0)
- || !strstr (vme->key, role))
+ if (strcmp (vme->option, "!log-level") != 0 ||
+ !strstr (vme->key, role))
return 0;
memcpy (&vme2, vme, sizeof (vme2));
@@ -1486,59 +1237,6 @@ server_check_marker_off (volgen_graph_t *graph, struct volopt_map_entry *vme,
}
static int
-sys_loglevel_option_handler (volgen_graph_t *graph,
- struct volopt_map_entry *vme,
- void *param)
-{
- char *role = NULL;
- struct volopt_map_entry vme2 = {0,};
-
- role = (char *) param;
-
- if (strcmp (vme->option, "!sys-log-level") != 0 ||
- !strstr (vme->key, role))
- return 0;
-
- memcpy (&vme2, vme, sizeof (vme2));
- vme2.option = "sys-log-level";
-
- return basic_option_handler (graph, &vme2, NULL);
-}
-
-static int
-volgen_graph_set_xl_options (volgen_graph_t *graph, dict_t *dict)
-{
- int32_t ret = -1;
- char *xlator = NULL;
- char xlator_match[1024] = {0,}; /* for posix* -> *posix* */
- char *loglevel = NULL;
- xlator_t *trav = NULL;
-
- ret = dict_get_str (dict, "xlator", &xlator);
- if (ret)
- goto out;
-
- ret = dict_get_str (dict, "loglevel", &loglevel);
- if (ret)
- goto out;
-
- snprintf (xlator_match, 1024, "*%s", xlator);
-
- for (trav = first_of (graph); trav; trav = trav->next) {
- if (fnmatch(xlator_match, trav->type, FNM_NOESCAPE) == 0) {
- gf_log ("glusterd", GF_LOG_DEBUG, "Setting log level for xlator: %s",
- trav->type);
- ret = xlator_set_option (trav, "log-level", loglevel);
- if (ret)
- break;
- }
- }
-
- out:
- return ret;
-}
-
-static int
server_spec_option_handler (volgen_graph_t *graph,
struct volopt_map_entry *vme, void *param)
{
@@ -1554,26 +1252,6 @@ server_spec_option_handler (volgen_graph_t *graph,
if (!ret)
ret = loglevel_option_handler (graph, vme, "brick");
- if (!ret)
- ret = sys_loglevel_option_handler (graph, vme, "brick");
-
- return ret;
-}
-
-static int
-server_spec_extended_option_handler (volgen_graph_t *graph,
- struct volopt_map_entry *vme, void *param)
-{
- int ret = 0;
- dict_t *dict = NULL;
-
- GF_ASSERT (param);
- dict = (dict_t *)param;
-
- ret = server_auth_option_handler (graph, vme, NULL);
- if (!ret)
- ret = volgen_graph_set_xl_options (graph, dict);
-
return ret;
}
@@ -1583,40 +1261,21 @@ static int
server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
dict_t *set_dict, void *param)
{
- char *volname = NULL;
- char *path = NULL;
- int pump = 0;
- xlator_t *xl = NULL;
- xlator_t *txl = NULL;
- xlator_t *rbxl = NULL;
- char transt[16] = {0,};
- char *ptranst = NULL;
- char volume_id[64] = {0,};
- char tstamp_file[PATH_MAX] = {0,};
- int ret = 0;
- char *xlator = NULL;
- char *loglevel = NULL;
- char *username = NULL;
- char *password = NULL;
- char index_basepath[PATH_MAX] = {0};
- char key[1024] = {0};
+ char *volname = NULL;
+ char *path = NULL;
+ int pump = 0;
+ xlator_t *xl = NULL;
+ xlator_t *txl = NULL;
+ xlator_t *rbxl = NULL;
+ char transt[16] = {0,};
+ char volume_id[64] = {0,};
+ char tstamp_file[PATH_MAX] = {0,};
+ int ret = 0;
path = param;
volname = volinfo->volname;
get_vol_transport_type (volinfo, transt);
- ret = dict_get_str (set_dict, "xlator", &xlator);
-
- /* got a cli log level request */
- if (!ret) {
- ret = dict_get_str (set_dict, "loglevel", &loglevel);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "could not get both"
- " translator name and loglevel for log level request");
- goto out;
- }
- }
-
xl = volgen_graph_add (graph, "storage/posix", volname);
if (!xl)
return -1;
@@ -1625,48 +1284,23 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (ret)
return -1;
- ret = xlator_set_option (xl, "volume-id",
- uuid_utoa (volinfo->volume_id));
- if (ret)
- return -1;
-
- ret = check_and_add_debug_xl (graph, set_dict, volname, "posix");
- if (ret)
- return -1;
-
xl = volgen_graph_add (graph, "features/access-control", volname);
if (!xl)
return -1;
- ret = check_and_add_debug_xl (graph, set_dict, volname, "acl");
- if (ret)
- return -1;
-
xl = volgen_graph_add (graph, "features/locks", volname);
if (!xl)
return -1;
- ret = check_and_add_debug_xl (graph, set_dict, volname, "locks");
- if (ret)
- return -1;
-
xl = volgen_graph_add (graph, "performance/io-threads", volname);
if (!xl)
return -1;
- ret = check_and_add_debug_xl (graph, set_dict, volname, "io-threads");
- if (ret)
- return -1;
-
ret = dict_get_int32 (volinfo->dict, "enable-pump", &pump);
if (ret == -ENOENT)
ret = pump = 0;
if (ret)
return -1;
-
- username = glusterd_auth_get_username (volinfo);
- password = glusterd_auth_get_password (volinfo);
-
if (pump) {
txl = first_of (graph);
@@ -1674,28 +1308,9 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
"%s-replace-brick", volname);
if (!rbxl)
return -1;
-
- ptranst = glusterd_get_trans_type_rb (volinfo->transport_type);
- if (NULL == ptranst)
- return -1;
-
- if (username) {
- ret = xlator_set_option (rbxl, "username", username);
- if (ret)
- return -1;
- }
-
- if (password) {
- ret = xlator_set_option (rbxl, "password", password);
- if (ret)
- return -1;
- }
-
- ret = xlator_set_option (rbxl, "transport-type", ptranst);
- GF_FREE (ptranst);
+ ret = xlator_set_option (rbxl, "transport-type", transt);
if (ret)
return -1;
-
xl = volgen_graph_add_nolink (graph, "cluster/pump", "%s-pump",
volname);
if (!xl)
@@ -1708,25 +1323,9 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
return -1;
}
- xl = volgen_graph_add (graph, "features/index", volname);
- if (!xl)
- return -1;
-
- snprintf (index_basepath, sizeof (index_basepath), "%s/%s",
- path, ".glusterfs/indices");
- ret = xlator_set_option (xl, "index-base", index_basepath);
- if (ret)
- return -1;
-
- ret = check_and_add_debug_xl (graph, set_dict, volname,
- "index");
- if (ret)
- return -1;
-
xl = volgen_graph_add (graph, "features/marker", volname);
if (!xl)
return -1;
-
uuid_unparse (volinfo->volume_id, volume_id);
ret = xlator_set_option (xl, "volume-uuid", volume_id);
if (ret)
@@ -1736,36 +1335,6 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (ret)
return -1;
- ret = check_and_add_debug_xl (graph, set_dict, volname, "marker");
- if (ret)
- return -1;
-
- if (dict_get_str_boolean (set_dict, "features.read-only", 0) &&
- dict_get_str_boolean (set_dict, "features.worm",0)) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "read-only and worm cannot be set together");
- ret = -1;
- goto out;
- }
-
- /* Check for read-only volume option, and add it to the graph */
- if (dict_get_str_boolean (set_dict, "features.read-only", 0)) {
- xl = volgen_graph_add (graph, "features/read-only", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
-
- /* Check for worm volume option, and add it to the graph */
- if (dict_get_str_boolean (set_dict, "features.worm", 0)) {
- xl = volgen_graph_add (graph, "features/worm", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
- }
-
xl = volgen_graph_add_as (graph, "debug/io-stats", path);
if (!xl)
return -1;
@@ -1777,31 +1346,9 @@ server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
if (ret)
return -1;
- if (username) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "auth.login.%s.allow", path);
+ ret = volgen_graph_set_options_generic (graph, set_dict, volinfo,
+ &server_spec_option_handler);
- ret = xlator_set_option (xl, key, username);
- if (ret)
- return -1;
- }
-
- if (password) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "auth.login.%s.password",
- username);
-
- ret = xlator_set_option (xl, key, password);
- if (ret)
- return -1;
- }
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- (xlator && loglevel) ? (void *)set_dict : volinfo,
- (xlator && loglevel) ? &server_spec_extended_option_handler :
- &server_spec_option_handler);
-
- out:
return ret;
}
@@ -1839,746 +1386,162 @@ perfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
}
static int
-nfsperfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- char *volname = NULL;
- gf_boolean_t enabled = _gf_false;
-
- volname = param;
-
- if (strcmp (vme->option, "!nfsperf") != 0)
- return 0;
-
- if (gf_string2boolean (vme->value, &enabled) == -1)
- return -1;
- if (!enabled)
- return 0;
-
- if (volgen_graph_add (graph, vme->voltype, volname))
- return 0;
- else
- return -1;
-}
-
-#if (HAVE_LIB_XML)
-static int
-end_sethelp_xml_doc (xmlTextWriterPtr writer)
-{
- int ret = -1;
-
- ret = xmlTextWriterEndElement(writer);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
- ret = xmlTextWriterEndDocument (writer);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "
- "xmlDocument");
- ret = -1;
- goto out;
- }
- ret = 0;
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-static int
-init_sethelp_xml_doc (xmlTextWriterPtr *writer, xmlBufferPtr *buf)
-{
- int ret;
-
- *buf = xmlBufferCreateSize (8192);
- if (buf == NULL) {
- gf_log ("glusterd", GF_LOG_ERROR, "Error creating the xml "
- "buffer");
- ret = -1;
- goto out;
- }
-
- xmlBufferSetAllocationScheme (*buf,XML_BUFFER_ALLOC_DOUBLEIT);
-
- *writer = xmlNewTextWriterMemory(*buf, 0);
- if (writer == NULL) {
- gf_log ("glusterd", GF_LOG_ERROR, " Error creating the xml "
- "writer");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterStartDocument(*writer, "1.0", "UTF-8", "yes");
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Error While starting the "
- "xmlDoc");
- goto out;
- }
-
- ret = xmlTextWriterStartElement(*writer, (xmlChar *)"options");
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
-
- ret = 0;
-
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-static int
-xml_add_volset_element (xmlTextWriterPtr writer, const char *name,
- const char *def_val, const char *dscrpt)
-{
-
- int ret = -1;
-
- GF_ASSERT (name);
-
- ret = xmlTextWriterStartElement(writer, (xmlChar *) "option");
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement(writer, (xmlChar*)"defaultValue",
- "%s", def_val);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"description",
- "%s", dscrpt );
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *) "name", "%s",
- name);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
- ret = xmlTextWriterEndElement(writer);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "
- "xmlElemetnt");
- ret = -1;
- goto out;
- }
-
- ret = 0;
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-#endif
-
-static int
-get_key_from_volopt ( struct volopt_map_entry *vme, char **key)
-{
- int ret = 0;
-
- GF_ASSERT (vme);
- GF_ASSERT (key);
-
-
- if (!strcmp (vme->key, AUTH_ALLOW_MAP_KEY))
- *key = gf_strdup (AUTH_ALLOW_OPT_KEY);
- else if (!strcmp (vme->key, AUTH_REJECT_MAP_KEY))
- *key = gf_strdup (AUTH_REJECT_OPT_KEY);
- else if (!strcmp (vme->key, NFS_DISABLE_MAP_KEY))
- *key = gf_strdup (NFS_DISABLE_OPT_KEY);
- else {
- if (vme->option) {
- if (vme->option[0] == '!') {
- *key = vme->option + 1;
- if (!*key[0])
- ret = -1;
- } else {
- *key = vme->option;
- }
- } else {
- *key = strchr (vme->key, '.');
- if (*key) {
- (*key) ++;
- if (!*key[0])
- ret = -1;
- } else {
- ret = -1;
- }
- }
- }
- if (ret)
- gf_log ("glusterd", GF_LOG_ERROR, "Wrong entry found in "
- "glusterd_volopt_map entry %s", vme->key);
- else
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_get_volopt_content (gf_boolean_t xml_out)
-{
-
- char *xlator_type = NULL;
- void *dl_handle = NULL;
- volume_opt_list_t vol_opt_handle = {{0},};
- char *key = NULL;
- struct volopt_map_entry *vme = NULL;
- int ret = -1;
- char *def_val = NULL;
- char *descr = NULL;
- char output_string[16384] = {0, };
- char *output = NULL;
- char tmp_str[1024] = {0, };
- dict_t *ctx = NULL;
-#if (HAVE_LIB_XML)
- xmlTextWriterPtr writer = NULL;
- xmlBufferPtr buf = NULL;
-
- if (xml_out) {
- ret = init_sethelp_xml_doc (&writer, &buf);
- if (ret) /*logging done in init_xml_lib*/
- goto out;
- }
-#endif
-
- ctx = glusterd_op_get_ctx ();
-
- if (!ctx) {
- /*extract the vol-set-help output only in host glusterd*/
- ret = 0;
- goto out;
- }
-
- INIT_LIST_HEAD (&vol_opt_handle.list);
-
- for (vme = &glusterd_volopt_map[0]; vme->key; vme++) {
-
- if ( ( vme->type == NO_DOC) || (vme->type == GLOBAL_NO_DOC) )
- continue;
-
- if (get_key_from_volopt (vme, &key))
- goto out; /*Some error while getin key*/
-
- if (!xlator_type || strcmp (vme->voltype, xlator_type)){
- ret = xlator_volopt_dynload (vme->voltype,
- &dl_handle,
- &vol_opt_handle);
- if (ret)
- continue;
- }
-
- ret = xlator_option_info_list (&vol_opt_handle, key,
- &def_val, &descr);
- if (ret) /*Swallow Error i.e if option not found*/
- continue;
-
- if (xml_out) {
-#if (HAVE_LIB_XML)
- if (xml_add_volset_element (writer,vme->key,
- def_val, descr))
- goto out;
-#else
- gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present");
-#endif
- } else {
- snprintf (tmp_str, 1024, "Option: %s\nDefault "
- "Value: %s\nDescription: %s\n\n",
- vme->key, def_val, descr);
- strcat (output_string, tmp_str);
- }
-
- if (!strcmp (key, AUTH_ALLOW_OPT_KEY) ||
- !strcmp (key, AUTH_REJECT_OPT_KEY) ||
- !strcmp (key, NFS_DISABLE_OPT_KEY))
- GF_FREE (key);
- }
-
-#if (HAVE_LIB_XML)
- if ((xml_out) &&
- (ret = end_sethelp_xml_doc (writer)))
- goto out;
-#else
- if (xml_out)
- gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present");
-#endif
-
- if (!xml_out)
- output = gf_strdup (output_string);
- else
-#if (HAVE_LIB_XML)
- output = gf_strdup ((char *)buf->content);
-#else
- gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present");
-#endif
-
- if (NULL == output) {
- ret = -1;
- goto out;
- }
-
- ret = dict_set_dynstr (ctx, "help-str", output);
- out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-
-}
-
-static int
-volgen_graph_build_clients (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *set_dict, void *param)
+client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
+ dict_t *set_dict, void *param)
{
- int i = 0;
- int ret = -1;
- uint32_t client_type = GF_CLIENT_OTHER;
+ int dist_count = 0;
char transt[16] = {0,};
+ char *tt = NULL;
char *volname = NULL;
- char *str = NULL;
- glusterd_brickinfo_t *brick = NULL;
+ dict_t *dict = NULL;
+ glusterd_brickinfo_t *brick = NULL;
+ char *replicate_args[] = {"cluster/replicate",
+ "%s-replicate-%d"};
+ char *stripe_args[] = {"cluster/stripe",
+ "%s-stripe-%d"};
+ char **cluster_args = NULL;
+ int i = 0;
+ int j = 0;
+ int ret = 0;
xlator_t *xl = NULL;
- char *ssl_str = NULL;
- gf_boolean_t ssl_bool;
+ xlator_t *txl = NULL;
+ xlator_t *trav = NULL;
volname = volinfo->volname;
+ dict = volinfo->dict;
+ GF_ASSERT (dict);
if (volinfo->brick_count == 0) {
gf_log ("", GF_LOG_ERROR,
"volume inconsistency: brick count is 0");
- goto out;
- }
- if ((volinfo->dist_leaf_count < volinfo->brick_count) &&
- ((volinfo->brick_count % volinfo->dist_leaf_count) != 0)) {
+ return -1;
+ }
+ if (volinfo->sub_count && volinfo->sub_count < volinfo->brick_count &&
+ volinfo->brick_count % volinfo->sub_count != 0) {
gf_log ("", GF_LOG_ERROR,
"volume inconsistency: "
"total number of bricks (%d) is not divisible with "
"number of bricks per cluster (%d) in a multi-cluster "
"setup",
- volinfo->brick_count, volinfo->dist_leaf_count);
- goto out;
+ volinfo->brick_count, volinfo->sub_count);
+ return -1;
}
- get_transport_type (volinfo, set_dict, transt, _gf_false);
-
- if (!strcmp (transt, "tcp,rdma"))
- strcpy (transt, "tcp");
+ ret = dict_get_str (set_dict, "client-transport-type", &tt);
+ if (ret)
+ get_vol_transport_type (volinfo, transt);
+ if (!ret)
+ strcpy (transt, tt);
i = 0;
- ret = -1;
list_for_each_entry (brick, &volinfo->bricks, brick_list) {
- ret = -1;
xl = volgen_graph_add_nolink (graph, "protocol/client",
"%s-client-%d", volname, i);
if (!xl)
- goto out;
+ return -1;
ret = xlator_set_option (xl, "remote-host", brick->hostname);
if (ret)
- goto out;
+ return -1;
ret = xlator_set_option (xl, "remote-subvolume", brick->path);
if (ret)
- goto out;
+ return -1;
ret = xlator_set_option (xl, "transport-type", transt);
if (ret)
- goto out;
-
- ret = dict_get_uint32 (set_dict, "trusted-client",
- &client_type);
-
- if (!ret && client_type == GF_CLIENT_TRUSTED) {
- str = NULL;
- str = glusterd_auth_get_username (volinfo);
- if (str) {
- ret = xlator_set_option (xl, "username",
- str);
- if (ret)
- goto out;
- }
-
- str = glusterd_auth_get_password (volinfo);
- if (str) {
- ret = xlator_set_option (xl, "password",
- str);
- if (ret)
- goto out;
- }
- }
-
- if (dict_get_str(set_dict,"client.ssl",&ssl_str) == 0) {
- if (gf_string2boolean(ssl_str,&ssl_bool) == 0) {
- if (ssl_bool) {
- ret = xlator_set_option(xl,
- "transport.socket.ssl-enabled",
- "true");
- if (ret) {
- goto out;
- }
- }
- }
- }
+ return -1;
i++;
}
-
if (i != volinfo->brick_count) {
gf_log ("", GF_LOG_ERROR,
"volume inconsistency: actual number of bricks (%d) "
"differs from brick count (%d)", i,
volinfo->brick_count);
- ret = -1;
- goto out;
+ return -1;
}
- ret = 0;
-out:
- return ret;
-}
-static int
-volgen_graph_build_clusters (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo, char *xl_type,
- char *xl_namefmt, size_t child_count,
- size_t sub_count)
-{
- int i = 0;
- int j = 0;
- xlator_t *txl = NULL;
- xlator_t *xl = NULL;
- xlator_t *trav = NULL;
- char *volname = NULL;
- int ret = -1;
-
- if (child_count == 0)
- goto out;
- volname = volinfo->volname;
- txl = first_of (graph);
- for (trav = txl; --child_count; trav = trav->next);
- for (;; trav = trav->prev) {
- if ((i % sub_count) == 0) {
- xl = volgen_graph_add_nolink (graph, xl_type,
- xl_namefmt, volname, j);
- if (!xl) {
- ret = -1;
- goto out;
- }
- j++;
- }
-
- ret = volgen_xlator_link (xl, trav);
- if (ret)
- goto out;
-
- if (trav == txl)
+ if (volinfo->sub_count > 1) {
+ switch (volinfo->type) {
+ case GF_CLUSTER_TYPE_REPLICATE:
+ cluster_args = replicate_args;
break;
-
- i++;
- }
-
- ret = j;
-out:
- return ret;
-}
-
-gf_boolean_t
-_xl_is_client_decommissioned (xlator_t *xl, glusterd_volinfo_t *volinfo)
-{
- int ret = 0;
- gf_boolean_t decommissioned = _gf_false;
- char *hostname = NULL;
- char *path = NULL;
-
- GF_ASSERT (!strcmp (xl->type, "protocol/client"));
- ret = xlator_get_option (xl, "remote-host", &hostname);
- if (ret) {
- GF_ASSERT (0);
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to get remote-host "
- "from client %s", xl->name);
- goto out;
- }
- ret = xlator_get_option (xl, "remote-subvolume", &path);
- if (ret) {
- GF_ASSERT (0);
- gf_log ("glusterd", GF_LOG_ERROR, "Failed to get remote-host "
- "from client %s", xl->name);
- goto out;
- }
-
- decommissioned = glusterd_is_brick_decommissioned (volinfo, hostname,
- path);
-out:
- return decommissioned;
-}
-
-gf_boolean_t
-_xl_has_decommissioned_clients (xlator_t *xl, glusterd_volinfo_t *volinfo)
-{
- xlator_list_t *xl_child = NULL;
- gf_boolean_t decommissioned = _gf_false;
- xlator_t *cxl = NULL;
-
- if (!xl)
- goto out;
-
- if (!strcmp (xl->type, "protocol/client")) {
- decommissioned = _xl_is_client_decommissioned (xl, volinfo);
- goto out;
- }
-
- xl_child = xl->children;
- while (xl_child) {
- cxl = xl_child->xlator;
- /* this can go into 2 depths if the volume type
- is stripe-replicate */
- decommissioned = _xl_has_decommissioned_clients (cxl, volinfo);
- if (decommissioned)
+ case GF_CLUSTER_TYPE_STRIPE:
+ cluster_args = stripe_args;
break;
+ default:
+ gf_log ("", GF_LOG_ERROR, "volume inconsistency: "
+ "unrecognized clustering type");
+ return -1;
+ }
- xl_child = xl_child->next;
- }
-out:
- return decommissioned;
-}
-
-static int
-_graph_get_decommissioned_children (xlator_t *dht, glusterd_volinfo_t *volinfo,
- char **children)
-{
- int ret = -1;
- xlator_list_t *xl_child = NULL;
- xlator_t *cxl = NULL;
- gf_boolean_t comma = _gf_false;
-
- *children = NULL;
- xl_child = dht->children;
- while (xl_child) {
- cxl = xl_child->xlator;
- if (_xl_has_decommissioned_clients (cxl, volinfo)) {
- if (!*children) {
- *children = GF_CALLOC (16 * GF_UNIT_KB, 1,
- gf_common_mt_char);
- if (!*children)
- goto out;
+ i = 0;
+ j = 0;
+ txl = first_of (graph);
+ for (trav = txl; trav->next; trav = trav->next);
+ for (;; trav = trav->prev) {
+ if (i % volinfo->sub_count == 0) {
+ xl = volgen_graph_add_nolink (graph,
+ cluster_args[0],
+ cluster_args[1],
+ volname, j);
+ if (!xl)
+ return -1;
+ j++;
}
- if (comma)
- strcat (*children, ",");
- strcat (*children, cxl->name);
- comma = _gf_true;
- }
-
- xl_child = xl_child->next;
- }
- ret = 0;
-out:
- return ret;
-}
+ ret = volgen_xlator_link (xl, trav);
+ if (ret)
+ return -1;
-static int
-volgen_graph_build_dht_cluster (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo, size_t child_count)
-{
- int32_t clusters = 0;
- int ret = -1;
- char *decommissioned_children = NULL;
- xlator_t *dht = NULL;
-
- clusters = volgen_graph_build_clusters (graph, volinfo,
- "cluster/distribute", "%s-dht",
- child_count, child_count);
- if (clusters < 0)
- goto out;
- dht = first_of (graph);
- ret = _graph_get_decommissioned_children (dht, volinfo,
- &decommissioned_children);
- if (ret)
- goto out;
- if (decommissioned_children) {
- ret = xlator_set_option (dht, "decommissioned-bricks",
- decommissioned_children);
- if (ret)
- goto out;
+ if (trav == txl)
+ break;
+ i++;
+ }
}
- ret = 0;
-out:
- GF_FREE (decommissioned_children);
- return ret;
-}
-
-static int
-volume_volgen_graph_build_clusters (volgen_graph_t *graph,
- glusterd_volinfo_t *volinfo)
-{
- char *replicate_args[] = {"cluster/replicate",
- "%s-replicate-%d"};
- char *stripe_args[] = {"cluster/stripe",
- "%s-stripe-%d"};
- int rclusters = 0;
- int clusters = 0;
- int dist_count = 0;
- int ret = -1;
-
- if (!volinfo->dist_leaf_count)
- goto out;
- if (volinfo->dist_leaf_count == 1)
- goto build_distribute;
-
- /* All other cases, it will have one or the other cluster type */
- switch (volinfo->type) {
- case GF_CLUSTER_TYPE_REPLICATE:
- clusters = volgen_graph_build_clusters (graph, volinfo,
- replicate_args[0],
- replicate_args[1],
- volinfo->brick_count,
- volinfo->replica_count);
- if (clusters < 0)
- goto out;
- break;
- case GF_CLUSTER_TYPE_STRIPE:
- clusters = volgen_graph_build_clusters (graph, volinfo,
- stripe_args[0],
- stripe_args[1],
- volinfo->brick_count,
- volinfo->stripe_count);
- if (clusters < 0)
- goto out;
- break;
- case GF_CLUSTER_TYPE_STRIPE_REPLICATE:
- /* Replicate after the clients, then stripe */
- if (volinfo->replica_count == 0)
- goto out;
- clusters = volgen_graph_build_clusters (graph, volinfo,
- replicate_args[0],
- replicate_args[1],
- volinfo->brick_count,
- volinfo->replica_count);
- if (clusters < 0)
- goto out;
-
- rclusters = volinfo->brick_count / volinfo->replica_count;
- GF_ASSERT (rclusters == clusters);
- clusters = volgen_graph_build_clusters (graph, volinfo,
- stripe_args[0],
- stripe_args[1],
- rclusters,
- volinfo->stripe_count);
- if (clusters < 0)
- goto out;
- break;
- default:
- gf_log ("", GF_LOG_ERROR, "volume inconsistency: "
- "unrecognized clustering type");
- goto out;
- }
+ if (volinfo->sub_count)
+ dist_count = volinfo->brick_count / volinfo->sub_count;
+ else
+ dist_count = volinfo->brick_count;
+ if (dist_count > 1) {
+ xl = volgen_graph_add_nolink (graph, "cluster/distribute",
+ "%s-dht", volname);
+ if (!xl)
+ return -1;
-build_distribute:
- dist_count = volinfo->brick_count / volinfo->dist_leaf_count;
- if (!dist_count) {
- ret = -1;
- goto out;
+ trav = xl;
+ for (i = 0; i < dist_count; i++)
+ trav = trav->next;
+ for (; trav != xl; trav = trav->prev) {
+ ret = volgen_xlator_link (xl, trav);
+ if (ret)
+ return -1;
+ }
}
- ret = volgen_graph_build_dht_cluster (graph, volinfo,
- dist_count);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- return ret;
-}
-
-static int
-client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
- dict_t *set_dict, void *param)
-{
- int ret = 0;
- xlator_t *xl = NULL;
- char *volname = NULL;
- data_t *tmp_data = NULL;
-
- volname = volinfo->volname;
- ret = volgen_graph_build_clients (graph, volinfo, set_dict, param);
- if (ret)
- goto out;
-
- ret = volume_volgen_graph_build_clusters (graph, volinfo);
- if (ret)
- goto out;
-
ret = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA);
if (ret == -1)
- goto out;
+ return -1;
if (ret) {
xl = volgen_graph_add (graph, "features/quota", volname);
- if (!xl) {
- ret = -1;
- goto out;
- }
+ if (!xl)
+ return -1;
}
- /* Logic to make sure NFS doesn't have performance translators by
- default for a volume */
- tmp_data = dict_get (set_dict, "nfs-volume-file");
- if (!tmp_data)
- ret = volgen_graph_set_options_generic (graph, set_dict, volname,
- &perfxl_option_handler);
- else
- ret = volgen_graph_set_options_generic (graph, set_dict, volname,
- &nfsperfxl_option_handler);
-
- if (ret)
- goto out;
-
- /* add debug translators depending on the options */
- ret = check_and_add_debug_xl (graph, set_dict, volname,
- "client");
+ ret = volgen_graph_set_options_generic (graph, set_dict, volname,
+ &perfxl_option_handler);
if (ret)
return -1;
- ret = -1;
xl = volgen_graph_add_as (graph, "debug/io-stats", volname);
if (!xl)
- goto out;
+ return -1;
ret = volgen_graph_set_options_generic (graph, set_dict, "client",
&loglevel_option_handler);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "changing client log level"
- " failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict, "client",
- &sys_loglevel_option_handler);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "changing client syslog "
- "level failed");
-out:
return ret;
}
@@ -2592,44 +1555,9 @@ build_client_graph (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
&client_graph_builder);
}
-char *gd_shd_options[] = {
- "!self-heal-daemon",
- "!heal-timeout",
- NULL
-};
-
-char*
-gd_get_matching_option (char **options, char *option)
-{
- while (*options && strcmp (*options, option))
- options++;
- return *options;
-}
-
-static int
-shd_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme,
- void *param)
-{
- int ret = 0;
- struct volopt_map_entry new_vme = {0};
- char *shd_option = NULL;
-
- if (vme->option[0] != '!')
- goto out;
- shd_option = gd_get_matching_option (gd_shd_options, vme->option);
- if (!shd_option)
- goto out;
- new_vme = *vme;
- new_vme.option = shd_option + 1;//option with out '!'
-
- ret = no_filter_option_handler (graph, &new_vme, param);
-out:
- return ret;
-}
-
static int
nfs_option_handler (volgen_graph_t *graph,
- struct volopt_map_entry *vme, void *param)
+ struct volopt_map_entry *vme, void *param)
{
xlator_t *xl = NULL;
char *aa = NULL;
@@ -2644,10 +1572,10 @@ nfs_option_handler (volgen_graph_t *graph,
ret = xlator_set_option (xl, vme->key, vme->value);
}*/
- if (!volinfo || (volinfo->volname[0] == '\0'))
+ if ( !volinfo || !volinfo->volname)
return 0;
- if (! strcmp (vme->option, "!rpc-auth.addr.*.allow")) {
+ if (! strcmp (vme->option, "!nfs.rpc-auth-addr-allow")) {
ret = gf_asprintf (&aa, "rpc-auth.addr.%s.allow",
volinfo->volname);
@@ -2660,7 +1588,7 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!rpc-auth.addr.*.reject")) {
+ if (! strcmp (vme->option, "!nfs.rpc-auth-addr-reject")) {
ret = gf_asprintf (&aa, "rpc-auth.addr.%s.reject",
volinfo->volname);
@@ -2673,8 +1601,8 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!rpc-auth.auth-unix.*")) {
- ret = gf_asprintf (&aa, "rpc-auth.auth-unix.%s",
+ if (! strcmp (vme->option, "!nfs.rpc-auth-auth-unix")) {
+ ret = gf_asprintf (&aa, "rpc-auth.auth.unix.%s",
volinfo->volname);
if (ret != -1) {
@@ -2685,8 +1613,8 @@ nfs_option_handler (volgen_graph_t *graph,
if (ret)
return -1;
}
- if (! strcmp (vme->option, "!rpc-auth.auth-null.*")) {
- ret = gf_asprintf (&aa, "rpc-auth.auth-null.%s",
+ if (! strcmp (vme->option, "!nfs.rpc-auth-auth-null")) {
+ ret = gf_asprintf (&aa, "rpc-auth.auth.null.%s",
volinfo->volname);
if (ret != -1) {
@@ -2698,7 +1626,7 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!nfs3.*.trusted-sync")) {
+ if (! strcmp (vme->option, "!nfs-trusted-sync")) {
ret = gf_asprintf (&aa, "nfs3.%s.trusted-sync",
volinfo->volname);
@@ -2711,7 +1639,7 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!nfs3.*.trusted-write")) {
+ if (! strcmp (vme->option, "!nfs-trusted-write")) {
ret = gf_asprintf (&aa, "nfs3.%s.trusted-write",
volinfo->volname);
@@ -2724,7 +1652,7 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!nfs3.*.volume-access")) {
+ if (! strcmp (vme->option, "!nfs-volume-access")) {
ret = gf_asprintf (&aa, "nfs3.%s.volume-access",
volinfo->volname);
@@ -2737,15 +1665,11 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if (! strcmp (vme->option, "!nfs3.*.export-dir")) {
+ if (! strcmp (vme->option, "!nfs-export-dir")) {
ret = gf_asprintf (&aa, "nfs3.%s.export-dir",
volinfo->volname);
if (ret != -1) {
- ret = gf_canonicalize_path (vme->value);
- if (ret)
- return -1;
-
ret = xlator_set_option (xl, aa, vme->value);
GF_FREE (aa);
}
@@ -2756,7 +1680,7 @@ nfs_option_handler (volgen_graph_t *graph,
- if (! strcmp (vme->option, "!rpc-auth.ports.*.insecure")) {
+ if (! strcmp (vme->option, "!nfs.ports-insecure")) {
ret = gf_asprintf (&aa, "rpc-auth.ports.%s.insecure",
volinfo->volname);
@@ -2783,13 +1707,6 @@ nfs_option_handler (volgen_graph_t *graph,
return -1;
}
- if ( (strcmp (vme->voltype, "nfs/server") == 0) &&
- (vme->option && vme->option[0]!='!') ) {
- ret = xlator_set_option (xl, vme->option, vme->value);
- if (ret)
- return -1;
- }
-
/*key = strchr (vme->key, '.') + 1;
@@ -2808,131 +1725,14 @@ nfs_option_handler (volgen_graph_t *graph,
}
static int
-volgen_graph_set_iam_shd (volgen_graph_t *graph)
-{
- xlator_t *trav;
- int ret = 0;
-
- for (trav = first_of (graph); trav; trav = trav->next) {
- if (strcmp (trav->type, "cluster/replicate") != 0)
- continue;
-
- ret = xlator_set_option (trav, "iam-self-heal-daemon", "yes");
- if (ret)
- break;
- }
- return ret;
-}
-
-static int
-build_shd_graph (volgen_graph_t *graph, dict_t *mod_dict)
+nfs_spec_option_handler (volgen_graph_t *graph,
+ struct volopt_map_entry *vme, void *param)
{
- volgen_graph_t cgraph = {0};
- glusterd_volinfo_t *voliter = NULL;
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- dict_t *set_dict = NULL;
- int ret = 0;
- gf_boolean_t valid_config = _gf_false;
- xlator_t *iostxl = NULL;
- int rclusters = 0;
- int replica_count = 0;
- gf_boolean_t graph_check = _gf_false;
-
- this = THIS;
- priv = this->private;
-
- set_dict = dict_new ();
- if (!set_dict) {
- ret = -ENOMEM;
- goto out;
- }
-
- graph_check = dict_get_str_boolean (mod_dict, "graph-check", 0);
- iostxl = volgen_graph_add_as (graph, "debug/io-stats", "glustershd");
- if (!iostxl) {
- ret = -1;
- goto out;
- }
-
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (!graph_check &&
- (voliter->status != GLUSTERD_STATUS_STARTED))
- continue;
-
- if (!glusterd_is_volume_replicate (voliter))
- continue;
-
- replica_count = voliter->replica_count;
-
- valid_config = _gf_true;
-
- ret = dict_set_str (set_dict, "cluster.self-heal-daemon", "on");
- if (ret)
- goto out;
-
- ret = dict_set_uint32 (set_dict, "trusted-client",
- GF_CLIENT_TRUSTED);
- if (ret)
- goto out;
-
- dict_copy (voliter->dict, set_dict);
- if (mod_dict)
- dict_copy (mod_dict, set_dict);
-
- memset (&cgraph, 0, sizeof (cgraph));
- ret = volgen_graph_build_clients (&cgraph, voliter, set_dict,
- NULL);
- if (ret)
- goto out;
-
- rclusters = volgen_graph_build_clusters (&cgraph, voliter,
- "cluster/replicate",
- "%s-replicate-%d",
- voliter->brick_count,
- replica_count);
- if (rclusters < 0) {
- ret = -1;
- goto out;
- }
-
- ret = volgen_graph_set_options_generic (&cgraph, set_dict, voliter,
- shd_option_handler);
- if (ret)
- goto out;
-
- ret = volgen_graph_set_iam_shd (&cgraph);
- if (ret)
- goto out;
-
- ret = volgen_graph_merge_sub (graph, &cgraph, rclusters);
- if (ret)
- goto out;
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &loglevel_option_handler);
-
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "changing loglevel "
- "of self-heal daemon failed");
-
- ret = volgen_graph_set_options_generic (graph, set_dict,
- "client",
- &sys_loglevel_option_handler);
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "changing syslog "
- "level of self-heal daemon failed");
+ int ret = 0;
- ret = dict_reset (set_dict);
- if (ret)
- goto out;
- }
-out:
- if (set_dict)
- dict_unref (set_dict);
- if (!valid_config)
- ret = -EINVAL;
+ ret = nfs_option_handler (graph, vme, param);
+ if (!ret)
+ return basic_option_handler (graph, vme, NULL);
return ret;
}
@@ -2948,7 +1748,6 @@ build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict)
xlator_t *nfsxl = NULL;
char *skey = NULL;
int ret = 0;
- char nfs_xprt[16] = {0,};
this = THIS;
GF_ASSERT (this);
@@ -2961,6 +1760,10 @@ build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict)
return -1;
}
+ ret = dict_set_str (set_dict, VKEY_PERF_STAT_PREFETCH, "off");
+ if (ret)
+ goto out;
+
nfsxl = volgen_graph_add_as (graph, "nfs/server", "nfs-server");
if (!nfsxl) {
ret = -1;
@@ -2968,11 +1771,7 @@ build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict)
}
ret = xlator_set_option (nfsxl, "nfs.dynamic-volumes", "on");
if (ret)
- goto out;
-
- ret = xlator_set_option (nfsxl, "nfs.nlm", "on");
- if (ret)
- goto out;
+ goto out;;
list_for_each_entry (voliter, &priv->volumes, vol_list) {
if (voliter->status != GLUSTERD_STATUS_STARTED)
@@ -3005,76 +1804,35 @@ build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict)
/* If both RDMA and TCP are the transport_type, use RDMA
for NFS client protocols */
- memset (&cgraph, 0, sizeof (cgraph));
- if (mod_dict)
- get_transport_type (voliter, mod_dict, nfs_xprt, _gf_true);
- else
- get_transport_type (voliter, voliter->dict, nfs_xprt, _gf_true);
-
- ret = dict_set_str (set_dict, VKEY_PERF_STAT_PREFETCH, "off");
- if (ret)
- goto out;
-
- ret = dict_set_str (set_dict, "performance.client-io-threads",
- "off");
- if (ret)
- goto out;
-
- ret = dict_set_str (set_dict, "client-transport-type",
- nfs_xprt);
- if (ret)
- goto out;
-
- ret = dict_set_uint32 (set_dict, "trusted-client",
- GF_CLIENT_TRUSTED);
- if (ret)
- goto out;
+ if (voliter->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
+ ret = dict_set_str (set_dict, "client-transport-type",
+ "rdma");
+ if (ret)
+ goto out;
+ }
- ret = dict_set_str (set_dict, "nfs-volume-file", "yes");
+ memset (&cgraph, 0, sizeof (cgraph));
+ ret = build_client_graph (&cgraph, voliter, mod_dict);
if (ret)
- goto out;
-
- ret = build_client_graph (&cgraph, voliter, set_dict);
+ goto out;;
+ ret = volgen_graph_merge_sub (graph, &cgraph);
if (ret)
goto out;
if (mod_dict) {
dict_copy (mod_dict, set_dict);
- ret = volgen_graph_set_options_generic (&cgraph, set_dict, voliter,
- basic_option_handler);
- } else {
- ret = volgen_graph_set_options_generic (&cgraph, voliter->dict, voliter,
- basic_option_handler);
+ ret = volgen_graph_set_options_generic (graph, set_dict, voliter,
+ nfs_spec_option_handler);
}
+ else
+ ret = volgen_graph_set_options_generic (graph, voliter->dict, voliter,
+ nfs_spec_option_handler);
- if (ret)
- goto out;
-
- ret = volgen_graph_merge_sub (graph, &cgraph, 1);
- if (ret)
- goto out;
- ret = dict_reset (set_dict);
- if (ret)
- goto out;
}
- list_for_each_entry (voliter, &priv->volumes, vol_list) {
- if (mod_dict) {
- ret = volgen_graph_set_options_generic (graph, mod_dict, voliter,
- nfs_option_handler);
- } else {
- ret = volgen_graph_set_options_generic (graph, voliter->dict, voliter,
- nfs_option_handler);
- }
-
- if (ret)
- gf_log ("glusterd", GF_LOG_WARNING, "Could not set "
- "vol-options for the volume %s", voliter->volname);
- }
out:
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
dict_destroy (set_dict);
return ret;
@@ -3109,39 +1867,6 @@ get_brick_filepath (char *filename, glusterd_volinfo_t *volinfo,
brick);
}
-gf_boolean_t
-glusterd_is_valid_volfpath (char *volname, char *brick)
-{
- char volfpath[PATH_MAX] = {0,};
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- int32_t ret = 0;
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "brick path validation failed");
- ret = 0;
- goto out;
- }
- ret = glusterd_volinfo_new (&volinfo);
- if (ret) {
- gf_log ("", GF_LOG_WARNING, "brick path validation failed");
- ret = 0;
- goto out;
- }
- strncpy (volinfo->volname, volname, sizeof (volinfo->volname));
- get_brick_filepath (volfpath, volinfo, brickinfo);
-
- ret = (strlen (volfpath) < _POSIX_PATH_MAX);
-
-out:
- if (brickinfo)
- glusterd_brickinfo_delete (brickinfo);
- if (volinfo)
- glusterd_volinfo_delete (volinfo);
- return ret;
-}
-
static int
glusterd_generate_brick_volfile (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo)
@@ -3164,8 +1889,6 @@ glusterd_generate_brick_volfile (glusterd_volinfo_t *volinfo,
return ret;
}
-
-
static void
get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
{
@@ -3178,7 +1901,7 @@ get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo)
PATH_MAX - strlen(filename) - 1);
}
-int
+static int
generate_brick_volfiles (glusterd_volinfo_t *volinfo)
{
glusterd_brickinfo_t *brickinfo = NULL;
@@ -3192,7 +1915,7 @@ generate_brick_volfiles (glusterd_volinfo_t *volinfo)
get_vol_tstamp_file (tstamp_file, volinfo);
if (ret) {
- ret = open (tstamp_file, O_WRONLY|O_CREAT|O_EXCL, 0600);
+ ret = open (tstamp_file, O_WRONLY|O_CREAT|O_EXCL, 0644);
if (ret == -1 && errno == EEXIST) {
gf_log ("", GF_LOG_DEBUG, "timestamp file exist");
ret = -2;
@@ -3233,84 +1956,79 @@ out:
return ret;
}
-static int
-generate_single_transport_client_volfile (glusterd_volinfo_t *volinfo,
- char *filepath, dict_t *dict)
+static void
+get_client_filepath (char *filename, glusterd_volinfo_t *volinfo)
{
- volgen_graph_t graph = {0,};
- int ret = -1;
+ char path[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
- ret = build_client_graph (&graph, volinfo, dict);
- if (!ret)
- ret = volgen_write_volfile (&graph, filepath);
+ priv = THIS->private;
- volgen_graph_free (&graph);
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
- return ret;
+ snprintf (filename, PATH_MAX, "%s/%s-fuse.vol",
+ path, volinfo->volname);
}
static void
-enumerate_transport_reqs (gf_transport_type type, char **types)
+get_rdma_client_filepath (char *filename, glusterd_volinfo_t *volinfo)
{
- switch (type) {
- case GF_TRANSPORT_TCP:
- types[0] = "tcp";
- break;
- case GF_TRANSPORT_RDMA:
- types[0] = "rdma";
- break;
- case GF_TRANSPORT_BOTH_TCP_RDMA:
- types[0] = "tcp";
- types[1] = "rdma";
- break;
- }
+ char path[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+
+ GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv);
+
+ snprintf (filename, PATH_MAX, "%s/%s-rdma-fuse.vol",
+ path, volinfo->volname);
}
static int
-generate_client_volfiles (glusterd_volinfo_t *volinfo,
- glusterd_client_type_t client_type)
-{
- char filepath[PATH_MAX] = {0,};
- int ret = -1;
- char *types[] = {NULL, NULL, NULL};
- int i = 0;
- dict_t *dict = NULL;
- gf_transport_type type = GF_TRANSPORT_TCP;
-
- enumerate_transport_reqs (volinfo->transport_type, types);
- dict = dict_new ();
- if (!dict)
- goto out;
- for (i = 0; types[i]; i++) {
- memset (filepath, 0, sizeof (filepath));
- ret = dict_set_str (dict, "client-transport-type", types[i]);
- if (ret)
- goto out;
- type = transport_str_to_type (types[i]);
+generate_client_volfile (glusterd_volinfo_t *volinfo)
+{
+ volgen_graph_t graph = {0,};
+ char filename[PATH_MAX] = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+
+ get_client_filepath (filename, volinfo);
- ret = dict_set_uint32 (dict, "trusted-client", client_type);
+ if (volinfo->transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) {
+ dict = dict_new ();
+ if (!dict)
+ goto out;
+ ret = dict_set_str (dict, "client-transport-type", "tcp");
if (ret)
goto out;
+ }
- if (client_type == GF_CLIENT_TRUSTED) {
- glusterd_get_trusted_client_filepath (filepath,
- volinfo,
- type);
- } else {
- glusterd_get_client_filepath (filepath,
- volinfo,
- type);
- }
+ ret = build_client_graph (&graph, volinfo, dict);
+ if (!ret)
+ ret = volgen_write_volfile (&graph, filename);
- ret = generate_single_transport_client_volfile (volinfo,
- filepath,
- dict);
+ volgen_graph_free (&graph);
+
+ if (dict) {
+ /* This means, transport type is both RDMA and TCP */
+
+ memset (&graph, 0, sizeof (graph));
+ get_rdma_client_filepath (filename, volinfo);
+
+ ret = dict_set_str (dict, "client-transport-type", "rdma");
if (ret)
goto out;
+
+ ret = build_client_graph (&graph, volinfo, dict);
+ if (!ret)
+ ret = volgen_write_volfile (&graph, filename);
+
+ volgen_graph_free (&graph);
+
+ dict_unref (dict);
}
+
out:
- if (dict)
- dict_unref (dict);
return ret;
}
@@ -3322,7 +2040,7 @@ glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,
ret = glusterd_generate_brick_volfile (volinfo, brickinfo);
if (!ret)
- ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED);
+ ret = generate_client_volfile (volinfo);
if (!ret)
ret = glusterd_fetchspec_notify (THIS);
@@ -3332,153 +2050,55 @@ glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo,
int
glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo)
{
- int ret = -1;
- xlator_t *this = NULL;
-
- this = THIS;
+ int ret = -1;
ret = generate_brick_volfiles (volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
+ gf_log ("", GF_LOG_ERROR,
"Could not generate volfiles for bricks");
goto out;
}
- ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not generate trusted client volfiles");
- goto out;
- }
-
- ret = generate_client_volfiles (volinfo, GF_CLIENT_OTHER);
+ ret = generate_client_volfile (volinfo);
if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Could not generate client volfiles");
+ gf_log ("", GF_LOG_ERROR,
+ "Could not generate volfile for client");
goto out;
}
- ret = glusterd_fetchspec_notify (this);
+ ret = glusterd_fetchspec_notify (THIS);
out:
return ret;
}
-int
-glusterd_create_global_volfile (int (*builder) (volgen_graph_t *graph,
- dict_t *set_dict),
- char *filepath, dict_t *mod_dict)
+void
+glusterd_get_nfs_filepath (char *filename)
{
- volgen_graph_t graph = {0,};
- int ret = -1;
+ char path[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
- ret = builder (&graph, mod_dict);
- if (!ret)
- ret = volgen_write_volfile (&graph, filepath);
+ priv = THIS->private;
- volgen_graph_free (&graph);
+ GLUSTERD_GET_NFS_DIR (path, priv);
- return ret;
+ snprintf (filename, PATH_MAX, "%s/nfs-server.vol", path);
}
int
glusterd_create_nfs_volfile ()
{
- char filepath[PATH_MAX] = {0,};
- glusterd_conf_t *conf = THIS->private;
-
- glusterd_get_nodesvc_volfile ("nfs", conf->workdir,
- filepath, sizeof (filepath));
- return glusterd_create_global_volfile (build_nfs_graph,
- filepath, NULL);
-}
-
-int
-glusterd_create_shd_volfile ()
-{
- char filepath[PATH_MAX] = {0,};
- int ret = -1;
- glusterd_conf_t *conf = THIS->private;
- dict_t *mod_dict = NULL;
-
- mod_dict = dict_new ();
- if (!mod_dict)
- goto out;
-
- ret = dict_set_uint32 (mod_dict, "cluster.background-self-heal-count", 0);
- if (ret)
- goto out;
-
- ret = dict_set_str (mod_dict, "cluster.data-self-heal", "on");
- if (ret)
- goto out;
-
- ret = dict_set_str (mod_dict, "cluster.metadata-self-heal", "on");
- if (ret)
- goto out;
-
- ret = dict_set_str (mod_dict, "cluster.entry-self-heal", "on");
- if (ret)
- goto out;
-
- glusterd_get_nodesvc_volfile ("glustershd", conf->workdir,
- filepath, sizeof (filepath));
- ret = glusterd_create_global_volfile (build_shd_graph, filepath,
- mod_dict);
-out:
- if (mod_dict)
- dict_unref (mod_dict);
- return ret;
-}
-
-int
-glusterd_check_nfs_volfile_identical (gf_boolean_t *identical)
-{
- char nfsvol[PATH_MAX] = {0,};
- char tmpnfsvol[PATH_MAX] = {0,};
- glusterd_conf_t *conf = NULL;
- xlator_t *this = NULL;
- int ret = -1;
- int need_unlink = 0;
- int tmp_fd = -1;
-
- this = THIS;
-
- GF_ASSERT (this);
- GF_ASSERT (identical);
-
- conf = this->private;
-
- glusterd_get_nodesvc_volfile ("nfs", conf->workdir,
- nfsvol, sizeof (nfsvol));
-
- snprintf (tmpnfsvol, sizeof (tmpnfsvol), "/tmp/gnfs-XXXXXX");
-
- tmp_fd = mkstemp (tmpnfsvol);
- if (tmp_fd < 0) {
- gf_log ("", GF_LOG_WARNING, "Unable to create temp file %s: "
- "(%s)", tmpnfsvol, strerror (errno));
- goto out;
- }
-
- need_unlink = 1;
-
- ret = glusterd_create_global_volfile (build_nfs_graph,
- tmpnfsvol, NULL);
- if (ret)
- goto out;
+ volgen_graph_t graph = {0,};
+ char filename[PATH_MAX] = {0,};
+ int ret = -1;
- ret = glusterd_check_files_identical (nfsvol, tmpnfsvol,
- identical);
- if (ret)
- goto out;
+ glusterd_get_nfs_filepath (filename);
-out:
- if (need_unlink)
- unlink (tmpnfsvol);
+ ret = build_nfs_graph (&graph, NULL);
+ if (!ret)
+ ret = volgen_write_volfile (&graph, filename);
- if (tmp_fd >= 0)
- close (tmp_fd);
+ volgen_graph_free (&graph);
return ret;
}
@@ -3502,137 +2122,32 @@ glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
}
int
-validate_shdopts (glusterd_volinfo_t *volinfo,
- dict_t *val_dict,
- char **op_errstr)
-{
- volgen_graph_t graph = {0,};
- int ret = -1;
-
- graph.errstr = op_errstr;
-
- if (!glusterd_is_volume_replicate (volinfo)) {
- ret = 0;
- goto out;
- }
- ret = dict_set_str (val_dict, "graph-check", "on");
- if (ret)
- goto out;
- ret = build_shd_graph (&graph, val_dict);
- if (!ret)
- ret = graph_reconf_validateopt (&graph.graph, op_errstr);
-
- volgen_graph_free (&graph);
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
-out:
- dict_del (val_dict, "graph-check");
- return ret;
-}
-
-int
validate_nfsopts (glusterd_volinfo_t *volinfo,
dict_t *val_dict,
char **op_errstr)
{
volgen_graph_t graph = {0,};
int ret = -1;
- char transport_type[16] = {0,};
- char *tt = NULL;
- char err_str[4096] = {0,};
graph.errstr = op_errstr;
- get_vol_transport_type (volinfo, transport_type);
- ret = dict_get_str (val_dict, "nfs.transport-type", &tt);
- if (!ret) {
- if (volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) {
- snprintf (err_str, sizeof (err_str), "Changing nfs "
- "transport type is allowed only for volumes "
- "of transport type tcp,rdma");
- gf_log ("", GF_LOG_ERROR, "%s", err_str);
- *op_errstr = gf_strdup (err_str);
- ret = -1;
- goto out;
- }
- if (strcmp (tt,"tcp") && strcmp (tt,"rdma")) {
- snprintf (err_str, sizeof (err_str), "wrong transport "
- "type %s", tt);
- *op_errstr = gf_strdup (err_str);
- ret = -1;
- goto out;
- }
- }
-
ret = build_nfs_graph (&graph, val_dict);
if (!ret)
ret = graph_reconf_validateopt (&graph.graph, op_errstr);
volgen_graph_free (&graph);
-out:
gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
int
-validate_wb_eagerlock (glusterd_volinfo_t *volinfo, dict_t *val_dict,
- char **op_errstr)
-{
- int ret = -1;
- gf_boolean_t wb_val = _gf_false;
- gf_boolean_t el_val = _gf_false;
- char msg[2048] = {0};
- char *wb_key = NULL;
- char *el_key = NULL;
-
- wb_key = "performance.write-behind";
- el_key = "cluster.eager-lock";
- ret = dict_get_str_boolean (val_dict, wb_key, -1);
- if (ret < 0)
- goto check_eager_lock;
- wb_val = ret;
- ret = glusterd_volinfo_get_boolean (volinfo, el_key);
- if (ret < 0)
- goto out;
- el_val = ret;
- goto done;
-
-check_eager_lock:
- ret = dict_get_str_boolean (val_dict, el_key, -1);
- if (ret < 0) {
- ret = 0; //Keys of intereset to this fn are not present.
- goto out;
- }
- el_val = ret;
- ret = glusterd_volinfo_get_boolean (volinfo, wb_key);
- if (ret < 0)
- goto out;
- wb_val = ret;
- goto done;
-
-done:
- ret = 0;
- if (!wb_val && el_val) {
- ret = -1;
- snprintf (msg, sizeof (msg), "%s off and %s on is not "
- "valid configuration", wb_key, el_key);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- if (op_errstr)
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-out:
- return ret;
-}
-
-int
validate_clientopts (glusterd_volinfo_t *volinfo,
- dict_t *val_dict,
- char **op_errstr)
+ dict_t *val_dict,
+ char **op_errstr)
{
volgen_graph_t graph = {0,};
- int ret = -1;
+ int ret = -1;
GF_ASSERT (volinfo);
@@ -3655,7 +2170,7 @@ validate_brickopts (glusterd_volinfo_t *volinfo,
char **op_errstr)
{
volgen_graph_t graph = {0,};
- int ret = -1;
+ int ret = -1;
GF_ASSERT (volinfo);
@@ -3690,8 +2205,8 @@ glusterd_validate_brickreconf (glusterd_volinfo_t *volinfo,
}
ret = 0;
-
out:
+
return ret;
}
@@ -3734,20 +2249,11 @@ glusterd_validate_globalopts (glusterd_volinfo_t *volinfo,
}
ret = validate_nfsopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Could not Validate nfs");
- goto out;
- }
- ret = validate_shdopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Could not Validate self-heald");
- goto out;
- }
out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
static void
@@ -3781,10 +2287,6 @@ glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict,
goto out;
}
- ret = validate_wb_eagerlock (volinfo, val_dict, op_errstr);
- if (ret)
- goto out;
-
ret = validate_clientopts (volinfo, val_dict, op_errstr);
if (ret) {
gf_log ("", GF_LOG_DEBUG,
@@ -3793,20 +2295,9 @@ glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict,
}
ret = validate_nfsopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Could not Validate nfs");
- goto out;
- }
-
-
- ret = validate_shdopts (volinfo, val_dict, op_errstr);
- if (ret) {
- gf_log ("", GF_LOG_DEBUG, "Could not Validate self-heald");
- goto out;
- }
out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h
index 9e8370c94..518ae94ad 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.h
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -36,31 +36,6 @@
#define VKEY_FEATURES_QUOTA "features.quota"
#define VKEY_PERF_STAT_PREFETCH "performance.stat-prefetch"
-typedef enum {
- GF_CLIENT_TRUSTED,
- GF_CLIENT_OTHER
-} glusterd_client_type_t;
-
-#define COMPLETE_OPTION(key, completion, ret) \
- do { \
- if (!strchr (key, '.')) { \
- ret = option_complete (key, &completion); \
- if (ret) { \
- gf_log ("", GF_LOG_ERROR, "Out of memory"); \
- return _gf_false; \
- } \
- \
- if (!completion) { \
- gf_log ("", GF_LOG_ERROR, "option %s does not" \
- "exist", key); \
- return _gf_false; \
- } \
- } \
- \
- if (completion) \
- GF_FREE (completion); \
- } while (0);
-
typedef enum gd_volopt_flags_ {
OPT_FLAG_NONE,
OPT_FLAG_FORCE = 1,
@@ -73,10 +48,7 @@ int glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo);
void glusterd_get_nfs_filepath (char *filename);
-void glusterd_get_shd_filepath (char *filename);
-
int glusterd_create_nfs_volfile ();
-int glusterd_create_shd_volfile ();
int glusterd_delete_volfile (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo);
@@ -90,12 +62,6 @@ int glusterd_validate_localopts (dict_t *val_dict, char **op_errstr);
gf_boolean_t glusterd_check_globaloption (char *key);
gf_boolean_t
glusterd_check_voloption_flags (char *key, int32_t flags);
-gf_boolean_t
-glusterd_is_valid_volfpath (char *volname, char *brick);
-int generate_brick_volfiles (glusterd_volinfo_t *volinfo);
-int glusterd_get_volopt_content (gf_boolean_t xml_out);
-char*
-glusterd_get_trans_type_rb (gf_transport_type ttype);
-int
-glusterd_check_nfs_volfile_identical (gf_boolean_t *identical);
+
+
#endif
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
deleted file mode 100644
index 829985022..000000000
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ /dev/null
@@ -1,1921 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "common-utils.h"
-#include "syscall.h"
-#include "cli1-xdr.h"
-#include "xdr-generic.h"
-#include "glusterd.h"
-#include "glusterd-op-sm.h"
-#include "glusterd-store.h"
-#include "glusterd-utils.h"
-#include "glusterd-volgen.h"
-#include "run.h"
-
-#define glusterd_op_start_volume_args_get(dict, volname, flags) \
- glusterd_op_stop_volume_args_get (dict, volname, flags)
-
-int
-glusterd_handle_create_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char *brick = NULL;
- char *bricks = NULL;
- char *volname = NULL;
- int brick_count = 0;
- char *tmpptr = NULL;
- int i = 0;
- char *brick_list = NULL;
- void *cli_rsp = NULL;
- char err_str[2048] = {0,};
- gf_cli_rsp rsp = {0,};
- xlator_t *this = NULL;
- char *free_ptr = NULL;
- char *trans_type = NULL;
- uuid_t volume_id = {0,};
- uuid_t tmp_uuid = {0};
- glusterd_volinfo_t tmpvolinfo = {{0},};
- int32_t type = 0;
- char *username = NULL;
- char *password = NULL;
-
- GF_ASSERT (req);
-
- INIT_LIST_HEAD (&tmpvolinfo.bricks);
-
- this = THIS;
- GF_ASSERT(this);
-
- ret = -1;
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- snprintf (err_str, sizeof (err_str), "Garbage args received");
- goto out;
- }
-
- gf_log ("glusterd", GF_LOG_INFO, "Received create volume req");
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- snprintf (err_str, sizeof (err_str), "Unable to decode "
- "the buffer");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "name");
- goto out;
- }
- gf_cmd_log ("Volume create", "on volname: %s attempted", volname);
-
- if ((ret = glusterd_check_volume_exists (volname))) {
- snprintf(err_str, 2048, "Volume %s already exists", volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", err_str);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "brick count");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "type", &type);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get type");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "type");
- goto out;
- }
-
- ret = dict_get_str (dict, "transport", &trans_type);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get transport-type");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "transport-type");
- goto out;
- }
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
- snprintf (err_str, sizeof (err_str), "Unable to get volume "
- "bricks");
- goto out;
- }
-
- uuid_generate (volume_id);
- free_ptr = gf_strdup (uuid_utoa (volume_id));
- ret = dict_set_dynstr (dict, "volume-id", free_ptr);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "unable to set volume-id");
- snprintf (err_str, sizeof (err_str), "Unable to set volume "
- "id");
- goto out;
- }
- free_ptr = NULL;
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- free_ptr = brick_list;
- }
-
- gf_cmd_log ("Volume create", "on volname: %s type:%s count:%d bricks:%s",
- volname, ((type == 0)? "DEFAULT":
- ((type == 1)? "STRIPE":"REPLICATE")), brick_count, bricks);
-
-
- while ( i < brick_count) {
- i++;
- brick= strtok_r (brick_list, " \n", &tmpptr);
- brick_list = tmpptr;
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret) {
- snprintf (err_str, sizeof (err_str), "Unable to get "
- "brick info from brick %s", brick);
- goto out;
- }
-
- ret = glusterd_new_brick_validate (brick, brickinfo, err_str,
- sizeof (err_str));
- if (ret)
- goto out;
-
- list_add_tail (&brickinfo->brick_list, &tmpvolinfo.bricks);
- brickinfo = NULL;
- }
-
- /* generate internal username and password */
-
- uuid_generate (tmp_uuid);
- username = gf_strdup (uuid_utoa (tmp_uuid));
- ret = dict_set_dynstr (dict, "internal-username", username);
- if (ret)
- goto out;
-
- uuid_generate (tmp_uuid);
- password = gf_strdup (uuid_utoa (tmp_uuid));
- ret = dict_set_dynstr (dict, "internal-password", password);
- if (ret)
- goto out;
-
- ret = glusterd_op_begin (req, GD_OP_CREATE_VOLUME, dict);
- gf_cmd_log ("Volume create", "on volname: %s %s", volname,
- (ret != 0) ? "FAILED": "SUCCESS");
-
-out:
- if (ret) {
- if (dict)
- dict_unref (dict);
- rsp.op_ret = -1;
- rsp.op_errno = 0;
- if (err_str[0] == '\0')
- snprintf (err_str, sizeof (err_str), "Operation failed");
- rsp.op_errstr = err_str;
- cli_rsp = &rsp;
- glusterd_submit_reply(req, cli_rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_cli_rsp);
-
- ret = 0; //Client response sent, prevent second response
- }
-
- GF_FREE(free_ptr);
-
- glusterd_volume_brickinfos_delete (&tmpvolinfo);
- if (brickinfo)
- glusterd_brickinfo_delete (brickinfo);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- return ret;
-}
-
-int
-glusterd_handle_cli_start_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- char *volname = NULL;
- dict_t *dict = NULL;
- glusterd_op_t cli_op = GD_OP_START_VOLUME;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "dict get failed");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received start vol req"
- " for volume %s", volname);
-
- ret = glusterd_op_begin (req, GD_OP_START_VOLUME, dict);
-
- gf_cmd_log ("volume start","on volname: %s %s", volname,
- ((ret == 0) ? "SUCCESS": "FAILED"));
-
-out:
- if (ret && dict)
- dict_unref (dict);
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret)
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
-
- return ret;
-}
-
-
-int
-glusterd_handle_cli_stop_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- char *dup_volname = NULL;
- dict_t *dict = NULL;
- glusterd_op_t cli_op = GD_OP_STOP_VOLUME;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &dup_volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received stop vol req "
- "for volume %s", dup_volname);
-
- ret = glusterd_op_begin (req, GD_OP_STOP_VOLUME, dict);
- gf_cmd_log ("Volume stop","on volname: %s %s", dup_volname,
- ((ret)?"FAILED":"SUCCESS"));
-
-out:
- free (cli_req.dict.dict_val); //its malloced by xdr
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (dict)
- dict_unref (dict);
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_delete_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,},};
- glusterd_op_t cli_op = GD_OP_DELETE_VOLUME;
- dict_t *dict = NULL;
- char *volname = NULL;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "Failed to get volname");
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- gf_cmd_log ("Volume delete","on volname: %s attempted", volname);
-
- gf_log ("glusterd", GF_LOG_INFO, "Received delete vol req"
- "for volume %s", volname);
-
- ret = glusterd_op_begin (req, GD_OP_DELETE_VOLUME, dict);
- gf_cmd_log ("Volume delete", "on volname: %s %s", volname,
- ((ret) ? "FAILED" : "SUCCESS"));
-
-out:
- free (cli_req.dict.dict_val); //its malloced by xdr
- if (ret && dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, "operation failed");
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_heal_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- dict_t *dict = NULL;
- glusterd_op_t cli_op = GD_OP_HEAL_VOLUME;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
- char *op_errstr = NULL;
-
- GF_ASSERT (req);
-
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- this = THIS;
-
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- } else {
- dict->extra_stdfree = cli_req.dict.dict_val;
- }
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to get volname");
- gf_asprintf (&op_errstr, "Unable to find volume name");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_INFO, "Received heal vol req "
- "for volume %s", volname);
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- gf_asprintf (&op_errstr, "Volume %s does not exist", volname);
- goto out;
- }
-
- ret = glusterd_add_bricks_hname_path_to_dict (dict, volinfo);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (dict, "count", volinfo->brick_count);
- if (ret)
- goto out;
-
- ret = glusterd_op_begin (req, GD_OP_HEAL_VOLUME, dict);
-
- gf_cmd_log ("volume heal","on volname: %s %s", volname,
- ((ret == 0) ? "SUCCESS": "FAILED"));
-
-out:
- if (ret && dict)
- dict_unref (dict);
-
- glusterd_friend_sm ();
- glusterd_op_sm ();
-
- if (ret) {
- if (!op_errstr)
- op_errstr = gf_strdup ("operation failed");
- ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
- NULL, op_errstr);
- GF_FREE (op_errstr);
- }
-
- return ret;
-}
-
-int
-glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req)
-{
- int32_t ret = -1;
- gf_cli_req cli_req = {{0,}};
- char *volname = NULL;
- char *options = NULL;
- dict_t *dict = NULL;
- int32_t option_cnt = 0;
-
- GF_ASSERT (req);
-
- ret = -1;
- if (!xdr_to_generic (req->msg[0], &cli_req,
- (xdrproc_t)xdr_gf_cli_req)) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
- if (cli_req.dict.dict_len) {
- /* Unserialize the dictionary */
- dict = dict_new ();
-
- ret = dict_unserialize (cli_req.dict.dict_val,
- cli_req.dict.dict_len,
- &dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to "
- "unserialize req-buffer to dictionary");
- goto out;
- }
- }
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get volname");
- goto out;
- }
-
- ret = dict_get_str (dict, "options", &options);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get options");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "option_cnt", &option_cnt);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "failed to get option cnt");
- goto out;
- }
-
-
- gf_log ("glusterd", GF_LOG_INFO, "Received statedump request for "
- "volume %s with options %s", volname, options);
-
- ret = glusterd_op_begin (req, GD_OP_STATEDUMP_VOLUME, dict);
-
- gf_cmd_log ("statedump", "on volume %s %s", volname,
- ((0 == ret) ? "SUCCEEDED" : "FAILED"));
-
-out:
- if (ret && dict)
- dict_unref (dict);
- free (cli_req.dict.dict_val);
- glusterd_friend_sm ();
- glusterd_op_sm();
-
- return ret;
-}
-
-/* op-sm */
-int
-glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- char *bricks = NULL;
- char *brick_list = NULL;
- char *free_ptr = NULL;
- glusterd_brickinfo_t *brick_info = NULL;
- int32_t brick_count = 0;
- int32_t i = 0;
- char *brick = NULL;
- char *tmpptr = NULL;
- char cmd_str[1024];
- xlator_t *this = NULL;
- glusterd_conf_t *priv = NULL;
- char msg[2048] = {0};
- uuid_t volume_uuid;
- char *volume_uuid_str;
-
- this = THIS;
- if (!this) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "this is NULL");
- goto out;
- }
-
- priv = this->private;
- if (!priv) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "priv is NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
-
- if (exists) {
- snprintf (msg, sizeof (msg), "Volume %s already exists",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
- ret = dict_get_int32 (dict, "count", &brick_count);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
- ret = dict_get_str (dict, "volume-id", &volume_uuid_str);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume id");
- goto out;
- }
- ret = uuid_parse (volume_uuid_str, volume_uuid);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to parse volume id");
- goto out;
- }
-
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get bricks");
- goto out;
- }
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- if (!brick_list) {
- ret = -1;
- gf_log ("", GF_LOG_ERROR, "Out of memory");
- goto out;
- } else {
- free_ptr = brick_list;
- }
- }
-
- while ( i < brick_count) {
- i++;
- brick= strtok_r (brick_list, " \n", &tmpptr);
- brick_list = tmpptr;
-
- if (!glusterd_store_is_valid_brickpath (volname, brick) ||
- !glusterd_is_valid_volfpath (volname, brick)) {
- snprintf (msg, sizeof (msg), "brick path %s is too "
- "long.", brick);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
-
- ret = -1;
- goto out;
- }
-
- ret = glusterd_brickinfo_new_from_brick (brick, &brick_info);
- if (ret)
- goto out;
- snprintf (cmd_str, 1024, "%s", brick_info->path);
- ret = glusterd_resolve_brick (brick_info);
- if (ret) {
- gf_log ("glusterd", GF_LOG_ERROR, "cannot resolve "
- "brick: %s:%s", brick_info->hostname,
- brick_info->path);
- goto out;
- }
-
- if (!uuid_compare (brick_info->uuid, MY_UUID)) {
- ret = glusterd_brick_create_path (brick_info->hostname,
- brick_info->path,
- volume_uuid,
- op_errstr);
- if (ret)
- goto out;
- brick_list = tmpptr;
- }
- glusterd_brickinfo_delete (brick_info);
- brick_info = NULL;
- }
-out:
- GF_FREE (free_ptr);
- if (brick_info)
- glusterd_brickinfo_delete (brick_info);
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stop_volume_args_get (dict_t *dict, char** volname, int *flags)
-{
- int ret = -1;
-
- if (!dict || !volname || !flags)
- goto out;
-
- ret = dict_get_str (dict, "volname", volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "flags", flags);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get flags");
- goto out;
- }
-out:
- return ret;
-}
-
-int
-glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname,
- char **options, int *option_cnt)
-{
- int ret = -1;
-
- if (!dict || !volname || !options || !option_cnt)
- goto out;
-
- ret = dict_get_str (dict, "volname", volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volname");
- goto out;
- }
-
- ret = dict_get_str (dict, "options", options);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get options");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "option_cnt", option_cnt);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get option count");
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- int flags = 0;
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
- char msg[2048];
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
- if (!priv) {
- gf_log ("glusterd", GF_LOG_ERROR,
- "priv is NULL");
- ret = -1;
- goto out;
- }
-
- ret = glusterd_op_start_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- exists = glusterd_check_volume_exists (volname);
-
- if (!exists) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist", volname);
- gf_log ("", GF_LOG_ERROR, "%s",
- msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- } else {
- ret = 0;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_resolve_brick (brickinfo);
- if (ret) {
- gf_log ("", GF_LOG_ERROR,
- "Unable to resolve brick %s:%s",
- brickinfo->hostname, brickinfo->path);
- goto out;
- }
-
- if (!(flags & GF_CLI_FLAG_OP_FORCE)) {
- if (glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof (msg), "Volume %s already"
- " started", volname);
- gf_log ("glusterd", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- }
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- int flags = 0;
- gf_boolean_t exists = _gf_false;
- gf_boolean_t is_run = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char msg[2048] = {0};
-
-
- ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- exists = glusterd_check_volume_exists (volname);
-
- if (!exists) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist", volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- /* If 'force' flag is given, no check is required */
- if (flags & GF_CLI_FLAG_OP_FORCE)
- goto out;
-
- if (_gf_false == glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof(msg), "Volume %s "
- "is not in the started state", volname);
- gf_log ("", GF_LOG_ERROR, "Volume %s "
- "has not been started", volname);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- ret = glusterd_check_gsync_running (volinfo, &is_run);
- if (ret && (is_run == _gf_false))
- gf_log ("", GF_LOG_WARNING, "Unable to get the status"
- " of active "GEOREP" session");
- if (is_run) {
- gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"
- "for the volume %s ", volname);
- snprintf (msg, sizeof(msg), GEOREP" sessions are active "
- "for the volume '%s'.\nUse 'volume "GEOREP" "
- "status' command for more info. Use 'force'"
- "option to ignore and stop stop the volume",
- volname);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (glusterd_is_rb_ongoing (volinfo)) {
- snprintf (msg, sizeof (msg), "Replace brick is in progress on "
- "volume %s. Please retry after replace-brick "
- "operation is committed or aborted", volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- if (glusterd_is_defrag_on (volinfo)) {
- snprintf (msg, sizeof(msg), "rebalance session is "
- "in progress for the volume '%s'", volname);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
- if (volinfo->rb_status != GF_RB_STATUS_NONE) {
- snprintf (msg, sizeof(msg), "replace-brick session is "
- "in progress for the volume '%s'", volname);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
-out:
-
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t exists = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char msg[2048] = {0};
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- exists = glusterd_check_volume_exists (volname);
-
- if (!exists) {
- snprintf (msg, sizeof (msg), "Volume %s does not exist",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- } else {
- ret = 0;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- if (glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof (msg), "Volume %s has been started."
- "Volume needs to be stopped before deletion.",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- gf_boolean_t enabled = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char msg[2048];
- glusterd_conf_t *priv = NULL;
- dict_t *opt_dict = NULL;
- gf_xl_afr_op_t heal_op = GF_AFR_OP_INVALID;
-
- priv = THIS->private;
- if (!priv) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_ERROR,
- "priv is NULL");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Volume %s does not exist", volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- if (!glusterd_is_volume_replicate (volinfo)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Volume %s is not of type "
- "replicate", volname);
- *op_errstr = gf_strdup (msg);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- goto out;
- }
-
- if (!glusterd_is_volume_started (volinfo)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Volume %s is not started.",
- volname);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- opt_dict = volinfo->dict;
- if (!opt_dict) {
- ret = 0;
- goto out;
- }
-
- enabled = dict_get_str_boolean (opt_dict, "cluster.self-heal-daemon",
- 1);
- if (!enabled) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Self-heal-daemon is "
- "disabled. Heal will not be triggered on volume %s",
- volname);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- if (!glusterd_nodesvc_is_running ("glustershd")) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Self-heal daemon is not "
- "running. Check self-heal daemon log file.");
- *op_errstr = gf_strdup (msg);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- goto out;
- }
-
- ret = dict_get_int32 (dict, "heal-op", (int32_t*)&heal_op);
- if (ret || (heal_op == GF_AFR_OP_INVALID)) {
- ret = -1;
- snprintf (msg, sizeof (msg), "Invalid heal-op");
- *op_errstr = gf_strdup (msg);
- gf_log (THIS->name, GF_LOG_WARNING, "%s", msg);
- goto out;
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
-
- return ret;
-}
-
-int
-glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- char *options = NULL;
- int option_cnt = 0;
- gf_boolean_t is_running = _gf_false;
- glusterd_volinfo_t *volinfo = NULL;
- char msg[2408] = {0,};
-
- ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options,
- &option_cnt);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof(msg), "Volume %s does not exist",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- is_running = glusterd_is_volume_started (volinfo);
- if (!is_running) {
- snprintf (msg, sizeof(msg), "Volume %s is not in a started"
- " state", volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- ret = -1;
- goto out;
- }
-
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_stage_clearlocks_volume (dict_t *dict, char **op_errstr)
-{
- int ret = -1;
- char *volname = NULL;
- char *path = NULL;
- char *type = NULL;
- char *kind = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- char msg[2048] = {0,};
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- snprintf (msg, sizeof(msg), "Failed to get volume name");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = dict_get_str (dict, "path", &path);
- if (ret) {
- snprintf (msg, sizeof(msg), "Failed to get path");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = dict_get_str (dict, "kind", &kind);
- if (ret) {
- snprintf (msg, sizeof(msg), "Failed to get kind");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = dict_get_str (dict, "type", &type);
- if (ret) {
- snprintf (msg, sizeof(msg), "Failed to get type");
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof(msg), "Volume %s does not exist",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = glusterd_validate_volume_id (dict, volinfo);
- if (ret)
- goto out;
-
- if (!glusterd_is_volume_started (volinfo)) {
- snprintf (msg, sizeof(msg), "Volume %s is not started",
- volname);
- gf_log ("", GF_LOG_ERROR, "%s", msg);
- *op_errstr = gf_strdup (msg);
- goto out;
- }
-
- ret = 0;
-out:
- gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-
-int
-glusterd_op_create_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- gf_boolean_t vol_added = _gf_false;
- glusterd_brickinfo_t *brickinfo = NULL;
- xlator_t *this = NULL;
- char *brick = NULL;
- int32_t count = 0;
- int32_t i = 1;
- char *bricks = NULL;
- char *brick_list = NULL;
- char *free_ptr = NULL;
- char *saveptr = NULL;
- char *trans_type = NULL;
- char *str = NULL;
- char *username = NULL;
- char *password = NULL;
-
- this = THIS;
- GF_ASSERT (this);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = glusterd_volinfo_new (&volinfo);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to allocate memory");
- goto out;
- }
-
- ret = dict_get_str (dict, "volname", &volname);
-
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get volume name");
- goto out;
- }
-
- strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME);
- GF_ASSERT (volinfo->volname);
-
- ret = dict_get_int32 (dict, "type", &volinfo->type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get type");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "count", &volinfo->brick_count);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get count");
- goto out;
- }
-
- ret = dict_get_int32 (dict, "port", &volinfo->port);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get port");
- goto out;
- }
-
- count = volinfo->brick_count;
-
- ret = dict_get_str (dict, "bricks", &bricks);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Unable to get bricks");
- goto out;
- }
-
- /* replica-count 1 means, no replication, file is in one brick only */
- volinfo->replica_count = 1;
- /* stripe-count 1 means, no striping, file is present as a whole */
- volinfo->stripe_count = 1;
-
- if (GF_CLUSTER_TYPE_REPLICATE == volinfo->type) {
- ret = dict_get_int32 (dict, "replica-count",
- &volinfo->replica_count);
- if (ret)
- goto out;
- } else if (GF_CLUSTER_TYPE_STRIPE == volinfo->type) {
- ret = dict_get_int32 (dict, "stripe-count",
- &volinfo->stripe_count);
- if (ret)
- goto out;
- } else if (GF_CLUSTER_TYPE_STRIPE_REPLICATE == volinfo->type) {
- ret = dict_get_int32 (dict, "stripe-count",
- &volinfo->stripe_count);
- if (ret)
- goto out;
- ret = dict_get_int32 (dict, "replica-count",
- &volinfo->replica_count);
- if (ret)
- goto out;
- }
-
- /* dist-leaf-count is the count of brick nodes for a given
- subvolume of distribute */
- volinfo->dist_leaf_count = (volinfo->stripe_count *
- volinfo->replica_count);
-
- /* Keep sub-count same as earlier, for the sake of backward
- compatibility */
- if (volinfo->dist_leaf_count > 1)
- volinfo->sub_count = volinfo->dist_leaf_count;
-
- ret = dict_get_str (dict, "transport", &trans_type);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get transport");
- goto out;
- }
-
- ret = dict_get_str (dict, "volume-id", &str);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to get volume-id");
- goto out;
- }
- ret = uuid_parse (str, volinfo->volume_id);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to parse uuid %s", str);
- goto out;
- }
-
- ret = dict_get_str (dict, "internal-username", &username);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to get internal username");
- goto out;
- }
- glusterd_auth_set_username (volinfo, username);
-
- ret = dict_get_str (dict, "internal-password", &password);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "unable to get internal password");
- goto out;
- }
- glusterd_auth_set_password (volinfo, password);
-
- if (strcasecmp (trans_type, "rdma") == 0) {
- volinfo->transport_type = GF_TRANSPORT_RDMA;
- volinfo->nfs_transport_type = GF_TRANSPORT_RDMA;
- } else if (strcasecmp (trans_type, "tcp") == 0) {
- volinfo->transport_type = GF_TRANSPORT_TCP;
- volinfo->nfs_transport_type = GF_TRANSPORT_TCP;
- } else {
- volinfo->transport_type = GF_TRANSPORT_BOTH_TCP_RDMA;
- volinfo->nfs_transport_type = GF_DEFAULT_NFS_TRANSPORT;
- }
-
- if (bricks) {
- brick_list = gf_strdup (bricks);
- free_ptr = brick_list;
- }
-
- if (count)
- brick = strtok_r (brick_list+1, " \n", &saveptr);
-
- while ( i <= count) {
- ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo);
- if (ret)
- goto out;
-
- ret = glusterd_resolve_brick (brickinfo);
- if (ret)
- goto out;
- list_add_tail (&brickinfo->brick_list, &volinfo->bricks);
- brick = strtok_r (NULL, " \n", &saveptr);
- i++;
- }
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret) {
- glusterd_store_delete_volume (volinfo);
- *op_errstr = gf_strdup ("Failed to store the Volume information");
- goto out;
- }
-
- ret = glusterd_create_volfiles_and_notify_services (volinfo);
- if (ret) {
- *op_errstr = gf_strdup ("Failed to create volume files");
- goto out;
- }
-
- ret = glusterd_volume_compute_cksum (volinfo);
- if (ret) {
- *op_errstr = gf_strdup ("Failed to compute checksum of volume");
- goto out;
- }
-
- volinfo->defrag_status = 0;
- list_add_tail (&volinfo->vol_list, &priv->volumes);
- vol_added = _gf_true;
-out:
- GF_FREE(free_ptr);
- if (!vol_added && volinfo)
- glusterd_volinfo_delete (volinfo);
- return ret;
-}
-
-int
-glusterd_op_start_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- int flags = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- ret = glusterd_op_start_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_brick_start (volinfo, brickinfo);
- if (ret)
- goto out;
- }
-
- glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STARTED);
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
-
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d ", ret);
- return ret;
-}
-
-
-int
-glusterd_op_stop_volume (dict_t *dict)
-{
- int ret = 0;
- int flags = 0;
- char *volname = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- ret = glusterd_op_stop_volume_args_get (dict, &volname, &flags);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_brick_stop (volinfo, brickinfo);
- if (ret)
- goto out;
- }
-
- glusterd_set_volume_status (volinfo, GLUSTERD_STATUS_STOPPED);
-
- ret = glusterd_store_volinfo (volinfo, GLUSTERD_VOLINFO_VER_AC_INCREMENT);
- if (ret)
- goto out;
-
- ret = glusterd_nodesvcs_handle_graph_change (volinfo);
-out:
- return ret;
-}
-
-int
-glusterd_op_delete_volume (dict_t *dict)
-{
- int ret = 0;
- char *volname = NULL;
- glusterd_conf_t *priv = NULL;
- glusterd_volinfo_t *volinfo = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
- GF_ASSERT (this);
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log ("", GF_LOG_ERROR, "Unable to get volume name");
- goto out;
- }
-
- ret = glusterd_volinfo_find (volname, &volinfo);
-
- if (ret)
- goto out;
-
- ret = glusterd_delete_volume (volinfo);
-out:
- gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
- return ret;
-}
-
-int
-glusterd_op_heal_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- /* Necessary subtasks of heal are completed in brick op */
-
- return ret;
-}
-
-int
-glusterd_op_statedump_volume (dict_t *dict, char **op_errstr)
-{
- int ret = 0;
- char *volname = NULL;
- char *options = NULL;
- int option_cnt = 0;
- glusterd_volinfo_t *volinfo = NULL;
- glusterd_brickinfo_t *brickinfo = NULL;
-
- ret = glusterd_op_statedump_volume_args_get (dict, &volname, &options,
- &option_cnt);
- if (ret)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret)
- goto out;
- gf_log ("", GF_LOG_DEBUG, "Performing statedump on volume %s", volname);
- if (strstr (options, "nfs") != NULL) {
- ret = glusterd_nfs_statedump (options, option_cnt, op_errstr);
- if (ret)
- goto out;
- } else {
- list_for_each_entry (brickinfo, &volinfo->bricks,
- brick_list) {
- ret = glusterd_brick_statedump (volinfo, brickinfo,
- options, option_cnt,
- op_errstr);
- /* Let us take the statedump of other bricks instead of
- * exiting, if statedump of this brick fails.
- */
- if (ret)
- gf_log (THIS->name, GF_LOG_WARNING, "could not "
- "take the statedump of the brick %s:%s."
- " Proceeding to other bricks",
- brickinfo->hostname, brickinfo->path);
- }
- }
-
-out:
- return ret;
-}
-
-int
-glusterd_clearlocks_send_cmd (glusterd_volinfo_t *volinfo, char *cmd,
- char *path, char *result, char *errstr,
- int err_len, char *mntpt)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- char abspath[PATH_MAX] = {0, };
-
- priv = THIS->private;
-
- snprintf (abspath, sizeof (abspath), "%s/%s", mntpt, path);
- ret = sys_lgetxattr (abspath, cmd, result, PATH_MAX);
- if (ret < 0) {
- snprintf (errstr, err_len, "clear-locks getxattr command "
- "failed. Reason: %s", strerror (errno));
- gf_log (THIS->name, GF_LOG_DEBUG, "%s", errstr);
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_clearlocks_rmdir_mount (glusterd_volinfo_t *volinfo, char *mntpt)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
-
- priv = THIS->private;
-
- ret = rmdir (mntpt);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG, "rmdir failed");
- goto out;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-void
-glusterd_clearlocks_unmount (glusterd_volinfo_t *volinfo, char *mntpt)
-{
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- int ret = 0;
-
- priv = THIS->private;
-
- /*umount failures are ignored. Using stat we could have avoided
- * attempting to unmount a non-existent filesystem. But a failure of
- * stat() on mount can be due to network failures.*/
-
- runinit (&runner);
- runner_add_args (&runner, "/bin/umount", "-f", NULL);
- runner_argprintf (&runner, "%s", mntpt);
-
- ret = runner_run (&runner);
- if (ret) {
- ret = 0;
- gf_log ("", GF_LOG_DEBUG,
- "umount failed on maintenance client");
- }
-
- return;
-}
-
-int
-glusterd_clearlocks_create_mount (glusterd_volinfo_t *volinfo, char **mntpt)
-{
- int ret = -1;
- glusterd_conf_t *priv = NULL;
- char template[PATH_MAX] = {0,};
- char *tmpl = NULL;
-
- priv = THIS->private;
-
- snprintf (template, sizeof (template), "/tmp/%s.XXXXXX",
- volinfo->volname);
- tmpl = mkdtemp (template);
- if (!tmpl) {
- gf_log (THIS->name, GF_LOG_DEBUG, "Couldn't create temporary "
- "mount directory. Reason %s", strerror (errno));
- goto out;
- }
-
- *mntpt = gf_strdup (tmpl);
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_clearlocks_mount (glusterd_volinfo_t *volinfo, char **xl_opts,
- char *mntpt)
-{
- int ret = -1;
- int i = 0;
- glusterd_conf_t *priv = NULL;
- runner_t runner = {0,};
- char client_volfpath[PATH_MAX] = {0,};
- char self_heal_opts[3][1024] = {"*replicate*.data-self-heal=off",
- "*replicate*.metadata-self-heal=off",
- "*replicate*.entry-self-heal=off"};
-
- priv = THIS->private;
-
- runinit (&runner);
- glusterd_get_trusted_client_filepath (client_volfpath, volinfo,
- volinfo->transport_type);
- runner_add_args (&runner, SBIN_DIR"/glusterfs", "-f", NULL);
- runner_argprintf (&runner, "%s", client_volfpath);
- runner_add_arg (&runner, "-l");
- runner_argprintf (&runner, DEFAULT_LOG_FILE_DIRECTORY
- "/%s-clearlocks-mnt.log", volinfo->volname);
- if (volinfo->memory_accounting)
- runner_add_arg (&runner, "--mem-accounting");
-
- for (i = 0; i < volinfo->brick_count && xl_opts[i]; i++) {
- runner_add_arg (&runner, "--xlator-option");
- runner_argprintf (&runner, "%s", xl_opts[i]);
- }
-
- for (i = 0; i < 3; i++) {
- runner_add_args (&runner, "--xlator-option",
- self_heal_opts[i], NULL);
- }
-
- runner_argprintf (&runner, "%s", mntpt);
- ret = runner_run (&runner);
- if (ret) {
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Could not start glusterfs");
- goto out;
- }
- gf_log (THIS->name, GF_LOG_DEBUG,
- "Started glusterfs successfully");
-
-out:
- return ret;
-}
-
-int
-glusterd_clearlocks_get_local_client_ports (glusterd_volinfo_t *volinfo,
- char **xl_opts)
-{
- glusterd_brickinfo_t *brickinfo = NULL;
- glusterd_conf_t *priv = NULL;
- int index = 0;
- int ret = -1;
- int i = 0;
- int port = 0;
-
- GF_ASSERT (xl_opts);
- if (!xl_opts) {
- gf_log (THIS->name, GF_LOG_DEBUG, "Should pass non-NULL "
- "xl_opts");
- goto out;
- }
-
- priv = THIS->private;
-
- index = -1;
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- index++;
- if (uuid_compare (brickinfo->uuid, MY_UUID))
- continue;
-
- port = pmap_registry_search (THIS, brickinfo->path,
- GF_PMAP_PORT_BRICKSERVER);
- if (!port) {
- ret = -1;
- gf_log (THIS->name, GF_LOG_DEBUG, "Couldn't get port "
- " for brick %s:%s", brickinfo->hostname,
- brickinfo->path);
- goto out;
- }
-
- ret = gf_asprintf (&xl_opts[i], "%s-client-%d.remote-port=%d",
- volinfo->volname, index, port);
- if (ret == -1) {
- xl_opts[i] = NULL;
- goto out;
- }
- i++;
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr)
-{
- int32_t ret = -1;
- int i = 0;
- char *volname = NULL;
- char *path = NULL;
- char *kind = NULL;
- char *type = NULL;
- char *opts = NULL;
- char *cmd_str = NULL;
- char *free_ptr = NULL;
- char msg[PATH_MAX] = {0,};
- char result[PATH_MAX] = {0,};
- char *mntpt = NULL;
- char **xl_opts = NULL;
- dict_t *ctx = NULL;
- glusterd_volinfo_t *volinfo = NULL;
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get volume name");
- goto out;
- }
- gf_log ("", GF_LOG_DEBUG, "Performing clearlocks on volume %s", volname);
-
- ret = dict_get_str (dict, "path", &path);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get path");
- goto out;
- }
-
- ret = dict_get_str (dict, "kind", &kind);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get kind");
- goto out;
- }
-
- ret = dict_get_str (dict, "type", &type);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "Failed to get type");
- goto out;
- }
-
- ret = dict_get_str (dict, "opts", &opts);
- if (ret)
- ret = 0;
-
- gf_log (THIS->name, GF_LOG_INFO, "Received clear-locks request for "
- "volume %s with kind %s type %s and options %s", volname,
- kind, type, opts);
-
- if (opts)
- ret = gf_asprintf (&cmd_str, GF_XATTR_CLRLK_CMD".t%s.k%s.%s",
- type, kind, opts);
- else
- ret = gf_asprintf (&cmd_str, GF_XATTR_CLRLK_CMD".t%s.k%s",
- type, kind);
- if (ret == -1)
- goto out;
-
- ret = glusterd_volinfo_find (volname, &volinfo);
- if (ret) {
- snprintf (msg, sizeof (msg), "Volume %s doesn't exist.",
- volname);
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- xl_opts = GF_CALLOC (volinfo->brick_count+1, sizeof (char*),
- gf_gld_mt_charptr);
- if (!xl_opts)
- goto out;
-
- ret = glusterd_clearlocks_get_local_client_ports (volinfo, xl_opts);
- if (ret) {
- snprintf (msg, sizeof (msg), "Couldn't get port numbers of "
- "local bricks");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = glusterd_clearlocks_create_mount (volinfo, &mntpt);
- if (ret) {
- snprintf (msg, sizeof (msg), "Creating mount directory "
- "for clear-locks failed.");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = glusterd_clearlocks_mount (volinfo, xl_opts, mntpt);
- if (ret) {
- snprintf (msg, sizeof (msg), "Failed to mount clear-locks "
- "maintenance client.");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto out;
- }
-
- ret = glusterd_clearlocks_send_cmd (volinfo, cmd_str, path, result,
- msg, sizeof (msg), mntpt);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- goto umount;
- }
-
- ctx = glusterd_op_get_ctx ();
- if (!ctx)
- /*Impossible. Only originator glusterd can
- * come here. */
- goto umount;
-
- free_ptr = gf_strdup(result);
- if (dict_set_dynstr (ctx, "lk-summary", free_ptr)) {
- GF_FREE (free_ptr);
- snprintf (msg, sizeof (msg), "Failed to set clear-locks "
- "result");
- gf_log (THIS->name, GF_LOG_ERROR, "%s", msg);
- }
-
-umount:
- glusterd_clearlocks_unmount (volinfo, mntpt);
-
- if (glusterd_clearlocks_rmdir_mount (volinfo, mntpt))
- gf_log (THIS->name, GF_LOG_WARNING, "Couldn't unmount "
- "clear-locks mount point");
-
-out:
- if (ret)
- *op_errstr = gf_strdup (msg);
-
- if (xl_opts) {
- for (i = 0; i < volinfo->brick_count && xl_opts[i]; i++)
- GF_FREE (xl_opts[i]);
- GF_FREE (xl_opts);
- }
-
- GF_FREE (cmd_str);
-
- GF_FREE (mntpt);
-
- return ret;
-}
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
index 87914ee49..c7c5088db 100644
--- a/xlators/mgmt/glusterd/src/glusterd.c
+++ b/xlators/mgmt/glusterd/src/glusterd.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ GlusterFS is GF_FREE software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,7 +23,6 @@
#include "config.h"
#endif
#include <time.h>
-#include <grp.h>
#include <sys/uio.h>
#include <sys/resource.h>
@@ -44,23 +43,17 @@
#include "glusterd-sm.h"
#include "glusterd-op-sm.h"
#include "glusterd-store.h"
-#include "glusterd-hooks.h"
#include "glusterd-utils.h"
#include "common-utils.h"
-#include "run.h"
-
-#include "syncop.h"
-
-#include "glusterd-mountbroker.h"
static uuid_t glusterd_uuid;
+extern struct rpcsvc_program glusterd1_mop_prog;
+extern struct rpcsvc_program gd_svc_mgmt_prog;
+extern struct rpcsvc_program gd_svc_cli_prog;
extern struct rpcsvc_program gluster_handshake_prog;
extern struct rpcsvc_program gluster_pmap_prog;
extern glusterd_op_info_t opinfo;
-extern struct rpcsvc_program gd_svc_mgmt_prog;
-extern struct rpcsvc_program gd_svc_peer_prog;
-extern struct rpcsvc_program gd_svc_cli_prog;
-extern struct rpc_clnt_program gd_brick_prog;
+extern struct rpc_clnt_program glusterd_glusterfs_3_1_mgmt_prog;
rpcsvc_cbk_program_t glusterd_cbk_prog = {
.progname = "Gluster Callback",
@@ -74,26 +67,28 @@ glusterd_opinfo_init ()
{
int32_t ret = -1;
- opinfo.op = GD_OP_NONE;
+ ret = pthread_mutex_init (&opinfo.lock, NULL);
return ret;
}
-int
-glusterd_uuid_init ()
+static int
+glusterd_uuid_init (int flag)
{
int ret = -1;
glusterd_conf_t *priv = NULL;
priv = THIS->private;
- ret = glusterd_retrieve_uuid ();
- if (ret == 0) {
- uuid_copy (glusterd_uuid, priv->uuid);
- gf_log ("glusterd", GF_LOG_INFO,
- "retrieved UUID: %s", uuid_utoa (priv->uuid));
- return 0;
- }
+ if (!flag) {
+ ret = glusterd_retrieve_uuid ();
+ if (!ret) {
+ uuid_copy (glusterd_uuid, priv->uuid);
+ gf_log ("glusterd", GF_LOG_INFO,
+ "retrieved UUID: %s", uuid_utoa (priv->uuid));
+ return 0;
+ }
+ }
uuid_generate (glusterd_uuid);
@@ -224,111 +219,79 @@ int
glusterd_rpcsvc_options_build (dict_t *options)
{
int ret = 0;
- uint32_t backlog = 0;
- ret = dict_get_uint32 (options, "transport.socket.listen-backlog",
- &backlog);
-
- if (ret) {
- backlog = GLUSTERD_SOCKET_LISTEN_BACKLOG;
- ret = dict_set_uint32 (options,
- "transport.socket.listen-backlog",
- backlog);
+ if (!dict_get (options, "rpc-auth-allow-insecure")) {
+ ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
if (ret)
goto out;
}
-
- gf_log ("", GF_LOG_DEBUG, "listen-backlog value: %d", backlog);
-
out:
return ret;
}
+/* defined in usterd-utils.c -- no
+ * glusterd header where it would be
+ * appropriate to put to, and too
+ * accidental routine to place in
+ * libglusterfs.
+ *
+ * (Indeed, XXX: we'd rather need a general
+ * "mkdir -p" like routine in
+ * libglusterfs)
+ */
+extern int mkdir_if_missing (char *path);
+
#if SYNCDAEMON_COMPILE
static int
-glusterd_check_gsync_present (int *valid_state)
+glusterd_check_gsync_present ()
{
+ FILE *in = NULL;
char buff[PATH_MAX] = {0, };
- runner_t runner = {0,};
+ char cmd[PATH_MAX + 256] = {0, };
char *ptr = NULL;
int ret = 0;
- runinit (&runner);
- runner_add_args (&runner, GSYNCD_PREFIX"/gsyncd", "--version", NULL);
- runner_redir (&runner, STDOUT_FILENO, RUN_PIPE);
- ret = runner_start (&runner);
- if (ret == -1) {
- if (errno == ENOENT) {
- gf_log ("glusterd", GF_LOG_INFO, GEOREP
- " module not installed in the system");
- *valid_state = 0;
- }
- else {
- gf_log ("glusterd", GF_LOG_ERROR, GEOREP
- " module not working as desired");
- *valid_state = -1;
- }
+ if (strlen (GSYNCD_PREFIX)+1 > PATH_MAX-strlen("/gsyncd")) {
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (cmd, sizeof(cmd), GSYNCD_PREFIX"/gsyncd --version");
+
+ if (!(in = popen(cmd, "r"))) {
+ gf_log ("", GF_LOG_INFO, "geo-replication module not installed"
+ " in the system");
+ ret = -1;
goto out;
}
- ptr = fgets(buff, sizeof(buff), runner_chio (&runner, STDOUT_FILENO));
+ ptr = fgets(buff, sizeof(buff), in);
if (ptr) {
if (!strstr (buff, "gsyncd")) {
ret = -1;
- gf_log ("glusterd", GF_LOG_ERROR, GEOREP" module not "
- "working as desired");
- *valid_state = -1;
goto out;
}
} else {
ret = -1;
- gf_log ("glusterd", GF_LOG_ERROR, GEOREP" module not "
- "working as desired");
- *valid_state = -1;
goto out;
}
-
ret = 0;
out:
+ if ((in)&& (-1 == pclose (in))) {
+ ret = -1;
+ gf_log ("", GF_LOG_INFO, "geo-replication module not"
+ " installed in the system");
+ }
- runner_end (&runner);
-
- gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret);
+ gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
-static int
-group_write_allow (char *path, gid_t gid)
-{
- struct stat st = {0,};
- int ret = 0;
-
- ret = stat (path, &st);
- if (ret == -1)
- goto out;
- GF_ASSERT (S_ISDIR (st.st_mode));
-
- ret = chown (path, -1, gid);
- if (ret == -1)
- goto out;
-
- ret = chmod (path, (st.st_mode & ~S_IFMT) | S_IWGRP|S_IXGRP|S_ISVTX);
-
- out:
- if (ret == -1)
- gf_log ("", GF_LOG_CRITICAL,
- "failed to set up write access to %s for group %d (%s)",
- path, gid, strerror (errno));
- return ret;
-}
-
-static int
+int
glusterd_crt_georep_folders (char *georepdir, glusterd_conf_t *conf)
{
- char *greplg_s = NULL;
- struct group *gr = NULL;
- int ret = 0;
+ int ret = 0;
GF_ASSERT (georepdir);
GF_ASSERT (conf);
@@ -342,7 +305,7 @@ glusterd_crt_georep_folders (char *georepdir, glusterd_conf_t *conf)
}
snprintf (georepdir, PATH_MAX, "%s/"GEOREP, conf->workdir);
- ret = mkdir_p (georepdir, 0777, _gf_true);
+ ret = mkdir_if_missing (georepdir);
if (-1 == ret) {
gf_log ("glusterd", GF_LOG_CRITICAL,
"Unable to create "GEOREP" directory %s",
@@ -357,7 +320,7 @@ glusterd_crt_georep_folders (char *georepdir, glusterd_conf_t *conf)
georepdir);
goto out;
}
- ret = mkdir_p (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP, 0777, _gf_true);
+ ret = mkdir_if_missing (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP);
if (-1 == ret) {
gf_log ("glusterd", GF_LOG_CRITICAL,
"Unable to create "GEOREP" log directory");
@@ -371,190 +334,151 @@ glusterd_crt_georep_folders (char *georepdir, glusterd_conf_t *conf)
georepdir);
goto out;
}
- ret = mkdir_p (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves", 0777,
- _gf_true);
+ ret = mkdir_if_missing (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves");
if (-1 == ret) {
gf_log ("glusterd", GF_LOG_CRITICAL,
"Unable to create "GEOREP" slave log directory");
goto out;
}
-
- ret = dict_get_str (THIS->options, GEOREP"-log-group", &greplg_s);
- if (ret)
- ret = 0;
- else {
- gr = getgrnam (greplg_s);
- if (!gr) {
- gf_log ("glusterd", GF_LOG_CRITICAL,
- "group "GEOREP"-log-group %s does not exist", greplg_s);
- ret = -1;
- goto out;
- }
-
- ret = group_write_allow (DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP,
- gr->gr_gid);
- if (ret == 0)
- ret = group_write_allow (DEFAULT_LOG_FILE_DIRECTORY"/"
- GEOREP"-slaves", gr->gr_gid);
- }
-
+ ret = 0;
out:
gf_log("", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
-}
-#endif
-static void
-runinit_gsyncd_setrx (runner_t *runner, glusterd_conf_t *conf)
-{
- runinit (runner);
- runner_add_args (runner, GSYNCD_PREFIX"/gsyncd", "-c", NULL);
- runner_argprintf (runner, "%s/"GSYNC_CONF,conf->workdir);
- runner_add_arg (runner, "--config-set-rx");
}
+#endif
static int
configure_syncdaemon (glusterd_conf_t *conf)
-#define RUN_GSYNCD_CMD do { \
- ret = runner_run_reuse (&runner); \
- if (ret == -1) { \
- runner_log (&runner, "glusterd", GF_LOG_ERROR, "command failed"); \
- runner_end (&runner); \
- goto out; \
- } \
- runner_end (&runner); \
-} while (0)
{
int ret = 0;
#if SYNCDAEMON_COMPILE
- runner_t runner = {0,};
char georepdir[PATH_MAX] = {0,};
- int valid_state = 0;
+ char cmd[2*PATH_MAX + 1024] = {0,};
+ char volid[64] = {0,};
+ int blen = 0;
ret = setenv ("_GLUSTERD_CALLED_", "1", 1);
if (ret < 0) {
ret = 0;
goto out;
}
- valid_state = -1;
- ret = glusterd_check_gsync_present (&valid_state);
+
+ ret = glusterd_check_gsync_present ();
if (-1 == ret) {
- ret = valid_state;
+ ret = 0;
goto out;
}
+
glusterd_crt_georep_folders (georepdir, conf);
if (ret) {
ret = 0;
goto out;
}
+ blen = snprintf (cmd, sizeof(cmd), GSYNCD_PREFIX"/gsyncd -c %s/"
+ GSYNC_CONF " --config-set-rx ", conf->workdir);
+
+ /* Calling out to gsyncd to configure it:
+ * - use system(3) for options with multi-word values as system
+ * groks quotes;
+ * - use gf_system() for options with template expanders so
+ * that they are not messed up by shell
+ */
+
/************
* master pre-configuration
************/
/* remote-gsyncd */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "remote-gsyncd", GSYNCD_PREFIX"/gsyncd", ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "remote-gsyncd",
- "/usr/local/libexec/glusterfs/gsyncd", ".", "^ssh:", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-command-dir */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-params */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "gluster-params",
- "xlator-option=*-dht.assert-no-child-down=true",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ strcpy (cmd + blen, "remote-gsyncd " GSYNCD_PREFIX"/gsyncd . .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ strcpy (cmd + blen,
+ "remote-gsyncd /usr/local/libexec/glusterfs/gsyncd . ^ssh:");
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ /* gluster-command */
+ /* XXX $sbindir should be used (throughout the codebase) */
+ strcpy (cmd + blen,
+ "gluster-command '"GFS_PREFIX"/sbin/glusterfs "
+ "--xlator-option *-dht.assert-no-child-down=true' . .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
/* ssh-command */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "ssh-command");
- runner_argprintf (&runner,
- "ssh -oPasswordAuthentication=no "
- "-oStrictHostKeyChecking=no "
- "-i %s/secret.pem", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ sprintf (cmd + blen,
+ "ssh-command "
+ "'ssh -oPasswordAuthentication=no -oStrictHostKeyChecking=no "
+ "-i %s/secret.pem' . .", georepdir);
+ ret = system (cmd);
+ if (ret)
+ goto out;
+
+ /* session-owner */
+ uuid_unparse (conf->uuid, volid);
+ sprintf (cmd + blen, "session-owner %s . .", volid);
+ ret = system (cmd);
+ if (ret)
+ goto out;
/* pid-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "pid-file");
- runner_argprintf (&runner, "%s/${mastervol}/${eSlave}.pid", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ sprintf (cmd + blen, "pid-file %s/${mastervol}/${eSlave}.pid . .", georepdir);
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
/* state-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "state-file");
- runner_argprintf (&runner, "%s/${mastervol}/${eSlave}.status", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* state-socket */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_arg (&runner, "state-socket-unencoded");
- runner_argprintf (&runner, "%s/${mastervol}/${eSlave}.socket", georepdir);
- runner_add_args (&runner, ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ sprintf (cmd + blen, "state-file %s/${mastervol}/${eSlave}.status . .", georepdir);
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
/* log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ strcpy (cmd + blen,
+ "log-file "DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.log . .");
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
/* gluster-log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "gluster-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.gluster.log",
- ".", ".", NULL);
- RUN_GSYNCD_CMD;
+ strcpy (cmd + blen, "gluster-log-file "
+ DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"/${mastervol}/${eSlave}.gluster.log . .");
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
/************
* slave pre-configuration
************/
- /* gluster-command-dir */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "gluster-command-dir", SBIN_DIR"/",
- ".", NULL);
- RUN_GSYNCD_CMD;
-
- /* gluster-params */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner, "gluster-params",
- "xlator-option=*-dht.assert-no-child-down=true",
- ".", NULL);
- RUN_GSYNCD_CMD;
+ /* gluster-command */
+ strcpy (cmd + blen,
+ "gluster-command '"GFS_PREFIX"/sbin/glusterfs "
+ "--xlator-option *-dht.assert-no-child-down=true' .");
+ ret = system (cmd);
+ if (ret)
+ goto out;
/* log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
+ strcpy (cmd + blen,
+ "log-file "DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.log .");
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
/* gluster-log-file */
- runinit_gsyncd_setrx (&runner, conf);
- runner_add_args (&runner,
- "gluster-log-file",
- DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.gluster.log",
- ".", NULL);
- RUN_GSYNCD_CMD;
+ strcpy (cmd + blen, "gluster-log-file "
+ DEFAULT_LOG_FILE_DIRECTORY"/"GEOREP"-slaves/${session_owner}:${eSlave}.gluster.log .");
+ ret = gf_system (cmd);
+ if (ret)
+ goto out;
out:
#else
@@ -562,189 +486,7 @@ configure_syncdaemon (glusterd_conf_t *conf)
#endif
return ret ? -1 : 0;
}
-#undef RUN_GSYNCD_CMD
-static int
-check_prepare_mountbroker_root (char *mountbroker_root)
-{
- int dfd0 = -1;
- int dfd = -1;
- int dfd2 = -1;
- struct stat st = {0,};
- struct stat st2 = {0,};
- int ret = 0;
-
- ret = open (mountbroker_root, O_RDONLY);
- if (ret != -1) {
- dfd = ret;
- ret = fstat (dfd, &st);
- }
- if (ret == -1 || !S_ISDIR (st.st_mode)) {
- gf_log ("", GF_LOG_ERROR,
- "cannot access mountbroker-root directory %s",
- mountbroker_root);
- ret = -1;
- goto out;
- }
- if (st.st_uid != 0 ||
- (st.st_mode & (S_IWGRP|S_IWOTH))) {
- gf_log ("", GF_LOG_ERROR,
- "permissions on mountbroker-root directory %s are "
- "too liberal", mountbroker_root);
- ret = -1;
- goto out;
- }
- if (!(st.st_mode & (S_IXGRP|S_IXOTH))) {
- gf_log ("", GF_LOG_WARNING,
- "permissions on mountbroker-root directory %s are "
- "probably too strict", mountbroker_root);
- }
-
- dfd0 = dup (dfd);
-
- for (;;) {
- ret = openat (dfd, "..", O_RDONLY);
- if (ret != -1) {
- dfd2 = ret;
- ret = fstat (dfd2, &st2);
- }
- if (ret == -1) {
- gf_log ("", GF_LOG_ERROR,
- "error while checking mountbroker-root ancestors "
- "%d (%s)", errno, strerror (errno));
- goto out;
- }
-
- if (st2.st_ino == st.st_ino)
- break; /* arrived to root */
-
- if (st2.st_uid != 0 ||
- ((st2.st_mode & (S_IWGRP|S_IWOTH)) &&
- !(st2.st_mode & S_ISVTX))) {
- gf_log ("", GF_LOG_ERROR,
- "permissions on ancestors of mountbroker-root "
- "directory are too liberal");
- ret = -1;
- goto out;
- }
- if (!(st.st_mode & (S_IXGRP|S_IXOTH))) {
- gf_log ("", GF_LOG_WARNING,
- "permissions on ancestors of mountbroker-root "
- "directory are probably too strict");
- }
-
- close (dfd);
- dfd = dfd2;
- st = st2;
- }
-
- ret = mkdirat (dfd0, MB_HIVE, 0711);
- if (ret == -1 && errno == EEXIST)
- ret = 0;
- if (ret != -1)
- ret = fstatat (dfd0, MB_HIVE, &st, AT_SYMLINK_NOFOLLOW);
- if (ret == -1 || st.st_mode != (S_IFDIR|0711)) {
- gf_log ("", GF_LOG_ERROR,
- "failed to set up mountbroker-root directory %s",
- mountbroker_root);
- ret = -1;
- goto out;
- }
-
- ret = 0;
-
- out:
- if (dfd0 != -1)
- close (dfd0);
- if (dfd != -1)
- close (dfd);
- if (dfd2 != -1)
- close (dfd2);
-
- return ret;
-}
-
-static void
-_install_mount_spec (dict_t *opts, char *key, data_t *value, void *data)
-{
- glusterd_conf_t *priv = THIS->private;
- char *label = NULL;
- gf_boolean_t georep = _gf_false;
- gf_boolean_t ghadoop = _gf_false;
- char *pdesc = value->data;
- char *volname = NULL;
- int *ret = data;
- int rv = 0;
- gf_mount_spec_t *mspec = NULL;
- char *user = NULL;
- char *volfile_server = NULL;
-
- if (*ret == -1)
- return;
-
- label = strtail (key, "mountbroker.");
-
- /* check for presence of geo-rep/hadoop label */
- if (!label) {
- label = strtail (key, "mountbroker-"GEOREP".");
- if (label)
- georep = _gf_true;
- else {
- label = strtail (key, "mountbroker-"GHADOOP".");
- if (label)
- ghadoop = _gf_true;
- }
- }
-
- if (!label)
- return;
-
- mspec = GF_CALLOC (1, sizeof (*mspec), gf_gld_mt_mount_spec);
- if (!mspec)
- goto err;
- mspec->label = label;
-
- if (georep || ghadoop) {
- volname = gf_strdup (pdesc);
- if (!volname)
- goto err;
- user = strchr (volname, ':');
- if (user) {
- *user = '\0';
- user++;
- } else
- user = label;
-
- if (georep)
- rv = make_georep_mountspec (mspec, volname, user);
-
- if (ghadoop) {
- volfile_server = strchr (user, ':');
- if (volfile_server)
- *volfile_server++ = '\0';
- else
- volfile_server = "localhost";
-
- rv = make_ghadoop_mountspec (mspec, volname, user, volfile_server);
- }
-
- GF_FREE (volname);
- if (rv != 0)
- goto err;
- } else if (parse_mount_pattern_desc (mspec, pdesc) != 0)
- goto err;
-
- list_add_tail (&mspec->speclist, &priv->mount_specs);
-
- return;
- err:
-
- gf_log ("", GF_LOG_ERROR,
- "adding %smount spec failed: label: %s desc: %s",
- georep ? GEOREP" " : "", label, pdesc);
-
- *ret = -1;
-}
/*
* init - called during glusterd initialization
@@ -763,13 +505,8 @@ init (xlator_t *this)
char voldir [PATH_MAX] = {0,};
char dirname [PATH_MAX];
char cmd_log_filename [PATH_MAX] = {0,};
- char hooks_dir [PATH_MAX] = {0,};
int first_time = 0;
- char *mountbroker_root = NULL;
-#ifdef DEBUG
- char *valgrind_str = NULL;
-#endif
dir_data = dict_get (this->options, "working-directory");
if (!dir_data) {
@@ -804,7 +541,6 @@ init (xlator_t *this)
" ,errno = %d", dirname, errno);
exit (1);
}
-
first_time = 1;
}
@@ -861,19 +597,10 @@ init (xlator_t *this)
exit (1);
}
- snprintf (voldir, PATH_MAX, "%s/glustershd", dirname);
- ret = mkdir (voldir, 0777);
- if ((-1 == ret) && (errno != EEXIST)) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create glustershd directory %s"
- " ,errno = %d", voldir, errno);
- exit (1);
- }
-
ret = glusterd_rpcsvc_options_build (this->options);
if (ret)
goto out;
- rpc = rpcsvc_init (this, this->ctx, this->options, 64);
+ rpc = rpcsvc_init (this->ctx, this->options);
if (rpc == NULL) {
gf_log (this->name, GF_LOG_ERROR,
"failed to init rpc");
@@ -899,27 +626,27 @@ init (xlator_t *this)
goto out;
}
- ret = glusterd_program_register (this, rpc, &gd_svc_peer_prog);
+ ret = glusterd_program_register (this, rpc, &glusterd1_mop_prog);
if (ret) {
goto out;
}
ret = glusterd_program_register (this, rpc, &gd_svc_cli_prog);
if (ret) {
- rpcsvc_program_unregister (rpc, &gd_svc_peer_prog);
+ rpcsvc_program_unregister (rpc, &glusterd1_mop_prog);
goto out;
}
ret = glusterd_program_register (this, rpc, &gd_svc_mgmt_prog);
if (ret) {
- rpcsvc_program_unregister (rpc, &gd_svc_peer_prog);
+ rpcsvc_program_unregister (rpc, &glusterd1_mop_prog);
rpcsvc_program_unregister (rpc, &gd_svc_cli_prog);
goto out;
}
ret = glusterd_program_register (this, rpc, &gluster_pmap_prog);
if (ret) {
- rpcsvc_program_unregister (rpc, &gd_svc_peer_prog);
+ rpcsvc_program_unregister (rpc, &glusterd1_mop_prog);
rpcsvc_program_unregister (rpc, &gd_svc_cli_prog);
rpcsvc_program_unregister (rpc, &gd_svc_mgmt_prog);
goto out;
@@ -927,7 +654,7 @@ init (xlator_t *this)
ret = glusterd_program_register (this, rpc, &gluster_handshake_prog);
if (ret) {
- rpcsvc_program_unregister (rpc, &gd_svc_peer_prog);
+ rpcsvc_program_unregister (rpc, &glusterd1_mop_prog);
rpcsvc_program_unregister (rpc, &gluster_pmap_prog);
rpcsvc_program_unregister (rpc, &gd_svc_cli_prog);
rpcsvc_program_unregister (rpc, &gd_svc_mgmt_prog);
@@ -937,25 +664,14 @@ init (xlator_t *this)
conf = GF_CALLOC (1, sizeof (glusterd_conf_t),
gf_gld_mt_glusterd_conf_t);
GF_VALIDATE_OR_GOTO(this->name, conf, out);
- conf->shd = GF_CALLOC (1, sizeof (nodesrv_t),
- gf_gld_mt_nodesrv_t);
- GF_VALIDATE_OR_GOTO(this->name, conf->shd, out);
- conf->nfs = GF_CALLOC (1, sizeof (nodesrv_t),
- gf_gld_mt_nodesrv_t);
- GF_VALIDATE_OR_GOTO(this->name, conf->nfs, out);
-
INIT_LIST_HEAD (&conf->peers);
INIT_LIST_HEAD (&conf->volumes);
pthread_mutex_init (&conf->mutex, NULL);
conf->rpc = rpc;
- conf->gfs_mgmt = &gd_brick_prog;
+ conf->gfs_mgmt = &glusterd_glusterfs_3_1_mgmt_prog;
strncpy (conf->workdir, dirname, PATH_MAX);
INIT_LIST_HEAD (&conf->xprt_list);
-
- glusterd_friend_sm_init ();
- glusterd_op_sm_init ();
- glusterd_opinfo_init ();
ret = glusterd_sm_tr_log_init (&conf->op_sm_log,
glusterd_op_sm_state_name_get,
glusterd_op_sm_event_name_get,
@@ -963,49 +679,11 @@ init (xlator_t *this)
if (ret)
goto out;
- /* Set option to run bricks on valgrind if enabled in glusterd.vol */
-#ifdef DEBUG
- conf->valgrind = _gf_false;
- ret = dict_get_str (this->options, "run-with-valgrind", &valgrind_str);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG,
- "cannot get run-with-valgrind value");
- }
- if (valgrind_str) {
- if (gf_string2boolean (valgrind_str, &(conf->valgrind))) {
- gf_log (this->name, GF_LOG_WARNING,
- "run-with-valgrind value not a boolean string");
- }
- }
-#endif
-
this->private = conf;
- (void) glusterd_nodesvc_set_running ("glustershd", _gf_false);
- /* this->ctx->top = this;*/
-
- GLUSTERD_GET_HOOKS_DIR (hooks_dir, GLUSTERD_HOOK_VER, conf);
- if (stat (hooks_dir, &buf)) {
- ret = glusterd_hooks_create_hooks_directory (dirname);
- if (-1 == ret) {
- gf_log (this->name, GF_LOG_CRITICAL,
- "Unable to create hooks directory ");
- exit (1);
- }
- }
-
- INIT_LIST_HEAD (&conf->mount_specs);
+ //this->ctx->top = this;
- ret = 0;
- dict_foreach (this->options, _install_mount_spec, &ret);
- if (ret)
- goto out;
- ret = dict_get_str (this->options, "mountbroker-root",
- &mountbroker_root);
- if (ret)
- ret = 0;
- else
- ret = check_prepare_mountbroker_root (mountbroker_root);
- if (ret)
+ ret = glusterd_uuid_init (first_time);
+ if (ret < 0)
goto out;
ret = configure_syncdaemon (conf);
@@ -1016,20 +694,14 @@ init (xlator_t *this)
if (ret < 0)
goto out;
- ret = glusterd_handle_upgrade_downgrade (this->options, conf);
- if (ret)
- goto out;
+ glusterd_friend_sm_init ();
+ glusterd_op_sm_init ();
+ glusterd_opinfo_init ();
glusterd_restart_bricks (conf);
ret = glusterd_restart_gsyncds (conf);
if (ret)
goto out;
-
- ret = glusterd_hooks_spawn_worker (this);
- if (ret)
- goto out;
-
- glusterd_restart_rebalance (conf);
ret = 0;
out:
if (ret < 0) {
@@ -1037,7 +709,6 @@ out:
GF_FREE (this->private);
this->private = NULL;
}
-
}
return ret;
@@ -1061,7 +732,8 @@ fini (xlator_t *this)
goto out;
conf = this->private;
- FREE (conf->pmap);
+ if (conf->pmap)
+ FREE (conf->pmap);
if (conf->handle)
glusterd_store_handle_destroy (conf->handle);
glusterd_sm_tr_log_delete (&conf->op_sm_log);
@@ -1130,34 +802,6 @@ struct volume_options options[] = {
{ .key = {"rpc-auth-allow-insecure"},
.type = GF_OPTION_TYPE_BOOL,
},
- { .key = {"upgrade"},
- .type = GF_OPTION_TYPE_BOOL,
- },
- { .key = {"downgrade"},
- .type = GF_OPTION_TYPE_BOOL,
- },
- { .key = {"bind-insecure"},
- .type = GF_OPTION_TYPE_BOOL,
- },
- { .key = {"mountbroker-root"},
- .type = GF_OPTION_TYPE_PATH,
- },
- { .key = {"mountbroker.*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {"mountbroker-"GEOREP".*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {"mountbroker-"GHADOOP".*"},
- .type = GF_OPTION_TYPE_ANY,
- },
- { .key = {GEOREP"-log-group"},
- .type = GF_OPTION_TYPE_ANY,
- },
-#ifdef DEBUG
- { .key = {"run-with-valgrind"},
- .type = GF_OPTION_TYPE_BOOL,
- },
-#endif
+
{ .key = {NULL} },
};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 7afbd53f1..2fcd11c11 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -45,14 +45,12 @@
#include "glusterd1-xdr.h"
#include "protocol-common.h"
#include "glusterd-pmap.h"
-#include "cli1-xdr.h"
-#include "syncop.h"
+
#define GLUSTERD_MAX_VOLUME_NAME 1000
#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
#define GLUSTERD_TR_LOG_SIZE 50
#define GLUSTERD_NAME "glusterd"
-#define GLUSTERD_SOCKET_LISTEN_BACKLOG 128
typedef enum glusterd_op_ {
@@ -63,6 +61,7 @@ typedef enum glusterd_op_ {
GD_OP_DELETE_VOLUME,
GD_OP_START_VOLUME,
GD_OP_STOP_VOLUME,
+ GD_OP_RENAME_VOLUME,
GD_OP_DEFRAG_VOLUME,
GD_OP_ADD_BRICK,
GD_OP_REMOVE_BRICK,
@@ -70,17 +69,12 @@ typedef enum glusterd_op_ {
GD_OP_SET_VOLUME,
GD_OP_RESET_VOLUME,
GD_OP_SYNC_VOLUME,
+ GD_OP_LOG_FILENAME,
+ GD_OP_LOG_LOCATE,
GD_OP_LOG_ROTATE,
GD_OP_GSYNC_SET,
GD_OP_PROFILE_VOLUME,
GD_OP_QUOTA,
- GD_OP_STATUS_VOLUME,
- GD_OP_REBALANCE,
- GD_OP_HEAL_VOLUME,
- GD_OP_STATEDUMP_VOLUME,
- GD_OP_LIST_VOLUME,
- GD_OP_CLEARLOCKS_VOLUME,
- GD_OP_DEFRAG_BRICK_VOLUME,
GD_OP_MAX,
} glusterd_op_t;
@@ -97,11 +91,6 @@ struct glusterd_volgen {
dict_t *dict;
};
typedef struct {
- struct rpc_clnt *rpc;
- gf_boolean_t running;
-} nodesrv_t;
-
-typedef struct {
struct _volfile_ctx *volfile;
pthread_mutex_t mutex;
struct list_head peers;
@@ -111,8 +100,6 @@ typedef struct {
uuid_t uuid;
char workdir[PATH_MAX];
rpcsvc_t *rpc;
- nodesrv_t *shd;
- nodesrv_t *nfs;
struct pmap_registry *pmap;
struct list_head volumes;
struct list_head xprt_list;
@@ -120,13 +107,6 @@ typedef struct {
gf_timer_t *timer;
glusterd_sm_tr_log_t op_sm_log;
struct rpc_clnt_program *gfs_mgmt;
- struct list_head mount_specs;
-#ifdef DEBUG
- gf_boolean_t valgrind;
-#endif
- pthread_t brick_thread;
- void *hooks_priv;
- xlator_t *xl; /* Should be set to 'THIS' before creating thread */
} glusterd_conf_t;
typedef enum gf_brick_status {
@@ -140,13 +120,12 @@ struct glusterd_brickinfo {
struct list_head brick_list;
uuid_t uuid;
int port;
- int rdma_port;
char *logfile;
gf_boolean_t signed_in;
glusterd_store_handle_t *shandle;
gf_brick_status_t status;
struct rpc_clnt *rpc;
- int decommissioned;
+ gf_timer_t *timer;
};
typedef struct glusterd_brickinfo glusterd_brickinfo_t;
@@ -157,28 +136,27 @@ struct gf_defrag_brickinfo_ {
int size;
};
-struct glusterd_volinfo_;
-typedef struct glusterd_volinfo_ glusterd_volinfo_t;
-
-typedef int (*defrag_cbk_fn_t) (glusterd_volinfo_t *volinfo,
- gf_defrag_status_t status);
+typedef enum gf_defrag_status_ {
+ GF_DEFRAG_STATUS_NOT_STARTED,
+ GF_DEFRAG_STATUS_LAYOUT_FIX_STARTED,
+ GF_DEFRAG_STATUS_MIGRATE_DATA_STARTED,
+ GF_DEFRAG_STATUS_STOPED,
+ GF_DEFRAG_STATUS_COMPLETE,
+ GF_DEFRAG_STATUS_FAILED,
+ GF_DEFRAG_STATUS_LAYOUT_FIX_COMPLETE,
+ GF_DEFRAG_STATUS_MIGRATE_DATA_COMPLETE,
+} gf_defrag_status_t;
struct glusterd_defrag_info_ {
uint64_t total_files;
uint64_t total_data;
uint64_t num_files_lookedup;
- uint64_t total_failures;
gf_lock_t lock;
int cmd;
pthread_t th;
- gf_defrag_status_t defrag_status;
- struct rpc_clnt * rpc;
- uint32_t connected;
char mount[1024];
char databuf[131072];
struct gf_defrag_brickinfo_ *bricks; /* volinfo->brick_count */
-
- defrag_cbk_fn_t cbk_fn;
};
@@ -190,7 +168,6 @@ typedef enum gf_transport_type_ {
GF_TRANSPORT_BOTH_TCP_RDMA,
} gf_transport_type;
-#define GF_DEFAULT_NFS_TRANSPORT GF_TRANSPORT_RDMA
typedef enum gf_rb_status_ {
GF_RB_STATUS_NONE,
@@ -198,13 +175,6 @@ typedef enum gf_rb_status_ {
GF_RB_STATUS_PAUSED,
} gf_rb_status_t;
-struct _auth {
- char *username;
- char *password;
-};
-
-typedef struct _auth auth_t;
-
struct glusterd_volinfo_ {
char volname[GLUSTERD_MAX_VOLUME_NAME];
int type;
@@ -212,15 +182,9 @@ struct glusterd_volinfo_ {
struct list_head vol_list;
struct list_head bricks;
glusterd_volume_status status;
- int sub_count; /* backward compatibility */
- int stripe_count;
- int replica_count;
- int dist_leaf_count; /* Number of bricks in one
- distribute subvolume */
+ int sub_count;
int port;
glusterd_store_handle_t *shandle;
- glusterd_store_handle_t *rb_shandle;
- glusterd_store_handle_t *node_state_shandle;
/* Defrag/rebalance related */
gf_defrag_status_t defrag_status;
@@ -228,9 +192,6 @@ struct glusterd_volinfo_ {
uint64_t rebalance_data;
uint64_t lookedup_files;
glusterd_defrag_info_t *defrag;
- gf_cli_defrag_type defrag_cmd;
- uint64_t rebalance_failures;
- double rebalance_time;
/* Replace brick status */
gf_rb_status_t rb_status;
@@ -240,35 +201,20 @@ struct glusterd_volinfo_ {
int version;
uint32_t cksum;
gf_transport_type transport_type;
- gf_transport_type nfs_transport_type;
dict_t *dict;
uuid_t volume_id;
- auth_t auth;
char *logdir;
dict_t *gsync_slaves;
-
- int decommission_in_progress;
- xlator_t *xl;
-
- gf_boolean_t memory_accounting;
};
-typedef enum gd_node_type_ {
- GD_NODE_NONE,
- GD_NODE_BRICK,
- GD_NODE_SHD,
- GD_NODE_REBALANCE,
- GD_NODE_NFS,
-} gd_node_type;
+typedef struct glusterd_volinfo_ glusterd_volinfo_t;
typedef struct glusterd_pending_node_ {
- struct list_head list;
void *node;
- gd_node_type type;
- int32_t index;
+ struct list_head list;
} glusterd_pending_node_t;
enum glusterd_op_ret {
@@ -282,28 +228,34 @@ enum glusterd_vol_comp_status_ {
GLUSTERD_VOL_COMP_RJT,
};
-#define GLUSTERD_DEFAULT_WORKDIR "/var/lib/glusterd"
+#define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd"
#define GLUSTERD_DEFAULT_PORT GF_DEFAULT_BASE_PORT
#define GLUSTERD_INFO_FILE "glusterd.info"
#define GLUSTERD_VOLUME_DIR_PREFIX "vols"
#define GLUSTERD_PEER_DIR_PREFIX "peers"
#define GLUSTERD_VOLUME_INFO_FILE "info"
-#define GLUSTERD_VOLUME_RBSTATE_FILE "rbstate"
#define GLUSTERD_BRICK_INFO_DIR "bricks"
#define GLUSTERD_CKSUM_FILE "cksum"
-#define GLUSTERD_NODE_STATE_FILE "node_state.info"
-/* definitions related to replace brick */
+/*All definitions related to replace brick */
+#define RB_PUMP_START_CMD "trusted.glusterfs.pump.start"
+#define RB_PUMP_PAUSE_CMD "trusted.glusterfs.pump.pause"
+#define RB_PUMP_ABORT_CMD "trusted.glusterfs.pump.abort"
+#define RB_PUMP_STATUS_CMD "trusted.glusterfs.pump.status"
#define RB_CLIENT_MOUNTPOINT "rb_mount"
#define RB_CLIENTVOL_FILENAME "rb_client.vol"
#define RB_DSTBRICK_PIDFILE "rb_dst_brick.pid"
#define RB_DSTBRICKVOL_FILENAME "rb_dst_brick.vol"
-#define RB_PUMP_DEF_ARG "default"
#define GLUSTERD_UUID_LEN 50
typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
+#define GLUSTERD_GET_NFS_DIR(path, priv) \
+ do { \
+ snprintf (path, PATH_MAX, "%s/nfs", priv->workdir);\
+ } while (0); \
+
#define GLUSTERD_GET_VOLUME_DIR(path, volinfo, priv) \
snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\
volinfo->volname);
@@ -313,8 +265,9 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \
GLUSTERD_BRICK_INFO_DIR);
-#define GLUSTERD_GET_NFS_DIR(path, priv) \
- snprintf (path, PATH_MAX, "%s/nfs", priv->workdir);
+#define GLUSTERD_GET_NFS_PIDFILE(pidfile) \
+ snprintf (pidfile, PATH_MAX, "%s/nfs/run/nfs.pid", \
+ priv->workdir); \
#define GLUSTERD_REMOVE_SLASH_FROM_PATH(path,string) do { \
int i = 0; \
@@ -332,51 +285,15 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
volpath, hostname, exp_path); \
}
-#define GLUSTERD_GET_NFS_PIDFILE(pidfile,nfspath) { \
- snprintf (pidfile, PATH_MAX, "%s/run/nfs.pid", \
- nfspath); \
- }
-
#define GLUSTERD_STACK_DESTROY(frame) do {\
+ void *__local = NULL; \
+ xlator_t *__xl = NULL; \
+ __xl = frame->this; \
+ __local = frame->local; \
frame->local = NULL; \
STACK_DESTROY (frame->root);\
} while (0)
-#define GLUSTERD_GET_DEFRAG_DIR(path, volinfo, priv) do { \
- char vol_path[PATH_MAX]; \
- GLUSTERD_GET_VOLUME_DIR(vol_path, volinfo, priv); \
- snprintf (path, PATH_MAX, "%s/rebalance",vol_path); \
- } while (0)
-
-#define GLUSTERD_GET_DEFRAG_SOCK_FILE(path, volinfo, priv) do { \
- char defrag_path[PATH_MAX]; \
- GLUSTERD_GET_DEFRAG_DIR(defrag_path, volinfo, priv); \
- snprintf (path, PATH_MAX, "%s/%s.sock", defrag_path, \
- uuid_utoa(priv->uuid)); \
- } while (0)
-
-#define GLUSTERD_GET_DEFRAG_PID_FILE(path, volinfo, priv) do { \
- char defrag_path[PATH_MAX]; \
- GLUSTERD_GET_DEFRAG_DIR(defrag_path, volinfo, priv); \
- snprintf (path, PATH_MAX, "%s/%s.pid", defrag_path, \
- uuid_utoa(priv->uuid)); \
- } while (0)
-
-
-int glusterd_uuid_init();
-
-#define MY_UUID (__glusterd_uuid())
-
-static inline unsigned char *
-__glusterd_uuid()
-{
- glusterd_conf_t *priv = THIS->private;
-
- if (uuid_is_null (priv->uuid))
- glusterd_uuid_init();
- return &priv->uuid[0];
-}
-
int32_t
glusterd_brick_from_brickinfo (glusterd_brickinfo_t *brickinfo,
char **new_brick);
@@ -394,8 +311,10 @@ glusterd_friend_find (uuid_t uuid, char *hostname,
int
glusterd_friend_add (const char *hoststr, int port,
glusterd_friend_sm_state_t state,
- uuid_t *uuid, glusterd_peerinfo_t **friend,
- gf_boolean_t restore, glusterd_peerctx_args_t *args);
+ uuid_t *uuid, struct rpc_clnt *rpc,
+ glusterd_peerinfo_t **friend,
+ gf_boolean_t restore,
+ glusterd_peerctx_args_t *args);
int
glusterd_friend_remove (uuid_t uuid, char *hostname);
@@ -450,8 +369,7 @@ glusterd_handle_defrag_volume_v2 (rpcsvc_request_t *req);
int
glusterd_xfer_cli_probe_resp (rpcsvc_request_t *req, int32_t op_ret,
- int32_t op_errno, char *op_errstr, char *hostname,
- int port);
+ int32_t op_errno, char *hostname, int port);
int
glusterd_op_commit_send_resp (rpcsvc_request_t *req,
@@ -505,6 +423,10 @@ int
glusterd_handle_remove_brick (rpcsvc_request_t *req);
int
+glusterd_handle_log_filename (rpcsvc_request_t *req);
+int
+glusterd_handle_log_locate (rpcsvc_request_t *req);
+int
glusterd_handle_log_rotate (rpcsvc_request_t *req);
int
@@ -548,8 +470,7 @@ glusterd_handle_fsm_log (rpcsvc_request_t *req);
int
glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
- int32_t op_errno, char *op_errstr,
- char *hostname);
+ int32_t op_errno, char *hostname);
int
glusterd_fetchspec_notify (xlator_t *this);
@@ -588,80 +509,7 @@ glusterd_brick_rpc_notify (struct rpc_clnt *rpc, void *mydata,
rpc_clnt_event_t event, void *data);
int
-glusterd_nodesvc_rpc_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t event, void *data);
-
-int
glusterd_rpc_create (struct rpc_clnt **rpc, dict_t *options,
rpc_clnt_notify_t notify_fn, void *notify_data);
-
-/* handler functions */
-int32_t glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx);
-
-/* removed other definitions as they have been defined elsewhere in this file*/
-
-int glusterd_handle_cli_statedump_volume (rpcsvc_request_t *req);
-int glusterd_handle_cli_clearlocks_volume (rpcsvc_request_t *req);
-
-int glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,
- size_t len, int cmd, defrag_cbk_fn_t cbk);
-int
-glusterd_rebalance_rpc_create (glusterd_volinfo_t *volinfo,
- glusterd_conf_t *priv, int cmd);
-
-int glusterd_handle_cli_heal_volume (rpcsvc_request_t *req);
-
-int glusterd_handle_cli_list_volume (rpcsvc_request_t *req);
-
-/* op-sm functions */
-int glusterd_op_stage_heal_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_heal_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_gsync_set (dict_t *dict, char **op_errstr);
-int glusterd_op_gsync_set (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-int glusterd_op_quota (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_quota (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
- dict_t *rsp_dict);
-int glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict);
-int glusterd_op_log_rotate (dict_t *dict);
-int glusterd_op_stage_log_rotate (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_start_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_delete_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_create_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_start_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_stop_volume (dict_t *dict);
-int glusterd_op_delete_volume (dict_t *dict);
-
-int glusterd_op_add_brick (dict_t *dict, char **op_errstr);
-int glusterd_op_remove_brick (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr);
-int glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr);
-
-int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr);
-int glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
-
-int glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_statedump_volume (dict_t *dict, char **op_errstr);
-
-int glusterd_op_stage_clearlocks_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_clearlocks_volume (dict_t *dict, char **op_errstr);
-
-/* misc */
-void glusterd_do_replace_brick (void *data);
-int glusterd_op_perform_remove_brick (glusterd_volinfo_t *volinfo, char *brick,
- int force, int *need_migrate);
-int glusterd_op_stop_volume_args_get (dict_t *dict, char** volname, int *flags);
-int glusterd_op_statedump_volume_args_get (dict_t *dict, char **volname,
- char **options, int *option_cnt);
-
-int glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,
- char **master, char **slave);
-/* Synctask part */
-int32_t glusterd_op_begin_synctask (rpcsvc_request_t *req, glusterd_op_t op,
- void *dict);
-int32_t
-glusterd_defrag_event_notify_handle (dict_t *dict);
#endif
diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am
index a92d68e9a..3dace143a 100644
--- a/xlators/mount/fuse/src/Makefile.am
+++ b/xlators/mount/fuse/src/Makefile.am
@@ -1,35 +1,25 @@
-noinst_HEADERS_linux = $(CONTRIBDIR)/fuse-include/fuse_kernel.h\
- $(CONTRIBDIR)/fuse-include/mount_util.h\
- $(CONTRIBDIR)/fuse-lib/mount-gluster-compat.h
-noinst_HEADERS_darwin = $(CONTRIBDIR)/fuse-include/fuse_kernel_macfuse.h
-noinst_HEADERS_common = $(CONTRIBDIR)/fuse-include/fuse-mount.h\
+noinst_HEADERS = $(CONTRIBDIR)/fuse-include/fuse_kernel.h\
+ $(CONTRIBDIR)/fuse-include/fuse-mount.h\
$(CONTRIBDIR)/fuse-include/fuse-misc.h fuse-mem-types.h \
fuse-bridge.h
-if GF_DARWIN_HOST_OS
- noinst_HEADERS = $(noinst_HEADERS_common) $(noinst_HEADERS_darwin)
-else
- noinst_HEADERS = $(noinst_HEADERS_common) $(noinst_HEADERS_linux)
-endif
-
xlator_LTLIBRARIES = fuse.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mount
if GF_DARWIN_HOST_OS
mount_source=$(CONTRIBDIR)/macfuse/mount_darwin.c
else
- mount_source=$(CONTRIBDIR)/fuse-lib/mount.c $(CONTRIBDIR)/fuse-lib/mount-common.c
+ mount_source=$(CONTRIBDIR)/fuse-lib/mount.c
endif
fuse_la_SOURCES = fuse-helpers.c fuse-resolve.c fuse-bridge.c \
$(CONTRIBDIR)/fuse-lib/misc.c $(mount_source)
fuse_la_LDFLAGS = -module -avoidversion -shared -nostartfiles
-fuse_la_LIBADD = @GF_FUSE_LDADD@
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \
-I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/fuse-include \
- -I$(CONTRIBDIR)/fuse-lib $(GF_CFLAGS) $(GF_FUSE_CFLAGS)
+ $(GF_CFLAGS) $(GF_FUSE_CFLAGS)
CLEANFILES =
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 2948aae97..d34a747f4 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -1,123 +1,34 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
-#include <sys/wait.h>
-#include "fuse-bridge.h"
-
-static int gf_fuse_conn_err_log;
-static int gf_fuse_xattr_enotsup_log;
-
-void fini (xlator_t *this_xl);
-
-static void fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino);
-
/*
- * Send an invalidate notification up to fuse to purge the file from local
- * page cache.
+ * TODO:
+ * Need to free_state() when fuse_reply_err() + return.
+ * Check loc->path for "" after fuse_loc_fill in all fops
+ * (now being done in getattr, lookup) or better - make
+ * fuse_loc_fill() and inode_path() return success/failure.
*/
-static int32_t
-fuse_invalidate(xlator_t *this, inode_t *inode)
-{
- fuse_private_t *priv = this->private;
- uint64_t nodeid;
-
- /*
- * NOTE: We only invalidate at the moment if fopen_keep_cache is
- * enabled because otherwise this is a departure from default
- * behavior. Specifically, the performance/write-behind xlator
- * causes unconditional invalidations on write requests.
- */
- if (!priv->fopen_keep_cache)
- return 0;
-
- nodeid = inode_to_fuse_nodeid(inode);
- gf_log(this->name, GF_LOG_DEBUG, "Invalidate inode id %lu.", nodeid);
- fuse_invalidate_inode(this, nodeid);
-
- return 0;
-}
-
-fuse_fd_ctx_t *
-__fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
-{
- uint64_t val = 0;
- int32_t ret = 0;
- fuse_fd_ctx_t *fd_ctx = NULL;
-
- ret = __fd_ctx_get (fd, this, &val);
- fd_ctx = (fuse_fd_ctx_t *)(unsigned long) val;
-
- if (fd_ctx == NULL) {
- fd_ctx = GF_CALLOC (1, sizeof (*fd_ctx),
- gf_fuse_mt_fd_ctx_t);
-
- ret = __fd_ctx_set (fd, this,
- (uint64_t)(unsigned long)fd_ctx);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "fd-ctx-set failed");
- GF_FREE (fd_ctx);
- fd_ctx = NULL;
- }
- }
-
- return fd_ctx;
-}
-
-fuse_fd_ctx_t *
-fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
-{
- fuse_fd_ctx_t *fd_ctx = NULL;
-
- if ((fd == NULL) || (this == NULL)) {
- goto out;
- }
-
- LOCK (&fd->lock);
- {
- fd_ctx = __fuse_fd_ctx_check_n_create (this, fd);
- }
- UNLOCK (&fd->lock);
-
-out:
- return fd_ctx;
-}
-
-
-fuse_fd_ctx_t *
-fuse_fd_ctx_get (xlator_t *this, fd_t *fd)
-{
- fuse_fd_ctx_t *fdctx = NULL;
- uint64_t value = 0;
- int ret = 0;
-
- ret = fd_ctx_get (fd, this, &value);
- if (ret < 0) {
- goto out;
- }
-
- fdctx = (fuse_fd_ctx_t *) (unsigned long)value;
+#include "fuse-bridge.h"
-out:
- return fdctx;
-}
+static int gf_fuse_conn_err_log;
+static int gf_fuse_xattr_enotsup_log;
/*
@@ -134,7 +45,7 @@ send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
if (!this || !finh || !iov_out) {
gf_log ("send_fuse_iov", GF_LOG_ERROR,"Invalid arguments");
- return EINVAL;
+ return -1;
}
priv = this->private;
@@ -187,95 +98,6 @@ send_fuse_data (xlator_t *this, fuse_in_header_t *finh, void *data, size_t size)
#define send_fuse_obj(this, finh, obj) \
send_fuse_data (this, finh, obj, sizeof (*(obj)))
-
-static void
-fuse_invalidate_entry (xlator_t *this, uint64_t fuse_ino)
-{
- struct fuse_out_header *fouh = NULL;
- struct fuse_notify_inval_entry_out *fnieo = NULL;
- fuse_private_t *priv = NULL;
- dentry_t *dentry = NULL;
- inode_t *inode = NULL;
- size_t nlen = 0;
- int rv = 0;
-
- char inval_buf[INVAL_BUF_SIZE] = {0,};
-
- fouh = (struct fuse_out_header *)inval_buf;
- fnieo = (struct fuse_notify_inval_entry_out *)(fouh + 1);
-
- priv = this->private;
- if (priv->revchan_out == -1)
- return;
-
- fouh->unique = 0;
- fouh->error = FUSE_NOTIFY_INVAL_ENTRY;
-
- inode = fuse_ino_to_inode (fuse_ino, this);
-
- list_for_each_entry (dentry, &inode->dentry_list, inode_list) {
- nlen = strlen (dentry->name);
- fouh->len = sizeof (*fouh) + sizeof (*fnieo) + nlen + 1;
- fnieo->parent = inode_to_fuse_nodeid (dentry->parent);
-
- fnieo->namelen = nlen;
- strcpy (inval_buf + sizeof (*fouh) + sizeof (*fnieo), dentry->name);
-
- rv = write (priv->revchan_out, inval_buf, fouh->len);
- if (rv != fouh->len) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "kernel notification daemon defunct");
-
- close (priv->fd);
- break;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE entry: "
- "%"PRIu64"/%s", fnieo->parent, dentry->name);
- }
-}
-
-/*
- * Send an inval inode notification to fuse. This causes an invalidation of the
- * entire page cache mapping on the inode.
- */
-static void
-fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino)
-{
- struct fuse_out_header *fouh = NULL;
- struct fuse_notify_inval_inode_out *fniio = NULL;
- fuse_private_t *priv = NULL;
- int rv = 0;
- char inval_buf[INVAL_BUF_SIZE] = {0};
-
- fouh = (struct fuse_out_header *) inval_buf;
- fniio = (struct fuse_notify_inval_inode_out *) (fouh + 1);
-
- priv = this->private;
-
- if (priv->revchan_out < 0)
- return;
-
- fouh->unique = 0;
- fouh->error = FUSE_NOTIFY_INVAL_INODE;
- fouh->len = sizeof(struct fuse_out_header) +
- sizeof(struct fuse_notify_inval_inode_out);
-
- /* inval the entire mapping until we learn how to be more granular */
- fniio->ino = fuse_ino;
- fniio->off = 0;
- fniio->len = -1;
-
- rv = write(priv->revchan_out, inval_buf, fouh->len);
- if (rv != fouh->len) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR, "kernel notification "
- "daemon defunct");
- close(priv->fd);
- }
-
- gf_log("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE inode: %lu", fuse_ino);
-}
-
int
send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
{
@@ -288,31 +110,30 @@ send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error)
return send_fuse_iov (this, finh, &iov_out, 1);
}
-
static int
fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xdata)
+ inode_t *inode, struct iatt *buf)
{
- fuse_state_t *state = NULL;
- fuse_in_header_t *finh = NULL;
- struct fuse_entry_out feo = {0, };
- fuse_private_t *priv = NULL;
- inode_t *linked_inode = NULL;
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
+ struct fuse_entry_out feo = {0, };
+ fuse_private_t *priv = NULL;
+ inode_t *linked_inode = NULL;
priv = this->private;
state = frame->root->state;
finh = state->finh;
- if (!op_ret && __is_root_gfid (state->loc.inode->gfid)) {
+ if (!op_ret && state->loc.ino == 1) {
buf->ia_ino = 1;
}
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64,
+ "%"PRIu64": %s() %s => %"PRId64" (%"PRId64")",
frame->root->unique, gf_fop_list[frame->root->op],
- state->loc.path, buf->ia_ino);
+ state->loc.path, buf->ia_ino, state->loc.ino);
buf->ia_blksize = this->ctx->page_size;
gf_fuse_stat2attr (buf, &feo.attr);
@@ -332,6 +153,8 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_lookup (linked_inode);
+ /* TODO: make these timeouts configurable (via meta?) */
+ /* should we do linked_node or inode */
feo.nodeid = inode_to_fuse_nodeid (linked_inode);
inode_unref (linked_inode);
@@ -359,15 +182,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
- if (op_errno == ENOENT) {
- feo.entry_valid =
- calc_timeout_sec (priv->negative_timeout);
- feo.entry_valid_nsec =
- calc_timeout_nsec (priv->negative_timeout);
- send_fuse_obj (this, finh, &feo);
- } else {
- send_fuse_err (this, state->finh, op_errno);
- }
+ send_fuse_err (this, state->finh, op_errno);
}
free_fuse_state (state);
@@ -380,10 +195,9 @@ static int
fuse_newentry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
- fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- xdata);
+ fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, buf);
return 0;
}
@@ -402,22 +216,18 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
if (op_ret == -1 && state->is_revalidate == 1) {
- itable = state->itable;
+ itable = state->loc.inode->table;
inode_unref (state->loc.inode);
state->loc.inode = inode_new (itable);
state->is_revalidate = 2;
- if (uuid_is_null (state->gfid))
- uuid_generate (state->gfid);
- fuse_gfid_set (state);
STACK_WIND (frame, fuse_lookup_cbk,
prev->this, prev->this->fops->lookup,
- &state->loc, state->xdata);
+ &state->loc, state->dict);
return 0;
}
- fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, stat,
- dict);
+ fuse_entry_cbk (frame, cookie, this, op_ret, op_errno, inode, stat);
return 0;
}
@@ -431,24 +241,11 @@ fuse_lookup_resume (fuse_state_t *state)
free_fuse_state (state);
return;
}
-
- if (state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s(%s)", state->finh->unique,
- state->loc.path, uuid_utoa (state->loc.inode->gfid));
- state->is_revalidate = 1;
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LOOKUP %s", state->finh->unique,
- state->loc.path);
+ if (!state->loc.inode)
state->loc.inode = inode_new (state->loc.parent->table);
- if (uuid_is_null (state->gfid))
- uuid_generate (state->gfid);
- fuse_gfid_set (state);
- }
FUSE_FOP (state, fuse_lookup_cbk, GF_FOP_LOOKUP,
- lookup, &state->loc, state->xdata);
+ lookup, &state->loc, state->dict);
}
static void
@@ -456,13 +253,39 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
char *name = msg;
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- (void) fuse_resolve_entry_init (state, &state->resolve,
- finh->nodeid, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": LOOKUP %"PRIu64"/%s (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid, name);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
+
+ if (state->loc.inode) {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LOOKUP %s(%"PRId64")", finh->unique,
+ state->loc.path, state->loc.inode->ino);
+ state->is_revalidate = 1;
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LOOKUP %s", finh->unique,
+ state->loc.path);
+ uuid_generate (state->gfid);
+ }
+
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_lookup_resume);
+
}
@@ -479,10 +302,6 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FORGET %"PRIu64"/%"PRIu64,
- finh->unique, finh->nodeid, ffi->nlookup);
-
fuse_inode = fuse_ino_to_inode (finh->nodeid, this);
inode_forget (fuse_inode, ffi->nlookup);
@@ -495,7 +314,7 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
static int
fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -513,6 +332,8 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.path ? state->loc.path : "ERR",
prebuf->ia_ino);
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
postbuf->ia_blksize = this->ctx->page_size;
gf_fuse_stat2attr (postbuf, &fao.attr);
@@ -547,7 +368,7 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int
fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -565,6 +386,8 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.path ? state->loc.path : "ERR",
buf->ia_ino);
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
buf->ia_blksize = this->ctx->page_size;
gf_fuse_stat2attr (buf, &fao.attr);
@@ -605,7 +428,7 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_t *inode, struct iatt *stat, dict_t *dict,
struct iatt *postparent)
{
- fuse_attr_cbk (frame, cookie, this, op_ret, op_errno, stat, dict);
+ fuse_attr_cbk (frame, cookie, this, op_ret, op_errno, stat);
return 0;
}
@@ -613,28 +436,14 @@ fuse_root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
void
fuse_getattr_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": GETATTR %"PRIu64" (%s) resolution failed",
- state->finh->unique, state->finh->nodeid,
- uuid_utoa (state->resolve.gfid));
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
- if (!IA_ISDIR (state->loc.inode->ia_type)) {
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
- }
-
- if (!state->fd) {
+ if (!state->fd || IA_ISDIR (state->loc.inode->ia_type)) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": GETATTR %"PRIu64" (%s)",
state->finh->unique, state->finh->nodeid,
state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_STAT,
- stat, &state->loc, state->xdata);
+ stat, &state->loc);
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@@ -643,7 +452,7 @@ fuse_getattr_resume (fuse_state_t *state)
state->loc.path, state->fd);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FSTAT,
- fstat, state->fd, state->xdata);
+ fstat, state->fd);
}
}
@@ -651,6 +460,7 @@ static void
fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state;
+ fd_t *fd = NULL;
int32_t ret = -1;
GET_STATE (this, finh, state);
@@ -671,67 +481,58 @@ fuse_getattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_gfid_set (state);
FUSE_FOP (state, fuse_root_lookup_cbk, GF_FOP_LOOKUP,
- lookup, &state->loc, state->xdata);
+ lookup, &state->loc, state->dict);
return;
}
- fuse_resolve_inode_init (state, &state->resolve, state->finh->nodeid);
-
- fuse_resolve_and_resume (state, fuse_getattr_resume);
-}
-
+ ret = fuse_loc_fill (&state->loc, state, state->finh->nodeid, 0, NULL);
-static int32_t
-fuse_fd_inherit_directio (xlator_t *this, fd_t *fd, struct fuse_open_out *foo)
-{
- int32_t ret = 0;
- fuse_fd_ctx_t *fdctx = NULL, *tmp_fdctx = NULL;
- fd_t *tmp_fd = NULL;
-
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("glusterfs-fuse", this, out, ret,
- -EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("glusterfs-fuse", fd, out, ret,
- -EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("glusterfs-fuse", foo, out, ret,
- -EINVAL);
-
- fdctx = fuse_fd_ctx_check_n_create (this, fd);
- if (!fdctx) {
- ret = -ENOMEM;
- goto out;
+ if (!state->loc.inode) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": GETATTR %"PRIu64" (%s) (fuse_loc_fill() returned NULL inode)",
+ state->finh->unique, state->finh->nodeid, state->loc.path);
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
+ return;
}
- tmp_fd = fd_lookup (fd->inode, 0);
- if (tmp_fd) {
- tmp_fdctx = fuse_fd_ctx_get (this, tmp_fd);
- if (tmp_fdctx) {
- foo->open_flags &= ~FOPEN_DIRECT_IO;
- foo->open_flags |= (tmp_fdctx->open_flags
- & FOPEN_DIRECT_IO);
+ fd = fd_lookup (state->loc.inode, state->finh->pid);
+ state->fd = fd;
+ if (!fd || IA_ISDIR (state->loc.inode->ia_type)) {
+ /* this is the @ret of fuse_loc_fill, checked here
+ to permit fstat() to happen even when fuse_loc_fill fails
+ */
+ if (ret < 0) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": GETATTR %"PRIu64" (fuse_loc_fill() failed)",
+ state->finh->unique, state->finh->nodeid);
+ send_fuse_err (state->this, state->finh, ENOENT);
+ free_fuse_state (state);
+ return;
}
- }
- fdctx->open_flags |= (foo->open_flags & FOPEN_DIRECT_IO);
+ if (state->fd)
+ fd_unref (state->fd);
- if (tmp_fd != NULL) {
- fd_unref (tmp_fd);
+ state->fd = NULL;
}
- ret = 0;
-out:
- return ret;
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ if (state->loc.path)
+ state->resolve.path = gf_strdup (state->loc.path);
+
+ fuse_resolve_and_resume (state, fuse_getattr_resume);
}
static int
fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- fuse_state_t *state = NULL;
- fuse_in_header_t *finh = NULL;
- fuse_private_t *priv = NULL;
- int32_t ret = 0;
- struct fuse_open_out foo = {0, };
+ fuse_state_t *state;
+ fuse_in_header_t *finh;
+ fuse_private_t *priv = NULL;
+ struct fuse_open_out foo = {0, };
priv = this->private;
state = frame->root->state;
@@ -747,27 +548,17 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|| (priv->direct_io_mode == 1))
foo.open_flags |= FOPEN_DIRECT_IO;
#ifdef GF_DARWIN_HOST_OS
- /* In Linux: by default, buffer cache
- * is purged upon open, setting
- * FOPEN_KEEP_CACHE implies no-purge
- *
- * In MacFUSE: by default, buffer cache
- * is left intact upon open, setting
- * FOPEN_PURGE_UBC implies purge
- *
- * [[Interesting...]]
- */
- if (!priv->fopen_keep_cache)
- foo.open_flags |= FOPEN_PURGE_UBC;
-#else
- /*
- * If fopen-keep-cache is enabled, we set the associated
- * flag here such that files are not invalidated on open.
- * File invalidations occur either in fuse or explicitly
- * when the cache is set invalid on the inode.
- */
- if (priv->fopen_keep_cache)
- foo.open_flags |= FOPEN_KEEP_CACHE;
+ /* In Linux: by default, buffer cache
+ * is purged upon open, setting
+ * FOPEN_KEEP_CACHE implies no-purge
+ *
+ * In MacFUSE: by default, buffer cache
+ * is left intact upon open, setting
+ * FOPEN_PURGE_UBC implies purge
+ *
+ * [[Innnnteresting...]]
+ */
+ foo.open_flags |= FOPEN_PURGE_UBC;
#endif
}
@@ -775,32 +566,22 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%"PRIu64": %s() %s => %p", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path, fd);
- ret = fuse_fd_inherit_directio (this, fd, &foo);
- if (ret < 0) {
- op_errno = -ret;
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "cannot inherit direct-io values from fds "
- "already opened");
- goto err;
- }
-
+ fd_ref (fd);
if (send_fuse_obj (this, finh, &foo) == ENOENT) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"open(%s) got EINTR", state->loc.path);
- gf_fd_put (priv->fdtable, state->fd_no);
- goto out;
+ fd_unref (fd);
+ goto out;
}
fd_bind (fd);
} else {
- err:
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": %s() %s => -1 (%s)", frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
strerror (op_errno));
send_fuse_err (this, finh, op_errno);
- gf_fd_put (priv->fdtable, state->fd_no);
}
out:
free_fuse_state (state);
@@ -814,10 +595,10 @@ fuse_do_truncate (fuse_state_t *state, size_t size)
{
if (state->fd) {
FUSE_FOP (state, fuse_truncate_cbk, GF_FOP_FTRUNCATE,
- ftruncate, state->fd, size, state->xdata);
+ ftruncate, state->fd, size);
} else {
FUSE_FOP (state, fuse_truncate_cbk, GF_FOP_TRUNCATE,
- truncate, &state->loc, size, state->xdata);
+ truncate, &state->loc, size);
}
return;
@@ -827,7 +608,7 @@ fuse_do_truncate (fuse_state_t *state, size_t size)
static int
fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpre, struct iatt *statpost)
{
fuse_state_t *state;
fuse_in_header_t *finh;
@@ -847,7 +628,11 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state->loc.path ? state->loc.path : "ERR",
statpost->ia_ino);
+ /* TODO: make these timeouts configurable via meta */
+ /* TODO: what if the inode number has changed by now */
+
statpost->ia_blksize = this->ctx->page_size;
+
gf_fuse_stat2attr (statpost, &fao.attr);
fao.attr_valid = calc_timeout_sec (priv->attribute_timeout);
@@ -923,26 +708,6 @@ fattr_to_gf_set_attr (int32_t valid)
void
fuse_setattr_resume (fuse_state_t *state)
{
- if (!state->fd && !state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": SETATTR %"PRIu64" (%s) resolution failed",
- state->finh->unique, state->finh->nodeid,
- uuid_utoa (state->resolve.gfid));
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETATTR (%"PRIu64")%s", state->finh->unique,
- state->finh->nodeid, state->loc.path);
-
-#ifdef GF_TEST_FFOP
- /* this is for calls like 'fchmod()' */
- if (!state->fd)
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
-
if ((state->valid & (FATTR_MASK)) != FATTR_SIZE) {
if (state->fd &&
!((state->valid & FATTR_ATIME) ||
@@ -954,13 +719,11 @@ fuse_setattr_resume (fuse_state_t *state)
FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_FSETATTR,
fsetattr, state->fd, &state->attr,
- fattr_to_gf_set_attr (state->valid),
- state->xdata);
+ fattr_to_gf_set_attr (state->valid));
} else {
FUSE_FOP (state, fuse_setattr_cbk, GF_FOP_SETATTR,
setattr, &state->loc, &state->attr,
- fattr_to_gf_set_attr (state->valid),
- state->xdata);
+ fattr_to_gf_set_attr (state->valid));
}
} else {
fuse_do_truncate (state, state->size);
@@ -975,18 +738,18 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
if (fsi->valid & FATTR_FH &&
- !(fsi->valid & (FATTR_ATIME|FATTR_MTIME))) {
+ !(fsi->valid & (FATTR_ATIME|FATTR_MTIME)))
/* We need no loc if kernel sent us an fd and
* we are not fiddling with times */
- state->fd = FH_TO_FD (fsi->fh);
- fuse_resolve_fd_init (state, &state->resolve, state->fd);
- } else {
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
- }
+ ret = 1;
+ else
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0,
+ NULL);
/*
* This is just stub code demonstrating how to retrieve
@@ -1007,8 +770,29 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->lk_owner = fsi->lock_owner;
#endif
+ if ((state->loc.inode == NULL && ret == 0) ||
+ (ret < 0)) {
+
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": SETATTR %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+
+ return;
+ }
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETATTR (%"PRIu64")%s", finh->unique,
+ finh->nodeid, state->loc.path);
+
state->valid = fsi->valid;
+ if (fsi->valid & FATTR_FH) {
+ state->fd = FH_TO_FD (fsi->fh);
+ }
+
if ((fsi->valid & (FATTR_MASK)) != FATTR_SIZE) {
if (fsi->valid & FATTR_SIZE) {
state->size = fsi->size;
@@ -1028,13 +812,18 @@ fuse_setattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->size = fsi->size;
}
+ if (!state->fd) {
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
+ }
+
fuse_resolve_and_resume (state, fuse_setattr_resume);
}
static int
fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
fuse_state_t *state = frame->root->state;
fuse_in_header_t *finh = state->finh;
@@ -1067,15 +856,15 @@ fuse_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int
fuse_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- return fuse_err_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ return fuse_err_cbk (frame, cookie, this, op_ret, op_errno);
}
static int
fuse_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
if (op_ret == -1 && op_errno == ENOTSUP)
GF_LOG_OCCASIONALLY (gf_fuse_xattr_enotsup_log,
@@ -1083,14 +872,14 @@ fuse_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"extended attribute not supported "
"by the backend storage");
- return fuse_err_cbk (frame, cookie, this, op_ret, op_errno, xdata);
+ return fuse_err_cbk (frame, cookie, this, op_ret, op_errno);
}
static int
fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1124,44 +913,46 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-
void
fuse_access_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": ACCESS %"PRIu64" (%s) resolution failed",
- state->finh->unique, state->finh->nodeid,
- uuid_utoa (state->resolve.gfid));
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64" ACCESS %s/%"PRIu64" mask=%d",
state->finh->unique, state->loc.path,
state->finh->nodeid, state->mask);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_ACCESS, access,
- &state->loc, state->mask, state->xdata);
-}
+ &state->loc, state->mask);
+}
static void
fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_access_in *fai = msg;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": ACCESS %"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, finh->nodeid, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->mask = fai->mask;
- fuse_resolve_and_resume (state, fuse_access_resume);
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
+ fuse_resolve_and_resume (state, fuse_access_resume);
return;
}
@@ -1169,7 +960,7 @@ fuse_access (xlator_t *this, fuse_in_header_t *finh, void *msg)
static int
fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *linkname,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1199,65 +990,58 @@ fuse_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-
void
fuse_readlink_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "READLINK %"PRIu64" (%s) resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid));
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64" READLINK %s/%s", state->finh->unique,
- state->loc.path, uuid_utoa (state->loc.inode->gfid));
+ "%"PRIu64" READLINK %s/%"PRId64, state->finh->unique,
+ state->loc.path, state->loc.inode->ino);
FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
- readlink, &state->loc, 4096, state->xdata);
-}
+ readlink, &state->loc, 4096);
+}
static void
fuse_readlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64" READLINK %s (fuse_loc_fill() returned NULL inode)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_readlink_resume);
return;
}
-
void
fuse_mknod_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "MKNOD %"PRId64"/%s (%s/%s) resolution failed",
- state->finh->nodeid, state->resolve.bname,
- uuid_utoa (state->resolve.gfid), state->resolve.bname);
+ gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s",
+ state->loc.path);
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
- if (state->resolve.op_errno == ENOENT) {
- state->resolve.op_ret = 0;
- state->resolve.op_errno = 0;
- }
-
if (state->loc.inode) {
gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");
inode_unref (state->loc.inode);
- state->loc.inode = NULL;
}
state->loc.inode = inode_new (state->loc.parent->table);
@@ -1267,10 +1051,9 @@ fuse_mknod_resume (fuse_state_t *state)
state->loc.path);
FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKNOD,
- mknod, &state->loc, state->mode, state->rdev, state->umask,
- state->xdata);
-}
+ mknod, &state->loc, state->mode, state->rdev, state->dict);
+}
static void
fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
@@ -1292,74 +1075,42 @@ fuse_mknod (xlator_t *this, fuse_in_header_t *finh, void *msg)
uuid_generate (state->gfid);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64" MKNOD %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->mode = fmi->mode;
state->rdev = fmi->rdev;
- priv = this->private;
-#if FUSE_KERNEL_MINOR_VERSION >=12
- if (priv->proto_minor >= 12)
- state->mode &= ~fmi->umask;
- if (priv->proto_minor >= 12 && priv->acl) {
- state->xdata = dict_new ();
- if (!state->xdata) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKNOD Failed to allocate a param dictionary");
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- state->umask = fmi->umask;
- ret = dict_set_int16 (state->xdata, "umask", fmi->umask);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKNOD Failed adding umask to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- ret = dict_set_int16 (state->xdata, "mode", fmi->mode);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKNOD Failed adding mode to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- }
-#endif
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_mknod_resume);
return;
}
-
void
fuse_mkdir_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "MKDIR %"PRId64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
+ gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s",
+ state->loc.path);
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
- if (state->resolve.op_errno == ENOENT) {
- state->resolve.op_ret = 0;
- state->resolve.op_errno = 0;
- }
-
if (state->loc.inode) {
gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");
inode_unref (state->loc.inode);
- state->loc.inode = NULL;
}
state->loc.inode = inode_new (state->loc.parent->table);
@@ -1369,16 +1120,14 @@ fuse_mkdir_resume (fuse_state_t *state)
state->loc.path);
FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_MKDIR,
- mkdir, &state->loc, state->mode, state->umask, state->xdata);
+ mkdir, &state->loc, state->mode, state->dict);
}
-
static void
fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_mkdir_in *fmi = msg;
char *name = (char *)(fmi + 1);
- fuse_private_t *priv = NULL;
fuse_state_t *state;
int32_t ret = -1;
@@ -1387,82 +1136,67 @@ fuse_mkdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
uuid_generate (state->gfid);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64" MKDIR %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->mode = fmi->mode;
- priv = this->private;
-#if FUSE_KERNEL_MINOR_VERSION >=12
- if (priv->proto_minor >= 12)
- state->mode &= ~fmi->umask;
- if (priv->proto_minor >= 12 && priv->acl) {
- state->xdata = dict_new ();
- if (!state->xdata) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKDIR Failed to allocate a param dictionary");
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- state->umask = fmi->umask;
- ret = dict_set_int16 (state->xdata, "umask", fmi->umask);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKDIR Failed adding umask to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- ret = dict_set_int16 (state->xdata, "mode", fmi->mode);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "MKDIR Failed adding mode to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- }
-#endif
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_mkdir_resume);
return;
}
-
void
fuse_unlink_resume (fuse_state_t *state)
{
- if (!state->loc.parent || !state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "UNLINK %"PRId64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
+ if (!state->loc.inode) {
+ gf_log ("fuse", GF_LOG_WARNING, "path resolving failed");
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": UNLINK %s", state->finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
- unlink, &state->loc, 0, state->xdata);
-}
+ unlink, &state->loc);
+}
static void
fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
char *name = msg;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": UNLINK %s (fuse_loc_fill() returned NULL inode)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_unlink_resume);
@@ -1472,11 +1206,8 @@ fuse_unlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
void
fuse_rmdir_resume (fuse_state_t *state)
{
- if (!state->loc.parent || !state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "RMDIR %"PRId64" (%s/%s) resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
+ if (!state->loc.inode) {
+ gf_log ("fuse", GF_LOG_WARNING, "path resolving failed");
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
@@ -1487,48 +1218,50 @@ fuse_rmdir_resume (fuse_state_t *state)
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
- rmdir, &state->loc, 0, state->xdata);
+ rmdir, &state->loc, 0);
}
-
static void
fuse_rmdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
char *name = msg;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": RMDIR %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_rmdir_resume);
-
return;
}
-
void
fuse_symlink_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "SYMLINK %"PRId64" (%s/%s) -> %s resolution failed",
- state->finh->nodeid, uuid_utoa (state->resolve.gfid),
- state->resolve.bname, state->name);
+ gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s",
+ state->loc.path);
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
- if (state->resolve.op_errno == ENOENT) {
- state->resolve.op_ret = 0;
- state->resolve.op_errno = 0;
- }
-
if (state->loc.inode) {
gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");
inode_unref (state->loc.inode);
- state->loc.inode = NULL;
}
state->loc.inode = inode_new (state->loc.parent->table);
@@ -1538,27 +1271,39 @@ fuse_symlink_resume (fuse_state_t *state)
state->loc.path, state->name);
FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_SYMLINK,
- symlink, state->name, &state->loc, state->umask, state->xdata);
+ symlink, state->name, &state->loc, state->dict);
}
-
static void
fuse_symlink (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- char *name = msg;
- char *linkname = name + strlen (name) + 1;
+ char *name = msg;
+ char *linkname = name + strlen (name) + 1;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
uuid_generate (state->gfid);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64" SYMLINK %s -> %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, linkname);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->name = gf_strdup (linkname);
- fuse_resolve_and_resume (state, fuse_symlink_resume);
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
+ fuse_resolve_and_resume (state, fuse_symlink_resume);
return;
}
@@ -1567,8 +1312,7 @@ int
fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -1578,14 +1322,15 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s -> %s => 0 (buf->ia_ino=%"PRId64")",
+ "%"PRIu64": %s -> %s => 0 (buf->ia_ino=%"PRId64" , loc->ino=%"PRId64")",
frame->root->unique, state->loc.path, state->loc2.path,
- buf->ia_ino);
+ buf->ia_ino, state->loc.ino);
{
/* ugly ugly - to stay blind to situation where
rename happens on a new inode
*/
+ buf->ia_ino = state->loc.ino;
buf->ia_type = state->loc.inode->ia_type;
}
buf->ia_blksize = this->ctx->page_size;
@@ -1612,113 +1357,120 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
void
fuse_rename_resume (fuse_state_t *state)
{
- char loc_uuid[64] = {0,};
- char loc2_uuid[64] = {0,};
-
- if (!state->loc.parent || !state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "RENAME %"PRIu64" %s/%s -> %s/%s src resolution failed",
- state->finh->unique,
- uuid_utoa_r (state->resolve.gfid, loc_uuid),
- state->resolve.bname,
- uuid_utoa_r (state->resolve2.gfid, loc2_uuid),
- state->resolve2.bname);
-
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
- if (!state->loc2.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "RENAME %"PRIu64" %s/%s -> %s/%s dst resolution failed",
- state->finh->unique,
- uuid_utoa_r (state->resolve.gfid, loc_uuid),
- state->resolve.bname,
- uuid_utoa_r (state->resolve2.gfid, loc2_uuid),
- state->resolve2.bname);
-
+ if (!state->loc.inode) {
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
- state->resolve.op_ret = 0;
- state->resolve2.op_ret = 0;
-
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": RENAME `%s (%s)' -> `%s (%s)'",
- state->finh->unique, state->loc.path, loc_uuid,
- state->loc2.path, loc2_uuid);
+ "%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
+ state->finh->unique, state->loc.path, state->loc.ino,
+ state->loc2.path, state->loc2.ino);
FUSE_FOP (state, fuse_rename_cbk, GF_FOP_RENAME,
- rename, &state->loc, &state->loc2, state->xdata);
+ rename, &state->loc, &state->loc2);
}
-
static void
fuse_rename (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_rename_in *fri = msg;
char *oldname = (char *)(fri + 1);
char *newname = oldname + strlen (oldname) + 1;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, oldname);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, oldname);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
+ state->loc.path, finh->unique, state->loc.path,
+ state->loc2.path);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
+
+ ret = fuse_loc_fill (&state->loc2, state, 0, fri->newdir, newname);
+ if (!state->loc2.parent && (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
+ state->loc.path, finh->unique, state->loc.path,
+ state->loc2.path);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_entry_init (state, &state->resolve2, fri->newdir, newname);
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (oldname);
+ state->resolve.path = gf_strdup (state->loc.path);
+
+ uuid_copy (state->resolve2.pargfid, state->loc2.parent->gfid);
+ state->resolve2.bname = gf_strdup (newname);
+ state->resolve2.path = gf_strdup (state->loc2.path);
fuse_resolve_and_resume (state, fuse_rename_resume);
return;
}
-
void
fuse_link_resume (fuse_state_t *state)
{
- if (!state->loc2.inode || !state->loc.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "fuse_loc_fill() failed %"PRIu64": LINK %s %s",
- state->finh->unique, state->loc2.path, state->loc.path);
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
+ if (state->loc.inode) {
+ gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");
+ inode_unref (state->loc.inode);
}
- state->resolve.op_ret = 0;
- state->resolve2.op_ret = 0;
-
- if (state->loc.inode) {
- inode_unref (state->loc.inode);
- state->loc.inode = NULL;
- }
- state->loc.inode = inode_ref (state->loc2.inode);
+ state->loc.inode = inode_ref (state->loc2.inode);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LINK() %s -> %s",
- state->finh->unique, state->loc2.path,
- state->loc.path);
+ "%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
+ state->finh->unique, state->loc2.path, state->loc2.ino,
+ state->loc.path, state->loc.ino);
FUSE_FOP (state, fuse_newentry_cbk, GF_FOP_LINK,
- link, &state->loc2, &state->loc, state->xdata);
+ link, &state->loc2, &state->loc);
}
-
static void
fuse_link (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_link_in *fli = msg;
char *name = (char *)(fli + 1);
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- fuse_resolve_inode_init (state, &state->resolve2, fli->oldnodeid);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (ret == 0)
+ ret = fuse_loc_fill (&state->loc2, state, fli->oldnodeid, 0,
+ NULL);
+
+ if (!state->loc2.inode || (ret < 0) || !state->loc.parent) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "fuse_loc_fill() failed %"PRIu64": LINK %s %s",
+ finh->unique, state->loc2.path, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
+
+ uuid_copy (state->resolve2.gfid, state->loc2.inode->gfid);
+ state->resolve2.path = gf_strdup (state->loc2.path);
fuse_resolve_and_resume (state, fuse_link_resume);
@@ -1730,16 +1482,16 @@ static int
fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
fd_t *fd, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
+ struct iatt *preparent, struct iatt *postparent)
{
- fuse_state_t *state = NULL;
- fuse_in_header_t *finh = NULL;
- fuse_private_t *priv = NULL;
- struct fuse_out_header fouh = {0, };
- struct fuse_entry_out feo = {0, };
- struct fuse_open_out foo = {0, };
- struct iovec iov_out[3];
- inode_t *linked_inode = NULL;
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
+ fuse_private_t *priv = NULL;
+ struct fuse_out_header fouh = {0, };
+ struct fuse_entry_out feo = {0, };
+ struct fuse_open_out foo = {0, };
+ struct iovec iov_out[3];
+ inode_t *linked_inode = NULL;
state = frame->root->state;
priv = this->private;
@@ -1778,6 +1530,8 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_unref (linked_inode);
+ fd_ref (fd);
+
feo.nodeid = inode_to_fuse_nodeid (linked_inode);
feo.entry_valid = calc_timeout_sec (priv->entry_timeout);
@@ -1802,7 +1556,7 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"create(%s) got EINTR", state->loc.path);
inode_forget (inode, 1);
- gf_fd_put (priv->fdtable, state->fd_no);
+ fd_unref (fd);
goto out;
}
@@ -1812,7 +1566,6 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"%"PRIu64": %s => -1 (%s)", finh->unique,
state->loc.path, strerror (op_errno));
send_fuse_err (this, finh, op_errno);
- gf_fd_put (priv->fdtable, state->fd_no);
}
out:
free_fuse_state (state);
@@ -1821,43 +1574,28 @@ out:
return 0;
}
-
void
fuse_create_resume (fuse_state_t *state)
{
- fd_t *fd = NULL;
- fuse_private_t *priv = NULL;
+ fd_t *fd = NULL;
if (!state->loc.parent) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64" CREATE %s/%s resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid),
- state->resolve.bname);
+ gf_log ("fuse", GF_LOG_ERROR, "failed to resolve path %s",
+ state->loc.path);
send_fuse_err (state->this, state->finh, ENOENT);
free_fuse_state (state);
return;
}
- if (state->resolve.op_errno == ENOENT) {
- state->resolve.op_ret = 0;
- state->resolve.op_errno = 0;
- }
-
if (state->loc.inode) {
- gf_log (state->this->name, GF_LOG_DEBUG,
- "inode already present");
+ gf_log (state->this->name, GF_LOG_DEBUG, "inode already present");
inode_unref (state->loc.inode);
}
state->loc.inode = inode_new (state->loc.parent->table);
fd = fd_create (state->loc.inode, state->finh->pid);
-
- priv = state->this->private;
-
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
-
- state->fd = fd_ref (fd);
+ state->fd = fd;
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@@ -1866,11 +1604,10 @@ fuse_create_resume (fuse_state_t *state)
FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
create, &state->loc, state->flags, state->mode,
- state->umask, fd, state->xdata);
+ fd, state->dict);
}
-
static void
fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -1895,67 +1632,32 @@ fuse_create (xlator_t *this, fuse_in_header_t *finh, void *msg)
uuid_generate (state->gfid);
- fuse_resolve_entry_init (state, &state->resolve, finh->nodeid, name);
+ ret = fuse_loc_fill (&state->loc, state, 0, finh->nodeid, name);
+ if (!state->loc.parent || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->mode = fci->mode;
state->flags = fci->flags;
- priv = this->private;
-#if FUSE_KERNEL_MINOR_VERSION >=12
- if (priv->proto_minor >= 12)
- state->mode &= ~fci->umask;
- if (priv->proto_minor >= 12 && priv->acl) {
- state->xdata = dict_new ();
- if (!state->xdata) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "CREATE Failed to allocate a param dictionary");
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- state->umask = fci->umask;
- ret = dict_set_int16 (state->xdata, "umask", fci->umask);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "CREATE Failed adding umask to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- ret = dict_set_int16 (state->xdata, "mode", fci->mode);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "CREATE Failed adding mode to request");
- dict_destroy (state->xdata);
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
- }
-#endif
+ uuid_copy (state->resolve.pargfid, state->loc.parent->gfid);
+ state->resolve.bname = gf_strdup (name);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_create_resume);
return;
}
-
void
fuse_open_resume (fuse_state_t *state)
{
- fd_t *fd = NULL;
- fuse_private_t *priv = NULL;
-
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "%"PRIu64": OPEN %s resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid));
-
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
+ fd_t *fd = NULL;
fd = fd_create (state->loc.inode, state->finh->pid);
if (!fd) {
@@ -1966,10 +1668,7 @@ fuse_open_resume (fuse_state_t *state)
return;
}
- priv = state->this->private;
-
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
- state->fd = fd_ref (fd);
+ state->fd = fd;
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@@ -1977,22 +1676,36 @@ fuse_open_resume (fuse_state_t *state)
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
- open, &state->loc, state->flags, fd, state->xdata);
+ open, &state->loc, state->flags, fd, 0);
}
-
static void
fuse_open (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_open_in *foi = msg;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": OPEN %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->flags = foi->flags;
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
+
fuse_resolve_and_resume (state, fuse_open_resume);
return;
@@ -2003,7 +1716,7 @@ static int
fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *stbuf, struct iobref *iobref)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2050,8 +1763,8 @@ fuse_readv_resume (fuse_state_t *state)
"%"PRIu64": READ (%p, size=%zu, offset=%"PRIu64")",
state->finh->unique, state->fd, state->size, state->off);
- FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ, readv, state->fd,
- state->size, state->off, state->io_flags, state->xdata);
+ FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ,
+ readv, state->fd, state->size, state->off);
}
static void
@@ -2065,11 +1778,10 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
+
fd = FH_TO_FD (fri->fh);
state->fd = fd;
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
/* See comment by similar code in fuse_settatr */
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 9
@@ -2079,8 +1791,6 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->size = fri->size;
state->off = fri->offset;
- /* lets ignore 'fri->read_flags', but just consider 'fri->flags' */
- state->io_flags = fri->flags;
fuse_resolve_and_resume (state, fuse_readv_resume);
}
@@ -2089,7 +1799,7 @@ fuse_readv (xlator_t *this, fuse_in_header_t *finh, void *msg)
static int
fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *stbuf, struct iatt *postbuf, dict_t *xdata)
+ struct iatt *stbuf, struct iatt *postbuf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2126,6 +1836,11 @@ fuse_write_resume (fuse_state_t *state)
struct iobref *iobref = NULL;
struct iobuf *iobuf = NULL;
+ if (!state->fd || !state->fd->inode) {
+ send_fuse_err (state->this, state->finh, EBADFD);
+ free_fuse_state (state);
+ return;
+ }
iobref = iobref_new ();
if (!iobref) {
@@ -2141,13 +1856,8 @@ fuse_write_resume (fuse_state_t *state)
iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
iobref_add (iobref, iobuf);
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE (%p, size=%"PRId64", offset=%"PRId64")",
- state->finh->unique, state->fd, state->size, state->off);
-
FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE, writev, state->fd,
- &state->vector, 1, state->off, state->io_flags, iobref,
- state->xdata);
+ &state->vector, 1, state->off, iobref);
iobref_unref (iobref);
}
@@ -2173,15 +1883,6 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->size = fwi->size;
state->off = fwi->offset;
- /* lets ignore 'fwi->write_flags', but just consider 'fwi->flags' */
- state->io_flags = fwi->flags;
- /* TODO: may need to handle below flag
- (fwi->write_flags & FUSE_WRITE_CACHE);
- */
-
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
/* See comment by similar code in fuse_settatr */
priv = this->private;
#if FUSE_KERNEL_MINOR_VERSION >= 9
@@ -2189,6 +1890,10 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
state->lk_owner = fwi->lock_owner;
#endif
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": WRITE (%p, size=%"PRIu32", offset=%"PRId64")",
+ finh->unique, fd, fwi->size, fwi->offset);
+
state->vector.iov_base = msg;
state->vector.iov_len = fwi->size;
@@ -2197,15 +1902,13 @@ fuse_write (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
-
void
fuse_flush_resume (fuse_state_t *state)
{
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
- flush, state->fd, state->xdata);
+ flush, state->fd);
}
-
static void
fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2218,8 +1921,6 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
fd = FH_TO_FD (ffi->fh);
state->fd = fd;
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
state->lk_owner = ffi->lock_owner;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@@ -2230,66 +1931,45 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
-
static void
fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
- fd_t *new_fd = NULL;
- fd_t *fd = NULL;
- uint64_t val = 0;
- int ret = 0;
- fuse_state_t *state = NULL;
- fuse_fd_ctx_t *fdctx = NULL;
- fuse_private_t *priv = NULL;
+ struct fuse_release_in *fri = msg;
+ fd_t *new_fd = NULL;
+ fd_t *fd = NULL;
+ uint64_t tmp_fd_ctx = 0;
+ int ret = 0;
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
fd = FH_TO_FD (fri->fh);
state->fd = fd;
- priv = this->private;
-
+ /* TODO */
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASE %p", finh->unique, state->fd);
- ret = fd_ctx_del (fd, this, &val);
+ ret = fd_ctx_get (fd, this, &tmp_fd_ctx);
if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- new_fd = fdctx->fd;
- if (new_fd) {
- fd_unref (new_fd);
- }
-
- GF_FREE (fdctx);
- }
+ new_fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_unref (new_fd);
}
fd_unref (fd);
- state->fd = NULL;
-
- gf_fdptr_put (priv->fdtable, fd);
-
send_fuse_err (this, finh, 0);
free_fuse_state (state);
return;
}
-
void
fuse_fsync_resume (fuse_state_t *state)
{
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": FSYNC %p", state->finh->unique,
- state->fd);
-
/* fsync_flags: 1 means "datasync" (no defines for this) */
FUSE_FOP (state, fuse_fsync_cbk, GF_FOP_FSYNC,
- fsync, state->fd, (state->flags & 1), state->xdata);
+ fsync, state->fd, state->flags & 1);
}
-
static void
fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2302,44 +1982,30 @@ fuse_fsync (xlator_t *this, fuse_in_header_t *finh, void *msg)
fd = FH_TO_FD (fsi->fh);
state->fd = fd;
- fuse_resolve_fd_init (state, &state->resolve, fd);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": FSYNC %p", finh->unique, fd);
state->flags = fsi->fsync_flags;
fuse_resolve_and_resume (state, fuse_fsync_resume);
return;
}
-
void
fuse_opendir_resume (fuse_state_t *state)
{
- fd_t *fd = NULL;
- fuse_private_t *priv = NULL;
-
- priv = state->this->private;
-
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": OPENDIR (%s) resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid));
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
+ fd_t *fd = NULL;
fd = fd_create (state->loc.inode, state->finh->pid);
- state->fd = fd_ref (fd);
- state->fd_no = gf_fd_unused_get (priv->fdtable, fd);
+ state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": OPENDIR %s", state->finh->unique,
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
- opendir, &state->loc, fd, state->xdata);
+ opendir, &state->loc, fd);
}
-
static void
fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2348,10 +2014,22 @@ fuse_opendir (xlator_t *this, fuse_in_header_t *finh, void *msg)
*/
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) || (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_opendir_resume);
}
@@ -2393,8 +2071,7 @@ d_type_from_stat (struct iatt *buf)
static int
fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2438,7 +2115,6 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fde = (struct fuse_dirent *)(buf + size);
fde->ino = entry->d_ino;
fde->off = entry->d_off;
- fde->type = entry->d_type;
fde->namelen = strlen (entry->d_name);
strncpy (fde->name, entry->d_name, fde->namelen);
size += FUSE_DIRENT_SIZE (fde);
@@ -2446,18 +2122,15 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
send_fuse_data (this, finh, buf, size);
- /* TODO: */
- /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */
-
out:
free_fuse_state (state);
STACK_DESTROY (frame->root);
- GF_FREE (buf);
+ if (buf)
+ GF_FREE (buf);
return 0;
}
-
void
fuse_readdir_resume (fuse_state_t *state)
{
@@ -2466,10 +2139,9 @@ fuse_readdir_resume (fuse_state_t *state)
state->finh->unique, state->fd, state->size, state->off);
FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
- readdir, state->fd, state->size, state->off, state->xdata);
+ readdir, state->fd, state->size, state->off);
}
-
static void
fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2484,8 +2156,6 @@ fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
fd = FH_TO_FD (fri->fh);
state->fd = fd;
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
fuse_resolve_and_resume (state, fuse_readdir_resume);
}
@@ -2493,42 +2163,27 @@ fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
static void
fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_release_in *fri = msg;
- fd_t *new_fd = NULL;
- uint64_t val = 0;
- int ret = 0;
- fuse_state_t *state = NULL;
- fuse_fd_ctx_t *fdctx = NULL;
- fuse_private_t *priv = NULL;
+ struct fuse_release_in *fri = msg;
+ fd_t *new_fd = NULL;
+ uint64_t tmp_fd_ctx = 0;
+ int ret = 0;
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
state->fd = FH_TO_FD (fri->fh);
- priv = this->private;
-
+ /* TODO: free 'new-fd' in the ctx */
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASEDIR %p", finh->unique, state->fd);
- ret = fd_ctx_del (state->fd, this, &val);
-
+ ret = fd_ctx_get (state->fd, this, &tmp_fd_ctx);
if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- new_fd = fdctx->fd;
- if (new_fd) {
- fd_unref (new_fd);
- }
-
- GF_FREE (fdctx);
- }
+ new_fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_unref (new_fd);
}
fd_unref (state->fd);
- gf_fdptr_put (priv->fdtable, state->fd);
-
- state->fd = NULL;
-
send_fuse_err (this, finh, 0);
free_fuse_state (state);
@@ -2540,7 +2195,7 @@ void
fuse_fsyncdir_resume (fuse_state_t *state)
{
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
- fsyncdir, state->fd, (state->flags & 1), state->xdata);
+ fsyncdir, state->fd, state->flags & 1);
}
@@ -2557,8 +2212,6 @@ fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
state->fd = fd;
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
state->flags = fsi->fsync_flags;
fuse_resolve_and_resume (state, fuse_fsyncdir_resume);
@@ -2568,8 +2221,7 @@ fuse_fsyncdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
static int
fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
fuse_state_t *state = NULL;
fuse_in_header_t *finh = NULL;
@@ -2579,6 +2231,19 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
state = frame->root->state;
priv = this->private;
finh = state->finh;
+ /*
+ Filesystems (like ZFS on solaris) reports
+ different ->f_frsize and ->f_bsize. Old coreutils
+ df tools use statfs() and do not see ->f_frsize.
+ the ->f_blocks, ->f_bavail and ->f_bfree are
+ w.r.t ->f_frsize and not ->f_bsize which makes the
+ df tools report wrong values.
+
+ Scale the block counts to match ->f_bsize.
+ */
+ /* TODO: with old coreutils, f_bsize is taken from stat()'s ia_blksize
+ * so the df with old coreutils this wont work :(
+ */
if (op_ret == 0) {
#ifndef GF_DARWIN_HOST_OS
@@ -2619,93 +2284,53 @@ fuse_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-
-void
-fuse_statfs_resume (fuse_state_t *state)
+static void
+fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- if (!state->loc.inode) {
+ fuse_state_t *state = NULL;
+ int32_t ret = -1;
+
+ GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, 1, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": STATFS (%s) resolution fail",
- state->finh->unique, uuid_utoa (state->resolve.gfid));
+ "%"PRIu64": STATFS (fuse_loc_fill() fail)",
+ finh->unique);
- send_fuse_err (state->this, state->finh, ENOENT);
+ send_fuse_err (this, finh, ENOENT);
free_fuse_state (state);
return;
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": STATFS", state->finh->unique);
+ "%"PRIu64": STATFS", finh->unique);
FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,
- statfs, &state->loc, state->xdata);
+ statfs, &state->loc);
}
-
-static void
-fuse_statfs (xlator_t *this, fuse_in_header_t *finh, void *msg)
-{
- fuse_state_t *state = NULL;
-
- GET_STATE (this, finh, state);
-
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
-
- fuse_resolve_and_resume (state, fuse_statfs_resume);
-}
-
-
void
fuse_setxattr_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": SETXATTR %s/%"PRIu64" (%s) "
- "resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid),
- state->finh->nodeid, state->name);
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
-#ifdef GF_TEST_FFOP
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
-
- if (state->fd) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETXATTR %p/%"PRIu64" (%s)", state->finh->unique,
- state->fd, state->finh->nodeid, state->name);
-
- FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_FSETXATTR,
- fsetxattr, state->fd, state->xattr, state->flags,
- state->xdata);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
- state->loc.path, state->finh->nodeid, state->name);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
- FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR,
- setxattr, &state->loc, state->xattr, state->flags,
- state->xdata);
- }
+ FUSE_FOP (state, fuse_setxattr_cbk, GF_FOP_SETXATTR,
+ setxattr, &state->loc, state->dict, state->flags);
}
-
static void
fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_setxattr_in *fsi = msg;
char *name = (char *)(fsi + 1);
char *value = name + strlen (name) + 1;
- struct fuse_private *priv = NULL;
fuse_state_t *state = NULL;
char *dict_value = NULL;
int32_t ret = -1;
- char *newkey = NULL;
-
- priv = this->private;
#ifdef GF_DARWIN_HOST_OS
if (fsi->position) {
@@ -2719,27 +2344,13 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
#endif
- if (fuse_ignore_xattr_set (priv, name)) {
- (void) send_fuse_err (this, finh, 0);
+#ifdef DISABLE_POSIX_ACL
+ if (!strncmp (name, "system.", 7)) {
+ send_fuse_err (this, finh, EOPNOTSUPP);
+ GF_FREE (finh);
return;
}
-
- if (!priv->acl) {
- if ((strcmp (name, "system.posix_acl_access") == 0) ||
- (strcmp (name, "system.posix_acl_default") == 0)) {
- send_fuse_err (this, finh, EOPNOTSUPP);
- GF_FREE (finh);
- return;
- }
- }
-
- if (!priv->selinux) {
- if (strncmp (name, "security.", 9) == 0) {
- send_fuse_err (this, finh, EOPNOTSUPP);
- GF_FREE (finh);
- return;
- }
- }
+#endif
/* Check if the command is for changing the log
level of process or specific xlator */
@@ -2750,28 +2361,23 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- if (!strcmp ("inode-invalidate", name)) {
- gf_log ("fuse", GF_LOG_TRACE,
- "got request to invalidate %"PRIu64, finh->nodeid);
- send_fuse_err (this, finh, 0);
- fuse_invalidate_entry (this, finh->nodeid);
- GF_FREE (finh);
- return;
- }
-
- if (!strcmp (GFID_XATTR_KEY, name)) {
- send_fuse_err (this, finh, EPERM);
- GF_FREE (finh);
- return;
- }
-
GET_STATE (this, finh, state);
state->size = fsi->size;
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": SETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique,
+ state->loc.path, finh->nodeid, name);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
- state->xattr = get_new_dict ();
- if (!state->xattr) {
+ state->dict = get_new_dict ();
+ if (!state->dict) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"%"PRIu64": SETXATTR dict allocation failed",
finh->unique);
@@ -2781,32 +2387,22 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- ret = fuse_flip_xattr_ns (priv, name, &newkey);
- if (ret) {
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- return;
- }
-
- if (fsi->size > 0) {
- dict_value = memdup (value, fsi->size);
- } else {
- gf_log (THIS->name, GF_LOG_ERROR, "value size zero");
- dict_value = NULL;
- }
- dict_set (state->xattr, newkey,
+ dict_value = memdup (value, fsi->size);
+ dict_set (state->dict, (char *)name,
data_from_dynptr ((void *)dict_value, fsi->size));
- dict_ref (state->xattr);
+ dict_ref (state->dict);
state->flags = fsi->flags;
- state->name = newkey;
+ state->name = gf_strdup (name);
+
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_setxattr_resume);
return;
}
-
static void
send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
size_t size, size_t expected)
@@ -2830,28 +2426,9 @@ send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
}
}
-/* filter out xattrs that need not be visible on the
- * mount point. this is _specifically_ for geo-rep
- * as of now, to prevent Rsync from crying out loud
- * when it tries to setxattr() for selinux xattrs
- */
-static int
-fuse_filter_xattr(xlator_t *this, char *key)
-{
- int need_filter = 0;
- struct fuse_private *priv = this->private;
-
- if ((priv->client_pid == GF_CLIENT_PID_GSYNCD)
- && fnmatch ("*.selinux*", key, FNM_PERIOD) == 0)
- need_filter = 1;
-
- return need_filter;
-}
-
-
static int
fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
int need_to_free_dict = 0;
char *value = "";
@@ -2886,13 +2463,9 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
} /* if(value_data)...else */
} else {
/* if callback for listxattr */
- /* we need to invoke fuse_filter_xattr() twice. Once
- * while counting size and then while filling buffer
- */
trav = dict->members_list;
while (trav) {
- if (!fuse_filter_xattr (this, trav->key))
- len += strlen (trav->key) + 1;
+ len += strlen (trav->key) + 1;
trav = trav->next;
} /* while(trav) */
value = alloca (len + 1);
@@ -2901,11 +2474,9 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
len = 0;
trav = dict->members_list;
while (trav) {
- if (!fuse_filter_xattr (this, trav->key)) {
- strcpy (value + len, trav->key);
- value[len + strlen (trav->key)] = '\0';
- len += strlen (trav->key) + 1;
- }
+ strcpy (value + len, trav->key);
+ value[len + strlen (trav->key)] = '\0';
+ len += strlen (trav->key) + 1;
trav = trav->next;
} /* while(trav) */
send_fuse_xattr (this, finh, value, len, state->size);
@@ -2948,45 +2519,17 @@ out:
return 0;
}
-
void
fuse_getxattr_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) "
- "resolution failed",
- state->finh->unique,
- uuid_utoa (state->resolve.gfid),
- state->finh->nodeid, state->name);
-
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
-#ifdef GF_TEST_FFOP
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
-
- if (state->fd) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETXATTR %p/%"PRIu64" (%s)", state->finh->unique,
- state->fd, state->finh->nodeid, state->name);
-
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_FGETXATTR,
- fgetxattr, state->fd, state->name, state->xdata);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": GETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
- state->loc.path, state->finh->nodeid, state->name);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
- getxattr, &state->loc, state->name, state->xdata);
- }
+ FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, state->name);
}
-
static void
fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2994,11 +2537,7 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
char *name = (char *)(fgxi + 1);
fuse_state_t *state = NULL;
- struct fuse_private *priv = NULL;
- int rv = 0;
- char *newkey = NULL;
-
- priv = this->private;
+ int32_t ret = -1;
#ifdef GF_DARWIN_HOST_OS
if (fgxi->position) {
@@ -3020,164 +2559,116 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
#endif
- if (!priv->acl) {
- if ((strcmp (name, "system.posix_acl_access") == 0) ||
- (strcmp (name, "system.posix_acl_default") == 0)) {
- send_fuse_err (this, finh, ENOTSUP);
- GF_FREE (finh);
- return;
- }
+#ifdef DISABLE_POSIX_ACL
+ if (!strncmp (name, "system.", 7)) {
+ send_fuse_err (this, finh, ENODATA);
+ GF_FREE (finh);
+ return;
}
-
- if (!priv->selinux) {
- if (strncmp (name, "security.", 9) == 0) {
- send_fuse_err (this, finh, ENODATA);
- GF_FREE (finh);
- return;
- }
- }
+#endif
GET_STATE (this, finh, state);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": GETXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid, name);
- rv = fuse_flip_xattr_ns (priv, name, &newkey);
- if (rv) {
- send_fuse_err (this, finh, ENOMEM);
+ send_fuse_err (this, finh, ENOENT);
free_fuse_state (state);
- goto out;
+ return;
}
state->size = fgxi->size;
- state->name = newkey;
+ state->name = gf_strdup (name);
+
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_getxattr_resume);
- out:
return;
}
-
void
fuse_listxattr_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRIu64": LISTXATTR %s/%"PRIu64
- "resolution failed", state->finh->unique,
- uuid_utoa (state->resolve.gfid), state->finh->nodeid);
-
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
-#ifdef GF_TEST_FFOP
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
-
- if (state->fd) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LISTXATTR %p/%"PRIu64, state->finh->unique,
- state->fd, state->finh->nodeid);
-
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_FGETXATTR,
- fgetxattr, state->fd, NULL, state->xdata);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": LISTXATTR %s/%"PRIu64, state->finh->unique,
- state->loc.path, state->finh->nodeid);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": LISTXATTR %s/%"PRIu64, state->finh->unique,
+ state->loc.path, state->finh->nodeid);
- FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
- getxattr, &state->loc, NULL, state->xdata);
- }
+ FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
+ getxattr, &state->loc, NULL);
}
-
static void
fuse_listxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_getxattr_in *fgxi = msg;
+
fuse_state_t *state = NULL;
+ int32_t ret = -1;
GET_STATE (this, finh, state);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": LISTXATTR %s/%"PRIu64" (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid);
+
+ send_fuse_err (this, finh, ENOENT);
+ free_fuse_state (state);
+ return;
+ }
state->size = fgxi->size;
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_listxattr_resume);
return;
}
-
void
fuse_removexattr_resume (fuse_state_t *state)
{
- if (!state->loc.inode) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s) "
- "resolution failed",
- state->finh->unique, uuid_utoa (state->resolve.gfid),
- state->finh->nodeid, state->name);
-
- send_fuse_err (state->this, state->finh, ENOENT);
- free_fuse_state (state);
- return;
- }
-
-#ifdef GF_TEST_FFOP
- state->fd = fd_lookup (state->loc.inode, state->finh->pid);
-#endif /* GF_TEST_FFOP */
-
- if (state->fd) {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": REMOVEXATTR %p/%"PRIu64" (%s)", state->finh->unique,
- state->fd, state->finh->nodeid, state->name);
-
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_FREMOVEXATTR,
- fremovexattr, state->fd, state->name, state->xdata);
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s)", state->finh->unique,
- state->loc.path, state->finh->nodeid, state->name);
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s)", state->finh->unique,
+ state->loc.path, state->finh->nodeid, state->name);
- FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
- removexattr, &state->loc, state->name, state->xdata);
- }
+ FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
+ removexattr, &state->loc, state->name);
}
-
static void
fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
+
{
char *name = msg;
fuse_state_t *state = NULL;
- fuse_private_t *priv = NULL;
int32_t ret = -1;
- char *newkey = NULL;
-
- if (!strcmp (GFID_XATTR_KEY, name)) {
- send_fuse_err (this, finh, EPERM);
- GF_FREE (finh);
- return;
- }
-
- priv = this->private;
GET_STATE (this, finh, state);
+ ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
+ if ((state->loc.inode == NULL) ||
+ (ret < 0)) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
+ "%"PRIu64": REMOVEXATTR %s/%"PRIu64" (%s) (fuse_loc_fill() failed)",
+ finh->unique, state->loc.path, finh->nodeid, name);
- fuse_resolve_inode_init (state, &state->resolve, finh->nodeid);
-
- ret = fuse_flip_xattr_ns (priv, name, &newkey);
- if (ret) {
- send_fuse_err (this, finh, ENOMEM);
+ send_fuse_err (this, finh, ENOENT);
free_fuse_state (state);
return;
}
- state->name = newkey;
+ state->name = gf_strdup (name);
+ uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
+ state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_removexattr_resume);
return;
@@ -3188,8 +2679,7 @@ static int gf_fuse_lk_enosys_log;
static int
fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
fuse_state_t *state = NULL;
@@ -3233,7 +2723,6 @@ fuse_getlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
return 0;
}
-
void
fuse_getlk_resume (fuse_state_t *state)
{
@@ -3241,10 +2730,9 @@ fuse_getlk_resume (fuse_state_t *state)
"%"PRIu64": GETLK %p", state->finh->unique, state->fd);
FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
- lk, state->fd, F_GETLK, &state->lk_lock, state->xdata);
+ lk, state->fd, F_GETLK, &state->lk_lock);
}
-
static void
fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -3256,9 +2744,6 @@ fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
fd = FH_TO_FD (fli->fh);
GET_STATE (this, finh, state);
state->fd = fd;
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
convert_fuse_file_lock (&fli->lk, &state->lk_lock,
fli->owner);
@@ -3272,22 +2757,15 @@ fuse_getlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
static int
fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
- uint32_t op = 0;
fuse_state_t *state = NULL;
state = frame->root->state;
- op = state->finh->opcode;
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": ERR => 0", frame->root->unique);
- fd_lk_insert_and_merge (state->fd,
- (op == FUSE_SETLK) ? F_SETLK : F_SETLKW,
- &state->lk_lock);
-
send_fuse_err (this, state->finh, 0);
} else {
if (op_errno == ENOSYS) {
@@ -3301,11 +2779,12 @@ fuse_setlk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
} else if (op_errno == EAGAIN) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"Returning EAGAIN Flock: "
- "start=%llu, len=%llu, pid=%llu, lk-owner=%s",
- (unsigned long long) state->lk_lock.l_start,
- (unsigned long long) state->lk_lock.l_len,
- (unsigned long long) state->lk_lock.l_pid,
- lkowner_utoa (&frame->root->lk_owner));
+ "start=%llu, len=%llu, pid=%llu, lk-owner=%llu",
+ (unsigned long long) lock->l_start,
+ (unsigned long long) lock->l_len,
+ (unsigned long long) lock->l_pid,
+ (unsigned long long) frame->root->lk_owner);
+
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": ERR => -1 (%s)",
@@ -3331,10 +2810,9 @@ fuse_setlk_resume (fuse_state_t *state)
FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK, lk, state->fd,
state->finh->opcode == FUSE_SETLK ? F_SETLK : F_SETLKW,
- &state->lk_lock, state->xdata);
+ &state->lk_lock);
}
-
static void
fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -3347,9 +2825,6 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
GET_STATE (this, finh, state);
state->finh = finh;
state->fd = fd;
-
- fuse_resolve_fd_init (state, &state->resolve, fd);
-
convert_fuse_file_lock (&fli->lk, &state->lk_lock,
fli->owner);
@@ -3360,53 +2835,14 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
-
-static void *
-notify_kernel_loop (void *data)
-{
- xlator_t *this = NULL;
- fuse_private_t *priv = NULL;
- struct fuse_out_header *fouh = NULL;
- int rv = 0;
-
- char inval_buf[INVAL_BUF_SIZE] = {0,};
-
- this = data;
- priv = this->private;
-
- for (;;) {
- rv = read (priv->revchan_in, inval_buf, sizeof (*fouh));
- if (rv != sizeof (*fouh))
- break;
- fouh = (struct fuse_out_header *)inval_buf;
- rv = read (priv->revchan_in, inval_buf + sizeof (*fouh),
- fouh->len - sizeof (*fouh));
- if (rv != fouh->len - sizeof (*fouh))
- break;
- rv = write (priv->fd, inval_buf, fouh->len);
- if (rv != fouh->len && !(rv == -1 && errno == ENOENT))
- break;
- }
-
- close (priv->revchan_in);
- close (priv->revchan_out);
-
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "kernel notifier loop terminated");
-
- return NULL;
-}
-
-
static void
fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_init_in *fini = msg;
- struct fuse_init_out fino = {0,};
- fuse_private_t *priv = NULL;
- int ret = 0;
- int pfd[2] = {0,};
- pthread_t messenger;
+ struct fuse_init_in *fini = msg;
+
+ struct fuse_init_out fino;
+ fuse_private_t *priv = NULL;
+ int ret;
priv = this->private;
@@ -3435,13 +2871,6 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
fino.max_readahead = 1 << 17;
fino.max_write = 1 << 17;
fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
-#if FUSE_KERNEL_MINOR_VERSION >= 12
- if (fini->minor >= 12) {
- /* let fuse leave the umask processing to us, so that it does not
- * break extended POSIX ACL defaults on server */
- fino.flags |= FUSE_DONT_MASK;
- }
-#endif
#if FUSE_KERNEL_MINOR_VERSION >= 9
if (fini->minor >= 6 /* fuse_init_in has flags */ &&
fini->flags & FUSE_BIG_WRITES) {
@@ -3450,47 +2879,9 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
priv->direct_io_mode = 0;
fino.flags |= FUSE_BIG_WRITES;
}
-
- /* Used for 'reverse invalidation of inode' */
- if (fini->minor >= 12) {
- if (pipe(pfd) == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "cannot create pipe pair (%s)",
- strerror(errno));
-
- close (priv->fd);
- goto out;
- }
- priv->revchan_in = pfd[0];
- priv->revchan_out = pfd[1];
- ret = pthread_create (&messenger, NULL, notify_kernel_loop,
- this);
- if (ret != 0) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "failed to start messenger daemon (%s)",
- strerror(errno));
-
- close (priv->fd);
- goto out;
- }
- priv->reverse_fuse_thread_started = _gf_true;
- } else {
- /*
- * FUSE minor < 12 does not implement invalidate notifications.
- * This mechanism is required for fopen-keep-cache to operate
- * correctly. Disable and warn the user.
- */
- if (priv->fopen_keep_cache) {
- gf_log("glusterfs-fuse", GF_LOG_WARNING, "FUSE version "
- "%d.%d does not support inval notifications. "
- "fopen-keep-cache disabled.", fini->major,
- fini->minor);
- priv->fopen_keep_cache = 0;
- }
- }
-
if (fini->minor >= 13) {
/* these values seemed to work fine during testing */
+
fino.max_background = 64;
fino.congestion_threshold = 48;
}
@@ -3586,8 +2977,8 @@ fuse_first_lookup (xlator_t *this)
loc.path = "/";
loc.name = "";
+ loc.ino = 1;
loc.inode = fuse_ino_to_inode (1, this);
- uuid_copy (loc.gfid, loc.inode->gfid);
loc.parent = NULL;
dict = dict_new ();
@@ -3605,8 +2996,6 @@ fuse_first_lookup (xlator_t *this)
memset (gfid, 0, 16);
gfid[15] = 1;
ret = dict_set_static_bin (dict, "gfid-req", gfid, 16);
- if (ret)
- gf_log (xl->name, GF_LOG_ERROR, "failed to set 'gfid-req'");
STACK_WIND (frame, fuse_first_lookup_cbk, xl, xl->fops->lookup,
&loc, dict);
@@ -3631,317 +3020,13 @@ fuse_first_lookup (xlator_t *this)
int
-fuse_nameless_lookup (xlator_t *xl, uuid_t gfid, loc_t *loc)
-{
- int ret = -1;
- dict_t *xattr_req = NULL;
- struct iatt iatt = {0, };
- inode_t *linked_inode = NULL;
-
- if ((loc == NULL) || (xl == NULL)) {
- goto out;
- }
-
- if (loc->inode == NULL) {
- loc->inode = inode_new (xl->itable);
- if (loc->inode == NULL) {
- goto out;
- }
- }
-
- uuid_copy (loc->gfid, gfid);
-
- xattr_req = dict_new ();
- if (xattr_req == NULL) {
- goto out;
- }
-
- ret = syncop_lookup (xl, loc, xattr_req, &iatt, NULL, NULL);
- if (ret < 0) {
- goto out;
- }
-
- linked_inode = inode_link (loc->inode, NULL, NULL, &iatt);
- inode_unref (loc->inode);
- loc->inode = linked_inode;
-
- ret = 0;
-out:
- if (xattr_req != NULL) {
- dict_unref (xattr_req);
- }
-
- return ret;
-}
-
-
-int
-fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
- xlator_t *new_subvol)
-{
- int ret = -1;
- loc_t loc = {0, };
- char create_in_progress = 0;
- inode_t *old_inode = NULL;
- int flags = 0;
-
- /* could've used pthread_cond_wait, but that requires a cond variable to
- * be mainted for each fd and that is a bit too much overhead.
- */
- do {
- LOCK (&fd->inode->lock);
- {
- if (uuid_is_null (fd->inode->gfid)) {
- create_in_progress = 1;
- } else {
- create_in_progress = 0;
- }
- }
- UNLOCK (&fd->inode->lock);
-
- if (create_in_progress) {
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
- "create call on fd (%p) is in progress, "
- "hence waiting", fd);
- sleep (1);
- }
-
- } while (create_in_progress);
-
- if (fd->inode->table->xl == old_subvol) {
- ret = syncop_fsync (old_subvol, fd);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "syncop_fsync failed (%s)", strerror (errno));
- }
- } else {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "fd (%p) was not "
- "migrated during previous graph switch", fd);
- }
-
- loc.path = "";
- loc.name = NULL;
-
- loc.inode = inode_find (new_subvol->itable, fd->inode->gfid);
-
- if (loc.inode == NULL) {
- ret = fuse_nameless_lookup (new_subvol, fd->inode->gfid, &loc);
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "name-less lookup of gfid (%s) failed (%s)",
- uuid_utoa (fd->inode->gfid), strerror (errno));
- goto out;
- }
-
- }
-
- old_inode = fd->inode;
-
- inode_ref (loc.inode);
-
- LOCK (&fd->inode->lock);
- {
- list_del_init (&fd->inode_list);
- }
- UNLOCK (&fd->inode->lock);
-
- LOCK (&fd->lock);
- {
- fd->inode = loc.inode;
- }
- UNLOCK (&fd->lock);
-
- if (IA_ISDIR (fd->inode->ia_type)) {
- ret = syncop_opendir (new_subvol, &loc, fd);
- } else {
- flags = fd->flags & ~(O_CREAT | O_EXCL);
- ret = syncop_open (new_subvol, &loc, flags, fd);
- }
-
- if (ret < 0) {
- gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "open on gfid (%s) failed (%s)",
- uuid_utoa (fd->inode->gfid), strerror (errno));
- goto out;
- }
-
- fd_bind (fd);
-
- ret = 0;
-out:
- if (loc.inode != NULL) {
- inode_unref (loc.inode);
- }
-
- if (old_inode != NULL) {
- inode_unref (old_inode);
- }
-
- return ret;
-}
-
-
-int
-fuse_handle_opened_fds (xlator_t *this, xlator_t *old_subvol,
- xlator_t *new_subvol)
-{
- fuse_private_t *priv = NULL;
- fdentry_t *fdentries = NULL;
- uint32_t count = 0;
- fdtable_t *fdtable = NULL;
- int i = 0;
- fd_t *fd = NULL;
- int32_t ret = 0;
- fuse_fd_ctx_t *fdctx = NULL;
-
- priv = this->private;
-
- fdtable = priv->fdtable;
-
- fdentries = gf_fd_fdtable_copy_all_fds (fdtable, &count);
- if (fdentries != NULL) {
- for (i = 0; i < count; i++) {
- fd = fdentries[i].fd;
- if (fd == NULL)
- continue;
-
- ret = fuse_migrate_fd (this, fd, old_subvol,
- new_subvol);
-
- fdctx = fuse_fd_ctx_check_n_create (this, fd);
- if (fdctx) {
- if (ret < 0) {
- fdctx->migration_failed = 1;
- } else {
- fdctx->migration_failed = 0;
- }
- }
- }
-
- for (i = 0; i < count ; i++) {
- fd = fdentries[i].fd;
- if (fd)
- fd_unref (fd);
- }
-
- GF_FREE (fdentries);
- }
-
- return 0;
-}
-
-
-static int
-fuse_handle_blocked_locks (xlator_t *this, xlator_t *old_subvol,
- xlator_t *new_subvol)
-{
- return 0;
-}
-
-
-static int
-fuse_graph_switch_task (void *data)
-{
- fuse_graph_switch_args_t *args = NULL;
-
- args = data;
- if (args == NULL) {
- goto out;
- }
-
- /* don't change the order of handling open fds and blocked locks, since
- * the act of opening files also reacquires granted locks in new graph.
- */
- fuse_handle_opened_fds (args->this, args->old_subvol, args->new_subvol);
-
- fuse_handle_blocked_locks (args->this, args->old_subvol,
- args->new_subvol);
-
-out:
- return 0;
-}
-
-
-fuse_graph_switch_args_t *
-fuse_graph_switch_args_alloc (void)
-{
- fuse_graph_switch_args_t *args = NULL;
-
- args = GF_CALLOC (1, sizeof (*args), gf_fuse_mt_graph_switch_args_t);
- if (args == NULL) {
- goto out;
- }
-
-out:
- return args;
-}
-
-
-void
-fuse_graph_switch_args_destroy (fuse_graph_switch_args_t *args)
-{
- if (args == NULL) {
- goto out;
- }
-
- GF_FREE (args);
-out:
- return;
-}
-
-
-int
-fuse_handle_graph_switch (xlator_t *this, xlator_t *old_subvol,
- xlator_t *new_subvol)
-{
- call_frame_t *frame = NULL;
- int32_t ret = -1;
- fuse_graph_switch_args_t *args = NULL;
-
- frame = create_frame (this, this->ctx->pool);
- if (frame == NULL) {
- goto out;
- }
-
- args = fuse_graph_switch_args_alloc ();
- if (args == NULL) {
- goto out;
- }
-
- args->this = this;
- args->old_subvol = old_subvol;
- args->new_subvol = new_subvol;
-
- ret = synctask_new (this->ctx->env, fuse_graph_switch_task, NULL, frame,
- args);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "starting sync-task to "
- "handle graph switch failed");
- goto out;
- }
-
- ret = 0;
-out:
- if (args != NULL) {
- fuse_graph_switch_args_destroy (args);
- }
-
- if (frame != NULL) {
- STACK_DESTROY (frame->root);
- }
-
- return ret;
-}
-
-
-int
fuse_graph_sync (xlator_t *this)
{
- fuse_private_t *priv = NULL;
- int need_first_lookup = 0;
- int ret = 0;
- xlator_t *old_subvol = NULL, *new_subvol = NULL;
- uint64_t winds_on_old_subvol = 0;
+ fuse_private_t *priv = NULL;
+ int need_first_lookup = 0;
+ struct timeval now = {0, };
+ struct timespec timeout = {0, };
+ int ret = 0;
priv = this->private;
@@ -3950,14 +3035,18 @@ fuse_graph_sync (xlator_t *this)
if (!priv->next_graph)
goto unlock;
- old_subvol = priv->active_subvol;
- new_subvol = priv->active_subvol = priv->next_graph->top;
+ priv->active_subvol = priv->next_graph->top;
priv->next_graph = NULL;
need_first_lookup = 1;
- while (!priv->event_recvd) {
- ret = pthread_cond_wait (&priv->sync_cond,
- &priv->sync_mutex);
+ gettimeofday (&now, NULL);
+ timeout.tv_sec = now.tv_sec + MAX_FUSE_PROC_DELAY;
+ timeout.tv_nsec = now.tv_usec * 1000;
+
+ while (!priv->child_up) {
+ ret = pthread_cond_timedwait (&priv->sync_cond,
+ &priv->sync_mutex,
+ &timeout);
if (ret != 0) {
gf_log (this->name, GF_LOG_DEBUG,
"timedwait returned non zero value "
@@ -3973,57 +3062,23 @@ unlock:
fuse_first_lookup (this);
}
- if ((old_subvol != NULL) && (new_subvol != NULL)) {
- fuse_handle_graph_switch (this, old_subvol, new_subvol);
-
- pthread_mutex_lock (&priv->sync_mutex);
- {
- old_subvol->switched = 1;
- winds_on_old_subvol = old_subvol->winds;
- }
- pthread_mutex_unlock (&priv->sync_mutex);
-
- if (winds_on_old_subvol == 0) {
- xlator_notify (old_subvol, GF_EVENT_PARENT_DOWN,
- old_subvol, NULL);
- }
- }
-
return 0;
}
-int
-fuse_get_mount_status (xlator_t *this)
-{
- int kid_status = -1;
- fuse_private_t *priv = this->private;
-
- if (read(priv->status_pipe[0],&kid_status, sizeof(kid_status)) < 0) {
- gf_log (this->name, GF_LOG_ERROR, "could not get mount status");
- kid_status = -1;
- }
- gf_log (this->name, GF_LOG_DEBUG, "mount status is %d", kid_status);
-
- close(priv->status_pipe[0]);
- close(priv->status_pipe[1]);
- return kid_status;
-}
static void *
fuse_thread_proc (void *data)
{
- char *mount_point = NULL;
- xlator_t *this = NULL;
- fuse_private_t *priv = NULL;
- ssize_t res = 0;
- struct iobuf *iobuf = NULL;
- fuse_in_header_t *finh;
- struct iovec iov_in[2];
- void *msg = NULL;
- const size_t msg0_size = sizeof (*finh) + 128;
- fuse_handler_t **fuse_ops = NULL;
- struct pollfd pfd[2] = {{0,}};
- gf_boolean_t mount_finished = _gf_false;
+ char *mount_point = NULL;
+ xlator_t *this = NULL;
+ fuse_private_t *priv = NULL;
+ ssize_t res = 0;
+ struct iobuf *iobuf = NULL;
+ fuse_in_header_t *finh;
+ struct iovec iov_in[2];
+ void *msg = NULL;
+ const size_t msg0_size = sizeof (*finh) + 128;
+ fuse_handler_t **fuse_ops = NULL;
this = data;
priv = this->private;
@@ -4033,59 +3088,19 @@ fuse_thread_proc (void *data)
iov_in[0].iov_len = sizeof (*finh) + sizeof (struct fuse_write_in);
iov_in[1].iov_len = ((struct iobuf_pool *)this->ctx->iobuf_pool)
- ->default_page_size;
+ ->page_size;
priv->msg0_len_p = &iov_in[0].iov_len;
for (;;) {
/* THIS has to be reset here */
THIS = this;
- if (!mount_finished) {
- memset(pfd,0,sizeof(pfd));
- pfd[0].fd = priv->status_pipe[0];
- pfd[0].events = POLLIN | POLLHUP | POLLERR;
- pfd[1].fd = priv->fd;
- pfd[1].events = POLLIN | POLLHUP | POLLERR;
- if (poll(pfd,2,-1) < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "poll error %s", strerror(errno));
- break;
- }
- if (pfd[0].revents & POLLIN) {
- if (fuse_get_mount_status(this) != 0) {
- break;
- }
- mount_finished = _gf_true;
- }
- else if (pfd[0].revents) {
- gf_log (this->name, GF_LOG_ERROR,
- "mount pipe closed without status");
- break;
- }
- if (!pfd[1].revents) {
- continue;
- }
- }
-
- /*
- * We don't want to block on readv while we're still waiting
- * for mount status. That means we only want to get here if
- * mount_status is true (meaning that our wait completed
- * already) or if we already called poll(2) on priv->fd to
- * make sure it's ready.
- */
-
if (priv->init_recvd)
fuse_graph_sync (this);
- /* TODO: This place should always get maximum supported buffer
- size from 'fuse', which is as of today 128KB. If we bring in
- support for higher block sizes support, then we should be
- changing this one too */
iobuf = iobuf_get (this->ctx->iobuf_pool);
-
/* Add extra 128 byte to the first iov so that it can
- * accommodate "ordinary" non-write requests. It's not
+ * accomodate "ordinary" non-write requests. It's not
* guaranteed to be big enough, as SETXATTR and namespace
* operations with very long names may grow behind it,
* but it's good enough in most cases (and we can handle
@@ -4176,10 +3191,6 @@ fuse_thread_proc (void *data)
msg = finh + 1;
}
- if (priv->uid_map_root &&
- finh->uid == priv->uid_map_root)
- finh->uid = 0;
-
#ifdef GF_DARWIN_HOST_OS
if (finh->opcode >= FUSE_OP_HIGH)
/* turn down MacFUSE specific messages */
@@ -4196,11 +3207,8 @@ fuse_thread_proc (void *data)
GF_FREE (iov_in[0].iov_base);
}
- /*
- * We could be in all sorts of states with respect to iobuf and iov_in
- * by the time we get here, and it's just not worth untangling them if
- * we're about to kill ourselves anyway.
- */
+ iobuf_unref (iobuf);
+ GF_FREE (iov_in[0].iov_base);
if (dict_get (this->options, ZR_MOUNTPOINT_OPT))
mount_point = data_to_str (dict_get (this->options,
@@ -4208,14 +3216,14 @@ fuse_thread_proc (void *data)
if (mount_point) {
gf_log (this->name, GF_LOG_INFO,
"unmounting %s", mount_point);
+ dict_del (this->options, ZR_MOUNTPOINT_OPT);
}
- /* Kill the whole process, not just this thread. */
kill (getpid(), SIGTERM);
+
return NULL;
}
-
int32_t
fuse_itable_dump (xlator_t *this)
{
@@ -4243,31 +3251,29 @@ fuse_priv_dump (xlator_t *this)
gf_proc_dump_add_section("xlator.mount.fuse.priv");
- gf_proc_dump_write("fd", "%d", private->fd);
- gf_proc_dump_write("proto_minor", "%u",
+ gf_proc_dump_write("xlator.mount.fuse.priv.fd", "%d", private->fd);
+ gf_proc_dump_write("xlator.mount.fuse.priv.proto_minor", "%u",
private->proto_minor);
- gf_proc_dump_write("volfile", "%s",
+ gf_proc_dump_write("xlator.mount.fuse.priv.volfile", "%s",
private->volfile?private->volfile:"None");
- gf_proc_dump_write("volfile_size", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.volfile_size", "%d",
private->volfile_size);
- gf_proc_dump_write("mount_point", "%s",
+ gf_proc_dump_write("xlator.mount.fuse.mount_point", "%s",
private->mount_point);
- gf_proc_dump_write("iobuf", "%u",
+ gf_proc_dump_write("xlator.mount.fuse.iobuf", "%u",
private->iobuf);
- gf_proc_dump_write("fuse_thread_started", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.fuse_thread_started", "%d",
(int)private->fuse_thread_started);
- gf_proc_dump_write("direct_io_mode", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.direct_io_mode", "%d",
private->direct_io_mode);
- gf_proc_dump_write("entry_timeout", "%lf",
+ gf_proc_dump_write("xlator.mount.fuse.entry_timeout", "%lf",
private->entry_timeout);
- gf_proc_dump_write("attribute_timeout", "%lf",
+ gf_proc_dump_write("xlator.mount.fuse.attribute_timeout", "%lf",
private->attribute_timeout);
- gf_proc_dump_write("init_recvd", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.init_recvd", "%d",
(int)private->init_recvd);
- gf_proc_dump_write("strict_volfile_check", "%d",
+ gf_proc_dump_write("xlator.mount.fuse.strict_volfile_check", "%d",
(int)private->strict_volfile_check);
- gf_proc_dump_write("reverse_thread_started", "%d",
- (int)private->reverse_fuse_thread_started);
return 0;
}
@@ -4300,7 +3306,7 @@ fuse_graph_setup (xlator_t *this, glusterfs_graph_t *graph)
pthread_mutex_lock (&priv->sync_mutex);
{
priv->next_graph = graph;
- priv->event_recvd = 0;
+ priv->child_up = 0;
pthread_cond_signal (&priv->sync_cond);
}
@@ -4343,11 +3349,10 @@ notify (xlator_t *this, int32_t event, void *data, ...)
"failed to setup the graph");
}
- if ((event == GF_EVENT_CHILD_UP)
- || (event == GF_EVENT_CHILD_DOWN)) {
+ if (event == GF_EVENT_CHILD_UP) {
pthread_mutex_lock (&private->sync_mutex);
{
- private->event_recvd = 1;
+ private->child_up = 1;
pthread_cond_broadcast (&private->sync_cond);
}
pthread_mutex_unlock (&private->sync_mutex);
@@ -4369,14 +3374,6 @@ notify (xlator_t *this, int32_t event, void *data, ...)
break;
}
- case GF_EVENT_AUTH_FAILED:
- {
- /* Authentication failure is an error and glusterfs should stop */
- gf_log (this->name, GF_LOG_ERROR, "Server authenication failed. Shutting down.");
- fini (this);
- break;
- }
-
default:
break;
}
@@ -4488,9 +3485,6 @@ init (xlator_t *this_xl)
int i = 0;
int xl_name_allocated = 0;
int fsname_allocated = 0;
- glusterfs_ctx_t *ctx = NULL;
- gf_boolean_t sync_to_mount = _gf_false;
- char *mnt_args = NULL;
if (this_xl == NULL)
return -1;
@@ -4498,10 +3492,6 @@ init (xlator_t *this_xl)
if (this_xl->options == NULL)
return -1;
- ctx = this_xl->ctx;
- if (!ctx)
- return -1;
-
options = this_xl->options;
if (this_xl->name == NULL) {
@@ -4525,8 +3515,6 @@ init (xlator_t *this_xl)
this_xl->private = (void *) priv;
priv->mount_point = NULL;
priv->fd = -1;
- priv->revchan_in = -1;
- priv->revchan_out = -1;
/* get options from option dictionary */
ret = dict_get_str (options, ZR_MOUNTPOINT_OPT, &value_string);
@@ -4569,19 +3557,20 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
- GF_OPTION_INIT ("attribute-timeout", priv->attribute_timeout, double,
- cleanup_exit);
-
- GF_OPTION_INIT ("entry-timeout", priv->attribute_timeout, double,
- cleanup_exit);
+ ret = dict_get_double (options, "attribute-timeout",
+ &priv->attribute_timeout);
+ if (ret != 0)
+ priv->attribute_timeout = 1.0; /* default */
- GF_OPTION_INIT ("negative-timeout", priv->attribute_timeout, double,
- cleanup_exit);
+ ret = dict_get_double (options, "entry-timeout",
+ &priv->entry_timeout);
+ if (ret != 0)
+ priv->entry_timeout = 1.0; /* default */
- GF_OPTION_INIT ("client-pid", priv->client_pid, int32, cleanup_exit);
-
- GF_OPTION_INIT ("uid-map-root", priv->uid_map_root, uint32,
- cleanup_exit);
+ ret = dict_get_int32 (options, "client-pid",
+ &priv->client_pid);
+ if (ret == 0)
+ priv->client_pid_set = _gf_true;
priv->direct_io_mode = 2;
ret = dict_get_str (options, ZR_DIRECT_IO_OPT, &value_string);
@@ -4590,17 +3579,13 @@ init (xlator_t *this_xl)
GF_ASSERT (ret == 0);
}
- GF_OPTION_INIT (ZR_STRICT_VOLFILE_CHECK, priv->strict_volfile_check,
- bool, cleanup_exit);
-
- GF_OPTION_INIT ("acl", priv->acl, bool, cleanup_exit);
-
- if (priv->uid_map_root)
- priv->acl = 1;
-
- GF_OPTION_INIT ("selinux", priv->selinux, bool, cleanup_exit);
-
- GF_OPTION_INIT ("read-only", priv->read_only, bool, cleanup_exit);
+ priv->strict_volfile_check = 0;
+ ret = dict_get_str (options, ZR_STRICT_VOLFILE_CHECK, &value_string);
+ if (ret == 0) {
+ ret = gf_string2boolean (value_string,
+ &priv->strict_volfile_check);
+ GF_ASSERT (ret == 0);
+ }
priv->fuse_dump_fd = -1;
ret = dict_get_str (options, "dump-fuse", &value_string);
@@ -4619,26 +3604,6 @@ init (xlator_t *this_xl)
priv->fuse_dump_fd = ret;
}
- sync_to_mount = _gf_false;
- ret = dict_get_str (options, "sync-to-mount", &value_string);
- if (ret == 0) {
- ret = gf_string2boolean (value_string,
- &sync_to_mount);
- GF_ASSERT (ret == 0);
- }
-
- GF_OPTION_INIT("fopen-keep-cache", priv->fopen_keep_cache, bool,
- cleanup_exit);
-
- GF_OPTION_INIT("gid-timeout", priv->gid_cache_timeout, int32,
- cleanup_exit);
-
- if (gid_cache_init(&priv->gid_cache, priv->gid_cache_timeout) < 0) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR, "Failed to initialize "
- "group cache.");
- goto cleanup_exit;
- }
-
cmd_args = &this_xl->ctx->cmd_args;
fsname = cmd_args->volfile;
if (!fsname && cmd_args->volfile_server) {
@@ -4662,34 +3627,17 @@ init (xlator_t *this_xl)
if (!fsname)
fsname = "glusterfs";
- priv->fdtable = gf_fd_fdtable_alloc ();
- if (priv->fdtable == NULL) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR, "Out of memory");
- goto cleanup_exit;
- }
- gf_asprintf (&mnt_args, "%s%sallow_other,max_read=131072",
- priv->read_only ? "ro," : "",
- priv->acl ? "" : "default_permissions,");
- if (!mnt_args)
- goto cleanup_exit;
-
- if (pipe(priv->status_pipe) < 0) {
- gf_log (this_xl->name, GF_LOG_ERROR,
- "could not create pipe to separate mount process");
- goto cleanup_exit;
- }
-
- priv->fd = gf_fuse_mount (priv->mount_point, fsname, mnt_args,
- sync_to_mount ? &ctx->mnt_pid : NULL,
- priv->status_pipe[1]);
+ priv->fd = gf_fuse_mount (priv->mount_point, fsname,
+ "allow_other,default_permissions,"
+ "max_read=131072");
if (priv->fd == -1)
goto cleanup_exit;
pthread_mutex_init (&priv->fuse_dump_mutex, NULL);
pthread_cond_init (&priv->sync_cond, NULL);
pthread_mutex_init (&priv->sync_mutex, NULL);
- priv->event_recvd = 0;
+ priv->child_up = 0;
for (i = 0; i < FUSE_OP_HIGH; i++) {
if (!fuse_std_ops[i])
@@ -4703,9 +3651,6 @@ init (xlator_t *this_xl)
priv->fuse_ops = fuse_dump_ops;
}
- if (fsname_allocated)
- GF_FREE (fsname);
- GF_FREE (mnt_args);
return 0;
cleanup_exit:
@@ -4715,13 +3660,10 @@ cleanup_exit:
GF_FREE (fsname);
if (priv) {
GF_FREE (priv->mount_point);
- if (priv->fd != -1)
- close (priv->fd);
- if (priv->fuse_dump_fd != -1)
- close (priv->fuse_dump_fd);
+ close (priv->fd);
+ close (priv->fuse_dump_fd);
GF_FREE (priv);
}
- GF_FREE (mnt_args);
return -1;
}
@@ -4745,21 +3687,16 @@ fini (xlator_t *this_xl)
gf_log (this_xl->name, GF_LOG_INFO,
"Unmounting '%s'.", mount_point);
+ dict_del (this_xl->options, ZR_MOUNTPOINT_OPT);
gf_fuse_unmount (mount_point, priv->fd);
close (priv->fuse_dump_fd);
- dict_del (this_xl->options, ZR_MOUNTPOINT_OPT);
}
- /* Process should terminate once fuse xlator is finished.
- * Required for AUTH_FAILED event.
- */
- kill (getpid (), SIGTERM);
}
struct xlator_fops fops = {
};
struct xlator_cbks cbks = {
- .invalidate = fuse_invalidate,
};
@@ -4779,48 +3716,16 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_PATH
},
{ .key = {ZR_ATTR_TIMEOUT_OPT},
- .type = GF_OPTION_TYPE_DOUBLE,
- .default_value = "1.0"
+ .type = GF_OPTION_TYPE_DOUBLE
},
{ .key = {ZR_ENTRY_TIMEOUT_OPT},
- .type = GF_OPTION_TYPE_DOUBLE,
- .default_value = "1.0"
- },
- { .key = {ZR_NEGATIVE_TIMEOUT_OPT},
- .type = GF_OPTION_TYPE_DOUBLE,
- .default_value = "0.0"
+ .type = GF_OPTION_TYPE_DOUBLE
},
{ .key = {ZR_STRICT_VOLFILE_CHECK},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"client-pid"},
.type = GF_OPTION_TYPE_INT
},
- { .key = {"uid-map-root"},
- .type = GF_OPTION_TYPE_INT
- },
- { .key = {"sync-to-mount"},
- .type = GF_OPTION_TYPE_BOOL
- },
- { .key = {"read-only"},
- .type = GF_OPTION_TYPE_BOOL
- },
- { .key = {"fopen-keep-cache"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
- { .key = {"gid-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .default_value = "0"
- },
- { .key = {"acl"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
- { .key = {"selinux"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
- },
{ .key = {NULL} },
};
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index cb5eb6001..f20e47272 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -54,10 +54,11 @@
#include "list.h"
#include "dict.h"
-#include "syncop.h"
-#include "gidcache.h"
-#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
+/* TODO: when supporting posix acl, remove this definition */
+#define DISABLE_POSIX_ACL
+
+#ifdef GF_LINUX_HOST_OS
#define FUSE_OP_HIGH (FUSE_POLL + 1)
#endif
#ifdef GF_DARWIN_HOST_OS
@@ -86,12 +87,11 @@ struct fuse_private {
size_t *msg0_len_p;
double entry_timeout;
- double negative_timeout;
double attribute_timeout;
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
- char event_recvd;
+ char child_up;
char init_recvd;
@@ -107,38 +107,9 @@ struct fuse_private {
pid_t client_pid;
gf_boolean_t client_pid_set;
- unsigned uid_map_root;
- gf_boolean_t acl;
- gf_boolean_t selinux;
- gf_boolean_t read_only;
- gf_boolean_t fopen_keep_cache;
- int32_t gid_cache_timeout;
- fdtable_t *fdtable;
- gid_cache_t gid_cache;
-
- /* For fuse-reverse-validation */
- int revchan_in;
- int revchan_out;
- gf_boolean_t reverse_fuse_thread_started;
-
- /* For communicating with separate mount thread. */
- int status_pipe[2];
};
typedef struct fuse_private fuse_private_t;
-struct fuse_graph_switch_args {
- xlator_t *this;
- xlator_t *old_subvol;
- xlator_t *new_subvol;
-};
-typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
-
-#define INVAL_BUF_SIZE (sizeof (struct fuse_out_header) + \
- max (sizeof (struct fuse_notify_inval_inode_out), \
- sizeof (struct fuse_notify_inval_entry_out) + \
- NAME_MAX + 1))
-
-
#define _FH_TO_FD(fh) ((fd_t *)(uintptr_t)(fh))
#define FH_TO_FD(fh) ((_FH_TO_FD (fh))?(fd_ref (_FH_TO_FD (fh))):((fd_t *) 0))
@@ -147,7 +118,6 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
do { \
call_frame_t *frame = NULL; \
xlator_t *xl = NULL; \
- int32_t op_ret = 0, op_errno = 0; \
\
frame = get_call_frame_for_req (state); \
if (!frame) { \
@@ -157,7 +127,7 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
* better than trying to go on with a NULL \
* frame ... \
*/ \
- gf_log_callingfn ("glusterfs-fuse", \
+ gf_log ("glusterfs-fuse", \
GF_LOG_ERROR, \
"FUSE message" \
" unique %"PRIu64" opcode %d:" \
@@ -165,44 +135,23 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
state->finh->unique, \
state->finh->opcode); \
free_fuse_state (state); \
- /* ideally, need to 'return', but let the */ \
- /* calling function take care of it */ \
- break; \
+ return; \
} \
\
frame->root->state = state; \
frame->root->op = op_num; \
frame->op = op_num; \
\
- xl = state->active_subvol; \
+ xl = fuse_state_subvol (state); \
if (!xl) { \
- gf_log_callingfn ("glusterfs-fuse", GF_LOG_ERROR, \
- "xl is NULL"); \
- op_errno = ENOENT; \
- op_ret = -1; \
- } else if (state->resolve.op_ret < 0) { \
- op_errno = state->resolve.op_errno; \
- op_ret = -1; \
-/* gf_log_callingfn ("glusterfs-fuse", GF_LOG_WARNING, \
- "resolve failed (%s)", \
- strerror (op_errno)); */ \
- } else if (state->resolve2.op_ret < 0) { \
- op_errno = state->resolve2.op_errno; \
- op_ret = -1; \
- /* gf_log_callingfn ("glusterfs-fuse", GF_LOG_WARNING, \
- "resolve of second entity " \
- "failed (%s)", \
- strerror (op_errno)); */ \
- } \
- \
- if (op_ret < 0) { \
- send_fuse_err (state->this, state->finh, op_errno); \
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR, \
+ "xl is NULL"); \
+ send_fuse_err (state->this, state->finh, ENOENT); \
free_fuse_state (state); \
STACK_DESTROY (frame->root); \
} else { \
STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
} \
- \
} while (0)
@@ -252,17 +201,6 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
-static inline xlator_t *
-fuse_active_subvol (xlator_t *fuse)
-{
- fuse_private_t *priv = NULL;
-
- priv = fuse->private;
-
- return priv->active_subvol;
-}
-
-
typedef enum {
RESOLVE_MUST = 1,
RESOLVE_NOT,
@@ -271,27 +209,35 @@ typedef enum {
RESOLVE_EXACT
} fuse_resolve_type_t;
+struct fuse_resolve_comp {
+ char *basename;
+ ino_t ino;
+ uint64_t gen;
+ inode_t *inode;
+};
typedef struct {
fuse_resolve_type_t type;
+ ino_t ino;
+ uint64_t gen;
+ ino_t par;
fd_t *fd;
char *path;
char *bname;
u_char gfid[16];
- inode_t *hint;
u_char pargfid[16];
- inode_t *parhint;
char *resolved;
int op_ret;
int op_errno;
- loc_t resolve_loc;
+ loc_t deep_loc;
+ struct fuse_resolve_comp *components;
+ int comp_count;
} fuse_resolve_t;
typedef struct {
void *pool;
xlator_t *this;
- xlator_t *active_subvol;
inode_table_t *itable;
loc_t loc;
loc_t loc2;
@@ -301,8 +247,7 @@ typedef struct {
size_t size;
unsigned long nlookup;
fd_t *fd;
- dict_t *xattr;
- dict_t *xdata;
+ dict_t *dict;
char *name;
char is_revalidate;
gf_boolean_t truncate_needed;
@@ -323,22 +268,13 @@ typedef struct {
int mask;
dev_t rdev;
mode_t mode;
- mode_t umask;
struct iatt attr;
struct gf_flock lk_lock;
struct iovec vector;
uuid_t gfid;
- uint32_t io_flags;
- int32_t fd_no;
} fuse_state_t;
-typedef struct fuse_fd_ctx {
- uint32_t open_flags;
- char migration_failed;
- fd_t *fd;
-} fuse_fd_ctx_t;
-
typedef void (*fuse_resume_fn_t) (fuse_state_t *state);
GF_MUST_CHECK int32_t
@@ -349,20 +285,10 @@ fuse_state_t *get_fuse_state (xlator_t *this, fuse_in_header_t *finh);
void free_fuse_state (fuse_state_t *state);
void gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa);
uint64_t inode_to_fuse_nodeid (inode_t *inode);
+xlator_t *fuse_state_subvol (fuse_state_t *state);
xlator_t *fuse_active_subvol (xlator_t *fuse);
inode_t *fuse_ino_to_inode (uint64_t ino, xlator_t *fuse);
+int fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn);
int send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error);
int fuse_gfid_set (fuse_state_t *state);
-int fuse_flip_xattr_ns (struct fuse_private *priv, char *okey, char **nkey);
-fuse_fd_ctx_t * __fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd);
-fuse_fd_ctx_t * fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd);
-
-int fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn);
-int fuse_resolve_inode_init (fuse_state_t *state, fuse_resolve_t *resolve,
- ino_t ino);
-int fuse_resolve_entry_init (fuse_state_t *state, fuse_resolve_t *resolve,
- ino_t par, char *name);
-int fuse_resolve_fd_init (fuse_state_t *state, fuse_resolve_t *resolve,
- fd_t *fd);
-int fuse_ignore_xattr_set (fuse_private_t *priv, char *key);
#endif /* _GF_FUSE_BRIDGE_H_ */
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 832f57e1c..cd35d7192 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -1,82 +1,96 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#include "fuse-bridge.h"
-#if defined(GF_SOLARIS_HOST_OS)
-#include <sys/procfs.h>
-#else
-#include <sys/sysctl.h>
-#endif
-#ifndef GF_REQUEST_MAXGROUPS
-#define GF_REQUEST_MAXGROUPS 16
-#endif /* GF_REQUEST_MAXGROUPS */
+xlator_t *
+fuse_state_subvol (fuse_state_t *state)
+{
+ xlator_t *subvol = NULL;
+
+ if (!state)
+ return NULL;
+
+ if (state->loc.inode)
+ subvol = state->loc.inode->table->xl;
+
+ if (state->fd)
+ subvol = state->fd->inode->table->xl;
+
+ return subvol;
+}
+
+
+xlator_t *
+fuse_active_subvol (xlator_t *fuse)
+{
+ fuse_private_t *priv = NULL;
+
+ priv = fuse->private;
+
+ return priv->active_subvol;
+}
+
+
static void
fuse_resolve_wipe (fuse_resolve_t *resolve)
{
- GF_FREE ((void *)resolve->path);
+ struct fuse_resolve_comp *comp = NULL;
- GF_FREE ((void *)resolve->bname);
+ if (resolve->path)
+ GF_FREE ((void *)resolve->path);
- GF_FREE ((void *)resolve->resolved);
+ if (resolve->bname)
+ GF_FREE ((void *)resolve->bname);
- if (resolve->fd)
- fd_unref (resolve->fd);
+ if (resolve->resolved)
+ GF_FREE ((void *)resolve->resolved);
- loc_wipe (&resolve->resolve_loc);
+ loc_wipe (&resolve->deep_loc);
- if (resolve->hint) {
- inode_unref (resolve->hint);
- resolve->hint = 0;
- }
+ comp = resolve->components;
- if (resolve->parhint) {
- inode_unref (resolve->parhint);
- resolve->parhint = 0;
- }
-}
+ if (comp) {
+/*
+ int i = 0;
+ for (i = 0; comp[i].basename; i++) {
+ if (comp[i].inode)
+ inode_unref (comp[i].inode);
+ }
+*/
+ GF_FREE ((void *)resolve->components);
+ }
+}
void
free_fuse_state (fuse_state_t *state)
{
- xlator_t *this = NULL;
- fuse_private_t *priv = NULL;
- uint64_t winds = 0;
- char switched = 0;
-
- this = state->this;
-
- priv = this->private;
-
loc_wipe (&state->loc);
loc_wipe (&state->loc2);
- if (state->xdata) {
- dict_unref (state->xdata);
- state->xdata = (void *)0xaaaaeeee;
+ if (state->dict) {
+ dict_unref (state->dict);
+ state->dict = (void *)0xaaaaeeee;
}
- if (state->xattr)
- dict_unref (state->xattr);
-
if (state->name) {
GF_FREE (state->name);
state->name = NULL;
@@ -93,18 +107,6 @@ free_fuse_state (fuse_state_t *state)
fuse_resolve_wipe (&state->resolve);
fuse_resolve_wipe (&state->resolve2);
- pthread_mutex_lock (&priv->sync_mutex);
- {
- winds = --state->active_subvol->winds;
- switched = state->active_subvol->switched;
- }
- pthread_mutex_unlock (&priv->sync_mutex);
-
- if ((winds == 0) && (switched)) {
- xlator_notify (state->active_subvol, GF_EVENT_PARENT_DOWN,
- state->active_subvol, NULL);
- }
-
#ifdef DEBUG
memset (state, 0x90, sizeof (*state));
#endif
@@ -116,28 +118,12 @@ free_fuse_state (fuse_state_t *state)
fuse_state_t *
get_fuse_state (xlator_t *this, fuse_in_header_t *finh)
{
- fuse_state_t *state = NULL;
- xlator_t *active_subvol = NULL;
- fuse_private_t *priv = NULL;
+ fuse_state_t *state = NULL;
state = (void *)GF_CALLOC (1, sizeof (*state),
gf_fuse_mt_fuse_state_t);
if (!state)
return NULL;
-
- state->this = THIS;
- priv = this->private;
-
- pthread_mutex_lock (&priv->sync_mutex);
- {
- active_subvol = fuse_active_subvol (state->this);
- active_subvol->winds++;
- }
- pthread_mutex_unlock (&priv->sync_mutex);
-
- state->active_subvol = active_subvol;
- state->itable = active_subvol->itable;
-
state->pool = this->ctx->pool;
state->finh = finh;
state->this = this;
@@ -148,143 +134,6 @@ get_fuse_state (xlator_t *this, fuse_in_header_t *finh)
}
-void
-frame_fill_groups (call_frame_t *frame)
-{
-#if defined(GF_LINUX_HOST_OS)
- char filename[32];
- char line[4096];
- char *ptr = NULL;
- FILE *fp = NULL;
- int idx = 0;
- long int id = 0;
- char *saveptr = NULL;
- char *endptr = NULL;
- int ret = 0;
-
- ret = snprintf (filename, sizeof filename, "/proc/%d/status", frame->root->pid);
- if (ret >= sizeof filename)
- goto out;
-
- fp = fopen (filename, "r");
- if (!fp)
- goto out;
-
- while ((ptr = fgets (line, sizeof line, fp))) {
- if (strncmp (ptr, "Groups:", 7) != 0)
- continue;
-
- ptr = line + 8;
-
- for (ptr = strtok_r (ptr, " \t\r\n", &saveptr);
- ptr;
- ptr = strtok_r (NULL, " \t\r\n", &saveptr)) {
- errno = 0;
- id = strtol (ptr, &endptr, 0);
- if (errno == ERANGE)
- break;
- if (!endptr || *endptr)
- break;
- frame->root->groups[idx++] = id;
- if (idx == GF_MAX_AUX_GROUPS)
- break;
- }
-
- frame->root->ngrps = idx;
- break;
- }
-out:
- if (fp)
- fclose (fp);
-#elif defined(GF_SOLARIS_HOST_OS)
- char filename[32];
- char scratch[128];
- prcred_t *prcred = (prcred_t *) scratch;
- FILE *fp = NULL;
- int ret = 0;
-
- ret = snprintf (filename, sizeof filename,
- "/proc/%d/cred", frame->root->pid);
-
- if (ret < sizeof filename) {
- fp = fopen (filename, "r");
- if (fp != NULL) {
- if (fgets (scratch, sizeof scratch, fp) != NULL) {
- frame->root->ngrps = MIN(prcred->pr_ngroups,
- GF_REQUEST_MAXGROUPS);
- }
- fclose (fp);
- }
- }
-#elif defined(CTL_KERN) /* DARWIN and *BSD */
- /*
- N.B. CTL_KERN is an enum on Linux. (Meaning, if it's not
- obvious, that it's not subject to preprocessor directives
- like '#if defined'.)
- Unlike Linux, on Mac OS and the BSDs it is a #define. We
- could test to see that KERN_PROC is defined, but, barring any
- evidence to the contrary, I think that's overkill.
- We might also test that GF_DARWIN_HOST_OS is defined, why
- limit this to just Mac OS. It's equally valid for the BSDs
- and we do have people building on NetBSD and FreeBSD.
- */
- int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, frame->root->pid };
- size_t namelen = sizeof name / sizeof name[0];
- struct kinfo_proc kp;
- size_t kplen = sizeof(kp);
- int i, ngroups;
-
- if (sysctl(name, namelen, &kp, &kplen, NULL, 0) != 0)
- return;
- ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_REQUEST_MAXGROUPS);
- for (i = 0; i < ngroups; i++)
- frame->root->groups[i] = kp.kp_eproc.e_ucred.cr_groups[i];
- frame->root->ngrps = ngroups;
-#else
- frame->root->ngrps = 0;
-#endif /* GF_LINUX_HOST_OS */
-}
-
-/*
- * Get the groups for the PID associated with this frame. If enabled,
- * use the gid cache to reduce group list collection.
- */
-static void get_groups(fuse_private_t *priv, call_frame_t *frame)
-{
- int i;
- const gid_list_t *gl;
- gid_list_t agl;
-
- if (!priv->gid_cache_timeout) {
- frame_fill_groups(frame);
- return;
- }
-
- gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid);
- if (gl) {
- frame->root->ngrps = gl->gl_count;
- for (i = 0; i < gl->gl_count; i++)
- frame->root->groups[i] = gl->gl_list[i];
- gid_cache_release(&priv->gid_cache, gl);
- return;
- }
-
- frame_fill_groups (frame);
-
- agl.gl_id = frame->root->pid;
- agl.gl_count = frame->root->ngrps;
- agl.gl_list = GF_CALLOC(frame->root->ngrps, sizeof(gid_t),
- gf_fuse_mt_gids_t);
- if (!agl.gl_list)
- return;
-
- for (i = 0; i < frame->root->ngrps; i++)
- agl.gl_list[i] = frame->root->groups[i];
-
- if (gid_cache_add(&priv->gid_cache, &agl) != 1)
- GF_FREE(agl.gl_list);
-}
-
call_frame_t *
get_call_frame_for_req (fuse_state_t *state)
{
@@ -307,13 +156,10 @@ get_call_frame_for_req (fuse_state_t *state)
frame->root->uid = finh->uid;
frame->root->gid = finh->gid;
frame->root->pid = finh->pid;
+ frame->root->lk_owner = state->lk_owner;
frame->root->unique = finh->unique;
- set_lk_owner_from_uint64 (&frame->root->lk_owner,
- state->lk_owner);
}
- get_groups(priv, frame);
-
if (priv && priv->client_pid_set)
frame->root->pid = priv->client_pid;
@@ -344,7 +190,7 @@ fuse_ino_to_inode (uint64_t ino, xlator_t *fuse)
uint64_t
inode_to_fuse_nodeid (inode_t *inode)
{
- if (!inode || __is_root_gfid (inode->gfid))
+ if (!inode || inode->ino == 1)
return 1;
return (unsigned long) inode;
@@ -359,7 +205,6 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
inode_t *parent = NULL;
int32_t ret = -1;
char *path = NULL;
- uuid_t null_gfid = {0,};
/* resistance against multiple invocation of loc_fill not to get
reference leaks via inode_search() */
@@ -369,8 +214,6 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
if (!parent) {
parent = fuse_ino_to_inode (par, state->this);
loc->parent = parent;
- if (parent)
- uuid_copy (loc->pargfid, parent->gfid);
}
inode = loc->inode;
@@ -382,8 +225,8 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
ret = inode_path (parent, name, &path);
if (ret <= 0) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "inode_path failed for %s/%s",
- (parent)?uuid_utoa (parent->gfid):"0", name);
+ "inode_path failed for %"PRId64"/%s",
+ (parent)?parent->ino:0, name);
goto fail;
}
loc->path = path;
@@ -392,29 +235,27 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
if (!inode) {
inode = fuse_ino_to_inode (ino, state->this);
loc->inode = inode;
- if (inode)
- uuid_copy (loc->gfid, inode->gfid);
}
parent = loc->parent;
if (!parent) {
- parent = inode_parent (inode, null_gfid, NULL);
+ parent = inode_parent (inode, par, name);
loc->parent = parent;
- if (parent)
- uuid_copy (loc->pargfid, parent->gfid);
-
}
ret = inode_path (inode, NULL, &path);
if (ret <= 0) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "inode_path failed for %s",
- (inode) ? uuid_utoa (inode->gfid) : "0");
+ "inode_path failed for %"PRId64,
+ (inode)?inode->ino:0);
goto fail;
}
loc->path = path;
}
+ if (inode)
+ loc->ino = inode->ino;
+
if (loc->path) {
loc->name = strrchr (loc->path, '/');
if (loc->name)
@@ -432,10 +273,6 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
}
ret = 0;
fail:
- /* this should not happen as inode_path returns -1 when buf is NULL
- for sure */
- if (path && !loc->path)
- GF_FREE (path);
return ret;
}
@@ -469,107 +306,5 @@ gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa)
#endif
}
-static int
-fuse_do_flip_xattr_ns (char *okey, const char *nns, char **nkey)
-{
- int ret = 0;
- char *key = NULL;
-
- okey = strchr (okey, '.');
- GF_ASSERT (okey);
- key = GF_CALLOC (1, strlen (nns) + strlen(okey) + 1,
- gf_common_mt_char);
- if (!key) {
- ret = -1;
- goto out;
- }
-
- strcpy (key, nns);
- strcat (key, okey);
- *nkey = key;
-
- out:
- return ret;
-}
-
-static int
-fuse_xattr_alloc_default (char *okey, char **nkey)
-{
- int ret = 0;
-
- *nkey = gf_strdup (okey);
- if (!*nkey)
- ret = -1;
- return ret;
-}
-
-#define PRIV_XA_NS "trusted"
-#define UNPRIV_XA_NS "system"
-
-int
-fuse_flip_xattr_ns (fuse_private_t *priv, char *okey, char **nkey)
-{
- int ret = 0;
- gf_boolean_t need_flip = _gf_false;
-
- switch (priv->client_pid) {
- case GF_CLIENT_PID_GSYNCD:
- /* valid xattr(s): *xtime, volume-mark* */
- gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "
- "volume-mark*, *xtime", priv->client_pid);
- if ( (strcmp (okey, UNPRIV_XA_NS".glusterfs.volume-mark") == 0)
- || (fnmatch (UNPRIV_XA_NS".glusterfs.volume-mark.*", okey, FNM_PERIOD) == 0)
- || (fnmatch (UNPRIV_XA_NS".glusterfs.*.xtime", okey, FNM_PERIOD) == 0) )
- need_flip = _gf_true;
- break;
-
- case GF_CLIENT_PID_HADOOP:
- /* valid xattr(s): pathinfo */
- gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "
- "pathinfo", priv->client_pid);
- if (strcmp (okey, UNPRIV_XA_NS".glusterfs.pathinfo") == 0)
- need_flip = _gf_true;
- break;
- }
-
- if (need_flip) {
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "flipping %s to "PRIV_XA_NS" equivalent",
- okey);
- ret = fuse_do_flip_xattr_ns (okey, PRIV_XA_NS, nkey);
- } else {
- /* if we cannot match, continue with what we got */
- ret = fuse_xattr_alloc_default (okey, nkey);
- }
-
- return ret;
-}
-
-int
-fuse_ignore_xattr_set (fuse_private_t *priv, char *key)
-{
- int ret = 0;
-
- /* don't mess with user namespace */
- if (fnmatch ("user.*", key, FNM_PERIOD) == 0)
- goto out;
-
- if (priv->client_pid != GF_CLIENT_PID_GSYNCD)
- goto out;
-
- /* trusted NS check */
- if (!((fnmatch (PRIV_XA_NS".glusterfs.*.xtime", key, FNM_PERIOD) == 0)
- || (fnmatch (PRIV_XA_NS".glusterfs.volume-mark",
- key, FNM_PERIOD) == 0)
- || (fnmatch (PRIV_XA_NS".glusterfs.volume-mark.*",
- key, FNM_PERIOD) == 0)))
- ret = -1;
-
- out:
- gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%s setxattr: key [%s], "
- " client pid [%d]", (ret ? "disallowing" : "allowing"), key,
- priv->client_pid);
-
- return ret;
-}
diff --git a/xlators/mount/fuse/src/fuse-mem-types.h b/xlators/mount/fuse/src/fuse-mem-types.h
index d1c5e511b..cce447e19 100644
--- a/xlators/mount/fuse/src/fuse-mem-types.h
+++ b/xlators/mount/fuse/src/fuse-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -29,9 +29,6 @@ enum gf_fuse_mem_types_ {
gf_fuse_mt_char,
gf_fuse_mt_iov_base,
gf_fuse_mt_fuse_state_t,
- gf_fuse_mt_fd_ctx_t,
- gf_fuse_mt_graph_switch_args_t,
- gf_fuse_mt_gids_t,
gf_fuse_mt_end
};
#endif
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index bd27af4d2..b13cb3606 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -26,482 +26,543 @@
static int
fuse_resolve_all (fuse_state_t *state);
+static int
+fuse_resolve_path_simple (fuse_state_t *state);
+
+static int
+component_count (const char *path)
+{
+ int count = 0;
+ const char *trav = NULL;
+
+ for (trav = path; *trav; trav++) {
+ if (*trav == '/')
+ count++;
+ }
+
+ return count + 2;
+}
+
+
+static int
+prepare_components (fuse_state_t *state)
+{
+ xlator_t *active_xl = NULL;
+ fuse_resolve_t *resolve = NULL;
+ char *resolved = NULL;
+ struct fuse_resolve_comp *components = NULL;
+ char *trav = NULL;
+ int count = 0;
+ int i = 0;
+
+ resolve = state->resolve_now;
-int fuse_resolve_continue (fuse_state_t *state);
-int fuse_resolve_entry_simple (fuse_state_t *state);
-int fuse_resolve_inode_simple (fuse_state_t *state);
-int fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
- xlator_t *new_subvol);
+ resolved = gf_strdup (resolve->path);
+ resolve->resolved = resolved;
+
+ count = component_count (resolve->path);
+ components = GF_CALLOC (sizeof (*components), count, 0); //TODO
+ if (!components)
+ goto out;
+ resolve->components = components;
+
+ active_xl = fuse_active_subvol (state->this);
+
+ components[0].basename = "";
+ components[0].ino = 1;
+ components[0].gen = 0;
+ components[0].inode = inode_ref (active_xl->itable->root);
+
+ i = 1;
+ for (trav = resolved; *trav; trav++) {
+ if (*trav == '/') {
+ components[i].basename = trav + 1;
+ *trav = 0;
+ i++;
+ }
+ }
+out:
+ return 0;
+}
-fuse_fd_ctx_t *
-fuse_fd_ctx_get (xlator_t *this, fd_t *fd);
static int
fuse_resolve_loc_touchup (fuse_state_t *state)
{
fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- char *path = NULL;
- int ret = 0;
+ loc_t *loc = NULL;
+ char *path = NULL;
+ int ret = 0;
resolve = state->resolve_now;
loc = state->loc_now;
if (!loc->path) {
- if (loc->parent && resolve->bname) {
+ if (loc->parent) {
ret = inode_path (loc->parent, resolve->bname, &path);
- uuid_copy (loc->pargfid, loc->parent->gfid);
- loc->name = resolve->bname;
} else if (loc->inode) {
ret = inode_path (loc->inode, NULL, &path);
- uuid_copy (loc->gfid, loc->inode->gfid);
}
if (ret)
- gf_log (THIS->name, GF_LOG_TRACE,
+ gf_log ("", GF_LOG_TRACE,
"return value inode_path %d", ret);
+
+ if (!path)
+ path = gf_strdup (resolve->path);
+
loc->path = path;
}
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+
+ if (!loc->parent && loc->inode) {
+ loc->parent = inode_parent (loc->inode, 0, NULL);
+ }
+
return 0;
}
-
-int
-fuse_resolve_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xattr,
- struct iatt *postparent)
+static int
+fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- fuse_state_t *state = NULL;
+ fuse_state_t *state = NULL;
fuse_resolve_t *resolve = NULL;
- inode_t *link_inode = NULL;
- loc_t *resolve_loc = NULL;
+ fd_t *old_fd = NULL;
+ fd_t *tmp_fd = NULL;
+ uint64_t tmp_fd_ctx = 0;
+ int ret = 0;
state = frame->root->state;
resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
STACK_DESTROY (frame->root);
if (op_ret == -1) {
- gf_log (this->name, (op_errno == ENOENT)
- ? GF_LOG_DEBUG : GF_LOG_WARNING,
- "%s/%s: failed to resolve (%s)",
- uuid_utoa (resolve_loc->pargfid), resolve_loc->name,
- strerror (op_errno));
- resolve->op_ret = -1;
+ resolve->op_ret = -1;
resolve->op_errno = op_errno;
goto out;
}
- link_inode = inode_link (inode, resolve_loc->parent,
- resolve_loc->name, buf);
+ old_fd = resolve->fd;
- state->loc_now->inode = link_inode;
-out:
- loc_wipe (resolve_loc);
+ state->fd = fd_ref (fd);
+
+ fd_bind (fd);
- fuse_resolve_continue (state);
+ resolve->fd = NULL;
+ ret = fd_ctx_del (old_fd, state->this, &tmp_fd_ctx);
+ if (!ret) {
+ tmp_fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_unref (tmp_fd);
+ }
+ ret = fd_ctx_set (old_fd, state->this, (uint64_t)(long)fd);
+ if (ret)
+ gf_log ("resolve", GF_LOG_WARNING,
+ "failed to set the fd ctx with resolved fd");
+out:
+ fuse_resolve_all (state);
return 0;
}
+static void
+fuse_resolve_new_fd (fuse_state_t *state)
+{
+ fuse_resolve_t *resolve = NULL;
+ fd_t *new_fd = NULL;
+ fd_t *fd = NULL;
-int
-fuse_resolve_entry (fuse_state_t *state)
+ resolve = state->resolve_now;
+ fd = resolve->fd;
+
+ new_fd = fd_create (state->loc.inode, state->finh->pid);
+ new_fd->flags = (fd->flags & ~O_TRUNC);
+
+ gf_log ("resolve", GF_LOG_DEBUG,
+ "%"PRIu64": OPEN %s", state->finh->unique,
+ state->loc.path);
+
+ FUSE_FOP (state, fuse_resolve_newfd_cbk, GF_FOP_OPEN,
+ open, &state->loc, new_fd->flags, new_fd, 0);
+}
+
+static int
+fuse_resolve_deep_continue (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- loc_t *resolve_loc = NULL;
+ fuse_resolve_t *resolve = NULL;
+ int ret = 0;
- resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
+ resolve = state->resolve_now;
+
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
- resolve_loc->parent = inode_ref (state->loc_now->parent);
- uuid_copy (resolve_loc->pargfid, state->loc_now->pargfid);
- resolve_loc->name = resolve->bname;
- resolve_loc->inode = inode_new (state->itable);
+ if (resolve->path)
+ ret = fuse_resolve_path_simple (state);
+ if (ret)
+ gf_log ("resolve", GF_LOG_TRACE,
+ "return value of resolve_*_simple %d", ret);
- inode_path (resolve_loc->parent, resolve_loc->name,
- (char **) &resolve_loc->path);
+ fuse_resolve_loc_touchup (state);
- FUSE_FOP (state, fuse_resolve_entry_cbk, GF_FOP_LOOKUP,
- lookup, resolve_loc, NULL);
+ /* This function is called by either fd resolve or inode resolve */
+ if (!resolve->fd)
+ fuse_resolve_all (state);
+ else
+ fuse_resolve_new_fd (state);
- return 0;
+ return 0;
}
-int
-fuse_resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
- dict_t *xattr, struct iatt *postparent)
+static int
+fuse_resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xattr, struct iatt *postparent)
{
- fuse_state_t *state = NULL;
- fuse_resolve_t *resolve = NULL;
- inode_t *link_inode = NULL;
- loc_t *loc_now = NULL;
+ xlator_t *active_xl = NULL;
+ fuse_state_t *state = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
+ inode_t *link_inode = NULL;
+ int i = 0;
state = frame->root->state;
resolve = state->resolve_now;
- loc_now = state->loc_now;
+ components = resolve->components;
+
+ i = (long) cookie;
STACK_DESTROY (frame->root);
if (op_ret == -1) {
- gf_log (this->name, (op_errno == ENOENT)
- ? GF_LOG_DEBUG : GF_LOG_WARNING,
- "%s: failed to resolve (%s)",
- uuid_utoa (resolve->resolve_loc.gfid),
- strerror (op_errno));
- loc_wipe (&resolve->resolve_loc);
- resolve->op_ret = -1;
- resolve->op_errno = op_errno;
- goto out;
+ goto get_out_of_here;
}
- loc_wipe (&resolve->resolve_loc);
-
- link_inode = inode_link (inode, NULL, NULL, buf);
-
- if (!link_inode)
- goto out;
+ if (i != 0) {
+ inode_ref (inode);
+ /* no linking for root inode */
+ link_inode = inode_link (inode, resolve->deep_loc.parent,
+ resolve->deep_loc.name, buf);
+ components[i].inode = inode_ref (link_inode);
+ link_inode = NULL;
+ }
+ inode_ref (resolve->deep_loc.parent);
+ inode_ref (inode);
+ loc_wipe (&resolve->deep_loc);
+ i++; /* next component */
+
+ if (!components[i].basename) {
+ /* all components of the path are resolved */
+ goto get_out_of_here;
+ }
- if (!uuid_is_null (resolve->gfid)) {
- loc_now->inode = link_inode;
- goto out;
- }
+ /* join the current component with the path resolved until now */
+ *(components[i].basename - 1) = '/';
- loc_now->parent = link_inode;
- uuid_copy (loc_now->pargfid, link_inode->gfid);
+ active_xl = fuse_active_subvol (state->this);
- fuse_resolve_entry (state);
+ resolve->deep_loc.path = gf_strdup (resolve->resolved);
+ resolve->deep_loc.parent = inode_ref (components[i-1].inode);
+ resolve->deep_loc.inode = inode_new (active_xl->itable);
+ resolve->deep_loc.name = components[i].basename;
+ FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i,
+ GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
return 0;
-out:
- fuse_resolve_continue (state);
+
+get_out_of_here:
+ fuse_resolve_deep_continue (state);
return 0;
}
-int
-fuse_resolve_gfid (fuse_state_t *state)
+static int
+fuse_resolve_path_deep (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- loc_t *resolve_loc = NULL;
- int ret = 0;
+ xlator_t *active_xl = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
+ inode_t *inode = NULL;
+ long i = 0;
resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
- if (!uuid_is_null (resolve->pargfid)) {
- uuid_copy (resolve_loc->gfid, resolve->pargfid);
- } else if (!uuid_is_null (resolve->gfid)) {
- uuid_copy (resolve_loc->gfid, resolve->gfid);
- }
+ prepare_components (state);
- resolve_loc->inode = inode_new (state->itable);
- ret = loc_path (resolve_loc, NULL);
+ components = resolve->components;
- if (ret <= 0) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to get the path for inode %s",
- uuid_utoa (resolve->gfid));
+ /* start from the root */
+ active_xl = fuse_active_subvol (state->this);
+ resolve->deep_loc.inode = inode_ref (active_xl->itable->root);
+ resolve->deep_loc.path = gf_strdup ("/");
+ resolve->deep_loc.name = "";
+
+ for (i = 1; components[i].basename; i++) {
+ *(components[i].basename - 1) = '/';
+ inode = inode_grep (active_xl->itable, components[i-1].inode,
+ components[i].basename);
+ if (!inode)
+ break;
+ components[i].inode = inode_ref (inode);
}
- FUSE_FOP (state, fuse_resolve_gfid_cbk, GF_FOP_LOOKUP,
- lookup, resolve_loc, NULL);
+ if (!components[i].basename)
+ goto resolved;
+
+ resolve->deep_loc.path = gf_strdup (resolve->resolved);
+ resolve->deep_loc.parent = inode_ref (components[i-1].inode);
+ resolve->deep_loc.inode = inode_new (active_xl->itable);
+ resolve->deep_loc.name = components[i].basename;
+ FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i,
+ GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
+
+ return 0;
+resolved:
+ fuse_resolve_deep_continue (state);
return 0;
}
-/*
- * Return value:
- * 0 - resolved parent and entry (as necessary)
- * -1 - resolved parent but not entry (though necessary)
- * 1 - resolved neither parent nor entry
- */
-
-int
-fuse_resolve_parent_simple (fuse_state_t *state)
+static int
+fuse_resolve_path_simple (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- inode_t *parent = NULL;
- inode_t *inode = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
+ int ret = -1;
+ int par_idx = 0;
+ int ino_idx = 0;
+ int i = 0;
resolve = state->resolve_now;
- loc = state->loc_now;
-
- loc->name = resolve->bname;
-
- parent = resolve->parhint;
- if (parent->table == state->itable) {
- /* no graph switches since */
- loc->parent = inode_ref (parent);
- loc->inode = inode_grep (state->itable, parent, loc->name);
- /* decisive result - resolution success */
- return 0;
- }
-
- parent = inode_find (state->itable, resolve->pargfid);
- if (!parent) {
- /* non decisive result - parent missing */
- return 1;
- }
-
- loc->parent = parent;
- uuid_copy (loc->pargfid, resolve->pargfid);
-
- inode = inode_grep (state->itable, parent, loc->name);
- if (inode) {
- loc->inode = inode;
- /* decisive result - resolution success */
- return 0;
- }
-
- /* non decisive result - entry missing */
- return -1;
-}
+ components = resolve->components;
+ if (!components) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
-int
-fuse_resolve_parent (fuse_state_t *state)
-{
- int ret = 0;
+ for (i = 0; components[i].basename; i++) {
+ par_idx = ino_idx;
+ ino_idx = i;
+ }
- ret = fuse_resolve_parent_simple (state);
- if (ret > 0) {
- fuse_resolve_gfid (state);
- return 0;
+ if (!components[par_idx].inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
}
- if (ret < 0) {
- fuse_resolve_entry (state);
- return 0;
- }
+ if (!components[ino_idx].inode &&
+ (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
- fuse_resolve_continue (state);
+ if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) {
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ goto out;
+ }
- return 0;
+ if (components[ino_idx].inode)
+ state->loc_now->inode = inode_ref (components[ino_idx].inode);
+ state->loc_now->parent = inode_ref (components[par_idx].inode);
+
+ ret = 0;
+
+out:
+ return ret;
}
+/*
+ Check if the requirements are fulfilled by entries in the inode cache itself
+ Return value:
+ <= 0 - simple resolution was decisive and complete (either success or failure)
+ > 0 - indecisive, need to perform deep resolution
+*/
int
-fuse_resolve_inode_simple (fuse_state_t *state)
+fuse_resolve_entry_simple (fuse_state_t *state)
{
+ xlator_t *active_xl = NULL;
+ xlator_t *this = NULL;
fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- inode_t *inode = NULL;
+ inode_t *parent = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+ this = state->this;
resolve = state->resolve_now;
- loc = state->loc_now;
- inode = resolve->hint;
- if (inode->table == state->itable) {
- inode_ref (inode);
- goto found;
- }
+ active_xl = fuse_active_subvol (state->this);
+
+ parent = inode_find (active_xl->itable, resolve->pargfid);
+ if (!parent) {
+ /* simple resolution is indecisive. need to perform
+ deep resolution */
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ /* expected @parent was found from the inode cache */
+ state->loc_now->parent = inode_ref (parent);
+
+ inode = inode_grep (active_xl->itable, parent, resolve->bname);
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (parent)
+ inode_unref (parent);
- inode = inode_find (state->itable, resolve->gfid);
if (inode)
- goto found;
+ inode_unref (inode);
- return 1;
-found:
- loc->inode = inode;
- return 0;
+ return ret;
}
int
-fuse_resolve_inode (fuse_state_t *state)
+fuse_resolve_entry (fuse_state_t *state)
{
- int ret = 0;
+ int ret = 0;
+ loc_t *loc = NULL;
- ret = fuse_resolve_inode_simple (state);
+ loc = state->loc_now;
+ ret = fuse_resolve_entry_simple (state);
if (ret > 0) {
- fuse_resolve_gfid (state);
+ loc_wipe (loc);
+ fuse_resolve_path_deep (state);
return 0;
}
- fuse_resolve_continue (state);
+ if (ret == 0)
+ fuse_resolve_loc_touchup (state);
+
+ fuse_resolve_all (state);
return 0;
}
int
-fuse_migrate_fd_task (void *data)
+fuse_resolve_inode_simple (fuse_state_t *state)
{
- int ret = -1;
- fuse_fd_ctx_t *fdctx = NULL;
- fuse_state_t *state = NULL;
-
- state = data;
- if (state == NULL) {
- goto out;
- }
+ xlator_t *active_xl = NULL;
+ fuse_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
- ret = fuse_migrate_fd (state->this, state->fd,
- state->fd->inode->table->xl,
- state->active_subvol);
+ resolve = state->resolve_now;
+ active_xl = fuse_active_subvol (state->this);
- fdctx = fuse_fd_ctx_check_n_create (state->this, state->fd);
- if (fdctx != NULL) {
- if (ret < 0) {
- fdctx->migration_failed = 1;
- } else {
- fdctx->migration_failed = 0;
- }
+ inode = inode_find (active_xl->itable, resolve->gfid);
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
}
ret = 0;
-out:
- return ret;
-}
-
+ state->loc_now->inode = inode_ref (inode);
-static inline int
-fuse_migrate_fd_error (xlator_t *this, fd_t *fd)
-{
- fuse_fd_ctx_t *fdctx = NULL;
- char error = 0;
-
- fdctx = fuse_fd_ctx_get (this, fd);
- if (fdctx != NULL) {
- if (fdctx->migration_failed) {
- error = 1;
- }
- }
+out:
+ if (inode)
+ inode_unref (inode);
- return error;
+ return ret;
}
-static int
-fuse_resolve_fd (fuse_state_t *state)
+int
+fuse_resolve_inode (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- fd_t *fd = NULL;
- xlator_t *active_subvol = NULL;
- int ret = 0;
- char fd_migration_error = 0;
+ int ret = 0;
+ loc_t *loc = NULL;
- resolve = state->resolve_now;
+ loc = state->loc_now;
- fd = resolve->fd;
- active_subvol = fd->inode->table->xl;
-
- fd_migration_error = fuse_migrate_fd_error (state->this, fd);
- if (fd_migration_error) {
- resolve->op_ret = -1;
- resolve->op_errno = EBADF;
- } else if (state->active_subvol != active_subvol) {
- ret = synctask_new (state->this->ctx->env, fuse_migrate_fd_task,
- NULL, NULL, state);
-
- fd_migration_error = fuse_migrate_fd_error (state->this, fd);
-
- if ((ret == -1) || fd_migration_error
- || (state->active_subvol != fd->inode->table->xl)) {
- if (ret == -1) {
- gf_log (state->this->name, GF_LOG_WARNING,
- "starting sync-task to migrate fd (%p)"
- " failed", fd);
- } else {
- gf_log (state->this->name, GF_LOG_WARNING,
- "fd migration of fd (%p) failed", fd);
- }
-
- resolve->op_ret = -1;
- resolve->op_errno = EBADF;
- } else {
- gf_log (state->this->name, GF_LOG_DEBUG,
- "fd (%p) migrated successfully in resolver",
- fd);
- }
- }
+ ret = fuse_resolve_inode_simple (state);
- if ((resolve->op_ret == -1) && (resolve->op_errno == EBADF)) {
- gf_log ("fuse-resolve", GF_LOG_WARNING, "migration of fd (%p) "
- "did not complete, failing fop with EBADF", fd);
+ if (ret > 0) {
+ loc_wipe (loc);
+ fuse_resolve_path_deep (state);
+ return 0;
}
- /* state->active_subvol = active_subvol; */
+ if (ret == 0)
+ fuse_resolve_loc_touchup (state);
- fuse_resolve_continue (state);
+ fuse_resolve_all (state);
return 0;
}
-
-int
-fuse_gfid_set (fuse_state_t *state)
+static int
+fuse_resolve_fd (fuse_state_t *state)
{
- int ret = 0;
+ fuse_resolve_t *resolve = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ uint64_t tmp_fd_ctx = 0;
+ char *path = NULL;
+ char *name = NULL;
- if (uuid_is_null (state->gfid))
- goto out;
+ resolve = state->resolve_now;
- if (!state->xdata)
- state->xdata = dict_new ();
+ fd = resolve->fd;
- if (!state->xdata) {
- ret = -1;
+ ret = fd_ctx_get (fd, state->this, &tmp_fd_ctx);
+ if (!ret) {
+ state->fd = (fd_t *)(long)tmp_fd_ctx;
+ fd_ref (state->fd);
+ fuse_resolve_all (state);
goto out;
}
- ret = dict_set_static_bin (state->xdata, "gfid-req",
- state->gfid, sizeof (state->gfid));
-out:
- return ret;
-}
-
+ ret = inode_path (fd->inode, 0, &path);
+ if (ret <= 0)
+ gf_log ("", GF_LOG_WARNING,
+ "failed to do inode-path on fd %d %s", ret, path);
-int
-fuse_resolve_entry_init (fuse_state_t *state, fuse_resolve_t *resolve,
- ino_t par, char *name)
-{
- inode_t *parent = NULL;
+ name = strrchr (path, '/');
+ if (name)
+ name++;
- parent = fuse_ino_to_inode (par, state->this);
- uuid_copy (resolve->pargfid, parent->gfid);
- resolve->parhint = parent;
- resolve->bname = gf_strdup (name);
+ resolve->path = path;
+ resolve->bname = gf_strdup (name);
- return 0;
-}
+ state->loc_now = &state->loc;
+ fuse_resolve_path_deep (state);
-int
-fuse_resolve_inode_init (fuse_state_t *state, fuse_resolve_t *resolve,
- ino_t ino)
-{
- inode_t *inode = NULL;
-
- inode = fuse_ino_to_inode (ino, state->this);
- uuid_copy (resolve->gfid, inode->gfid);
- resolve->hint = inode;
-
- return 0;
-}
-
-
-int
-fuse_resolve_fd_init (fuse_state_t *state, fuse_resolve_t *resolve,
- fd_t *fd)
-{
- resolve->fd = fd_ref (fd);
-
- return 0;
+out:
+ return 0;
}
static int
fuse_resolve (fuse_state_t *state)
-{
+ {
fuse_resolve_t *resolve = NULL;
resolve = state->resolve_now;
@@ -512,13 +573,21 @@ fuse_resolve (fuse_state_t *state)
} else if (!uuid_is_null (resolve->pargfid)) {
- fuse_resolve_parent (state);
+ fuse_resolve_entry (state);
} else if (!uuid_is_null (resolve->gfid)) {
fuse_resolve_inode (state);
+ } else if (resolve->path) {
+
+ fuse_resolve_path_deep (state);
+
} else {
+
+ resolve->op_ret = 0;
+ resolve->op_errno = EINVAL;
+
fuse_resolve_all (state);
}
@@ -531,10 +600,17 @@ fuse_resolve_done (fuse_state_t *state)
{
fuse_resume_fn_t fn = NULL;
+ if (state->resolve.op_ret || state->resolve2.op_ret) {
+ send_fuse_err (state->this, state->finh,
+ state->resolve.op_errno);
+ free_fuse_state (state);
+ goto out;
+ }
fn = state->resume_fn;
+ if (fn)
+ fn (state);
- fn (state);
-
+out:
return 0;
}
@@ -574,24 +650,69 @@ fuse_resolve_all (fuse_state_t *state)
int
-fuse_resolve_continue (fuse_state_t *state)
+fuse_gfid_set (fuse_state_t *state)
{
- fuse_resolve_loc_touchup (state);
+ int ret = 0;
- fuse_resolve_all (state);
+ if (uuid_is_null (state->gfid))
+ goto out;
- return 0;
+ if (!state->dict)
+ state->dict = dict_new ();
+
+ if (!state->dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_set_static_bin (state->dict, "gfid-req",
+ state->gfid, sizeof (state->gfid));
+out:
+ return ret;
}
int
fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn)
{
+ xlator_t *inode_xl = NULL;
+ xlator_t *active_xl = NULL;
+
fuse_gfid_set (state);
state->resume_fn = fn;
+ active_xl = fuse_active_subvol (state->this);
+ inode_xl = fuse_state_subvol (state);
+ if (!inode_xl && state->loc.parent)
+ inode_xl = state->loc.parent->table->xl;
+
+ /* If inode or fd is already in new graph, goto resume */
+ if (inode_xl == active_xl)
+ goto resume;
+
+ /* If the resolve is for 'fd' and its open with 'write' flag
+ set, don't switch to new graph yet */
+
+ /* TODO: fix it later */
+ /* if (state->fd && ((state->fd->flags & O_RDWR) ||
+ (state->fd->flags & O_WRONLY)))
+ */
+ if (state->fd)
+ goto resume;
+
+ /*
+ if (state->fd) {
+ state->resolve.fd = state->fd;
+ state->fd = NULL; // TODO: we may need a 'fd_unref()' here, not very sure'
+ }
+ */
+
fuse_resolve_all (state);
return 0;
+resume:
+ fn (state);
+
+ return 0;
}
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index a0a31660a..c805a7cd5 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -1,15 +1,15 @@
-#!/bin/sh
+#!/bin/bash
# (C) 2006, 2007, 2008 Gluster Inc. <http://www.gluster.com>
#
# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
+# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
@@ -27,40 +27,19 @@ _init ()
LOG_DEBUG=DEBUG;
LOG_TRACE=TRACE;
+ # set default log level to INFO
+ log_level=$LOG_INFO;
prefix="@prefix@";
exec_prefix=@exec_prefix@;
cmd_line=$(echo "@sbindir@/glusterfs");
- case `uname -s` in
- NetBSD)
- getinode="stat -f %i"
- getdev="stat -f %d"
- lgetinode="${getinode} -L"
- lgetdev="${getdev} -L"
-
- mounttab=/proc/mounts
- ;;
- Linux)
- getinode="stat -c %i $i"
- getdev="stat -c %d $d"
- lgetinode="${getinode} -L"
- lgetdev="${getdev} -L"
-
- mounttab=/etc/mtab
- ;;
- esac
-
UPDATEDBCONF=/etc/updatedb.conf
- LD_LIBRARY_PATH=@libdir@:${LD_LIBRARY_PATH}
- export LD_LIBRARY_PATH
}
start_glusterfs ()
{
- # lets the comparsion be case insensitive for all strings
-
if [ -n "$log_level_str" ]; then
- case "$( echo $log_level_str | tr '[a-z]' '[A-Z]')" in
+ case "$log_level_str" in
"ERROR")
log_level=$LOG_ERROR;
;;
@@ -88,26 +67,12 @@ start_glusterfs ()
;;
esac
fi
- if [ -n "$log_level" ]; then
- cmd_line=$(echo "$cmd_line --log-level=$log_level");
- fi
+ cmd_line=$(echo "$cmd_line --log-level=$log_level");
if [ -n "$read_only" ]; then
cmd_line=$(echo "$cmd_line --read-only");
fi
- if [ -n "$acl" ]; then
- cmd_line=$(echo "$cmd_line --acl");
- fi
-
- if [ -n "$selinux" ]; then
- cmd_line=$(echo "$cmd_line --selinux");
- fi
-
- if [ -n "$worm" ]; then
- cmd_line=$(echo "$cmd_line --worm");
- fi
-
if [ -n "$log_file" ]; then
cmd_line=$(echo "$cmd_line --log-file=$log_file");
fi
@@ -124,30 +89,14 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --volume-name=$volume_name");
fi
- if [ -n "$attribute_timeout" ]; then
- cmd_line=$(echo "$cmd_line --attribute-timeout=$attribute_timeout");
- fi
-
- if [ -n "$entry_timeout" ]; then
- cmd_line=$(echo "$cmd_line --entry-timeout=$entry_timeout");
- fi
-
- if [ -n "$negative_timeout" ]; then
- cmd_line=$(echo "$cmd_line --negative-timeout=$negative_timeout");
- fi
-
- if [ -n "$gid_timeout" ]; then
- cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout");
- fi
-
- if [ -n "$fopen_keep_cache" ]; then
- cmd_line=$(echo "$cmd_line --fopen-keep-cache");
+ if [ -n "$log_server" ]; then
+ if [ -n "$log_server_port" ]; then
+ cmd_line=$(echo "$cmd_line \
+--log-server=$log_server \
+--log-server-port=$log_server_port");
+ fi
fi
- # for rdma volume, we have to fetch volfile with '.rdma' added
- # to volume name, so that it fetches the right client vol file
- volume_id_rdma="";
-
if [ -z "$volfile_loc" ]; then
if [ -n "$server_ip" ]; then
if [ -n "$server_port" ]; then
@@ -155,23 +104,15 @@ start_glusterfs ()
fi
if [ -n "$transport" ]; then
cmd_line=$(echo "$cmd_line --volfile-server-transport=$transport");
- if [ "$transport" = "rdma" ]; then
- volume_id_rdma=".rdma";
- fi
fi
if [ -n "$volume_id" ]; then
- if [ -n "$volume_id_rdma" ]; then
- volume_id="$volume_id$volume_id_rdma";
- fi
cmd_line=$(echo "$cmd_line --volfile-id=$volume_id");
fi
if [ -n "$backupvolfile_server" ]; then
cmd_line1=$(echo "$cmd_line --volfile-server=$backupvolfile_server");
fi
- if [ -n "$volfile_max_fetch_attempts" ]; then
- cmd_line=$(echo "$cmd_line --volfile-max-fetch-attempts=$volfile_max_fetch_attempts");
- fi
+
cmd_line=$(echo "$cmd_line --volfile-server=$server_ip");
fi
else
@@ -182,29 +123,13 @@ start_glusterfs ()
err=0;
$cmd_line;
-
- inode=$( ${getinode} $mount_point 2>/dev/null);
-
- # this is required if the stat returns error
- if [ -z "$inode" ]; then
- inode="0";
- fi
-
# retry the failover
- # if [ $? != "0" ]; then # <--- TODO: Once glusterfs returns proper error code, change it.
- if [ $inode -ne 1 ]; then
+ if [ $? != "0" ]; then
err=1;
if [ -n "$cmd_line1" ]; then
cmd_line1=$(echo "$cmd_line1 $mount_point");
- $cmd_line1;
- err=0;
-
- inode=$( ${getinode} $mount_point 2>/dev/null);
- # this is required if the stat returns error
- if [ -z "$inode" ]; then
- inode="0";
- fi
- if [ $inode -ne 1 ]; then
+ $cmd_line1
+ if [ $? != "0"]; then
err=1;
fi
fi
@@ -212,7 +137,6 @@ start_glusterfs ()
if [ $err -eq "1" ]; then
echo "Mount failed. Please check the log file for more details."
- umount $mount_point > /dev/null 2>&1;
exit 1;
fi
}
@@ -229,135 +153,43 @@ mount.glusterfs --version"
}
-# check for recursive mounts. i.e, mounting over an existing brick
-check_recursive_mount ()
+main ()
{
- if [ $2 = "/" ]; then
- echo Cannot mount over root;
- exit 2;
- fi
- # GFID check first
- # remove trailing / from mount point
- mnt_dir=${2%/};
-
- export PATH;
- # check whether getfattr exists
- which getfattr > /dev/null 2>&1;
- if [ $? -ne 0 ]; then
- return;
- fi
+ helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p');
- getfattr -n trusted.gfid $mnt_dir 2>/dev/null | grep -iq "trusted.gfid=";
- if [ $? -eq 0 ]; then
- echo "ERROR: $mnt_dir is in use as a brick of a gluster volume";
- exit 2;
- fi
+ options=$(echo "$@" | sed -n 's/.*\-o[ ]*\([^ ]*\).*/\1/p');
- # check if the mount point is a brick's parent directory
- GLUSTERD_WORKDIR="/var/lib/glusterd";
+ new_log_level=$(echo "$options" | sed -n 's/.*log-level=\([^,]*\).*/\1/p');
- ls -L "$GLUSTERD_WORKDIR"/vols/*/bricks/* > /dev/null 2>&1;
- if [ $? -ne 0 ]; then
- return;
- fi
+ [ -n "$new_log_level" ] && {
+ log_level_str="$new_log_level";
+ }
- brick_path=`grep ^path "$GLUSTERD_WORKDIR"/vols/*/bricks/* | cut -d "=" -f 2`;
- root_inode=`${lgetinode} /`;
- root_dev=`${lgetdev} /`;
- mnt_inode=`${lgetinode} $mnt_dir`;
- mnt_dev=`${lgetdev} $mnt_dir`;
- for brick in "$brick_path";
- do
- # evaluate brick path to see if this is local, if non-local, skip iteration
- ls $brick > /dev/null 2>&1;
- if [ $? -ne 0 ]; then
- continue;
- fi
- getfattr -n trusted.gfid "$brick" 2>/dev/null | grep -iq "trusted.gfid=";
- if [ $? -ne 0 ]; then
- continue;
- else
- # brick is local
- while [ 1 ];
- do
- tmp_brick="$brick";
- brick="$brick"/..;
- brick_dev=`${lgetdev} $brick`;
- brick_inode=`${lgetinode} $brick`;
- if [ "$mnt_inode" -eq "$brick_inode" -a "$mnt_dev" -eq "$brick_dev" ]; then
- echo ERROR: $mnt_dir is a parent of the brick $tmp_brick;
- exit 2;
- fi
- [ "$root_inode" -ne "$brick_inode" -o "$root_dev" -ne "$brick_dev" ] || break;
- done;
- fi
- done;
-}
+ log_file=$(echo "$options" | sed -n 's/.*log-file=\([^,]*\).*/\1/p');
-main ()
-{
- helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p');
+ read_only=$(echo "$options" | sed -n 's/.*\(ro\)[^,]*.*/\1/p');
- in_opt="no"
- pos_args=0
- for opt in "$@"; do
- if [ "$in_opt" = "yes" ]; then
- for pair in $(echo "$opt" | tr "," " "); do
- # Handle options without values.
- case "$pair" in
- "ro") read_only=1 ;;
- "acl") acl=1 ;;
- "selinux") selinux=1 ;;
- "worm") worm=1 ;;
- "fopen-keep-cache") fopen_keep_cache=1 ;;
- # "mount -t glusterfs" sends this, but it's useless.
- "rw") ;;
- *)
- key=$(echo "$pair" | cut -f1 -d'=');
- value=$(echo "$pair" | cut -f2- -d'=');
-
- # Handle options with values.
- case "$key" in
- "log-level") log_level_str=$value ;;
- "log-file") log_file=$value ;;
- "transport") transport=$value ;;
- "direct-io-mode") direct_io_mode=$value ;;
- "volume-name") volume_name=$value ;;
- "volume-id") volume_id=$value ;;
- "volfile-check") volfile_check=$value ;;
- "server-port") server_port=$value ;;
- "fetch-attempts")
- volfile_max_fetch_attempts=$value ;;
- "backupvolfile-server")
- backupvolfile_server=$value ;;
- "attribute-timeout")
- attribute_timeout=$value ;;
- "entry-timeout") entry_timeout=$value ;;
- "negative-timeout") negative_timeout=$value ;;
- "gid-timeout") gid_timeout=$value ;;
- *) echo "unknown option $key (ignored)" ;;
- esac
- esac
- done
- in_opt="no"
- elif [ "$opt" = "-o" ]; then
- in_opt="yes"
- else
- case $pos_args in
- 0) volfile_loc=$opt ;;
- 1) mount_point=$opt ;;
- *) echo "extra arguments at end (ignored)" ;;
- esac
- pos_args=$((pos_args+1))
- fi
- done
- if [ $in_opt = "yes" -o $pos_args -lt 2 ]; then
- usage
- exit 1
- fi
+ transport=$(echo "$options" | sed -n 's/.*transport=\([^,]*\).*/\1/p');
+
+ direct_io_mode=$(echo "$options" | sed -n 's/.*direct-io-mode=\([^,]*\).*/\1/p');
+
+ volume_name=$(echo "$options" | sed -n 's/.*volume-name=\([^,]*\).*/\1/p');
+
+ volume_id=$(echo "$options" | sed -n 's/.*volume_id=\([^,]*\).*/\1/p');
+
+ volfile_check=$(echo "$options" | sed -n 's/.*volfile-check=\([^,]*\).*/\1/p');
+
+ server_port=$(echo "$options" | sed -n 's/.*server-port=\([^,]*\).*/\1/p');
+ backupvolfile_server=$(echo "$options" | sed -n 's/.*backupvolfile-server=\([^,]*\).*/\1/p');
+
+ log_server=$(echo "$options" | sed -n 's/.*log-server=\([^,]*\).*/\1/p');
+
+ log_server_port=$(echo "$options" | sed -n 's/.*log-server-port=\([^,]*\).*/\1/p');
+
+ volfile_loc="$1";
[ -r "$volfile_loc" ] || {
- server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p');
+ server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
test_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
[ -n "$test_str" ] && {
volume_id="$test_str";
@@ -365,6 +197,19 @@ main ()
volfile_loc="";
}
+ new_fs_options=$(echo "$options" | sed -e 's/[,]*log-file=[^,]*//' \
+ -e 's/[,]*log-level=[^,]*//' \
+ -e 's/[,]*volume-name=[^,]*//' \
+ -e 's/[,]*direct-io-mode=[^,]*//' \
+ -e 's/[,]*volfile-check=[^,]*//' \
+ -e 's/[,]*transport=[^,]*//' \
+ -e 's/[,]*backupvolfile-server=[^,]*//' \
+ -e 's/[,]*server-port=[^,]*//' \
+ -e 's/[,]*volume-id=[^,]*//' \
+ -e 's/[,]*log-server=[^,]*//' \
+ -e 's/[,]*ro[^,]*//' \
+ -e 's/[,]*log-server-port=[^,]*//');
+
#
[ -n "$helper" ] && {
cmd_line=$(echo "$cmd_line --$helper");
@@ -372,22 +217,27 @@ main ()
exit 0;
}
- # No need to do a ! -d test, it is taken care while initializing the
- # variable mount_point
- [ -z "$mount_point" -o ! -d "$mount_point" ] && {
- echo "ERROR: Mount point does not exist."
+ mount_point=""
+ for arg in "$@"; do
+ [ -d "$arg" ] && {
+ mount_point=$arg
+ }
+ done
+
+ [ -z "$mount_point" ] && {
usage;
exit 0;
}
# Simple check to avoid multiple identical mounts
- if grep -q " ${mount_point}.*fuse" $mounttab; then
+ if grep -q " $mount_point fuse" /etc/mtab; then
echo -n "$0: according to mtab, GlusterFS is already mounted on "
echo "$mount_point"
+ sleep 1;
exit 0;
fi
- check_recursive_mount "$@";
+ fs_options=$(echo "$fs_options,$new_fs_options");
# Append fuse.glusterfs to PRUNEFS variable in updatedb.conf(5). updatedb(8)
# should not index files under GlusterFS, indexing will slow down GlusteFS
@@ -401,6 +251,8 @@ main ()
}
start_glusterfs;
+
+ sleep 3;
}
_init "$@" && main "$@";
diff --git a/xlators/mount/fuse/utils/mount_glusterfs.in b/xlators/mount/fuse/utils/mount_glusterfs.in
index b12b4e04e..d36fdeeda 100755
--- a/xlators/mount/fuse/utils/mount_glusterfs.in
+++ b/xlators/mount/fuse/utils/mount_glusterfs.in
@@ -2,14 +2,14 @@
# (C) 2008 Gluster Inc. <http://www.gluster.com>
#
# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
+# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
@@ -85,7 +85,7 @@ start_glusterfs ()
--volfile-server-transport=$transport");
else
cmd_line=$(echo "$cmd_line \
---volfile-server=$server_ip");
+--volfile-server=$server_ip \
fi
else
cmd_line=$(echo "$cmd_line --volfile=$volfile_loc");
@@ -165,15 +165,14 @@ main ()
# TODO: use getopt. This is very much darwin specific
volfile_loc="$1";
- while [ "$volfile_loc" = "-o" ] ; do
+ while [ "$volfile_loc" == "-o" ] ; do
shift ;
shift ;
volfile_loc="$1";
done
[ -r "$volfile_loc" ] || {
- server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p');
- volume_id=$(echo "$volfile_loc" | sed -n 's/[a-zA-Z0-9:.\-]*:\(.*\)/\1/p');
+ server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
volfile_loc="";
}
# following line is product of love towards sed
diff --git a/xlators/nfs/lib/src/auth-null.c b/xlators/nfs/lib/src/auth-null.c
new file mode 100644
index 000000000..0c8e335db
--- /dev/null
+++ b/xlators/nfs/lib/src/auth-null.c
@@ -0,0 +1,72 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpcsvc.h"
+#include "list.h"
+#include "dict.h"
+
+
+int
+nfs_auth_null_request_init (rpcsvc_request_t *req, void *priv)
+{
+ if (!req)
+ return -1;
+
+ memset (req->cred.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ req->cred.datalen = 0;
+
+ memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ req->verf.datalen = 0;
+
+ return 0;
+}
+
+int
+nfs_auth_null_authenticate (rpcsvc_request_t *req, void *priv)
+{
+ /* Always succeed. */
+ return RPCSVC_AUTH_ACCEPT;
+}
+
+rpcsvc_auth_ops_t nfs_auth_null_ops = {
+ .conn_init = NULL,
+ .request_init = nfs_auth_null_request_init,
+ .authenticate = nfs_auth_null_authenticate
+};
+
+rpcsvc_auth_t nfs_rpcsvc_auth_null = {
+ .authname = "AUTH_NULL",
+ .authnum = AUTH_NULL,
+ .authops = &nfs_auth_null_ops,
+ .authprivate = NULL
+};
+
+
+rpcsvc_auth_t *
+nfs_rpcsvc_auth_null_init (rpcsvc_t *svc, dict_t *options)
+{
+ return &nfs_rpcsvc_auth_null;
+}
+
diff --git a/xlators/nfs/lib/src/auth-unix.c b/xlators/nfs/lib/src/auth-unix.c
new file mode 100644
index 000000000..50ca381ec
--- /dev/null
+++ b/xlators/nfs/lib/src/auth-unix.c
@@ -0,0 +1,97 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpcsvc.h"
+#include "list.h"
+#include "dict.h"
+#include "xdr-rpc.h"
+
+
+int
+nfs_auth_unix_request_init (rpcsvc_request_t *req, void *priv)
+{
+ if (!req)
+ return -1;
+ memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES);
+ req->verf.datalen = 0;
+ req->verf.flavour = AUTH_NULL;
+
+ return 0;
+}
+
+int
+nfs_auth_unix_authenticate (rpcsvc_request_t *req, void *priv)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ struct authunix_parms aup;
+ char machname[MAX_MACHINE_NAME];
+
+ if (!req)
+ return ret;
+
+ ret = nfs_xdr_to_auth_unix_cred (req->cred.authdata, req->cred.datalen,
+ &aup, machname, req->auxgids);
+ if (ret == -1) {
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ if (aup.aup_len > 16) {
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ req->uid = aup.aup_uid;
+ req->gid = aup.aup_gid;
+ req->auxgidcount = aup.aup_len;
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: machine name: %s, uid: %d"
+ ", gid: %d", machname, req->uid, req->gid);
+ ret = RPCSVC_AUTH_ACCEPT;
+err:
+ return ret;
+}
+
+rpcsvc_auth_ops_t nfs_auth_unix_ops = {
+ .conn_init = NULL,
+ .request_init = nfs_auth_unix_request_init,
+ .authenticate = nfs_auth_unix_authenticate
+};
+
+rpcsvc_auth_t nfs_rpcsvc_auth_unix = {
+ .authname = "AUTH_UNIX",
+ .authnum = AUTH_UNIX,
+ .authops = &nfs_auth_unix_ops,
+ .authprivate = NULL
+};
+
+
+rpcsvc_auth_t *
+nfs_rpcsvc_auth_unix_init (rpcsvc_t *svc, dict_t *options)
+{
+ return &nfs_rpcsvc_auth_unix;
+}
+
diff --git a/xlators/nfs/lib/src/msg-nfs3.c b/xlators/nfs/lib/src/msg-nfs3.c
new file mode 100644
index 000000000..e6e722051
--- /dev/null
+++ b/xlators/nfs/lib/src/msg-nfs3.c
@@ -0,0 +1,554 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/uio.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <sys/types.h>
+
+#include "xdr-nfs3.h"
+#include "msg-nfs3.h"
+#include "xdr-common.h"
+
+
+/* Decode the mount path from the network message in inmsg
+ * into the memory referenced by outpath.iov_base.
+ * The size allocated for outpath.iov_base is outpath.iov_len.
+ * The size of the path extracted from the message is returned.
+ */
+ssize_t
+xdr_to_mountpath (struct iovec outpath, struct iovec inmsg)
+{
+ XDR xdr;
+ ssize_t ret = -1;
+ char *mntpath = NULL;
+
+ if ((!outpath.iov_base) || (!inmsg.iov_base))
+ return -1;
+
+ xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
+ XDR_DECODE);
+
+ mntpath = outpath.iov_base;
+ if (!xdr_dirpath (&xdr, (dirpath *)&mntpath)) {
+ ret = -1;
+ goto ret;
+ }
+
+ ret = nfs_xdr_decoded_length (xdr);
+
+ret:
+ return ret;
+}
+
+
+ssize_t
+nfs_xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc)
+{
+ ssize_t ret = -1;
+ XDR xdr;
+
+ if ((!outmsg.iov_base) || (!res) || (!proc))
+ return -1;
+
+ xdrmem_create (&xdr, outmsg.iov_base, (unsigned int)outmsg.iov_len,
+ XDR_ENCODE);
+
+ if (!proc (&xdr, res)) {
+ ret = -1;
+ goto ret;
+ }
+
+ ret = nfs_xdr_encoded_length (xdr);
+
+ret:
+ return ret;
+}
+
+
+ssize_t
+nfs_xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc)
+{
+ XDR xdr;
+ ssize_t ret = -1;
+
+ if ((!inmsg.iov_base) || (!args) || (!proc))
+ return -1;
+
+ xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
+ XDR_DECODE);
+
+ if (!proc (&xdr, args)) {
+ ret = -1;
+ goto ret;
+ }
+
+ ret = nfs_xdr_decoded_length (xdr);
+ret:
+ return ret;
+}
+
+
+ssize_t
+nfs_xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc,
+ struct iovec *pendingpayload)
+{
+ XDR xdr;
+ ssize_t ret = -1;
+
+ if ((!inmsg.iov_base) || (!args) || (!proc))
+ return -1;
+
+ xdrmem_create (&xdr, inmsg.iov_base, (unsigned int)inmsg.iov_len,
+ XDR_DECODE);
+
+ if (!proc (&xdr, args)) {
+ ret = -1;
+ goto ret;
+ }
+
+ ret = nfs_xdr_decoded_length (xdr);
+
+ if (pendingpayload) {
+ pendingpayload->iov_base = nfs_xdr_decoded_remaining_addr (xdr);
+ pendingpayload->iov_len = nfs_xdr_decoded_remaining_len (xdr);
+ }
+
+ret:
+ return ret;
+}
+
+
+/* Translate the mountres3 structure in res into XDR format into memory
+ * referenced by outmsg.iov_base.
+ * Returns the number of bytes used in encoding into XDR format.
+ */
+ssize_t
+xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_mountres3);
+}
+
+
+ssize_t
+xdr_serialize_mountbody (struct iovec outmsg, mountbody *mb)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)mb,
+ (xdrproc_t)xdr_mountbody);
+}
+
+ssize_t
+xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)ml,
+ (xdrproc_t)xdr_mountlist);
+}
+
+
+ssize_t
+xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)m,
+ (xdrproc_t)xdr_mountstat3);
+}
+
+
+ssize_t
+xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ga,
+ (xdrproc_t)xdr_getattr3args);
+}
+
+
+ssize_t
+xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_getattr3res);
+}
+
+
+ssize_t
+xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_setattr3res);
+}
+
+
+ssize_t
+xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)sa,
+ (xdrproc_t)xdr_setattr3args);
+}
+
+
+ssize_t
+xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_lookup3res);
+}
+
+
+ssize_t
+xdr_to_lookup3args (struct iovec inmsg, lookup3args *la)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)la,
+ (xdrproc_t)xdr_lookup3args);
+}
+
+
+ssize_t
+xdr_to_access3args (struct iovec inmsg, access3args *ac)
+{
+ return nfs_xdr_to_generic (inmsg,(void *)ac,
+ (xdrproc_t)xdr_access3args);
+}
+
+
+ssize_t
+xdr_serialize_access3res (struct iovec outmsg, access3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_access3res);
+}
+
+
+ssize_t
+xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ra,
+ (xdrproc_t)xdr_readlink3args);
+}
+
+
+ssize_t
+xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_readlink3res);
+}
+
+
+ssize_t
+xdr_to_read3args (struct iovec inmsg, read3args *ra)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_read3args);
+}
+
+
+ssize_t
+xdr_serialize_read3res (struct iovec outmsg, read3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_read3res);
+}
+
+ssize_t
+xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_read3res_nocopy);
+}
+
+
+ssize_t
+xdr_to_write3args (struct iovec inmsg, write3args *wa)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)wa,(xdrproc_t)xdr_write3args);
+}
+
+
+ssize_t
+xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa,
+ struct iovec *payload)
+{
+ return nfs_xdr_to_generic_payload (inmsg, (void *)wa,
+ (xdrproc_t)xdr_write3args, payload);
+}
+
+
+ssize_t
+xdr_serialize_write3res (struct iovec outmsg, write3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_write3res);
+}
+
+
+ssize_t
+xdr_to_create3args (struct iovec inmsg, create3args *ca)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ca,
+ (xdrproc_t)xdr_create3args);
+}
+
+
+ssize_t
+xdr_serialize_create3res (struct iovec outmsg, create3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_create3res);
+}
+
+
+ssize_t
+xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_mkdir3res);
+}
+
+
+ssize_t
+xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ma,
+ (xdrproc_t)xdr_mkdir3args);
+}
+
+
+ssize_t
+xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)sa,
+ (xdrproc_t)xdr_symlink3args);
+}
+
+
+ssize_t
+xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_symlink3res);
+}
+
+
+ssize_t
+xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ma,
+ (xdrproc_t)xdr_mknod3args);
+}
+
+
+ssize_t
+xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_mknod3res);
+}
+
+
+ssize_t
+xdr_to_remove3args (struct iovec inmsg, remove3args *ra)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ra,
+ (xdrproc_t)xdr_remove3args);
+}
+
+
+ssize_t
+xdr_serialize_remove3res (struct iovec outmsg, remove3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_remove3res);
+}
+
+
+ssize_t
+xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ra,
+ (xdrproc_t)xdr_rmdir3args);
+}
+
+
+ssize_t
+xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_rmdir3res);
+}
+
+
+ssize_t
+xdr_serialize_rename3res (struct iovec outmsg, rename3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_rename3res);
+}
+
+
+ssize_t
+xdr_to_rename3args (struct iovec inmsg, rename3args *ra)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ra,
+ (xdrproc_t)xdr_rename3args);
+}
+
+
+ssize_t
+xdr_serialize_link3res (struct iovec outmsg, link3res *li)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)li,
+ (xdrproc_t)xdr_link3res);
+}
+
+
+ssize_t
+xdr_to_link3args (struct iovec inmsg, link3args *la)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_link3args);
+}
+
+
+ssize_t
+xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)rd,
+ (xdrproc_t)xdr_readdir3args);
+}
+
+
+ssize_t
+xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_readdir3res);
+}
+
+
+ssize_t
+xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)rp,
+ (xdrproc_t)xdr_readdirp3args);
+}
+
+
+ssize_t
+xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_readdirp3res);
+}
+
+
+ssize_t
+xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)fa,
+ (xdrproc_t)xdr_fsstat3args);
+}
+
+
+ssize_t
+xdr_serialize_fsstat3res (struct iovec outmsg, fsstat3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_fsstat3res);
+}
+
+ssize_t
+xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)fi,
+ (xdrproc_t)xdr_fsinfo3args);
+}
+
+
+ssize_t
+xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_fsinfo3res);
+}
+
+
+ssize_t
+xdr_to_pathconf3args (struct iovec inmsg, pathconf3args *pc)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)pc,
+ (xdrproc_t)xdr_pathconf3args);}
+
+
+ssize_t
+xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_pathconf3res);
+}
+
+
+ssize_t
+xdr_to_commit3args (struct iovec inmsg, commit3args *ca)
+{
+ return nfs_xdr_to_generic (inmsg, (void *)ca,
+ (xdrproc_t)xdr_commit3args);
+}
+
+
+ssize_t
+xdr_serialize_commit3res (struct iovec outmsg, commit3res *res)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)res,
+ (xdrproc_t)xdr_commit3res);
+}
+
+
+ssize_t
+xdr_serialize_exports (struct iovec outmsg, exports *elist)
+{
+ XDR xdr;
+ ssize_t ret = -1;
+
+ if ((!outmsg.iov_base) || (!elist))
+ return -1;
+
+ xdrmem_create (&xdr, outmsg.iov_base, (unsigned int)outmsg.iov_len,
+ XDR_ENCODE);
+
+ if (!xdr_exports (&xdr, elist))
+ goto ret;
+
+ ret = nfs_xdr_decoded_length (xdr);
+
+ret:
+ return ret;
+}
+
+
+ssize_t
+xdr_serialize_nfsstat3 (struct iovec outmsg, nfsstat3 *s)
+{
+ return nfs_xdr_serialize_generic (outmsg, (void *)s,
+ (xdrproc_t)xdr_nfsstat3);
+}
+
+
diff --git a/xlators/nfs/lib/src/msg-nfs3.h b/xlators/nfs/lib/src/msg-nfs3.h
new file mode 100644
index 000000000..f0d57c646
--- /dev/null
+++ b/xlators/nfs/lib/src/msg-nfs3.h
@@ -0,0 +1,186 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _MSG_NFS3_H_
+#define _MSG_NFS3_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "xdr-nfs3.h"
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+extern ssize_t
+xdr_to_mountpath (struct iovec outpath, struct iovec inmsg);
+
+extern ssize_t
+xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res);
+
+extern ssize_t
+xdr_serialize_mountbody (struct iovec outmsg, mountbody *mb);
+
+extern ssize_t
+xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga);
+
+extern ssize_t
+xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res);
+
+extern ssize_t
+xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res);
+
+extern ssize_t
+xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa);
+
+extern ssize_t
+xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res);
+
+extern ssize_t
+xdr_to_lookup3args (struct iovec inmsg, lookup3args *la);
+
+extern ssize_t
+xdr_to_access3args (struct iovec inmsg, access3args *ac);
+
+extern ssize_t
+xdr_serialize_access3res (struct iovec outmsg, access3res *res);
+
+extern ssize_t
+xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra);
+
+extern ssize_t
+xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res);
+
+extern ssize_t
+xdr_to_read3args (struct iovec inmsg, read3args *ra);
+
+extern ssize_t
+xdr_serialize_read3res (struct iovec outmsg, read3res *res);
+
+extern ssize_t
+xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res);
+
+extern ssize_t
+xdr_to_write3args (struct iovec inmsg, write3args *wa);
+
+extern ssize_t
+xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa,
+ struct iovec *payload);
+
+extern ssize_t
+xdr_serialize_write3res (struct iovec outmsg, write3res *res);
+
+extern ssize_t
+xdr_to_create3args (struct iovec inmsg, create3args *ca);
+
+extern ssize_t
+xdr_serialize_create3res (struct iovec outmsg, create3res *res);
+
+extern ssize_t
+xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res);
+
+extern ssize_t
+xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma);
+
+extern ssize_t
+xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa);
+
+extern ssize_t
+xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res);
+
+extern ssize_t
+xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma);
+
+extern ssize_t
+xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res);
+
+extern ssize_t
+xdr_to_remove3args (struct iovec inmsg, remove3args *ra);
+
+extern ssize_t
+xdr_serialize_remove3res (struct iovec outmsg, remove3res *res);
+
+extern ssize_t
+xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra);
+
+extern ssize_t
+xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res);
+
+extern ssize_t
+xdr_serialize_rename3res (struct iovec outmsg, rename3res *res);
+
+extern ssize_t
+xdr_to_rename3args (struct iovec inmsg, rename3args *ra);
+
+extern ssize_t
+xdr_serialize_link3res (struct iovec outmsg, link3res *li);
+
+extern ssize_t
+xdr_to_link3args (struct iovec inmsg, link3args *la);
+
+extern ssize_t
+xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd);
+
+extern ssize_t
+xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res);
+
+extern ssize_t
+xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp);
+
+extern ssize_t
+xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res);
+
+extern ssize_t
+xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa);
+
+extern ssize_t
+xdr_serialize_fsstat3res (struct iovec outmsg, fsstat3res *res);
+
+extern ssize_t
+xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi);
+
+extern ssize_t
+xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res);
+
+extern ssize_t
+xdr_to_pathconf3args (struct iovec inmsg, pathconf3args *pc);
+
+extern ssize_t
+xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res);
+
+extern ssize_t
+xdr_to_commit3args (struct iovec inmsg, commit3args *ca);
+
+extern ssize_t
+xdr_serialize_commit3res (struct iovec outmsg, commit3res *res);
+
+extern ssize_t
+xdr_serialize_exports (struct iovec outmsg, exports *elist);
+
+extern ssize_t
+xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml);
+
+extern ssize_t
+xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m);
+
+extern ssize_t
+xdr_serialize_nfsstat3 (struct iovec outmsg, nfsstat3 *s);
+#endif
diff --git a/xlators/nfs/lib/src/rpc-socket.c b/xlators/nfs/lib/src/rpc-socket.c
new file mode 100644
index 000000000..ec56f3fc4
--- /dev/null
+++ b/xlators/nfs/lib/src/rpc-socket.c
@@ -0,0 +1,361 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpc-socket.h"
+#include "rpcsvc.h"
+#include "dict.h"
+#include "logging.h"
+#include "byte-order.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+static int
+nfs_rpcsvc_socket_server_get_local_socket (int addrfam, char *listenhost,
+ uint16_t listenport,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ struct addrinfo hints, *res = 0;
+ char service[NI_MAXSERV];
+ int ret = -1;
+
+ memset (service, 0, sizeof (service));
+ sprintf (service, "%d", listenport);
+
+ memset (&hints, 0, sizeof (hints));
+ addr->sa_family = hints.ai_family = addrfam;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+
+ ret = getaddrinfo(listenhost, service, &hints, &res);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR,
+ "getaddrinfo failed for host %s, service %s (%s)",
+ listenhost, service, gai_strerror (ret));
+ ret = -1;
+ goto err;
+ }
+
+ memcpy (addr, res->ai_addr, res->ai_addrlen);
+ *addr_len = res->ai_addrlen;
+
+ freeaddrinfo (res);
+ ret = 0;
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_socket_listen (int addrfam, char *listenhost, uint16_t listenport)
+{
+ int sock = -1;
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ int flags = 0;
+ int ret = -1;
+ int opt = 1;
+
+ ret = nfs_rpcsvc_socket_server_get_local_socket (addrfam, listenhost,
+ listenport,
+ SA (&sockaddr),
+ &sockaddr_len);
+
+ if (ret == -1)
+ return ret;
+
+ sock = socket (SA (&sockaddr)->sa_family, SOCK_STREAM, 0);
+ if (sock == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "socket creation failed"
+ " (%s)", strerror (errno));
+ goto err;
+ }
+
+ flags = fcntl (sock, F_GETFL);
+ if (flags == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot get socket flags"
+ " (%s)", strerror(errno));
+ goto close_err;
+ }
+
+ ret = fcntl (sock, F_SETFL, flags | O_NONBLOCK);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set socket "
+ "non-blocking (%s)", strerror (errno));
+ goto close_err;
+ }
+
+ ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "setsockopt() for "
+ "SO_REUSEADDR failed (%s)", strerror (errno));
+ goto close_err;
+ }
+
+ ret = bind (sock, (struct sockaddr *)&sockaddr, sockaddr_len);
+ if (ret == -1) {
+ if (errno != EADDRINUSE) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "binding socket "
+ "failed: %s", strerror (errno));
+ goto close_err;
+ }
+ }
+
+ ret = listen (sock, 10);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "could not listen on"
+ " socket (%s)", strerror (errno));
+ goto close_err;
+ }
+
+ return sock;
+
+close_err:
+ close (sock);
+ sock = -1;
+
+err:
+ return sock;
+}
+
+
+int
+nfs_rpcsvc_socket_accept (int listenfd)
+{
+ int new_sock = -1;
+ struct sockaddr_storage new_sockaddr = {0, };
+ socklen_t addrlen = sizeof (new_sockaddr);
+ int flags = 0;
+ int ret = -1;
+ int on = 1;
+
+ new_sock = accept (listenfd, SA (&new_sockaddr), &addrlen);
+ if (new_sock == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR,"accept on socket failed");
+ goto err;
+ }
+
+ flags = fcntl (new_sock, F_GETFL);
+ if (flags == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot get socket flags"
+ " (%s)", strerror(errno));
+ goto close_err;
+ }
+
+ ret = fcntl (new_sock, F_SETFL, flags | O_NONBLOCK);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set socket "
+ "non-blocking (%s)", strerror (errno));
+ goto close_err;
+ }
+
+#ifdef TCP_NODELAY
+ ret = setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set no-delay "
+ " socket option");
+ }
+#endif
+
+ return new_sock;
+
+close_err:
+ close (new_sock);
+ new_sock = -1;
+
+err:
+ return new_sock;
+}
+
+ssize_t
+nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize)
+{
+ ssize_t dataread = 0;
+ ssize_t readlen = -1;
+
+ if (!readaddr)
+ return -1;
+
+ while (readsize > 0) {
+ readlen = read (sockfd, readaddr, readsize);
+ if (readlen == -1) {
+ if (errno != EAGAIN) {
+ dataread = -1;
+ break;
+ } else
+ break;
+ } else if (readlen == 0)
+ break;
+
+ dataread += readlen;
+ readaddr += readlen;
+ readsize -= readlen;
+ }
+
+ return dataread;
+}
+
+
+ssize_t
+nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain)
+{
+ size_t writelen = -1;
+ ssize_t written = 0;
+
+ if (!buffer)
+ return -1;
+
+ while (size > 0) {
+ writelen = write (sockfd, buffer, size);
+ if (writelen == -1) {
+ if (errno != EAGAIN) {
+ written = -1;
+ break;
+ } else {
+ *eagain = 1;
+ break;
+ }
+ } else if (writelen == 0)
+ break;
+
+ written += writelen;
+ size -= writelen;
+ buffer += writelen;
+ }
+
+ return written;
+}
+
+
+int
+nfs_rpcsvc_socket_peername (int sockfd, char *hostname, int hostlen)
+{
+ struct sockaddr sa;
+ socklen_t sl = sizeof (sa);
+ int ret = EAI_FAIL;
+
+ if (!hostname)
+ return ret;
+
+ ret = getpeername (sockfd, &sa, &sl);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "Failed to get peer name:"
+ " %s", strerror (errno));
+ ret = EAI_FAIL;
+ goto err;
+ }
+
+ ret = getnameinfo (&sa, sl, hostname, hostlen, NULL, 0, 0);
+ if (ret != 0)
+ goto err;
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_socket_peeraddr (int sockfd, char *addrstr, int addrlen,
+ struct sockaddr *returnsa, socklen_t sasize)
+{
+ struct sockaddr sa;
+ int ret = EAI_FAIL;
+
+ if (returnsa)
+ ret = getpeername (sockfd, returnsa, &sasize);
+ else {
+ sasize = sizeof (sa);
+ ret = getpeername (sockfd, &sa, &sasize);
+ }
+
+ if (ret == -1) {
+ gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "Failed to get peer addr:"
+ " %s", strerror (errno));
+ ret = EAI_FAIL;
+ goto err;
+ }
+
+ /* If caller did not specify a string into which the address can be
+ * stored, dont bother getting it.
+ */
+ if (!addrstr) {
+ ret = 0;
+ goto err;
+ }
+
+ if (returnsa)
+ ret = getnameinfo (returnsa, sasize, addrstr, addrlen, NULL, 0,
+ NI_NUMERICHOST);
+ else
+ ret = getnameinfo (&sa, sasize, addrstr, addrlen, NULL, 0,
+ NI_NUMERICHOST);
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_socket_block_tx (int sockfd)
+{
+
+ int ret = -1;
+ int on = 1;
+
+#ifdef TCP_CORK
+ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, &on, sizeof(on));
+#endif
+
+#ifdef TCP_NOPUSH
+ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof(on));
+#endif
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_socket_unblock_tx (int sockfd)
+{
+ int ret = -1;
+ int off = 0;
+
+#ifdef TCP_CORK
+ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, &off, sizeof(off));
+#endif
+
+#ifdef TCP_NOPUSH
+ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &off, sizeof(off));
+#endif
+ return ret;
+}
+
diff --git a/xlators/nfs/lib/src/rpc-socket.h b/xlators/nfs/lib/src/rpc-socket.h
new file mode 100644
index 000000000..8662df0a7
--- /dev/null
+++ b/xlators/nfs/lib/src/rpc-socket.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NFS_RPCSVC_SOCKET_H_
+#define _NFS_RPCSVC_SOCKET_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpcsvc.h"
+#include "dict.h"
+#include "logging.h"
+#include "byte-order.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#define SA(ptr) ((struct sockaddr *)ptr)
+#define GF_RPCSVC_SOCK "rpc-socket"
+extern int
+nfs_rpcsvc_socket_listen (int addrfam, char *listenhost, uint16_t listenport);
+
+extern int
+nfs_rpcsvc_socket_accept (int listenfd);
+
+extern ssize_t
+nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize);
+
+extern ssize_t
+nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain);
+
+extern int
+nfs_rpcsvc_socket_peername (int sockfd, char *hostname, int hostlen);
+
+extern int
+nfs_rpcsvc_socket_peeraddr (int sockfd, char *addrstr, int addrlen,
+ struct sockaddr *returnsa, socklen_t sasize);
+extern int
+nfs_rpcsvc_socket_block_tx (int sockfd);
+
+extern int
+nfs_rpcsvc_socket_unblock_tx (int sockfd);
+#endif
diff --git a/xlators/nfs/lib/src/rpcsvc-auth.c b/xlators/nfs/lib/src/rpcsvc-auth.c
new file mode 100644
index 000000000..6d07619e4
--- /dev/null
+++ b/xlators/nfs/lib/src/rpcsvc-auth.c
@@ -0,0 +1,400 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "rpcsvc.h"
+#include "logging.h"
+#include "dict.h"
+
+extern rpcsvc_auth_t *
+nfs_rpcsvc_auth_null_init (rpcsvc_t *svc, dict_t *options);
+
+extern rpcsvc_auth_t *
+nfs_rpcsvc_auth_unix_init (rpcsvc_t *svc, dict_t *options);
+
+int
+nfs_rpcsvc_auth_add_initer (struct list_head *list, char *idfier,
+ rpcsvc_auth_initer_t init)
+{
+ struct rpcsvc_auth_list *new = NULL;
+
+ if ((!list) || (!init) || (!idfier))
+ return -1;
+
+ new = GF_CALLOC (1, sizeof (*new), gf_common_mt_rpcsvc_auth_list);
+ if (!new) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Memory allocation failed");
+ return -1;
+ }
+
+ new->init = init;
+ strcpy (new->name, idfier);
+ INIT_LIST_HEAD (&new->authlist);
+ list_add_tail (&new->authlist, list);
+ return 0;
+}
+
+
+
+int
+nfs_rpcsvc_auth_add_initers (rpcsvc_t *svc)
+{
+ int ret = -1;
+
+ ret = nfs_rpcsvc_auth_add_initer (&svc->authschemes, "auth-unix",
+ (rpcsvc_auth_initer_t)
+ nfs_rpcsvc_auth_unix_init);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add AUTH_UNIX");
+ goto err;
+ }
+
+ ret = nfs_rpcsvc_auth_add_initer (&svc->authschemes, "auth-null",
+ (rpcsvc_auth_initer_t)
+ nfs_rpcsvc_auth_null_init);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add AUTH_NULL");
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_auth_init_auth (rpcsvc_t *svc, dict_t *options,
+ struct rpcsvc_auth_list *authitem)
+{
+ int ret = -1;
+
+ if ((!svc) || (!options) || (!authitem))
+ return -1;
+
+ if (!authitem->init) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "No init function defined");
+ ret = -1;
+ goto err;
+ }
+
+ authitem->auth = authitem->init (svc, options);
+ if (!authitem->auth) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Registration of auth failed:"
+ " %s", authitem->name);
+ ret = -1;
+ goto err;
+ }
+
+ authitem->enable = 1;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Authentication enabled: %s",
+ authitem->auth->authname);
+
+ ret = 0;
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_auth_init_auths (rpcsvc_t *svc, dict_t *options)
+{
+ int ret = -1;
+ struct rpcsvc_auth_list *auth = NULL;
+ struct rpcsvc_auth_list *tmp = NULL;
+
+ if (!svc)
+ return -1;
+
+ if (list_empty (&svc->authschemes)) {
+ gf_log (GF_RPCSVC, GF_LOG_WARNING, "No authentication!");
+ ret = 0;
+ goto err;
+ }
+
+ /* If auth null and sys are not disabled by the user, we must enable
+ * it by default. This is a globally default rule, the user is still
+ * allowed to disable the two for particular subvolumes.
+ */
+ if (!dict_get (options, "rpc-auth.auth-null")) {
+ ret = dict_set_dynstr (options, "rpc-auth.auth-null", "on");
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,
+ "Failed to set dict value.");
+ goto err;
+ }
+ }
+
+ if (!dict_get (options, "rpc-auth.auth-unix")) {
+ ret = dict_set_dynstr (options, "rpc-auth.auth-unix", "on");
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,
+ "Failed to set dict value.");
+ goto err;
+ }
+ }
+
+ list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) {
+ ret = nfs_rpcsvc_auth_init_auth (svc, options, auth);
+ if (ret == -1)
+ goto err;
+ }
+
+ ret = 0;
+err:
+ return ret;
+
+}
+
+int
+nfs_rpcsvc_auth_init (rpcsvc_t *svc, dict_t *options)
+{
+ int ret = -1;
+
+ if ((!svc) || (!options))
+ return -1;
+
+ ret = nfs_rpcsvc_auth_add_initers (svc);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add initers");
+ goto out;
+ }
+
+ ret = nfs_rpcsvc_auth_init_auths (svc, options);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init auth schemes");
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+rpcsvc_auth_t *
+__nfs_rpcsvc_auth_get_handler (rpcsvc_request_t *req)
+{
+ struct rpcsvc_auth_list *auth = NULL;
+ struct rpcsvc_auth_list *tmp = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if (!req)
+ return NULL;
+
+ svc = nfs_rpcsvc_request_service (req);
+ if (list_empty (&svc->authschemes)) {
+ gf_log (GF_RPCSVC, GF_LOG_WARNING, "No authentication!");
+ goto err;
+ }
+
+ list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) {
+ if (!auth->enable)
+ continue;
+ if (auth->auth->authnum == req->cred.flavour)
+ goto err;
+
+ }
+
+ auth = NULL;
+err:
+ if (auth)
+ return auth->auth;
+ else
+ return NULL;
+}
+
+rpcsvc_auth_t *
+nfs_rpcsvc_auth_get_handler (rpcsvc_request_t *req)
+{
+ rpcsvc_auth_t *auth = NULL;
+
+ auth = __nfs_rpcsvc_auth_get_handler (req);
+ if (auth)
+ goto ret;
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "No auth handler: %d",
+ req->cred.flavour);
+
+ /* The requested scheme was not available so fall back the to one
+ * scheme that will always be present.
+ */
+ req->cred.flavour = AUTH_NULL;
+ req->verf.flavour = AUTH_NULL;
+ auth = __nfs_rpcsvc_auth_get_handler (req);
+ret:
+ return auth;
+}
+
+
+int
+nfs_rpcsvc_auth_request_init (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ rpcsvc_auth_t *auth = NULL;
+
+ if (!req)
+ return -1;
+
+ auth = nfs_rpcsvc_auth_get_handler (req);
+ if (!auth)
+ goto err;
+ ret = 0;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth handler: %s", auth->authname);
+ if (!auth->authops->request_init)
+ ret = auth->authops->request_init (req, auth->authprivate);
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_authenticate (rpcsvc_request_t *req)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ rpcsvc_auth_t *auth = NULL;
+ int minauth = 0;
+
+ if (!req)
+ return ret;
+
+ minauth = nfs_rpcsvc_request_prog_minauth (req);
+ if (minauth > nfs_rpcsvc_request_cred_flavour (req)) {
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Auth too weak");
+ nfs_rpcsvc_request_set_autherr (req, AUTH_TOOWEAK);
+ goto err;
+ }
+
+ auth = nfs_rpcsvc_auth_get_handler (req);
+ if (!auth) {
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "No auth handler found");
+ goto err;
+ }
+
+ if (auth->authops->authenticate)
+ ret = auth->authops->authenticate (req, auth->authprivate);
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen)
+{
+ int count = 0;
+ int gen = RPCSVC_AUTH_REJECT;
+ int spec = RPCSVC_AUTH_REJECT;
+ int final = RPCSVC_AUTH_REJECT;
+ char *srchstr = NULL;
+ char *valstr = NULL;
+ gf_boolean_t boolval = _gf_false;
+ int ret = 0;
+
+ struct rpcsvc_auth_list *auth = NULL;
+ struct rpcsvc_auth_list *tmp = NULL;
+
+ if ((!svc) || (!autharr) || (!volname))
+ return -1;
+
+ memset (autharr, 0, arrlen * sizeof(int));
+ if (list_empty (&svc->authschemes)) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "No authentication!");
+ goto err;
+ }
+
+ list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) {
+ if (count >= arrlen)
+ break;
+
+ gen = gf_asprintf (&srchstr, "rpc-auth.%s", auth->name);
+ if (gen == -1) {
+ count = -1;
+ goto err;
+ }
+
+ gen = RPCSVC_AUTH_REJECT;
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (valstr, &boolval);
+ if (ret == 0) {
+ if (boolval == _gf_true)
+ gen = RPCSVC_AUTH_ACCEPT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ }
+
+ GF_FREE (srchstr);
+ spec = gf_asprintf (&srchstr, "rpc-auth.%s.%s", auth->name,
+ volname);
+ if (spec == -1) {
+ count = -1;
+ goto err;
+ }
+
+ spec = RPCSVC_AUTH_DONTCARE;
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (valstr, &boolval);
+ if (ret == 0) {
+ if (boolval == _gf_true)
+ spec = RPCSVC_AUTH_ACCEPT;
+ else
+ spec = RPCSVC_AUTH_REJECT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile"
+ "d to read auth val");
+ }
+
+ GF_FREE (srchstr);
+ final = nfs_rpcsvc_combine_gen_spec_volume_checks (gen, spec);
+ if (final == RPCSVC_AUTH_ACCEPT) {
+ autharr[count] = auth->auth->authnum;
+ ++count;
+ }
+ }
+
+err:
+ return count;
+}
+
+
+gid_t *
+nfs_rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen)
+{
+ if ((!req) || (!arrlen))
+ return NULL;
+
+ if (req->cred.flavour != AUTH_UNIX)
+ return NULL;
+
+ *arrlen = req->auxgidcount;
+ if (*arrlen == 0)
+ return NULL;
+
+ return &req->auxgids[0];
+}
+
diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c
new file mode 100644
index 000000000..0831cf49a
--- /dev/null
+++ b/xlators/nfs/lib/src/rpcsvc.c
@@ -0,0 +1,2923 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpcsvc.h"
+#include "rpc-socket.h"
+#include "dict.h"
+#include "logging.h"
+#include "byte-order.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+#include "list.h"
+#include "xdr-rpc.h"
+#include "iobuf.h"
+#include "globals.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <arpa/inet.h>
+#include <rpc/xdr.h>
+#include <fnmatch.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+
+#define nfs_rpcsvc_alloc_request(con, request) \
+ do { \
+ request = (rpcsvc_request_t *) mem_get ((con)->rxpool); \
+ memset (request, 0, sizeof (rpcsvc_request_t)); \
+ } while (0) \
+
+/* The generic event handler for every stage */
+void *
+nfs_rpcsvc_stage_proc (void *arg)
+{
+ rpcsvc_stage_t *stg = (rpcsvc_stage_t *)arg;
+
+ if (!stg)
+ return NULL;
+
+ event_dispatch (stg->eventpool);
+ return NULL;
+}
+
+
+rpcsvc_stage_t *
+nfs_rpcsvc_stage_init (rpcsvc_t *svc)
+{
+ rpcsvc_stage_t *stg = NULL;
+ int ret = -1;
+ size_t stacksize = RPCSVC_THREAD_STACK_SIZE;
+ pthread_attr_t stgattr;
+ unsigned int eventpoolsize = 0;
+
+ if (!svc)
+ return NULL;
+
+ stg = GF_CALLOC (1, sizeof(*stg), gf_common_mt_rpcsvc_stage_t);
+ if (!stg)
+ return NULL;
+
+ eventpoolsize = svc->memfactor * RPCSVC_EVENTPOOL_SIZE_MULT;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "event pool size: %d", eventpoolsize);
+ stg->eventpool = event_pool_new (eventpoolsize);
+ if (!stg->eventpool)
+ goto free_stg;
+
+ pthread_attr_init (&stgattr);
+ ret = pthread_attr_setstacksize (&stgattr, stacksize);
+ if (ret == EINVAL)
+ gf_log (GF_RPCSVC, GF_LOG_WARNING,
+ "Using default thread stack size");
+
+ ret = pthread_create (&stg->tid, &stgattr, nfs_rpcsvc_stage_proc,
+ (void *)stg);
+ if (ret != 0) {
+ ret = -1;
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Stage creation failed");
+ goto free_stg;
+ }
+
+ stg->svc = svc;
+ ret = 0;
+free_stg:
+ if (ret == -1) {
+ GF_FREE (stg);
+ stg = NULL;
+ }
+
+ return stg;
+}
+
+
+int
+nfs_rpcsvc_init_options (rpcsvc_t *svc, dict_t *options)
+{
+ char *optstr = NULL;
+ int ret = -1;
+
+ if ((!svc) || (!options))
+ return -1;
+
+ svc->memfactor = RPCSVC_DEFAULT_MEMFACTOR;
+
+ svc->register_portmap = _gf_true;
+ if (dict_get (options, "rpc.register-with-portmap")) {
+ ret = dict_get_str (options, "rpc.register-with-portmap",
+ &optstr);
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse "
+ "dict");
+ goto out;
+ }
+
+ ret = gf_string2boolean (optstr, &svc->register_portmap);
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse bool "
+ "string");
+ goto out;
+ }
+ }
+
+ if (!svc->register_portmap)
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Portmap registration "
+ "disabled");
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+/* The global RPC service initializer.
+ * Starts up the stages and then waits for RPC program registrations
+ * to come in.
+ */
+rpcsvc_t *
+nfs_rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options)
+{
+ rpcsvc_t *svc = NULL;
+ int ret = -1;
+
+ if ((!ctx) || (!options))
+ return NULL;
+
+ svc = GF_CALLOC (1, sizeof (*svc), gf_common_mt_rpcsvc_t);
+ if (!svc)
+ return NULL;
+
+ pthread_mutex_init (&svc->rpclock, NULL);
+ INIT_LIST_HEAD (&svc->stages);
+ INIT_LIST_HEAD (&svc->authschemes);
+ INIT_LIST_HEAD (&svc->allprograms);
+
+ ret = nfs_rpcsvc_init_options (svc, options);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init options");
+ goto free_svc;
+ }
+
+ ret = nfs_rpcsvc_auth_init (svc, options);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init "
+ "authentication");
+ goto free_svc;
+ }
+
+ ret = -1;
+ svc->defaultstage = nfs_rpcsvc_stage_init (svc);
+ if (!svc->defaultstage) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,"RPC service init failed.");
+ goto free_svc;
+ }
+ svc->options = options;
+ svc->ctx = ctx;
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC service inited.");
+
+ ret = 0;
+free_svc:
+ if (ret == -1) {
+ GF_FREE (svc);
+ svc = NULL;
+ }
+
+ return svc;
+}
+
+
+/* Once multi-threaded support is complete, we'll be able to round-robin
+ * the various incoming connections over the many available stages. This
+ * function selects one from among all the stages.
+ */
+rpcsvc_stage_t *
+nfs_rpcsvc_select_stage (rpcsvc_t *rpcservice)
+{
+ if (!rpcservice)
+ return NULL;
+
+ return rpcservice->defaultstage;
+}
+
+
+int
+nfs_rpcsvc_conn_peer_check_search (dict_t *options, char *pattern, char *clstr)
+{
+ int ret = -1;
+ char *addrtok = NULL;
+ char *addrstr = NULL;
+ char *svptr = NULL;
+
+ if ((!options) || (!clstr))
+ return -1;
+
+ if (!dict_get (options, pattern))
+ return -1;
+
+ ret = dict_get_str (options, pattern, &addrstr);
+ if (ret < 0) {
+ ret = -1;
+ goto err;
+ }
+
+ if (!addrstr) {
+ ret = -1;
+ goto err;
+ }
+
+ addrtok = strtok_r (addrstr, ",", &svptr);
+ while (addrtok) {
+
+ /* CASEFOLD not present on Solaris */
+#ifdef FNM_CASEFOLD
+ ret = fnmatch (addrtok, clstr, FNM_CASEFOLD);
+#else
+ ret = fnmatch (addrtok, clstr, 0);
+#endif
+ if (ret == 0)
+ goto err;
+
+ addrtok = strtok_r (NULL, ",", &svptr);
+ }
+
+ ret = -1;
+err:
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_peer_check_allow (dict_t *options, char *volname, char *clstr)
+{
+ int ret = RPCSVC_AUTH_DONTCARE;
+ char *srchstr = NULL;
+ char globalrule[] = "rpc-auth.addr.allow";
+
+ if ((!options) || (!clstr))
+ return ret;
+
+ /* If volname is NULL, then we're searching for the general rule to
+ * determine the current address in clstr is allowed or not for all
+ * subvolumes.
+ */
+ if (volname) {
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_DONTCARE;
+ goto out;
+ }
+ } else
+ srchstr = globalrule;
+
+ ret = nfs_rpcsvc_conn_peer_check_search (options, srchstr, clstr);
+ if (volname)
+ GF_FREE (srchstr);
+
+ if (ret == 0)
+ ret = RPCSVC_AUTH_ACCEPT;
+ else
+ ret = RPCSVC_AUTH_DONTCARE;
+out:
+ return ret;
+}
+
+int
+nfs_rpcsvc_conn_peer_check_reject (dict_t *options, char *volname, char *clstr)
+{
+ int ret = RPCSVC_AUTH_DONTCARE;
+ char *srchstr = NULL;
+ char generalrule[] = "rpc-auth.addr.reject";
+
+ if ((!options) || (!clstr))
+ return ret;
+
+ if (volname) {
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.reject",
+ volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_REJECT;
+ goto out;
+ }
+ } else
+ srchstr = generalrule;
+
+ ret = nfs_rpcsvc_conn_peer_check_search (options, srchstr, clstr);
+ if (volname)
+ GF_FREE (srchstr);
+
+ if (ret == 0)
+ ret = RPCSVC_AUTH_REJECT;
+ else
+ ret = RPCSVC_AUTH_DONTCARE;
+out:
+ return ret;
+}
+
+
+/* This function tests the results of the allow rule and the reject rule to
+ * combine them into a single result that can be used to determine if the
+ * connection should be allowed to proceed.
+ * Heres the test matrix we need to follow in this function.
+ *
+ * A - Allow, the result of the allow test. Never returns R.
+ * R - Reject, result of the reject test. Never returns A.
+ * Both can return D or dont care if no rule was given.
+ *
+ * | @allow | @reject | Result |
+ * | A | R | R |
+ * | D | D | D |
+ * | A | D | A |
+ * | D | R | R |
+ */
+int
+nfs_rpcsvc_combine_allow_reject_volume_check (int allow, int reject)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ /* If allowed rule allows but reject rule rejects, we stay cautious
+ * and reject. */
+ if ((allow == RPCSVC_AUTH_ACCEPT) && (reject == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ /* if both are dont care, that is user did not specify for either allow
+ * or reject, we leave it up to the general rule to apply, in the hope
+ * that there is one.
+ */
+ else if ((allow == RPCSVC_AUTH_DONTCARE) &&
+ (reject == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_DONTCARE;
+ /* If one is dont care, the other one applies. */
+ else if ((allow == RPCSVC_AUTH_ACCEPT) &&
+ (reject == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((allow == RPCSVC_AUTH_DONTCARE) &&
+ (reject == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+/* Combines the result of the general rule test against, the specific rule
+ * to determine final permission for the client's address.
+ *
+ * | @gen | @spec | Result |
+ * | A | A | A |
+ * | A | R | R |
+ * | A | D | A |
+ * | D | A | A |
+ * | D | R | R |
+ * | D | D | D |
+ * | R | A | A |
+ * | R | D | R |
+ * | R | R | R |
+ */
+int
+nfs_rpcsvc_combine_gen_spec_addr_checks (int gen, int spec)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_DONTCARE;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+
+/* Combines the result of the general rule test against, the specific rule
+ * to determine final test for the connection coming in for a given volume.
+ *
+ * | @gen | @spec | Result |
+ * | A | A | A |
+ * | A | R | R |
+ * | A | D | A |
+ * | D | A | A |
+ * | D | R | R |
+ * | D | D | R |, special case, we intentionally disallow this.
+ * | R | A | A |
+ * | R | D | R |
+ * | R | R | R |
+ */
+int
+nfs_rpcsvc_combine_gen_spec_volume_checks (int gen, int spec)
+{
+ int final = RPCSVC_AUTH_REJECT;
+
+ if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+ /* On no rule, we reject. */
+ else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT))
+ final = RPCSVC_AUTH_ACCEPT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE))
+ final = RPCSVC_AUTH_REJECT;
+ else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT))
+ final = RPCSVC_AUTH_REJECT;
+
+ return final;
+}
+
+
+int
+nfs_rpcsvc_conn_peer_check_name (dict_t *options, char *volname,
+ rpcsvc_conn_t *conn)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ int aret = RPCSVC_AUTH_REJECT;
+ int rjret = RPCSVC_AUTH_REJECT;
+ char clstr[RPCSVC_PEER_STRLEN];
+
+ if (!conn)
+ return ret;
+
+ ret = nfs_rpcsvc_conn_peername (conn, clstr, RPCSVC_PEER_STRLEN);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "
+ "%s", gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ aret = nfs_rpcsvc_conn_peer_check_allow (options, volname, clstr);
+ rjret = nfs_rpcsvc_conn_peer_check_reject (options, volname, clstr);
+
+ ret = nfs_rpcsvc_combine_allow_reject_volume_check (aret, rjret);
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_peer_check_addr (dict_t *options, char *volname,
+ rpcsvc_conn_t *conn)
+{
+ int ret = RPCSVC_AUTH_REJECT;
+ int aret = RPCSVC_AUTH_DONTCARE;
+ int rjret = RPCSVC_AUTH_REJECT;
+ char clstr[RPCSVC_PEER_STRLEN];
+
+ if (!conn)
+ return ret;
+
+ ret = nfs_rpcsvc_conn_peeraddr (conn, clstr, RPCSVC_PEER_STRLEN, NULL,
+ 0);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "
+ "%s", gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ aret = nfs_rpcsvc_conn_peer_check_allow (options, volname, clstr);
+ rjret = nfs_rpcsvc_conn_peer_check_reject (options, volname, clstr);
+
+ ret = nfs_rpcsvc_combine_allow_reject_volume_check (aret, rjret);
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_check_volume_specific (dict_t *options, char *volname,
+ rpcsvc_conn_t *conn)
+{
+ int namechk = RPCSVC_AUTH_REJECT;
+ int addrchk = RPCSVC_AUTH_REJECT;
+ gf_boolean_t namelookup = _gf_true;
+ char *namestr = NULL;
+ int ret = 0;
+
+ if ((!options) || (!volname) || (!conn))
+ return RPCSVC_AUTH_REJECT;
+
+ /* Enabled by default */
+ if ((dict_get (options, "rpc-auth.addr.namelookup"))) {
+ ret = dict_get_str (options, "rpc-auth.addr.namelookup"
+ , &namestr);
+ if (ret == 0)
+ ret = gf_string2boolean (namestr, &namelookup);
+ }
+
+ /* We need two separate checks because the rules with addresses in them
+ * can be network addresses which can be general and names can be
+ * specific which will over-ride the network address rules.
+ */
+ if (namelookup)
+ namechk = nfs_rpcsvc_conn_peer_check_name (options, volname,
+ conn);
+ addrchk = nfs_rpcsvc_conn_peer_check_addr (options, volname, conn);
+
+ if (namelookup)
+ ret = nfs_rpcsvc_combine_gen_spec_addr_checks (addrchk,
+ namechk);
+ else
+ ret = addrchk;
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_check_volume_general (dict_t *options, rpcsvc_conn_t *conn)
+{
+ int addrchk = RPCSVC_AUTH_REJECT;
+ int namechk = RPCSVC_AUTH_REJECT;
+ gf_boolean_t namelookup = _gf_true;
+ char *namestr = NULL;
+ int ret = 0;
+
+ if ((!options) || (!conn))
+ return RPCSVC_AUTH_REJECT;
+
+ /* Enabled by default */
+ if ((dict_get (options, "rpc-auth.addr.namelookup"))) {
+ ret = dict_get_str (options, "rpc-auth.addr.namelookup"
+ , &namestr);
+ if (ret == 0)
+ ret = gf_string2boolean (namestr, &namelookup);
+ }
+
+ /* We need two separate checks because the rules with addresses in them
+ * can be network addresses which can be general and names can be
+ * specific which will over-ride the network address rules.
+ */
+ if (namelookup)
+ namechk = nfs_rpcsvc_conn_peer_check_name (options, NULL, conn);
+ addrchk = nfs_rpcsvc_conn_peer_check_addr (options, NULL, conn);
+
+ if (namelookup)
+ ret = nfs_rpcsvc_combine_gen_spec_addr_checks (addrchk,
+ namechk);
+ else
+ ret = addrchk;
+
+ return ret;
+}
+
+int
+nfs_rpcsvc_conn_peer_check (dict_t *options, char *volname, rpcsvc_conn_t *conn)
+{
+ int general_chk = RPCSVC_AUTH_REJECT;
+ int specific_chk = RPCSVC_AUTH_REJECT;
+
+ if ((!options) || (!volname) || (!conn))
+ return RPCSVC_AUTH_REJECT;
+
+ general_chk = nfs_rpcsvc_conn_check_volume_general (options, conn);
+ specific_chk = nfs_rpcsvc_conn_check_volume_specific (options, volname,
+ conn);
+
+ return nfs_rpcsvc_combine_gen_spec_volume_checks (general_chk,
+ specific_chk);
+}
+
+
+char *
+nfs_rpcsvc_volume_allowed (dict_t *options, char *volname)
+{
+ char globalrule[] = "rpc-auth.addr.allow";
+ char *srchstr = NULL;
+ char *addrstr = NULL;
+ int ret = -1;
+
+ if ((!options) || (!volname))
+ return NULL;
+
+ ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ goto out;
+ }
+
+ if (!dict_get (options, srchstr)) {
+ GF_FREE (srchstr);
+ srchstr = globalrule;
+ ret = dict_get_str (options, srchstr, &addrstr);
+ } else
+ ret = dict_get_str (options, srchstr, &addrstr);
+
+out:
+ return addrstr;
+}
+
+
+/* Initialize the core of a connection */
+rpcsvc_conn_t *
+nfs_rpcsvc_conn_init (rpcsvc_t *svc, int sockfd)
+{
+ rpcsvc_conn_t *conn = NULL;
+ int ret = -1;
+ unsigned int poolcount = 0;
+
+ conn = GF_CALLOC (1, sizeof(*conn), gf_common_mt_rpcsvc_conn_t);
+ if (!conn) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "memory allocation failed");
+ return NULL;
+ }
+
+ conn->sockfd = sockfd;
+ INIT_LIST_HEAD (&conn->txbufs);
+ poolcount = RPCSVC_POOLCOUNT_MULT * svc->memfactor;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "tx pool: %d", poolcount);
+ conn->txpool = mem_pool_new (rpcsvc_txbuf_t, poolcount);
+ if (!conn->txpool) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed");
+ goto free_conn;
+ }
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "rx pool: %d", poolcount);
+ conn->rxpool = mem_pool_new (rpcsvc_request_t, poolcount);
+ if (!conn->rxpool) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed");
+ goto free_txp;
+ }
+
+ /* Cannot consider a connection connected unless the user of this
+ * connection decides it is ready to use. It is possible that we have
+ * to free this connection soon after. That free will not happpen
+ * unless the state is disconnected.
+ */
+ conn->connstate = RPCSVC_CONNSTATE_DISCONNECTED;
+ pthread_mutex_init (&conn->connlock, NULL);
+ conn->connref = 0;
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New connection inited: sockfd: %d",
+ sockfd);
+
+ ret = 0;
+free_txp:
+ if (ret == -1)
+ mem_pool_destroy (conn->txpool);
+
+free_conn:
+ if (ret == -1) {
+ GF_FREE (conn);
+ conn = NULL;
+ }
+
+ return conn;
+}
+
+
+void
+nfs_rpcsvc_conn_destroy (rpcsvc_conn_t *conn)
+{
+ mem_pool_destroy (conn->txpool);
+ mem_pool_destroy (conn->rxpool);
+
+ /* Need to destory record state, txlists etc. */
+ GF_FREE (conn);
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection destroyed");
+}
+
+
+int
+__nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn)
+{
+ --conn->connref;
+ return conn->connref;
+}
+
+
+void
+__nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn)
+{
+ if (!conn)
+ return;
+
+ if ((conn->stage) && (conn->stage->eventpool)) {
+ event_unregister (conn->stage->eventpool, conn->sockfd,
+ conn->eventidx);
+ }
+
+ if (nfs_rpcsvc_conn_check_active (conn)) {
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection de-activated:"
+ " sockfd: %d", conn->sockfd);
+ conn->connstate = RPCSVC_CONNSTATE_DISCONNECTED;
+ }
+
+ if (conn->sockfd != -1) {
+ close (conn->sockfd);
+ conn->sockfd = -1;
+ }
+}
+
+
+void
+nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn)
+{
+ int ref = 0;
+
+ if (!conn)
+ return;
+
+ pthread_mutex_lock (&conn->connlock);
+ {
+ __nfs_rpcsvc_conn_deinit (conn);
+ ref = __nfs_rpcsvc_conn_unref (conn);
+ }
+ pthread_mutex_unlock (&conn->connlock);
+
+ if (ref == 0)
+ nfs_rpcsvc_conn_destroy (conn);
+
+ return;
+}
+
+
+void
+nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn)
+{
+ int ref = 0;
+ if (!conn)
+ return;
+
+ pthread_mutex_lock (&conn->connlock);
+ {
+ ref = __nfs_rpcsvc_conn_unref (conn);
+ }
+ pthread_mutex_unlock (&conn->connlock);
+
+ if (ref == 0)
+ nfs_rpcsvc_conn_destroy (conn);
+}
+
+
+int
+nfs_rpcsvc_conn_active (rpcsvc_conn_t *conn)
+{
+ int status = 0;
+
+ if (!conn)
+ return 0;
+
+ pthread_mutex_lock (&conn->connlock);
+ {
+ status = nfs_rpcsvc_conn_check_active (conn);
+ }
+ pthread_mutex_unlock (&conn->connlock);
+
+ return status;
+}
+
+
+
+void
+nfs_rpcsvc_conn_ref (rpcsvc_conn_t *conn)
+{
+ if (!conn)
+ return;
+
+ pthread_mutex_lock (&conn->connlock);
+ {
+ ++conn->connref;
+ }
+ pthread_mutex_unlock (&conn->connlock);
+
+ return;
+}
+
+
+void
+nfs_rpcsvc_conn_state_init (rpcsvc_conn_t *conn)
+{
+ if (!conn)
+ return;
+
+ ++conn->connref;
+ conn->connstate = RPCSVC_CONNSTATE_CONNECTED;
+}
+
+/* Builds a rpcsvc_conn_t with the aim of listening on it.
+ */
+rpcsvc_conn_t *
+nfs_rpcsvc_conn_listen_init (rpcsvc_t *svc, rpcsvc_program_t *newprog)
+{
+ rpcsvc_conn_t *conn = NULL;
+ int sock = -1;
+
+ if (!newprog)
+ return NULL;
+
+ sock = nfs_rpcsvc_socket_listen (newprog->progaddrfamily,
+ newprog->proghost, newprog->progport);
+ if (sock == -1)
+ goto err;
+
+ conn = nfs_rpcsvc_conn_init (svc, sock);
+ if (!conn)
+ goto sock_close_err;
+
+ nfs_rpcsvc_conn_state_init (conn);
+sock_close_err:
+ if (!conn)
+ close (sock);
+
+err:
+ return conn;
+}
+
+void
+nfs_rpcsvc_record_init (rpcsvc_record_state_t *rs, struct iobuf_pool *pool)
+{
+ if (!rs)
+ return;
+
+ rs->state = RPCSVC_READ_FRAGHDR;
+ rs->vecstate = 0;
+ rs->remainingfraghdr = RPCSVC_FRAGHDR_SIZE;
+ rs->remainingfrag = 0;
+ rs->fragsize = 0;
+ rs->recordsize = 0;
+ rs->islastfrag = 0;
+
+ /* If the rs preserves a ref to the iob used by the previous request,
+ * we must unref it here to prevent memory leak.
+ * If program actor wanted to keep that memory around, it should've
+ * refd it on entry into the actor.
+ */
+ if (rs->activeiob)
+ iobuf_unref (rs->activeiob);
+
+ if (rs->vectoriob) {
+ iobuf_unref (rs->vectoriob);
+ rs->vectoriob = NULL;
+ }
+
+ rs->activeiob = iobuf_get (pool);
+ rs->fragcurrent = iobuf_ptr (rs->activeiob);
+
+ memset (rs->fragheader, 0, RPCSVC_FRAGHDR_SIZE);
+ rs->hdrcurrent = &rs->fragheader[0];
+
+}
+
+
+int
+nfs_rpcsvc_conn_privport_check (rpcsvc_t *svc, char *volname,
+ rpcsvc_conn_t *conn)
+{
+ struct sockaddr_in sa;
+ int ret = RPCSVC_AUTH_REJECT;
+ socklen_t sasize = sizeof (sa);
+ char *srchstr = NULL;
+ char *valstr = NULL;
+ int globalinsecure = RPCSVC_AUTH_REJECT;
+ int exportinsecure = RPCSVC_AUTH_DONTCARE;
+ uint16_t port = 0;
+ gf_boolean_t insecure = _gf_false;
+
+ if ((!svc) || (!volname) || (!conn))
+ return ret;
+
+ ret = nfs_rpcsvc_conn_peeraddr (conn, NULL, 0, (struct sockaddr *)&sa,
+ sasize);
+ if (ret != 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s",
+ gai_strerror (ret));
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ port = ntohs (sa.sin_port);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port);
+ /* If the port is already a privileged one, dont bother with checking
+ * options.
+ */
+ if (port <= 1024) {
+ ret = RPCSVC_AUTH_ACCEPT;
+ goto err;
+ }
+
+ /* Disabled by default */
+ if ((dict_get (svc->options, "rpc-auth.ports.insecure"))) {
+ ret = dict_get_str (svc->options, "rpc-auth.ports.insecure"
+ , &srchstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (srchstr, &insecure);
+ if (ret == 0) {
+ if (insecure == _gf_true)
+ globalinsecure = RPCSVC_AUTH_ACCEPT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ }
+
+ /* Disabled by default */
+ ret = gf_asprintf (&srchstr, "rpc-auth.ports.%s.insecure", volname);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed");
+ ret = RPCSVC_AUTH_REJECT;
+ goto err;
+ }
+
+ if (dict_get (svc->options, srchstr)) {
+ ret = dict_get_str (svc->options, srchstr, &valstr);
+ if (ret == 0) {
+ ret = gf_string2boolean (srchstr, &insecure);
+ if (ret == 0) {
+ if (insecure == _gf_true)
+ exportinsecure = RPCSVC_AUTH_ACCEPT;
+ else
+ exportinsecure = RPCSVC_AUTH_REJECT;
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to"
+ " read rpc-auth.ports.insecure value");
+ }
+
+ ret = nfs_rpcsvc_combine_gen_spec_volume_checks (globalinsecure,
+ exportinsecure);
+ if (ret == RPCSVC_AUTH_ACCEPT)
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port allowed");
+ else
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port not"
+ " allowed");
+
+err:
+ return ret;
+}
+
+/* Inits a rpcsvc_conn_t after accepting the connection.
+ */
+rpcsvc_conn_t *
+nfs_rpcsvc_conn_accept_init (rpcsvc_t *svc, int listenfd)
+{
+ rpcsvc_conn_t *newconn = NULL;
+ int sock = -1;
+ int ret = -1;
+
+ sock = nfs_rpcsvc_socket_accept (listenfd);
+ if (sock == -1)
+ goto err;
+
+ newconn = nfs_rpcsvc_conn_init (svc, sock);
+ if (!newconn) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init conn object");
+ ret = -1;
+ goto err;
+ }
+
+ nfs_rpcsvc_record_init (&newconn->rstate, svc->ctx->iobuf_pool);
+ nfs_rpcsvc_conn_state_init (newconn);
+ ret = 0;
+
+err:
+ if (ret == -1)
+ close (sock);
+
+ return newconn;
+}
+
+
+/* Once the connection has been created, we need to associate it with
+ * a stage so that the selected stage will handle the event on this connection.
+ * This function also allows the caller to decide which handler should
+ * be executed in the context of the stage, and also which specific events
+ * should be handed to the handler when running in this particular stage.
+ */
+int
+nfs_rpcsvc_stage_conn_associate (rpcsvc_stage_t *stg, rpcsvc_conn_t *conn,
+ event_handler_t handler, void *data)
+{
+ int ret = -1;
+
+ if ((!stg) || (!conn))
+ return -1;
+
+ conn->stage = stg;
+ conn->eventidx = event_register (stg->eventpool, conn->sockfd, handler,
+ data, 1, 0);
+ if (conn->eventidx == -1)
+ goto err;
+
+ ret = 0;
+err:
+ return ret;
+}
+
+
+/* Depending on the state we're in, return the size of the next read request. */
+size_t
+nfs_rpcsvc_record_read_size (rpcsvc_record_state_t *rs)
+{
+ size_t toread = -1;
+
+ if (!rs)
+ return -1;
+
+ if (nfs_rpcsvc_record_readfraghdr (rs))
+ toread = rs->remainingfraghdr;
+ else if (nfs_rpcsvc_record_readfrag (rs))
+ toread = rs->remainingfrag;
+ else
+ toread = RPCSVC_CONN_READ;
+
+ return toread;
+}
+
+
+uint32_t
+nfs_rpcsvc_record_extract_fraghdr (char *fraghdr)
+{
+ uint32_t hdr = 0;
+ if (!fraghdr)
+ return 0;
+
+ memcpy ((void *)&hdr, fraghdr, sizeof (hdr));
+
+ hdr = ntohl (hdr);
+ return hdr;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_read_complete_fraghdr (rpcsvc_record_state_t *rs,
+ ssize_t dataread)
+{
+ uint32_t remhdr = 0;
+ char *fraghdrstart = NULL;
+ uint32_t fraghdr = 0;
+
+ fraghdrstart = &rs->fragheader[0];
+ remhdr = rs->remainingfraghdr;
+ fraghdr = nfs_rpcsvc_record_extract_fraghdr (fraghdrstart);
+ rs->fragsize = RPCSVC_FRAGSIZE (fraghdr);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Received fragment size: %d",
+ rs->fragsize);
+ if (nfs_rpcsvc_record_vectored (rs)) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC header,"
+ " remaining: %d", RPCSVC_BARERPC_MSGSZ);
+ rs->remainingfrag = RPCSVC_BARERPC_MSGSZ;
+ } else {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Regular RPC header,"
+ " remaining: %d", rs->fragsize);
+ rs->remainingfrag = rs->fragsize;
+ }
+
+ rs->state = RPCSVC_READ_FRAG;
+ dataread -= remhdr;
+ rs->remainingfraghdr -= remhdr;
+ rs->islastfrag = RPCSVC_LASTFRAG (fraghdr);
+
+ return dataread;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_read_partial_fraghdr (rpcsvc_record_state_t *rs,
+ ssize_t dataread)
+{
+
+ /* In case we got less than even the remaining header size,
+ * we need to consume it all and wait for remaining frag hdr
+ * bytes to come in.
+ */
+ rs->remainingfraghdr -= dataread;
+ nfs_rpcsvc_record_update_currenthdr (rs, dataread);
+ dataread = 0;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment header remaining: %d",
+ rs->remainingfraghdr);
+
+ return dataread;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_update_fraghdr (rpcsvc_record_state_t *rs, ssize_t dataread)
+{
+ if ((!rs) || (dataread <= 0))
+ return -1;
+
+ /* Why are we even here, we're not supposed to be in the fragment
+ * header processing state.
+ */
+ if (!nfs_rpcsvc_record_readfraghdr(rs)) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent"
+ ": request to update frag header when state is not"
+ "RPCSVC_READ_FRAGHDR");
+ return -1;
+ }
+
+ /* Again, if header has been read then the state member above should've
+ * been different, this is crazy. We should not be here.
+ */
+ if (rs->remainingfraghdr == 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent"
+ ": request to update frag header when frag header"
+ "remaining is 0.");
+ return -1;
+ }
+
+ /* We've definitely got the full header now and may be even more. */
+ if (dataread >= rs->remainingfraghdr)
+ dataread = nfs_rpcsvc_record_read_complete_fraghdr (rs,
+ dataread);
+ else
+ dataread = nfs_rpcsvc_record_read_partial_fraghdr (rs,
+ dataread);
+
+ return dataread;
+}
+
+ssize_t
+nfs_rpcsvc_record_read_complete_frag (rpcsvc_record_state_t *rs,
+ ssize_t dataread)
+{
+ uint32_t remfrag;
+
+ /* Since the frag is now complete, change the state to the next
+ * one, i.e. to read the header of the next fragment.
+ */
+ remfrag = rs->remainingfrag;
+ rs->state = RPCSVC_READ_FRAGHDR;
+ dataread -= remfrag;
+
+ /* This will be 0 now. */
+ rs->remainingfrag -= remfrag;
+
+ /* Now that the fragment is complete, we must update the
+ * record size. Recall that fragsize was got from the frag
+ * header.
+ */
+ rs->recordsize += rs->fragsize;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment remaining: %d",
+ rs->remainingfrag);
+
+ return dataread;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_read_partial_frag (rpcsvc_record_state_t *rs,
+ ssize_t dataread)
+{
+ /* Just take whatever has come through the current network buffer. */
+ rs->remainingfrag -= dataread;
+
+ nfs_rpcsvc_record_update_currentfrag (rs, dataread);
+ /* Since we know we're consuming the whole buffer from dataread
+ * simply setting to 0 zero is fine.
+ */
+ dataread = 0;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment remaining: %d",
+ rs->remainingfrag);
+ return dataread;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_update_frag (rpcsvc_record_state_t *rs, ssize_t dataread)
+{
+ if ((!rs) || (dataread <= 0))
+ return -1;
+
+ if (!nfs_rpcsvc_record_readfrag (rs)) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent"
+ ": request to update fragment when record state is not"
+ "RPCSVC_READ_FRAG.");
+ return -1;
+ }
+
+ if (rs->remainingfrag == 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent"
+ ": request to update fragment when there is no fragment"
+ " data remaining to be read.");
+ return -1;
+ }
+
+ /* We've read in more data than the current fragment requires. */
+ if (dataread >= rs->remainingfrag)
+ dataread = nfs_rpcsvc_record_read_complete_frag (rs, dataread);
+ else
+ dataread = nfs_rpcsvc_record_read_partial_frag (rs, dataread);
+
+ return dataread;
+}
+
+
+
+/* This needs to change to returning errors, since
+ * we need to return RPC specific error messages when some
+ * of the pointers below are NULL.
+ */
+int
+__nfs_rpcsvc_program_actor (rpcsvc_request_t *req, rpcsvc_program_t **prg)
+{
+ rpcsvc_program_t *program = NULL;
+ int ret = PROG_UNAVAIL;
+ rpcsvc_actor_t *actor = NULL;
+ struct list_head *prglist = NULL;
+
+ if (!req)
+ return ret;
+
+ prglist = &((nfs_rpcsvc_request_service (req))->allprograms);
+ if (list_empty (prglist))
+ goto err;
+
+ list_for_each_entry (program, prglist, proglist) {
+ ret = PROG_UNAVAIL;
+ if (req->prognum != program->prognum)
+ continue;
+
+ if (!program->actors) {
+ ret = SYSTEM_ERR;
+ goto err;
+ }
+
+ ret = PROG_MISMATCH;
+ if (req->progver != program->progver)
+ continue;
+
+ ret = PROC_UNAVAIL;
+ if ((req->procnum < 0) || (req->procnum >= program->numactors))
+ goto err;
+
+ actor = &program->actors[req->procnum];
+ if (!actor->actor) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC Program procedure"
+ " not defined");
+ actor = NULL;
+ goto err;
+ } else {
+ ret = SUCCESS;
+ break;
+ }
+ }
+
+ *prg = program;
+err:
+ switch (ret) {
+
+ case PROG_UNAVAIL:
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC program not available");
+ break;
+
+ case PROG_MISMATCH:
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC program version "
+ "not available");
+ break;
+
+ case PROC_UNAVAIL:
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC Program procedure"
+ " not available");
+ break;
+
+ case SUCCESS:
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "RPC Program found");
+ break;
+
+ default:
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "System error");
+ break;
+ }
+
+ /* If the error is not RPC_MISMATCH, we consider the call as accepted
+ * since we are not handling authentication failures for now.
+ */
+ req->rpc_stat = MSG_ACCEPTED;
+ req->rpc_err = ret;
+
+ return ret;
+}
+
+/* This needs to change to returning errors, since
+ * we need to return RPC specific error messages when some
+ * of the pointers below are NULL.
+ */
+rpcsvc_actor_t *
+nfs_rpcsvc_program_actor (rpcsvc_request_t *req)
+{
+ int err = SYSTEM_ERR;
+ rpcsvc_actor_t *actor = NULL;
+
+ if (!req)
+ goto err;
+
+ actor = &req->program->actors[req->procnum];
+ err = SUCCESS;
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Actor found: %s - %s",
+ req->program->progname, actor->procname);
+err:
+ if (req)
+ req->rpc_err = err;
+
+ return actor;
+}
+
+
+rpcsvc_txbuf_t *
+nfs_rpcsvc_init_txbuf (rpcsvc_conn_t *conn, struct iovec msg, struct iobuf *iob,
+ struct iobref *iobref, int txflags)
+{
+ rpcsvc_txbuf_t *txbuf = NULL;
+
+ txbuf = (rpcsvc_txbuf_t *) mem_get(conn->txpool);
+ if (!txbuf) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get txbuf");
+ return NULL;
+ }
+
+ memset (txbuf, 0, sizeof (*txbuf));
+ INIT_LIST_HEAD (&txbuf->txlist);
+ txbuf->buf = msg;
+
+ /* If it was required, this iob must've been ref'd already
+ * so I dont have to bother here.
+ */
+ txbuf->iob = iob;
+ txbuf->iobref = iobref;
+ txbuf->offset = 0;
+ txbuf->txbehave = txflags;
+
+ return txbuf;
+}
+
+
+int
+nfs_rpcsvc_conn_append_txlist (rpcsvc_conn_t *conn, struct iovec msg,
+ struct iobuf *iob, int txflags)
+{
+ rpcsvc_txbuf_t *txbuf = NULL;
+
+ if ((!conn) || (!msg.iov_base) || (!iob))
+ return -1;
+
+ txbuf = nfs_rpcsvc_init_txbuf (conn, msg, iob, NULL, txflags);
+ if (!txbuf)
+ return -1;
+
+ list_add_tail (&txbuf->txlist, &conn->txbufs);
+ return 0;
+}
+
+
+void
+nfs_rpcsvc_set_lastfrag (uint32_t *fragsize) {
+ (*fragsize) |= 0x80000000U;
+}
+
+void
+nfs_rpcsvc_set_frag_header_size (uint32_t size, char *haddr)
+{
+ size = htonl (size);
+ memcpy (haddr, &size, sizeof (size));
+}
+
+void
+nfs_rpcsvc_set_last_frag_header_size (uint32_t size, char *haddr)
+{
+ nfs_rpcsvc_set_lastfrag (&size);
+ nfs_rpcsvc_set_frag_header_size (size, haddr);
+}
+
+
+/* Given the RPC reply structure and the payload handed by the RPC program,
+ * encode the RPC record header into the buffer pointed by recordstart.
+ */
+struct iovec
+nfs_rpcsvc_record_build_header (char *recordstart, size_t rlen,
+ struct rpc_msg reply, size_t payload)
+{
+ struct iovec replyhdr;
+ struct iovec txrecord = {0, 0};
+ size_t fraglen = 0;
+ int ret = -1;
+
+ /* After leaving aside the 4 bytes for the fragment header, lets
+ * encode the RPC reply structure into the buffer given to us.
+ */
+ ret = nfs_rpc_reply_to_xdr (&reply,(recordstart + RPCSVC_FRAGHDR_SIZE),
+ rlen, &replyhdr);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to create RPC reply");
+ goto err;
+ }
+
+ fraglen = payload + replyhdr.iov_len;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Reply fraglen %zu, payload: %zu, "
+ "rpc hdr: %zu", fraglen, payload, replyhdr.iov_len);
+
+ /* Since we're not spreading RPC records over mutiple fragments
+ * we just set this fragment as the first and last fragment for this
+ * record.
+ */
+ nfs_rpcsvc_set_last_frag_header_size (fraglen, recordstart);
+
+ /* Even though the RPC record starts at recordstart+RPCSVC_FRAGHDR_SIZE
+ * we need to transmit the record with the fragment header, which starts
+ * at recordstart.
+ */
+ txrecord.iov_base = recordstart;
+
+ /* Remember, this is only the vec for the RPC header and does not
+ * include the payload above. We needed the payload only to calculate
+ * the size of the full fragment. This size is sent in the fragment
+ * header.
+ */
+ txrecord.iov_len = RPCSVC_FRAGHDR_SIZE + replyhdr.iov_len;
+
+err:
+ return txrecord;
+}
+
+
+int
+nfs_rpcsvc_conn_submit (rpcsvc_conn_t *conn, struct iovec hdr,
+ struct iobuf *hdriob, struct iovec msgvec,
+ struct iobuf *msgiob)
+{
+ int ret = -1;
+
+ if ((!conn) || (!hdr.iov_base) || (!hdriob))
+ return -1;
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx Header: %zu, payload: %zu",
+ hdr.iov_len, msgvec.iov_len);
+ /* Now that we have both the RPC and Program buffers in xdr format
+ * lets hand it to the transmission layer.
+ */
+ pthread_mutex_lock (&conn->connlock);
+ {
+ if (!nfs_rpcsvc_conn_check_active (conn)) {
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection inactive");
+ goto unlock_err;
+ }
+
+ ret = nfs_rpcsvc_conn_append_txlist (conn, hdr, hdriob,
+ RPCSVC_TXB_FIRST);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to append "
+ "header to transmission list");
+ goto unlock_err;
+ }
+
+ /* It is possible that this RPC reply is an error reply. In that
+ * case we might not have been handed a payload.
+ */
+ ret = 0;
+ if (msgiob)
+ ret = nfs_rpcsvc_conn_append_txlist (conn, msgvec,
+ msgiob,
+ RPCSVC_TXB_LAST);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to append"
+ " payload to transmission list");
+ goto unlock_err;
+ }
+ }
+unlock_err:
+ pthread_mutex_unlock (&conn->connlock);
+
+ if (ret == -1)
+ goto err;
+
+ /* Tell event pool, we're interested in poll_out to trigger flush
+ * of our tx buffers.
+ */
+ conn->eventidx = event_select_on (conn->stage->eventpool, conn->sockfd,
+ conn->eventidx, -1, 1);
+ ret = 0;
+err:
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_fill_reply (rpcsvc_request_t *req, struct rpc_msg *reply)
+{
+ rpcsvc_program_t *prog = NULL;
+ if ((!req) || (!reply))
+ return -1;
+
+ prog = nfs_rpcsvc_request_program (req);
+ nfs_rpc_fill_empty_reply (reply, req->xid);
+
+ if (req->rpc_stat == MSG_DENIED)
+ nfs_rpc_fill_denied_reply (reply, req->rpc_err, req->auth_err);
+ else if (req->rpc_stat == MSG_ACCEPTED) {
+ if (!prog)
+ nfs_rpc_fill_accepted_reply (reply, req->rpc_err, 0, 0,
+ req->verf.flavour,
+ req->verf.datalen,
+ req->verf.authdata);
+ else
+ nfs_rpc_fill_accepted_reply (reply, req->rpc_err,
+ prog->proglowvers,
+ prog->proghighvers,
+ req->verf.flavour,
+ req->verf.datalen,
+ req->verf.authdata);
+
+ } else
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Invalid rpc_stat value");
+
+ return 0;
+}
+
+
+/* Given a request and the reply payload, build a reply and encodes the reply
+ * into a record header. This record header is encoded into the vector pointed
+ * to be recbuf.
+ * msgvec is the buffer that points to the payload of the RPC program.
+ * This buffer can be NULL, if an RPC error reply is being constructed.
+ * The only reason it is needed here is that in case the buffer is provided,
+ * we should account for the length of that buffer in the RPC fragment header.
+ */
+struct iobuf *
+nfs_rpcsvc_record_build_record (rpcsvc_request_t *req, size_t payload,
+ struct iovec *recbuf)
+{
+ struct rpc_msg reply;
+ struct iobuf *replyiob = NULL;
+ char *record = NULL;
+ struct iovec recordhdr = {0, };
+ size_t pagesize = 0;
+ rpcsvc_conn_t *conn = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if ((!req) || (!req->conn) || (!recbuf))
+ return NULL;
+
+ /* First, try to get a pointer into the buffer which the RPC
+ * layer can use.
+ */
+ conn = req->conn;
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ replyiob = iobuf_get (svc->ctx->iobuf_pool);
+ pagesize = iobpool_pagesize ((struct iobuf_pool *)svc->ctx->iobuf_pool);
+ if (!replyiob) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get iobuf");
+ goto err_exit;
+ }
+
+ record = iobuf_ptr (replyiob); /* Now we have it. */
+
+ /* Fill the rpc structure and XDR it into the buffer got above. */
+ nfs_rpcsvc_fill_reply (req, &reply);
+ recordhdr = nfs_rpcsvc_record_build_header (record, pagesize, reply,
+ payload);
+ if (!recordhdr.iov_base) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to build record "
+ " header");
+ iobuf_unref (replyiob);
+ replyiob = NULL;
+ recbuf->iov_base = NULL;
+ goto err_exit;
+ }
+
+ recbuf->iov_base = recordhdr.iov_base;
+ recbuf->iov_len = recordhdr.iov_len;
+err_exit:
+ return replyiob;
+}
+
+
+/*
+ * The function to submit a program message to the RPC service.
+ * This message is added to the transmission queue of the
+ * conn.
+ *
+ * Program callers are not expected to use the msgvec->iov_base
+ * address for anything else.
+ * Nor are they expected to free it once this function returns.
+ * Once the transmission of the buffer is completed by the RPC service,
+ * the memory area as referenced through @msg will be unrefed.
+ * If a higher layer does not want anything to do with this iobuf
+ * after this function returns, it should call unref on it. For keeping
+ * it around till the transmission is actually complete, rpcsvc also refs it.
+ * *
+ * If this function returns an error by returning -1, the
+ * higher layer programs should assume that a disconnection happened
+ * and should know that the conn memory area as well as the req structure
+ * has been freed internally.
+ *
+ * For now, this function assumes that a submit is always called
+ * to send a new record. Later, if there is a situation where different
+ * buffers for the same record come from different sources, then we'll
+ * need to change this code to account for multiple submit calls adding
+ * the buffers into a single record.
+ */
+
+int
+nfs_rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec msgvec,
+ struct iobuf *msg)
+{
+ int ret = -1;
+ struct iobuf *replyiob = NULL;
+ struct iovec recordhdr = {0, };
+ rpcsvc_conn_t *conn = NULL;
+ int rpc_status = 0;
+ int rpc_error = 0;
+
+ if ((!req) || (!req->conn))
+ return -1;
+
+ conn = req->conn;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx message: %zu", msgvec.iov_len);
+ /* Build the buffer containing the encoded RPC reply. */
+ replyiob = nfs_rpcsvc_record_build_record (req, msgvec.iov_len,
+ &recordhdr);
+ if (!replyiob) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed");
+ goto disconnect_exit;
+ }
+
+ /* Must ref the iobuf got from higher layer so that the higher layer
+ * can rest assured that it can unref it and leave the final freeing
+ * of the buffer to us. Note msg can be NULL if an RPC-only message
+ * was being sent. Happens when an RPC error reply is being sent.
+ */
+ if (msg)
+ iobuf_ref (msg);
+ ret = nfs_rpcsvc_conn_submit (conn, recordhdr, replyiob, msgvec, msg);
+
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to submit message");
+ iobuf_unref (replyiob);
+ }
+
+disconnect_exit:
+ /* Note that a unref is called everytime a reply is sent. This is in
+ * response to the ref that is performed on the conn when a request is
+ * handed to the RPC program.
+ *
+ * The catch, however, is that if the reply is an rpc error, we must
+ * not unref. This is because the ref only contains
+ * references for the actors to which the request was handed plus one
+ * reference maintained by the RPC layer. By unrefing for a case where
+ * no actor was called, we will be losing the ref held for the RPC
+ * layer.
+ */
+
+ /* If the request succeeded and was handed to the actor, then unref the
+ * conn.
+ */
+
+ rpc_status = req->rpc_stat;
+ rpc_error = req->rpc_err;
+ /* Must mem_put req back to rxpool before the possibility of destroying
+ * conn in conn_unref, where the rxpool itself is destroyed.
+ */
+ mem_put (conn->rxpool, req);
+ if ((rpc_status == MSG_ACCEPTED) && (rpc_error == SUCCESS))
+ nfs_rpcsvc_conn_unref (conn);
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_request_attach_vector (rpcsvc_request_t *req, struct iovec msgvec,
+ struct iobuf *iob, struct iobref *iobref,
+ int finalvector)
+{
+ rpcsvc_txbuf_t *txb = NULL;
+ int txflags = 0;
+
+ if ((!req) || (!msgvec.iov_base))
+ return -1;
+
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx Vector: %zu", msgvec.iov_len);
+ if (finalvector)
+ txflags |= RPCSVC_TXB_LAST;
+ /* We only let the user decide whether this is the last vector for the
+ * record, since the first vector is always the RPC header.
+ */
+ txb = nfs_rpcsvc_init_txbuf (req->conn, msgvec, iob, iobref, txflags);
+ if (!txb) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not init tx buf");
+ return -1;
+ }
+
+ req->payloadsize += msgvec.iov_len;
+ if (iob)
+ iobuf_ref (iob);
+ if (iobref)
+ iobref_ref (iobref);
+ list_add_tail (&txb->txlist, &req->txlist);
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_request_attach_vectors (rpcsvc_request_t *req, struct iovec *payload,
+ int vcount, struct iobref *piobref)
+{
+ int c = 0;
+ int ret = -1;
+
+ for (;c < (vcount-1); c++) {
+ ret = nfs_rpcsvc_request_attach_vector (req, payload[c], NULL,
+ piobref, 0);
+ if (ret < 0) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to attach "
+ "vector");
+ goto out;
+ }
+ }
+
+ ret = nfs_rpcsvc_request_attach_vector (req, payload[vcount-1], NULL,
+ piobref, 1);
+ if (ret < 0)
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to attach final vec");
+
+out:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_submit_vectors (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ struct iobuf *replyiob = NULL;
+ struct iovec recordhdr = {0, };
+ rpcsvc_txbuf_t *rpctxb = NULL;
+ rpcsvc_conn_t *conn = NULL;
+
+ if ((!req) || (!req->conn))
+ return -1;
+
+ /* Build the buffer containing the encoded RPC reply. */
+ replyiob = nfs_rpcsvc_record_build_record (req, req->payloadsize,
+ &recordhdr);
+ if (!replyiob) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed");
+ goto disconnect_exit;
+ }
+
+ rpctxb = nfs_rpcsvc_init_txbuf (req->conn, recordhdr, replyiob, NULL,
+ RPCSVC_TXB_FIRST);
+ if (!rpctxb) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to create tx buf");
+ goto disconnect_exit;
+ }
+
+ pthread_mutex_lock (&req->conn->connlock);
+ {
+ list_add_tail (&rpctxb->txlist, &req->conn->txbufs);
+ list_append_init (&req->txlist, &req->conn->txbufs);
+ }
+ pthread_mutex_unlock (&req->conn->connlock);
+
+ ret = 0;
+ req->conn->eventidx = event_select_on (req->conn->stage->eventpool,
+ req->conn->sockfd,
+ req->conn->eventidx, -1, 1);
+disconnect_exit:
+ /* Note that a unref is called everytime a reply is sent. This is in
+ * response to the ref that is performed on the conn when a request is
+ * handed to the RPC program.
+ */
+ conn = req->conn;
+ /* Must mem_put req back to rxpool before the possibility of destroying
+ * conn in conn_unref, where the rxpool itself is destroyed.
+ */
+ mem_put (conn->rxpool, req);
+
+ nfs_rpcsvc_conn_unref (conn);
+ if (ret == -1)
+ iobuf_unref (replyiob);
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_error_reply (rpcsvc_request_t *req)
+{
+ struct iovec dummyvec = {0, };
+
+ if (!req)
+ return -1;
+
+ /* At this point the req should already have been filled with the
+ * appropriate RPC error numbers.
+ */
+ return nfs_rpcsvc_submit_generic (req, dummyvec, NULL);
+}
+
+
+rpcsvc_request_t *
+nfs_rpcsvc_request_init (rpcsvc_conn_t *conn, struct rpc_msg *callmsg,
+ struct iovec progmsg, rpcsvc_request_t *req)
+{
+ if ((!conn) || (!callmsg)|| (!req))
+ return NULL;
+
+
+ /* We start a RPC request as always denied. */
+ req->rpc_stat = MSG_DENIED;
+ req->xid = nfs_rpc_call_xid (callmsg);
+ req->prognum = nfs_rpc_call_program (callmsg);
+ req->progver = nfs_rpc_call_progver (callmsg);
+ req->procnum = nfs_rpc_call_progproc (callmsg);
+ req->conn = conn;
+ req->msg = progmsg;
+ req->recordiob = conn->rstate.activeiob;
+ INIT_LIST_HEAD (&req->txlist);
+ req->payloadsize = 0;
+
+ /* By this time, the data bytes for the auth scheme would have already
+ * been copied into the required sections of the req structure,
+ * we just need to fill in the meta-data about it now.
+ */
+ req->cred.flavour = nfs_rpc_call_cred_flavour (callmsg);
+ req->cred.datalen = nfs_rpc_call_cred_len (callmsg);
+ req->verf.flavour = nfs_rpc_call_verf_flavour (callmsg);
+ req->verf.datalen = nfs_rpc_call_verf_len (callmsg);
+
+ /* AUTH */
+ nfs_rpcsvc_auth_request_init (req);
+ return req;
+}
+
+
+rpcsvc_request_t *
+nfs_rpcsvc_request_create (rpcsvc_conn_t *conn)
+{
+ char *msgbuf = NULL;
+ struct rpc_msg rpcmsg;
+ struct iovec progmsg; /* RPC Program payload */
+ rpcsvc_request_t *req = NULL;
+ int ret = -1;
+ rpcsvc_program_t *program = NULL;
+
+ if (!conn)
+ return NULL;
+
+ /* We need to allocate the request before actually calling
+ * rpcsvc_request_init on the request so that we, can fill the auth
+ * data directly into the request structure from the message iobuf.
+ * This avoids a need to keep a temp buffer into which the auth data
+ * would've been copied otherwise.
+ */
+ nfs_rpcsvc_alloc_request (conn, req);
+ if (!req) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to alloc request");
+ goto err;
+ }
+
+ msgbuf = iobuf_ptr (conn->rstate.activeiob);
+ ret = nfs_xdr_to_rpc_call (msgbuf, conn->rstate.recordsize, &rpcmsg,
+ &progmsg, req->cred.authdata,
+ req->verf.authdata);
+
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC call decoding failed");
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ req->conn = conn;
+ goto err;
+ }
+
+ ret = -1;
+ nfs_rpcsvc_request_init (conn, &rpcmsg, progmsg, req);
+
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC XID: %lx, Ver: %ld, Program: %ld,"
+ " ProgVers: %ld, Proc: %ld", nfs_rpc_call_xid (&rpcmsg),
+ nfs_rpc_call_rpcvers (&rpcmsg), nfs_rpc_call_program (&rpcmsg),
+ nfs_rpc_call_progver (&rpcmsg),
+ nfs_rpc_call_progproc (&rpcmsg));
+
+ if (nfs_rpc_call_rpcvers (&rpcmsg) != 2) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC version not supported");
+ nfs_rpcsvc_request_seterr (req, RPC_MISMATCH);
+ goto err;
+ }
+
+ ret = __nfs_rpcsvc_program_actor (req, &program);
+ if (ret != SUCCESS) {
+ ret = -1;
+ goto err;
+ }
+
+ req->program = program;
+ ret = nfs_rpcsvc_authenticate (req);
+ if (ret == RPCSVC_AUTH_REJECT) {
+ /* No need to set auth_err, that is the responsibility of
+ * the authentication handler since only that know what exact
+ * error happened.
+ */
+ nfs_rpcsvc_request_seterr (req, AUTH_ERROR);
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed authentication");
+ ret = -1;
+ goto err;
+ }
+
+ ret = 0;
+err:
+ if (ret == -1) {
+ ret = nfs_rpcsvc_error_reply (req);
+ req = NULL;
+ }
+
+ return req;
+}
+
+
+int
+nfs_rpcsvc_handle_rpc_call (rpcsvc_conn_t *conn)
+{
+ rpcsvc_actor_t *actor = NULL;
+ rpcsvc_request_t *req = NULL;
+ int ret = -1;
+
+ if (!conn)
+ return -1;
+
+ req = nfs_rpcsvc_request_create (conn);
+ if (!req)
+ goto err;
+
+ if (!nfs_rpcsvc_request_accepted (req))
+ goto err_reply;
+
+ actor = nfs_rpcsvc_program_actor (req);
+ if (!actor)
+ goto err_reply;
+
+ if ((actor) && (actor->actor)) {
+ THIS = nfs_rpcsvc_request_actorxl (req);
+ nfs_rpcsvc_conn_ref (conn);
+ ret = actor->actor (req);
+ }
+
+err_reply:
+ if (ret == RPCSVC_ACTOR_ERROR)
+ ret = nfs_rpcsvc_error_reply (req);
+ else if (ret == RPCSVC_ACTOR_IGNORE)
+ mem_put (conn->rxpool, req);
+
+ /* No need to propagate error beyond this function since the reply
+ * has now been queued. */
+ ret = 0;
+err:
+ return ret;
+}
+
+#define nfs_rpc_call_cred_addr(rs) (iobuf_ptr ((rs)->activeiob) + RPCSVC_BARERPC_MSGSZ - 4)
+
+uint32_t
+nfs_rpcsvc_call_credlen (rpcsvc_record_state_t *rs)
+{
+ char *credaddr = NULL;
+ uint32_t credlen_nw = 0;
+ uint32_t credlen_host = 0;
+
+ /* Position to the start of the credential length field. */
+ credaddr = nfs_rpc_call_cred_addr (rs);
+ credlen_nw = *(uint32_t *)credaddr;
+ credlen_host = ntohl (credlen_nw);
+
+ return credlen_host;
+}
+
+uint32_t
+nfs_rpcsvc_call_verflen (rpcsvc_record_state_t *rs)
+{
+ char *verfaddr = NULL;
+ uint32_t verflen_nw = 0;
+ uint32_t verflen_host = 0;
+ uint32_t credlen = 0;
+
+ /* Position to the start of the verifier length field. */
+ credlen = nfs_rpcsvc_call_credlen (rs);
+ verfaddr = (nfs_rpc_call_cred_addr (rs) + 4 + credlen);
+ verflen_nw = *(uint32_t *)verfaddr;
+ verflen_host = ntohl (verflen_nw);
+
+ return verflen_host;
+}
+
+
+void
+nfs_rpcsvc_update_vectored_verf (rpcsvc_record_state_t *rs)
+{
+ if (!rs)
+ return;
+
+ rs->recordsize += nfs_rpcsvc_call_verflen (rs);
+ return;
+}
+
+
+void
+nfs_rpcsvc_handle_vectored_prep_rpc_call (rpcsvc_conn_t *conn)
+{
+ rpcsvc_actor_t *actor = NULL;
+ rpcsvc_request_t *req = NULL;
+ rpcsvc_record_state_t *rs = NULL;
+ rpcsvc_t *svc = NULL;
+ int ret = -1;
+ ssize_t remfrag = RPCSVC_ACTOR_ERROR;
+ int newbuf = 0;
+
+ if (!conn)
+ return;
+
+ rs = &conn->rstate;
+
+ /* In case one of the steps below fails, we need to make sure that the
+ * remaining frag in the kernel's buffers are read-out so that the
+ * requests that follow can be served.
+ */
+ rs->remainingfrag = rs->fragsize - rs->recordsize;
+ rs->vecstate = RPCSVC_VECTOR_IGNORE;
+ req = nfs_rpcsvc_request_create (conn);
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ if (!req)
+ goto err;
+
+ if (!nfs_rpcsvc_request_accepted (req))
+ goto err_reply;
+
+ actor = nfs_rpcsvc_program_actor (req);
+ if (!actor)
+ goto err_reply;
+
+ if (!actor->vector_sizer) {
+ ret = -1;
+ nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL);
+ goto err_reply;
+ }
+
+ nfs_rpcsvc_conn_ref (conn);
+ THIS = nfs_rpcsvc_request_actorxl (req);
+ ret = actor->vector_sizer (req, &remfrag, &newbuf);
+ nfs_rpcsvc_conn_unref (conn);
+
+ if (ret == RPCSVC_ACTOR_ERROR) {
+ ret = -1;
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
+ goto err_reply;
+ }
+
+ rs->remainingfrag = remfrag;
+ rs->vecstate = RPCSVC_VECTOR_READPROCHDR;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC proc header remaining:"
+ " %d", rs->remainingfrag);
+ conn->vectoredreq = req;
+
+ /* Store the reference to the current frag pointer. This is where the
+ * proc header will be read into.
+ */
+ req->msg.iov_base = rs->fragcurrent;
+ req->msg.iov_len = rs->remainingfrag;
+ ret = 0;
+
+err_reply:
+ if (ret == -1)
+ ret = nfs_rpcsvc_error_reply (req);
+
+ /* No need to propagate error beyond this function since the reply
+ * has now been queued. */
+ ret = 0;
+err:
+ return;
+}
+
+
+void
+nfs_rpcsvc_update_vectored_verfsz (rpcsvc_conn_t *conn)
+{
+ rpcsvc_record_state_t *rs = NULL;
+ uint32_t verflen = 0;
+
+ if (!conn)
+ return;
+
+ rs = &conn->rstate;
+
+ verflen = nfs_rpcsvc_call_verflen (rs);
+ rs->recordsize += 8;
+ if (verflen > 0) {
+ rs->remainingfrag = verflen;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verf remaining: "
+ " %d", rs->remainingfrag);
+ rs->vecstate = RPCSVC_VECTOR_READVERF;
+ } else {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC preparing call");
+ nfs_rpcsvc_handle_vectored_prep_rpc_call (conn);
+ }
+
+ return;
+}
+
+
+void
+nfs_rpcsvc_update_vectored_cred (rpcsvc_record_state_t *rs)
+{
+ uint32_t credlen = 0;
+
+ if (!rs)
+ return;
+
+ credlen = nfs_rpcsvc_call_credlen (rs);
+ /* Update remainingfrag to read the 8 bytes needed for
+ * reading verf flavour and verf len.
+ */
+ rs->remainingfrag = (2 * sizeof (uint32_t));
+ rs->vecstate = RPCSVC_VECTOR_READVERFSZ;
+ rs->recordsize += credlen;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verfsz remaining: %d",
+ rs->remainingfrag);
+
+ return;
+}
+
+void
+nfs_rpcsvc_update_vectored_barerpc (rpcsvc_record_state_t *rs)
+{
+ uint32_t credlen = 0;
+
+ if (!rs)
+ return;
+
+ credlen = nfs_rpcsvc_call_credlen (rs);
+ rs->recordsize = RPCSVC_BARERPC_MSGSZ;
+ if (credlen == 0) {
+ rs->remainingfrag = 8;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verfsz remaining"
+ ": %d", rs->remainingfrag);
+ rs->vecstate = RPCSVC_VECTOR_READVERFSZ;
+ } else {
+ rs->remainingfrag = credlen;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC cred remaining: "
+ "%d", rs->remainingfrag);
+ rs->vecstate = RPCSVC_VECTOR_READCRED;
+ }
+
+ return;
+}
+
+
+void
+nfs_rpcsvc_handle_vectored_rpc_call (rpcsvc_conn_t *conn)
+{
+ rpcsvc_actor_t *actor = NULL;
+ rpcsvc_request_t *req = NULL;
+ rpcsvc_record_state_t *rs = NULL;
+ rpcsvc_t *svc = NULL;
+ int ret = -1;
+ ssize_t remfrag = -1;
+ int newbuf = 0;
+
+ if (!conn)
+ return;
+
+ rs = &conn->rstate;
+
+ req = conn->vectoredreq;
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+
+ if (!req)
+ goto err;
+
+ actor = nfs_rpcsvc_program_actor (req);
+ if (!actor)
+ goto err_reply;
+
+ if (!actor->vector_sizer) {
+ ret = -1;
+ nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL);
+ goto err_reply;
+ }
+
+ req->msg.iov_len = (unsigned long)((long)rs->fragcurrent - (long)req->msg.iov_base);
+ nfs_rpcsvc_conn_ref (conn);
+ THIS = nfs_rpcsvc_request_actorxl (req);
+ ret = actor->vector_sizer (req, &remfrag, &newbuf);
+ nfs_rpcsvc_conn_unref (conn);
+ if (ret == RPCSVC_ACTOR_ERROR) {
+ ret = -1;
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
+ goto err_reply;
+ }
+
+ if (newbuf) {
+ rs->vectoriob = iobuf_get (svc->ctx->iobuf_pool);
+ rs->fragcurrent = iobuf_ptr (rs->vectoriob);
+ rs->vecstate = RPCSVC_VECTOR_READVEC;
+ rs->remainingfrag = remfrag;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC buf remaining:"
+ " %d", rs->remainingfrag);
+ } else {
+ rs->remainingfrag = remfrag;
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC proc remaining:"
+ " %d", rs->remainingfrag);
+ }
+
+ ret = 0;
+err_reply:
+ if (ret == -1)
+ ret = nfs_rpcsvc_error_reply (req);
+
+ /* No need to propagate error beyond this function since the reply
+ * has now been queued. */
+ ret = 0;
+err:
+ return;
+}
+
+
+
+void
+nfs_rpcsvc_record_vectored_call_actor (rpcsvc_conn_t *conn)
+{
+ rpcsvc_actor_t *actor = NULL;
+ rpcsvc_request_t *req = NULL;
+ rpcsvc_record_state_t *rs = NULL;
+ rpcsvc_t *svc = NULL;
+ int ret = -1;
+
+ if (!conn)
+ return;
+
+ rs = &conn->rstate;
+ req = conn->vectoredreq;
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+
+ if (!req)
+ goto err;
+
+ actor = nfs_rpcsvc_program_actor (req);
+ if (!actor)
+ goto err_reply;
+
+ if (actor->vector_actor) {
+ nfs_rpcsvc_conn_ref (conn);
+ THIS = nfs_rpcsvc_request_actorxl (req);
+ ret = actor->vector_actor (req, rs->vectoriob);
+ } else {
+ nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL);
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "No vectored handler present");
+ ret = RPCSVC_ACTOR_ERROR;
+ }
+
+err_reply:
+ if (ret == RPCSVC_ACTOR_ERROR)
+ ret = nfs_rpcsvc_error_reply (req);
+ else if (ret == RPCSVC_ACTOR_IGNORE)
+ mem_put (conn->rxpool, req);
+
+ /* No need to propagate error beyond this function since the reply
+ * has now been queued. */
+ ret = 0;
+err:
+ return;
+}
+
+
+
+ssize_t
+nfs_rpcsvc_update_vectored_state (rpcsvc_conn_t *conn)
+{
+ rpcsvc_record_state_t *rs = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if (!conn)
+ return 0;
+
+ /* At this point, we can be confident that the activeiob contains
+ * exactly the first RPCSVC_BARERPC_MSGSZ bytes needed in order to
+ * determine the program and actor. So the next state will be
+ * to read the credentials.
+ *
+ * But first, try to determine how many more bytes do we need from the
+ * network to complete the RPC message including the credentials.
+ */
+
+ rs = &conn->rstate;
+ if (nfs_rpcsvc_record_vectored_baremsg (rs))
+ nfs_rpcsvc_update_vectored_barerpc (rs);
+ else if (nfs_rpcsvc_record_vectored_cred (rs))
+ nfs_rpcsvc_update_vectored_cred (rs);
+ else if (nfs_rpcsvc_record_vectored_verfsz (rs))
+ nfs_rpcsvc_update_vectored_verfsz (conn);
+ else if (nfs_rpcsvc_record_vectored_verfread (rs)) {
+ nfs_rpcsvc_update_vectored_verf (rs);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC preparing call");
+ nfs_rpcsvc_handle_vectored_prep_rpc_call (conn);
+ } else if (nfs_rpcsvc_record_vectored_readprochdr (rs))
+ nfs_rpcsvc_handle_vectored_rpc_call (conn);
+ else if (nfs_rpcsvc_record_vectored_ignore (rs)) {
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool);
+ } else if (nfs_rpcsvc_record_vectored_readvec (rs)) {
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC vector read");
+ nfs_rpcsvc_record_vectored_call_actor (conn);
+ nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool);
+ }
+
+ return 0;
+}
+
+
+ssize_t
+nfs_rpcsvc_record_read_partial_frag (rpcsvc_record_state_t *rs,
+ ssize_t dataread);
+
+ssize_t
+nfs_rpcsvc_update_vectored_msg (rpcsvc_conn_t *conn, ssize_t dataread)
+{
+
+ if (!conn)
+ return dataread;
+
+ /* find out how much of the bare msg is pending and set that up to be
+ * read into the updated fragcurrent along with the updated size into
+ * remainingfrag.
+ */
+
+
+ /* Incidently, the logic needed here is similar to a regular partial
+ * fragment read since we've already set the remainingfrag member in
+ * rstate to be RPCSVC_BARERPC_MSGSZ for the purpose of a vectored
+ * fragment.
+ */
+ return nfs_rpcsvc_record_read_partial_frag (&conn->rstate, dataread);
+}
+
+/* FIX: As a first version of vectored reading, I am assuming dataread will
+ * always be equal to RPCSVC_BARERPC_MSGSZ for the sake of simplicity on the
+ * belief that we're never actually reading more bytes than needed in each
+ * poll_in.
+ */
+ssize_t
+nfs_rpcsvc_handle_vectored_frag (rpcsvc_conn_t *conn, ssize_t dataread)
+{
+ if (!conn)
+ return dataread;
+
+ /* At this point we can be confident that only the frag size has been
+ * read from the network. Now it is up to us to have the remaining RPC
+ * fields given to us here.
+ */
+
+ /* Since the poll_in handler uses the remainingfrag field to determine
+ * how much to read from the network, we'll hack this scheme to tell
+ * the poll_in to read at most RPCSVC_BARERPC_MSGSZ bytes. This is done
+ * to, as a first step, identify which (program, actor) we need to call.
+ */
+
+ dataread = nfs_rpcsvc_update_vectored_msg (conn, dataread);
+
+ if (conn->rstate.remainingfrag == 0) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored frag complete");
+ dataread = nfs_rpcsvc_update_vectored_state (conn);
+ }
+
+ return dataread;
+}
+
+
+int
+nfs_rpcsvc_record_update_state (rpcsvc_conn_t *conn, ssize_t dataread)
+{
+ rpcsvc_record_state_t *rs = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if (!conn)
+ return -1;
+
+ rs = &conn->rstate;
+ /* At entry into this function, fragcurrent will be pointing to the\
+ * start of the area into which dataread number of bytes were read.
+ */
+
+ if (nfs_rpcsvc_record_readfraghdr(rs))
+ dataread = nfs_rpcsvc_record_update_fraghdr (rs, dataread);
+
+ if (nfs_rpcsvc_record_readfrag(rs)) {
+ /* The minimum needed for triggering the vectored handler is
+ * the frag size field. The fragsize member remains set to this
+ * size till this request is completely extracted from the
+ * network. Once all the data has been read from the network,
+ * the request structure would've been created. The point being
+ * that even if it takes multiple calls to network IO for
+ * getting the vectored fragment, we can continue to use this
+ * condition as the flag to tell us that this is a vectored
+ * fragment.
+ */
+ if ((dataread > 0) && (nfs_rpcsvc_record_vectored (rs))) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored frag");
+ dataread = nfs_rpcsvc_handle_vectored_frag (conn,
+ dataread);
+ } else if (dataread > 0) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Regular frag");
+ dataread = nfs_rpcsvc_record_update_frag (rs, dataread);
+ }
+ }
+
+ /* This should not happen. We are never reading more than the current
+ * fragment needs. Something is seriously wrong.
+ */
+ if (dataread > 0) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Data Left: %zd", dataread);
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Unwanted data read from "
+ " connection.");
+ }
+
+ /* If we're now supposed to wait for a new fragment header and if the
+ * fragment that we just completed in the previous call to
+ * rpcsvc_record_update_frag was the last fragment for the current
+ * RPC record, then, it is time to perform the translation from
+ * XDR formatted buffer in activeiob followed by the upcall to the
+ * protocol actor.
+ */
+ if ((nfs_rpcsvc_record_readfraghdr(rs)) && (rs->islastfrag)) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Full Record Received.");
+ nfs_rpcsvc_handle_rpc_call (conn);
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool);
+ }
+
+ return 0;
+}
+
+
+char *
+nfs_rpcsvc_record_read_addr (rpcsvc_record_state_t *rs)
+{
+
+ if (nfs_rpcsvc_record_readfraghdr (rs))
+ return nfs_rpcsvc_record_currenthdr_addr (rs);
+ else if (nfs_rpcsvc_record_readfrag (rs))
+ return nfs_rpcsvc_record_currentfrag_addr (rs);
+
+ return NULL;
+}
+
+
+int
+nfs_rpcsvc_conn_data_poll_in (rpcsvc_conn_t *conn)
+{
+ ssize_t dataread = -1;
+ size_t readsize = 0;
+ char *readaddr = NULL;
+ int ret = -1;
+
+ readaddr = nfs_rpcsvc_record_read_addr (&conn->rstate);
+ if (!readaddr)
+ goto err;
+
+ readsize = nfs_rpcsvc_record_read_size (&conn->rstate);
+ if (readsize == -1)
+ goto err;
+
+ dataread = nfs_rpcsvc_socket_read (conn->sockfd, readaddr, readsize);
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "conn: 0x%lx, readsize: %zu, dataread:"
+ "%zd", (long)conn, readsize, dataread);
+
+ if (dataread > 0)
+ ret = nfs_rpcsvc_record_update_state (conn, dataread);
+
+err:
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_data_poll_err (rpcsvc_conn_t *conn)
+{
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Received error event");
+ nfs_rpcsvc_conn_deinit (conn);
+ return 0;
+}
+
+
+int
+__nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn)
+{
+ rpcsvc_txbuf_t *txbuf = NULL;
+ rpcsvc_txbuf_t *tmp = NULL;
+ ssize_t written = -1;
+ char *writeaddr = NULL;
+ size_t writesize = -1;
+ int eagain = 0;
+
+ if (!conn)
+ return -1;
+
+ /* Attempt transmission of each of the pending buffers */
+ list_for_each_entry_safe (txbuf, tmp, &conn->txbufs, txlist) {
+tx_remaining:
+ eagain = 0;
+ writeaddr = (char *)(txbuf->buf.iov_base + txbuf->offset);
+ writesize = (txbuf->buf.iov_len - txbuf->offset);
+
+ if (txbuf->txbehave & RPCSVC_TXB_FIRST) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "First Tx Buf");
+ nfs_rpcsvc_socket_block_tx (conn->sockfd);
+ }
+
+ written = nfs_rpcsvc_socket_write (conn->sockfd, writeaddr,
+ writesize, &eagain);
+ if (txbuf->txbehave & RPCSVC_TXB_LAST) {
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "Last Tx Buf");
+ nfs_rpcsvc_socket_unblock_tx (conn->sockfd);
+ }
+ gf_log (GF_RPCSVC, GF_LOG_TRACE, "conn: 0x%lx, Tx request: %zu,"
+ " Tx sent: %zd", (long)conn, writesize, written);
+
+ /* There was an error transmitting this buffer */
+ if (written == -1)
+ break;
+
+ if (written >= 0)
+ txbuf->offset += written;
+
+ /* If the current buffer has been completely transmitted,
+ * delete it from the list and move on to the next buffer.
+ */
+ if (txbuf->offset == txbuf->buf.iov_len) {
+ /* It doesnt matter who ref'ed this iobuf, rpcsvc for
+ * its own header or a RPC program.
+ */
+ if (txbuf->iob)
+ iobuf_unref (txbuf->iob);
+ if (txbuf->iobref)
+ iobref_unref (txbuf->iobref);
+
+ list_del (&txbuf->txlist);
+ mem_put (conn->txpool, txbuf);
+ } else {
+ /* If the current buffer is incompletely tx'd, do not
+ * go to the head of the loop, since that moves us to
+ * the next buffer.
+ *
+ * BUT, if the current transmission exited due to EAGAIN
+ * we need to leave the buffers where they are and come
+ * back later for retransmission.
+ */
+ if (!eagain)
+ goto tx_remaining;
+ else
+ break;
+ }
+
+ }
+
+ /* If we've broken out of the loop above then we must unblock
+ * the transmission now.
+ */
+ nfs_rpcsvc_socket_unblock_tx (conn->sockfd);
+ if (list_empty (&conn->txbufs))
+ conn->eventidx = event_select_on (conn->stage->eventpool,
+ conn->sockfd, conn->eventidx,
+ -1, 0);
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn)
+{
+ if (!conn)
+ return -1;
+
+
+ pthread_mutex_lock (&conn->connlock);
+ {
+ __nfs_rpcsvc_conn_data_poll_out (conn);
+ }
+ pthread_mutex_unlock (&conn->connlock);
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_conn_data_handler (int fd, int idx, void *data, int poll_in,
+ int poll_out, int poll_err)
+{
+ rpcsvc_conn_t *conn = NULL;
+ int ret = 0;
+
+ if (!data)
+ return 0;
+
+ conn = (rpcsvc_conn_t *)data;
+
+ if (poll_out)
+ ret = nfs_rpcsvc_conn_data_poll_out (conn);
+
+ if (poll_err) {
+ ret = nfs_rpcsvc_conn_data_poll_err (conn);
+ return 0;
+ }
+
+ if (poll_in) {
+ ret = 0;
+ ret = nfs_rpcsvc_conn_data_poll_in (conn);
+ }
+
+ if (ret == -1)
+ nfs_rpcsvc_conn_data_poll_err (conn);
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_conn_listening_handler (int fd, int idx, void *data, int poll_in,
+ int poll_out, int poll_err)
+{
+ rpcsvc_conn_t *newconn = NULL;
+ rpcsvc_stage_t *selectedstage = NULL;
+ int ret = -1;
+ rpcsvc_conn_t *conn = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if (!poll_in)
+ return 0;
+
+ conn = (rpcsvc_conn_t *)data;
+ svc = nfs_rpcsvc_conn_rpcsvc (conn);
+ newconn = nfs_rpcsvc_conn_accept_init (svc, fd);
+ if (!newconn) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "failed to accept connection");
+ goto err;
+ }
+
+ selectedstage = nfs_rpcsvc_select_stage (svc);
+ if (!selectedstage)
+ goto close_err;
+
+ /* Now that we've accepted the connection, we need to associate
+ * its events to a stage.
+ */
+ ret = nfs_rpcsvc_stage_conn_associate (selectedstage, newconn,
+ nfs_rpcsvc_conn_data_handler,
+ newconn);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "could not associated stage "
+ " with new connection");
+ goto close_err;
+ }
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New Connection");
+ ret = 0;
+close_err:
+ if (ret == -1)
+ nfs_rpcsvc_conn_unref (newconn);
+
+err:
+ return ret;
+}
+
+
+/* Register the program with the local portmapper service. */
+int
+nfs_rpcsvc_program_register_portmap (rpcsvc_t *svc, rpcsvc_program_t *newprog)
+{
+ if (!newprog)
+ return -1;
+
+ if (!svc->register_portmap)
+ return 0;
+
+ if (!(pmap_set(newprog->prognum, newprog->progver, IPPROTO_TCP,
+ newprog->progport))) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not register with"
+ " portmap");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_program_unregister_portmap (rpcsvc_t *svc, rpcsvc_program_t *prog)
+{
+ if (!prog)
+ return -1;
+
+ if (!svc->register_portmap)
+ return 0;
+
+ if (!(pmap_unset(prog->prognum, prog->progver))) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not unregister with"
+ " portmap");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_stage_program_register (rpcsvc_stage_t *stg,
+ rpcsvc_program_t *newprog)
+{
+ rpcsvc_conn_t *newconn = NULL;
+ rpcsvc_t *svc = NULL;
+
+ if ((!stg) || (!newprog))
+ return -1;
+
+ svc = nfs_rpcsvc_stage_service (stg);
+ /* Create a listening socket */
+ newconn = nfs_rpcsvc_conn_listen_init (svc, newprog);
+ if (!newconn) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "could not create listening"
+ " connection");
+ return -1;
+ }
+
+ if ((nfs_rpcsvc_stage_conn_associate (stg, newconn,
+ nfs_rpcsvc_conn_listening_handler,
+ newconn)) == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,"could not associate stage with"
+ " listening connection");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+nfs_rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t program)
+{
+ rpcsvc_program_t *newprog = NULL;
+ rpcsvc_stage_t *selectedstage = NULL;
+ int ret = -1;
+
+ if (!svc)
+ return -1;
+
+ newprog = GF_CALLOC (1, sizeof(*newprog),gf_common_mt_rpcsvc_program_t);
+ if (!newprog)
+ return -1;
+
+ if (!program.actors)
+ goto free_prog;
+
+ memcpy (newprog, &program, sizeof (program));
+ INIT_LIST_HEAD (&newprog->proglist);
+ list_add_tail (&newprog->proglist, &svc->allprograms);
+ selectedstage = nfs_rpcsvc_select_stage (svc);
+
+ ret = nfs_rpcsvc_stage_program_register (selectedstage, newprog);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "stage registration of program"
+ " failed");
+ goto free_prog;
+ }
+
+ ret = nfs_rpcsvc_program_register_portmap (svc, newprog);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap registration of"
+ " program failed");
+ goto free_prog;
+ }
+
+ ret = 0;
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New program registered: %s, Num: %d,"
+ " Ver: %d, Port: %d", newprog->progname, newprog->prognum,
+ newprog->progver, newprog->progport);
+
+free_prog:
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program registration failed:"
+ " %s, Num: %d, Ver: %d, Port: %d", newprog->progname,
+ newprog->prognum, newprog->progver, newprog->progport);
+ list_del (&newprog->proglist);
+ GF_FREE (newprog);
+ }
+
+ return ret;
+}
+
+/* The only difference between the generic submit and this one is that the
+ * generic submit is also used for submitting RPC error replies in where there
+ * are no payloads so the msgvec and msgbuf can be NULL.
+ * Since RPC programs should be using this function along with their payloads
+ * we must perform NULL checks before calling the generic submit.
+ */
+int
+nfs_rpcsvc_submit_message (rpcsvc_request_t *req, struct iovec msgvec,
+ struct iobuf *msg)
+{
+ if ((!req) || (!req->conn) || (!msg) || (!msgvec.iov_base))
+ return -1;
+
+ return nfs_rpcsvc_submit_generic (req, msgvec, msg);
+}
+
+
+int
+nfs_rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t prog)
+{
+ int ret = -1;
+
+ if (!svc)
+ return -1;
+
+ /* TODO: De-init the listening connection for this program. */
+ ret = nfs_rpcsvc_program_unregister_portmap (svc, &prog);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap unregistration of"
+ " program failed");
+ goto err;
+ }
+
+ ret = 0;
+ gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d,"
+ " Ver: %d, Port: %d", prog.progname, prog.prognum,
+ prog.progver, prog.progport);
+
+err:
+ if (ret == -1)
+ gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program unregistration failed"
+ ": %s, Num: %d, Ver: %d, Port: %d", prog.progname,
+ prog.prognum, prog.progver, prog.progport);
+
+ return ret;
+}
+
+
+int
+nfs_rpcsvc_conn_peername (rpcsvc_conn_t *conn, char *hostname, int hostlen)
+{
+ if (!conn)
+ return -1;
+
+ return nfs_rpcsvc_socket_peername (conn->sockfd, hostname, hostlen);
+}
+
+
+int
+nfs_rpcsvc_conn_peeraddr (rpcsvc_conn_t *conn, char *addrstr, int addrlen,
+ struct sockaddr *sa, socklen_t sasize)
+{
+ if (!conn)
+ return -1;
+
+ return nfs_rpcsvc_socket_peeraddr (conn->sockfd, addrstr, addrlen, sa,
+ sasize);
+}
+
diff --git a/xlators/nfs/lib/src/rpcsvc.h b/xlators/nfs/lib/src/rpcsvc.h
new file mode 100644
index 000000000..4e7c81845
--- /dev/null
+++ b/xlators/nfs/lib/src/rpcsvc.h
@@ -0,0 +1,728 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NFS_RPCSVC_H
+#define _NFS_RPCSVC_H
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "event.h"
+#include "logging.h"
+#include "dict.h"
+#include "mem-pool.h"
+#include "list.h"
+#include "iobuf.h"
+#include "xdr-rpc.h"
+#include "glusterfs.h"
+#include "xlator.h"
+
+#include <pthread.h>
+#include <sys/uio.h>
+
+#ifdef GF_DARWIN_HOST_OS
+#include <nfs/rpcv2.h>
+#define NGRPS RPCAUTH_UNIXGIDS
+#endif
+
+#define GF_RPCSVC "nfsrpc"
+#define RPCSVC_THREAD_STACK_SIZE ((size_t)(1024 * GF_UNIT_KB))
+
+#define RPCSVC_DEFAULT_MEMFACTOR 15
+#define RPCSVC_EVENTPOOL_SIZE_MULT 1024
+#define RPCSVC_POOLCOUNT_MULT 35
+#define RPCSVC_CONN_READ (128 * GF_UNIT_KB)
+#define RPCSVC_PAGE_SIZE (128 * GF_UNIT_KB)
+
+/* Defines for RPC record and fragment assembly */
+
+#define RPCSVC_FRAGHDR_SIZE 4 /* 4-byte RPC fragment header size */
+
+/* Given the 4-byte fragment header, returns non-zero if this fragment
+ * is the last fragment for the RPC record being assemebled.
+ * RPC Record marking standard defines a 32 bit value as the fragment
+ * header with the MSB signifying whether the fragment is the last
+ * fragment for the record being asembled.
+ */
+#define RPCSVC_LASTFRAG(fraghdr) ((uint32_t)(fraghdr & 0x80000000U))
+
+/* Given the 4-byte fragment header, extracts the bits that contain
+ * the fragment size.
+ */
+#define RPCSVC_FRAGSIZE(fraghdr) ((uint32_t)(fraghdr & 0x7fffffffU))
+
+/* RPC Record States */
+#define RPCSVC_READ_FRAGHDR 1
+#define RPCSVC_READ_FRAG 2
+/* The size in bytes, if crossed by a fragment will be handed over to the
+ * vectored actor so that it can allocate its buffers the way it wants.
+ * In our RPC layer, we assume that vectored RPC requests/records are never
+ * spread over multiple RPC fragments since that prevents us from determining
+ * whether the record should be handled in RPC layer completely or handed to
+ * the vectored handler.
+ */
+#define RPCSVC_VECTORED_FRAGSZ 4096
+#define RPCSVC_VECTOR_READCRED 1003
+#define RPCSVC_VECTOR_READVERFSZ 1004
+#define RPCSVC_VECTOR_READVERF 1005
+#define RPCSVC_VECTOR_IGNORE 1006
+#define RPCSVC_VECTOR_READVEC 1007
+#define RPCSVC_VECTOR_READPROCHDR 1008
+
+#define nfs_rpcsvc_record_vectored_baremsg(rs) (((rs)->state == RPCSVC_READ_FRAG) && (rs)->vecstate == 0)
+#define nfs_rpcsvc_record_vectored_cred(rs) ((rs)->vecstate == RPCSVC_VECTOR_READCRED)
+#define nfs_rpcsvc_record_vectored_verfsz(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERFSZ)
+#define nfs_rpcsvc_record_vectored_verfread(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERF)
+#define nfs_rpcsvc_record_vectored_ignore(rs) ((rs)->vecstate == RPCSVC_VECTOR_IGNORE)
+#define nfs_rpcsvc_record_vectored_readvec(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVEC)
+#define nfs_rpcsvc_record_vectored_readprochdr(rs) ((rs)->vecstate == RPCSVC_VECTOR_READPROCHDR)
+#define nfs_rpcsvc_record_vectored(rs) ((rs)->fragsize > RPCSVC_VECTORED_FRAGSZ)
+/* Includes bytes up to and including the credential length field. The credlen
+ * will be followed by @credlen bytes of credential data which will have to be
+ * read separately by the vectored reader. After the credentials comes the
+ * verifier which will also have to be read separately including the 8 bytes of
+ * verf flavour and verflen.
+ */
+#define RPCSVC_BARERPC_MSGSZ 32
+#define nfs_rpcsvc_record_readfraghdr(rs) ((rs)->state == RPCSVC_READ_FRAGHDR)
+#define nfs_rpcsvc_record_readfrag(rs) ((rs)->state == RPCSVC_READ_FRAG)
+
+#define nfs_rpcsvc_conn_rpcsvc(conn) ((conn)->stage->svc)
+#define RPCSVC_LOWVERS 2
+#define RPCSVC_HIGHVERS 2
+
+typedef struct rpc_svc_program rpcsvc_program_t;
+/* A Stage is the event handler thread together with
+ * the connections being served by this thread.
+ * It is called a stage because all the actors, i.e, protocol actors,
+ * defined by higher level users of the RPC layer, are executed here.
+ */
+typedef struct rpc_svc_stage_context {
+ pthread_t tid;
+ struct event_pool *eventpool; /* Per-stage event-pool */
+ void *svc; /* Ref to the rpcsvc_t */
+} rpcsvc_stage_t;
+
+
+/* RPC Records and Fragments assembly state.
+ * This is per-connection state that is used to determine
+ * how much data has come in, how much more needs to be read
+ * and where it needs to be read.
+ *
+ * All this state is then used to re-assemble network buffers into
+ * RPC fragments, which are then re-assembled into RPC records.
+ *
+ * See RFC 1831: "RPC: Remote Procedure Call Protocol Specification Version 2",
+ * particularly the section on Record Marking Standard.
+ */
+typedef struct rpcsvc_record_state {
+
+ /* Pending messages storage
+ * This memory area is currently being used to assemble
+ * the latest RPC record.
+ *
+ * Note that this buffer contains the data other than the
+ * fragment headers received from the network. This is so that we can
+ * directly pass this buffer to higher layers without requiring to
+ * perform memory copies and marshalling of data.
+ */
+ struct iobuf *activeiob;
+
+ struct iobuf *vectoriob;
+ /* The pointer into activeiob memory, into which will go the
+ * contents from the next read from the network.
+ */
+ char *fragcurrent;
+
+ /* Size of the currently incomplete RPC fragment.
+ * This is filled in when the fragment header comes in.
+ * Even though only the 31 least significant bits are used from the
+ * fragment header, we use a 32 bit variable to store the size.
+ */
+ uint32_t fragsize;
+
+ /* The fragment header is always read in here so that
+ * the RPC messages contained in a RPC records can be processed
+ * separately without copying them out of the activeiob above.
+ */
+ char fragheader[RPCSVC_FRAGHDR_SIZE];
+ char *hdrcurrent;
+
+ /* Bytes remaining to come in for the current fragment. */
+ uint32_t remainingfrag;
+
+ /* It is possible for the frag header to be split over separate
+ * read calls, so we need to keep track of how much is left.
+ */
+ uint32_t remainingfraghdr;
+
+ /* Record size, the total size of the RPC record, i.e. the total
+ * of all fragment sizes received till now. Does not include the size
+ * of a partial fragment which is continuing to be assembled right now.
+ */
+ int recordsize;
+
+ /* Current state of the record */
+ int state;
+
+ /* Current state of the vectored reading process. */
+ int vecstate;
+
+ /* Set to non-zero when the currently partial or complete fragment is
+ * the last fragment being received for the current RPC record.
+ */
+ uint32_t islastfrag;
+
+} rpcsvc_record_state_t;
+
+
+#define RPCSVC_CONNSTATE_CONNECTED 1
+#define RPCSVC_CONNSTATE_DISCONNECTED 2
+
+#define nfs_rpcsvc_conn_check_active(conn) ((conn)->connstate==RPCSVC_CONNSTATE_CONNECTED)
+
+typedef struct rpcsvc_request rpcsvc_request_t;
+/* Contains the state for each connection that is used for transmitting and
+ * receiving RPC messages.
+ *
+ * There is also an eventidx because each connection's fd is added to the event
+ * pool of the stage to which a connection belongs.
+ * Anything that can be accessed by a RPC program must be synced through
+ * connlock.
+ */
+typedef struct rpc_conn_state {
+
+ /* Transport or connection state */
+
+ /* Once we start working on RDMA support, this TCP specific state will
+ * have to be abstracted away.
+ */
+ int sockfd;
+ int eventidx;
+ int windowsize;
+
+ /* Reference to the stage which is handling this
+ * connection.
+ */
+ rpcsvc_stage_t *stage;
+
+ /* RPC Records and Fragments assembly state.
+ * All incoming data is staged here before being
+ * called a full RPC message.
+ */
+ rpcsvc_record_state_t rstate;
+
+ /* It is possible that a client disconnects while
+ * the higher layer RPC service is busy in a call.
+ * In this case, we cannot just free the conn
+ * structure, since the higher layer service could
+ * still have a reference to it.
+ * The refcount avoids freeing until all references
+ * have been given up, although the connection is clos()ed at the first
+ * call to unref.
+ */
+ int connref;
+ pthread_mutex_t connlock;
+ int connstate;
+
+ /* List of buffers awaiting transmission */
+ /* Accesses to txbufs between multiple threads calling
+ * rpcsvc_submit is synced through connlock. Prefer spinlock over
+ * mutex because this is a low overhead op that needs simple
+ * appending to the tx list.
+ */
+ struct list_head txbufs;
+
+ /* Mem pool for the txbufs above. */
+ struct mem_pool *txpool;
+
+ /* Memory pool for rpcsvc_request_t */
+ struct mem_pool *rxpool;
+
+ /* The request which hasnt yet been handed to the RPC program because
+ * this request is being treated as a vector request and so needs some
+ * more data to be got from the network.
+ */
+ rpcsvc_request_t *vectoredreq;
+} rpcsvc_conn_t;
+
+
+#define RPCSVC_MAX_AUTH_BYTES 400
+typedef struct rpcsvc_auth_data {
+ int flavour;
+ int datalen;
+ char authdata[RPCSVC_MAX_AUTH_BYTES];
+} rpcsvc_auth_data_t;
+
+#define nfs_rpcsvc_auth_flavour(au) ((au).flavour)
+
+/* The container for the RPC call handed up to an actor.
+ * Dynamically allocated. Lives till the call reply is completely
+ * transmitted.
+ * */
+struct rpcsvc_request {
+ /* Connection over which this request came. */
+ rpcsvc_conn_t *conn;
+
+ /* The identifier for the call from client.
+ * Needed to pair the reply with the call.
+ */
+ uint32_t xid;
+
+ int prognum;
+
+ int progver;
+
+ int procnum;
+ /* Uid and gid filled by the rpc-auth module during the authentication
+ * phase.
+ */
+ uid_t uid;
+ gid_t gid;
+
+ /* Might want to move this to AUTH_UNIX specifix state since this array
+ * is not available for every authenticatino scheme.
+ */
+ gid_t auxgids[NGRPS];
+ int auxgidcount;
+
+
+ /* The RPC message payload, contains the data required
+ * by the program actors. This is the buffer that will need to
+ * be de-xdred by the actor.
+ */
+ struct iovec msg;
+
+ /* The full message buffer allocated to store the RPC headers.
+ * This buffer is ref'd when allocated why RPC svc and unref'd after
+ * the buffer is handed to the actor. That means if the actor or any
+ * higher layer wants to keep this buffer around, they too must ref it
+ * right after entering the program actor.
+ */
+ struct iobuf *recordiob;
+
+ /* Status of the RPC call, whether it was accepted or denied. */
+ int rpc_stat;
+
+ /* In case, the call was denied, the RPC error is stored here
+ * till the reply is sent.
+ */
+ int rpc_err;
+
+ /* In case the failure happened because of an authentication problem
+ * , this value needs to be assigned the correct auth error number.
+ */
+ int auth_err;
+
+ /* There can be cases of RPC requests where the reply needs to
+ * be built from multiple sources. For eg. where even the NFS reply can
+ * contain a payload, as in the NFSv3 read reply. Here the RPC header
+ * ,NFS header and the read data are brought together separately from
+ * different buffers, so we need to stage the buffers temporarily here
+ * before all of them get added to the connection's transmission list.
+ */
+ struct list_head txlist;
+
+ /* While the reply record is being built, this variable keeps track
+ * of how many bytes have been added to the record.
+ */
+ size_t payloadsize;
+
+ /* The credentials extracted from the rpc request */
+ rpcsvc_auth_data_t cred;
+
+ /* The verified extracted from the rpc request. In request side
+ * processing this contains the verifier sent by the client, on reply
+ * side processing, it is filled with the verified that will be
+ * sent to the client.
+ */
+ rpcsvc_auth_data_t verf;
+
+ /* Container for a RPC program wanting to store a temp
+ * request-specific item.
+ */
+ void *private;
+
+ /* To save a ref to the program for which this request is. */
+ rpcsvc_program_t *program;
+};
+
+#define nfs_rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->program))
+#define nfs_rpcsvc_request_program_private(req) ((req)->program->private)
+#define nfs_rpcsvc_request_conn(req) (req)->conn
+#define nfs_rpcsvc_program_xlator(prg) ((prg)->actorxl)
+#define nfs_rpcsvc_request_actorxl(rq) (nfs_rpcsvc_request_program(rq))->actorxl
+#define nfs_rpcsvc_request_accepted(req) ((req)->rpc_stat == MSG_ACCEPTED)
+#define nfs_rpcsvc_request_accepted_success(req) ((req)->rpc_err == SUCCESS)
+#define nfs_rpcsvc_request_uid(req) ((req)->uid)
+#define nfs_rpcsvc_request_gid(req) ((req)->gid)
+#define nfs_rpcsvc_stage_service(stg) ((rpcsvc_t *)((stg)->svc))
+#define nfs_rpcsvc_conn_stage(conn) ((conn)->stage)
+#define nfs_rpcsvc_request_service(req) (nfs_rpcsvc_stage_service(nfs_rpcsvc_conn_stage(nfs_rpcsvc_request_conn(req))))
+#define nfs_rpcsvc_request_prog_minauth(req) (nfs_rpcsvc_request_program(req)->min_auth)
+#define nfs_rpcsvc_request_cred_flavour(req) (nfs_rpcsvc_auth_flavour(req->cred))
+#define nfs_rpcsvc_request_verf_flavour(req) (nfs_rpcsvc_auth_flavour(req->verf))
+
+#define nfs_rpcsvc_request_uid(req) ((req)->uid)
+#define nfs_rpcsvc_request_gid(req) ((req)->gid)
+#define nfs_rpcsvc_request_private(req) ((req)->private)
+#define nfs_rpcsvc_request_xid(req) ((req)->xid)
+#define nfs_rpcsvc_request_set_private(req,prv) (req)->private = (void *)(prv)
+#define nfs_rpcsvc_request_record_iob(rq) ((rq)->recordiob)
+#define nfs_rpcsvc_request_record_ref(req) (iobuf_ref ((req)->recordiob))
+#define nfs_rpcsvc_request_record_unref(req) (iobuf_unref ((req)->recordiob))
+#define nfs_rpcsvc_request_procnum(rq) ((rq)->procnum)
+
+
+#define RPCSVC_ACTOR_SUCCESS 0
+#define RPCSVC_ACTOR_ERROR (-1)
+#define RPCSVC_ACTOR_IGNORE (-2)
+
+/* Functor for every type of protocol actor
+ * must be defined like this.
+ *
+ * See the request structure for info on how to handle the request
+ * in the program actor.
+ *
+ * On successful santify checks inside the actor, it should return
+ * RPCSVC_ACTOR_SUCCESS.
+ * On an error, on which the RPC layer is expected to return a reply, the actor
+ * should return RPCSVC_ACTOR_ERROR.
+ *
+ */
+typedef int (*rpcsvc_actor) (rpcsvc_request_t *req);
+typedef int (*rpcsvc_vector_actor) (rpcsvc_request_t *req, struct iobuf *iob);
+typedef int (*rpcsvc_vector_sizer) (rpcsvc_request_t *req, ssize_t *readsize,
+ int *newiob);
+
+/* Every protocol actor will also need to specify the function the RPC layer
+ * will use to serialize or encode the message into XDR format just before
+ * transmitting on the connection.
+ */
+typedef void *(*rpcsvc_encode_reply) (void *msg);
+
+/* Once the reply has been transmitted, the message will have to be de-allocated
+ * , so every actor will need to provide a function that deallocates the message
+ * it had allocated as a response.
+ */
+typedef void (*rpcsvc_deallocate_reply) (void *msg);
+
+
+#define RPCSVC_NAME_MAX 32
+/* The descriptor for each procedure/actor that runs
+ * over the RPC service.
+ */
+typedef struct rpc_svc_actor_desc {
+ char procname[RPCSVC_NAME_MAX];
+ int procnum;
+ rpcsvc_actor actor;
+
+ /* Handler for cases where the RPC requests fragments are large enough
+ * to benefit from being decoded into aligned memory addresses. While
+ * decoding the request in a non-vectored manner, due to the nature of
+ * the XDR scheme, RPC cannot guarantee memory aligned addresses for
+ * the resulting message-specific structures. Allowing a specialized
+ * handler for letting the RPC program read the data from the network
+ * directly into its alligned buffers.
+ */
+ rpcsvc_vector_actor vector_actor;
+ rpcsvc_vector_sizer vector_sizer;
+
+} rpcsvc_actor_t;
+
+/* Describes a program and its version along with the function pointers
+ * required to handle the procedures/actors of each program/version.
+ * Never changed ever by any thread so no need for a lock.
+ */
+struct rpc_svc_program {
+ struct list_head proglist;
+ char progname[RPCSVC_NAME_MAX];
+ int prognum;
+ int progver;
+ uint16_t progport; /* Registered with portmap */
+ int progaddrfamily; /* AF_INET or AF_INET6 */
+ char *proghost; /* Bind host, can be NULL */
+ rpcsvc_actor_t *actors; /* All procedure handlers */
+ int numactors; /* Num actors in actor array */
+ int proghighvers; /* Highest ver for program
+ supported by the system. */
+ int proglowvers; /* Lowest ver */
+
+ /* Program specific state handed to actors */
+ void *private;
+
+ /* An integer that identifies the min auth strength that is required
+ * by this protocol, for eg. MOUNT3 needs AUTH_UNIX at least.
+ * See RFC 1813, Section 5.2.1.
+ */
+ int min_auth;
+
+ /* The translator in whose context the actor must execute. This is
+ * needed to setup THIS for memory accounting to work correctly.
+ */
+ xlator_t *actorxl;
+};
+
+
+/* Contains global state required for all the RPC services.
+ */
+typedef struct rpc_svc_state {
+
+ /* Contains the list of rpcsvc_stage_t
+ * list of (program, version) handlers.
+ * other options.
+ */
+
+ /* At this point, lock is not used to protect anything. Later, it'll
+ * be used for protecting stages.
+ */
+ pthread_mutex_t rpclock;
+
+ /* This is the first stage that is inited, so that any RPC based
+ * services that do not need multi-threaded support can just use the
+ * service right away. This is not added to the stages list
+ * declared later.
+ * This is also the stage over which all service listeners are run.
+ */
+ rpcsvc_stage_t *defaultstage;
+
+ /* When we have multi-threaded RPC support, we'll use this to link
+ * to the multiple Stages.
+ */
+ struct list_head stages; /* All stages */
+
+ unsigned int memfactor;
+
+ /* List of the authentication schemes available. */
+ struct list_head authschemes;
+
+ /* Reference to the options */
+ dict_t *options;
+
+ /* Allow insecure ports. */
+ int allow_insecure;
+
+ glusterfs_ctx_t *ctx;
+
+ gf_boolean_t register_portmap;
+
+ struct list_head allprograms;
+} rpcsvc_t;
+
+
+/* All users of RPC services should use this API to register their
+ * procedure handlers.
+ */
+extern int
+nfs_rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t program);
+
+extern int
+nfs_rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t program);
+
+/* Inits the global RPC service data structures.
+ * Called in main.
+ */
+extern rpcsvc_t *
+nfs_rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options);
+
+
+extern int
+nfs_rpcsvc_submit_message (rpcsvc_request_t * req, struct iovec msg,
+ struct iobuf *iob);
+
+int
+nfs_rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec msgvec,
+ struct iobuf *msg);
+#define nfs_rpcsvc_record_currentfrag_addr(rs) ((rs)->fragcurrent)
+#define nfs_rpcsvc_record_currenthdr_addr(rs) ((rs)->hdrcurrent)
+
+#define nfs_rpcsvc_record_update_currentfrag(rs, size) \
+ do { \
+ (rs)->fragcurrent += size; \
+ } while (0) \
+
+#define nfs_rpcsvc_record_update_currenthdr(rs, size) \
+ do { \
+ (rs)->hdrcurrent += size; \
+ } while (0) \
+
+
+/* These are used to differentiate between multiple txbufs which form
+ * a single RPC record. For eg, one purpose we use these for is to
+ * prevent dividing a RPC record over multiple TCP segments. Multiple
+ * TCP segments are possible for a single RPC record because we generally do not
+ * have control over how the kernel's TCP segments the buffers when putting
+ * them on the wire. So, on Linux, we use these to set TCP_CORK to create
+ * a single TCP segment from multiple txbufs that are part of the same RPC
+ * record. This improves network performance by reducing tiny message
+ * transmissions.
+ */
+#define RPCSVC_TXB_FIRST 0x1
+#define RPCSVC_TXB_LAST 0x2
+
+/* The list of buffers appended to a connection's pending
+ * transmission list.
+ */
+typedef struct rpcsvc_txbuf {
+ struct list_head txlist;
+ /* The iobuf which contains the full message to be transmitted */
+ struct iobuf *iob;
+
+ /* For vectored messages from an RPC program, we need to be able
+ * maintain a ref to an iobuf which we do not have access to directly
+ * except through the iobref which in turn could've been passed to
+ * the RPC program by a higher layer.
+ *
+ * So either the iob is defined or iobref is defined for a reply,
+ * never both.
+ */
+ struct iobref *iobref;
+ /* In order to handle non-blocking writes, we'll need to keep track of
+ * how much data from an iobuf has been written and where the next
+ * transmission needs to start from. This iov.base points to the base of
+ * the iobuf, iov.len is the size of iobuf being used for the message
+ * from the total size in the iobuf.
+ */
+ struct iovec buf;
+ /* offset is the point from where the next transmission for this buffer
+ * should start.
+ */
+ size_t offset;
+
+ /* This is a special field that tells us what kind of transmission
+ * behaviour to provide to a particular buffer.
+ * See the RPCSVC_TXB_* defines for more info.
+ */
+ int txbehave;
+} rpcsvc_txbuf_t;
+
+extern int
+nfs_rpcsvc_error_reply (rpcsvc_request_t *req);
+
+#define RPCSVC_PEER_STRLEN 1024
+#define RPCSVC_AUTH_ACCEPT 1
+#define RPCSVC_AUTH_REJECT 2
+#define RPCSVC_AUTH_DONTCARE 3
+
+extern int
+nfs_rpcsvc_conn_peername (rpcsvc_conn_t *conn, char *hostname, int hostlen);
+
+extern int
+nfs_rpcsvc_conn_peeraddr (rpcsvc_conn_t *conn, char *addrstr, int addrlen,
+ struct sockaddr *returnsa, socklen_t sasize);
+
+extern int
+nfs_rpcsvc_conn_peer_check (dict_t *options, char *volname,rpcsvc_conn_t *conn);
+
+extern int
+nfs_rpcsvc_conn_privport_check (rpcsvc_t *svc, char *volname,
+ rpcsvc_conn_t *conn);
+#define nfs_rpcsvc_request_seterr(req, err) (req)->rpc_err = err
+#define nfs_rpcsvc_request_set_autherr(req, err) \
+ do { \
+ (req)->auth_err = err; \
+ (req)->rpc_stat = MSG_DENIED; \
+ } while (0) \
+
+extern void
+nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn);
+extern void nfs_rpcsvc_conn_ref (rpcsvc_conn_t *conn);
+extern void nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn);
+
+extern int nfs_rpcsvc_submit_vectors (rpcsvc_request_t *req);
+
+extern int nfs_rpcsvc_request_attach_vector (rpcsvc_request_t *req,
+ struct iovec msgvec,
+ struct iobuf *iob,
+ struct iobref *ioref,
+ int finalvector);
+extern int
+nfs_rpcsvc_request_attach_vectors (rpcsvc_request_t *req, struct iovec *payload,
+ int vcount, struct iobref *piobref);
+
+typedef int (*auth_init_conn) (rpcsvc_conn_t *conn, void *priv);
+typedef int (*auth_init_request) (rpcsvc_request_t *req, void *priv);
+typedef int (*auth_request_authenticate) (rpcsvc_request_t *req, void *priv);
+
+/* This structure needs to be registered by every authentication scheme.
+ * Our authentication schemes are stored per connection because
+ * each connection will end up using a different authentication scheme.
+ */
+typedef struct rpcsvc_auth_ops {
+ auth_init_conn conn_init;
+ auth_init_request request_init;
+ auth_request_authenticate authenticate;
+} rpcsvc_auth_ops_t;
+
+typedef struct rpcsvc_auth_flavour_desc {
+ char authname[RPCSVC_NAME_MAX];
+ int authnum;
+ rpcsvc_auth_ops_t *authops;
+ void *authprivate;
+} rpcsvc_auth_t;
+
+typedef void * (*rpcsvc_auth_initer_t) (rpcsvc_t *svc, dict_t *options);
+
+struct rpcsvc_auth_list {
+ struct list_head authlist;
+ rpcsvc_auth_initer_t init;
+ /* Should be the name with which we identify the auth scheme given
+ * in the volfile options.
+ * This should be different from the authname in rpc_auth_t
+ * in way that makes it easier to specify this scheme in the volfile.
+ * This is because the technical names of the schemes can be a bit
+ * arcane.
+ */
+ char name[RPCSVC_NAME_MAX];
+ rpcsvc_auth_t *auth;
+ int enable;
+};
+
+extern int
+nfs_rpcsvc_auth_request_init (rpcsvc_request_t *req);
+
+extern int
+nfs_rpcsvc_auth_init (rpcsvc_t *svc, dict_t *options);
+
+extern int
+nfs_rpcsvc_auth_conn_init (rpcsvc_conn_t *conn);
+
+extern int
+nfs_rpcsvc_authenticate (rpcsvc_request_t *req);
+
+extern int
+nfs_rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen);
+
+/* If the request has been sent using AUTH_UNIX, this function returns the
+ * auxiliary gids as an array, otherwise, it returns NULL.
+ * Move to auth-unix specific source file when we need to modularize the
+ * authentication code even further to support mode auth schemes.
+ */
+extern gid_t *
+nfs_rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen);
+
+extern int
+nfs_rpcsvc_combine_gen_spec_volume_checks (int gen, int spec);
+
+extern char *
+nfs_rpcsvc_volume_allowed (dict_t *options, char *volname);
+#endif
diff --git a/xlators/nfs/lib/src/xdr-common.h b/xlators/nfs/lib/src/xdr-common.h
new file mode 100644
index 000000000..b3992ab05
--- /dev/null
+++ b/xlators/nfs/lib/src/xdr-common.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NFS_XDR_COMMON_H_
+#define _NFS_XDR_COMMON_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#define NFS_XDR_BYTES_PER_UNIT 4
+
+/* Returns the address of the byte that follows the
+ * last byte used for decoding the previous xdr component.
+ * For eg, once the RPC call for NFS has been decoded, thie macro will return
+ * the address from which the NFS header starts.
+ */
+#define nfs_xdr_decoded_remaining_addr(xdr) ((&xdr)->x_private)
+
+/* Returns the length of the remaining record after the previous decode
+ * operation completed.
+ */
+#define nfs_xdr_decoded_remaining_len(xdr) ((&xdr)->x_handy)
+
+/* Returns the number of bytes used by the last encode operation. */
+#define nfs_xdr_encoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base))
+
+#define nfs_xdr_decoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base))
+
+#endif
diff --git a/xlators/nfs/lib/src/xdr-nfs3.c b/xlators/nfs/lib/src/xdr-nfs3.c
new file mode 100644
index 000000000..febc6a695
--- /dev/null
+++ b/xlators/nfs/lib/src/xdr-nfs3.c
@@ -0,0 +1,1897 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "xdr-nfs3.h"
+#include "mem-pool.h"
+
+#if GF_DARWIN_HOST_OS
+#define xdr_u_quad_t xdr_u_int64_t
+#define xdr_quad_t xdr_int64_t
+#define xdr_uint32_t xdr_u_int32_t
+#endif
+
+bool_t
+xdr_uint64 (XDR *xdrs, uint64 *objp)
+{
+ if (!xdr_uint64_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_int64 (XDR *xdrs, int64 *objp)
+{
+ if (!xdr_int64_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_uint32 (XDR *xdrs, uint32 *objp)
+{
+ if (!xdr_uint32_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_int32 (XDR *xdrs, int32 *objp)
+{
+ if (!xdr_int32_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_filename3 (XDR *xdrs, filename3 *objp)
+{
+ if (!xdr_string (xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfspath3 (XDR *xdrs, nfspath3 *objp)
+{
+ if (!xdr_string (xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fileid3 (XDR *xdrs, fileid3 *objp)
+{
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_cookie3 (XDR *xdrs, cookie3 *objp)
+{
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_cookieverf3 (XDR *xdrs, cookieverf3 objp)
+{
+ if (!xdr_opaque (xdrs, objp, NFS3_COOKIEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_createverf3 (XDR *xdrs, createverf3 objp)
+{
+ if (!xdr_opaque (xdrs, objp, NFS3_CREATEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_writeverf3 (XDR *xdrs, writeverf3 objp)
+{
+ if (!xdr_opaque (xdrs, objp, NFS3_WRITEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_uid3 (XDR *xdrs, uid3 *objp)
+{
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gid3 (XDR *xdrs, gid3 *objp)
+{
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_size3 (XDR *xdrs, size3 *objp)
+{
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_offset3 (XDR *xdrs, offset3 *objp)
+{
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mode3 (XDR *xdrs, mode3 *objp)
+{
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_count3 (XDR *xdrs, count3 *objp)
+{
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfsstat3 (XDR *xdrs, nfsstat3 *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ftype3 (XDR *xdrs, ftype3 *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_specdata3 (XDR *xdrs, specdata3 *objp)
+{
+ if (!xdr_uint32 (xdrs, &objp->specdata1))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->specdata2))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfs_fh3 (XDR *xdrs, nfs_fh3 *objp)
+{
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS3_FHSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfstime3 (XDR *xdrs, nfstime3 *objp)
+{
+ if (!xdr_uint32 (xdrs, &objp->seconds))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->nseconds))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fattr3 (XDR *xdrs, fattr3 *objp)
+{
+ if (!xdr_ftype3 (xdrs, &objp->type))
+ return FALSE;
+ if (!xdr_mode3 (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_uid3 (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_gid3 (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->used))
+ return FALSE;
+ if (!xdr_specdata3 (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_uint64 (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_post_op_attr (XDR *xdrs, post_op_attr *objp)
+{
+ if (!xdr_bool (xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_fattr3 (xdrs, &objp->post_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_wcc_attr (XDR *xdrs, wcc_attr *objp)
+{
+ if (!xdr_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_pre_op_attr (XDR *xdrs, pre_op_attr *objp)
+{
+ if (!xdr_bool (xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_wcc_attr (xdrs, &objp->pre_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_wcc_data (XDR *xdrs, wcc_data *objp)
+{
+ if (!xdr_pre_op_attr (xdrs, &objp->before))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->after))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_post_op_fh3 (XDR *xdrs, post_op_fh3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->handle_follows))
+ return FALSE;
+ switch (objp->handle_follows) {
+ case TRUE:
+ if (!xdr_nfs_fh3 (xdrs, &objp->post_op_fh3_u.handle))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_time_how (XDR *xdrs, time_how *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_set_mode3 (XDR *xdrs, set_mode3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_mode3 (xdrs, &objp->set_mode3_u.mode))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_uid3 (XDR *xdrs, set_uid3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_uid3 (xdrs, &objp->set_uid3_u.uid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_gid3 (XDR *xdrs, set_gid3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_gid3 (xdrs, &objp->set_gid3_u.gid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_size3 (XDR *xdrs, set_size3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_size3 (xdrs, &objp->set_size3_u.size))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_atime (XDR *xdrs, set_atime *objp)
+{
+ if (!xdr_time_how (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (!xdr_nfstime3 (xdrs, &objp->set_atime_u.atime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_mtime (XDR *xdrs, set_mtime *objp)
+{
+ if (!xdr_time_how (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (!xdr_nfstime3 (xdrs, &objp->set_mtime_u.mtime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_sattr3 (XDR *xdrs, sattr3 *objp)
+{
+ if (!xdr_set_mode3 (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_set_uid3 (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_set_gid3 (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_set_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_set_atime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_set_mtime (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_diropargs3 (XDR *xdrs, diropargs3 *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_getattr3args (XDR *xdrs, getattr3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_getattr3resok (XDR *xdrs, getattr3resok *objp)
+{
+ if (!xdr_fattr3 (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_getattr3res (XDR *xdrs, getattr3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_getattr3resok (xdrs, &objp->getattr3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_sattrguard3 (XDR *xdrs, sattrguard3 *objp)
+{
+ if (!xdr_bool (xdrs, &objp->check))
+ return FALSE;
+ switch (objp->check) {
+ case TRUE:
+ if (!xdr_nfstime3 (xdrs, &objp->sattrguard3_u.obj_ctime))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_setattr3args (XDR *xdrs, setattr3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_sattr3 (xdrs, &objp->new_attributes))
+ return FALSE;
+ if (!xdr_sattrguard3 (xdrs, &objp->guard))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_setattr3resok (XDR *xdrs, setattr3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_setattr3resfail (XDR *xdrs, setattr3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_setattr3res (XDR *xdrs, setattr3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_setattr3resok (xdrs, &objp->setattr3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_setattr3resfail (xdrs, &objp->setattr3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_lookup3args (XDR *xdrs, lookup3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_lookup3resok (XDR *xdrs, lookup3resok *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_lookup3resfail (XDR *xdrs, lookup3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_lookup3res (XDR *xdrs, lookup3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_lookup3resok (xdrs, &objp->lookup3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_lookup3resfail (xdrs, &objp->lookup3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_access3args (XDR *xdrs, access3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_access3resok (XDR *xdrs, access3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_access3resfail (XDR *xdrs, access3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_access3res (XDR *xdrs, access3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_access3resok (xdrs, &objp->access3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_access3resfail (xdrs, &objp->access3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_readlink3args (XDR *xdrs, readlink3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readlink3resok (XDR *xdrs, readlink3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_nfspath3 (xdrs, &objp->data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readlink3resfail (XDR *xdrs, readlink3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readlink3res (XDR *xdrs, readlink3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_readlink3resok (xdrs, &objp->readlink3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_readlink3resfail (xdrs, &objp->readlink3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_read3args (XDR *xdrs, read3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_read3resok_nocopy (XDR *xdrs, read3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ if (!xdr_u_int (xdrs, (u_int *) &objp->data.data_len))
+ return FALSE;
+ return TRUE;
+}
+
+
+bool_t
+xdr_read3resok (XDR *xdrs, read3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_read3resfail (XDR *xdrs, read3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+
+bool_t
+xdr_read3res_nocopy (XDR *xdrs, read3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_read3resok_nocopy (xdrs, &objp->read3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_read3resfail (xdrs, &objp->read3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+
+bool_t
+xdr_read3res (XDR *xdrs, read3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_read3resok (xdrs, &objp->read3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_read3resfail (xdrs, &objp->read3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_stable_how (XDR *xdrs, stable_how *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_write3args (XDR *xdrs, write3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_stable_how (xdrs, &objp->stable))
+ return FALSE;
+
+ /* Added specifically to avoid copies from the xdr buffer into
+ * the write3args structure, which will also require an already
+ * allocated buffer. That is not optimal.
+ */
+ if (!xdr_u_int (xdrs, (u_int *) &objp->data.data_len))
+ return FALSE;
+
+ /* The remaining bytes in the xdr buffer are the bytes that need to be
+ * written. See how these bytes are extracted in the xdr_to_write3args
+ * code path. Be careful, while using the write3args structure, since
+ * only the data.data_len has been filled. The actual data is
+ * extracted in xdr_to_write3args path.
+ */
+
+ /* if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ */
+ return TRUE;
+}
+
+bool_t
+xdr_write3resok (XDR *xdrs, write3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_stable_how (xdrs, &objp->committed))
+ return FALSE;
+ if (!xdr_writeverf3 (xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_write3resfail (XDR *xdrs, write3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_write3res (XDR *xdrs, write3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_write3resok (xdrs, &objp->write3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_write3resfail (xdrs, &objp->write3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_createmode3 (XDR *xdrs, createmode3 *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_createhow3 (XDR *xdrs, createhow3 *objp)
+{
+ if (!xdr_createmode3 (xdrs, &objp->mode))
+ return FALSE;
+ switch (objp->mode) {
+ case UNCHECKED:
+ case GUARDED:
+ if (!xdr_sattr3 (xdrs, &objp->createhow3_u.obj_attributes))
+ return FALSE;
+ break;
+ case EXCLUSIVE:
+ if (!xdr_createverf3 (xdrs, objp->createhow3_u.verf))
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_create3args (XDR *xdrs, create3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_createhow3 (xdrs, &objp->how))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_create3resok (XDR *xdrs, create3resok *objp)
+{
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_create3resfail (XDR *xdrs, create3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_create3res (XDR *xdrs, create3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_create3resok (xdrs, &objp->create3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_create3resfail (xdrs, &objp->create3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_mkdir3args (XDR *xdrs, mkdir3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_sattr3 (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mkdir3resok (XDR *xdrs, mkdir3resok *objp)
+{
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mkdir3resfail (XDR *xdrs, mkdir3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mkdir3res (XDR *xdrs, mkdir3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_mkdir3resok (xdrs, &objp->mkdir3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_mkdir3resfail (xdrs, &objp->mkdir3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_symlinkdata3 (XDR *xdrs, symlinkdata3 *objp)
+{
+ if (!xdr_sattr3 (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_nfspath3 (xdrs, &objp->symlink_data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_symlink3args (XDR *xdrs, symlink3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_symlinkdata3 (xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_symlink3resok (XDR *xdrs, symlink3resok *objp)
+{
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_symlink3resfail (XDR *xdrs, symlink3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_symlink3res (XDR *xdrs, symlink3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_symlink3resok (xdrs, &objp->symlink3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_symlink3resfail (xdrs, &objp->symlink3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_devicedata3 (XDR *xdrs, devicedata3 *objp)
+{
+ if (!xdr_sattr3 (xdrs, &objp->dev_attributes))
+ return FALSE;
+ if (!xdr_specdata3 (xdrs, &objp->spec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mknoddata3 (XDR *xdrs, mknoddata3 *objp)
+{
+ if (!xdr_ftype3 (xdrs, &objp->type))
+ return FALSE;
+ switch (objp->type) {
+ case NF3CHR:
+ case NF3BLK:
+ if (!xdr_devicedata3 (xdrs, &objp->mknoddata3_u.device))
+ return FALSE;
+ break;
+ case NF3SOCK:
+ case NF3FIFO:
+ if (!xdr_sattr3 (xdrs, &objp->mknoddata3_u.pipe_attributes))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_mknod3args (XDR *xdrs, mknod3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_mknoddata3 (xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mknod3resok (XDR *xdrs, mknod3resok *objp)
+{
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mknod3resfail (XDR *xdrs, mknod3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mknod3res (XDR *xdrs, mknod3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_mknod3resok (xdrs, &objp->mknod3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_mknod3resfail (xdrs, &objp->mknod3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_remove3args (XDR *xdrs, remove3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remove3resok (XDR *xdrs, remove3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remove3resfail (XDR *xdrs, remove3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remove3res (XDR *xdrs, remove3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_remove3resok (xdrs, &objp->remove3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_remove3resfail (xdrs, &objp->remove3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_rmdir3args (XDR *xdrs, rmdir3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rmdir3resok (XDR *xdrs, rmdir3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rmdir3resfail (XDR *xdrs, rmdir3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rmdir3res (XDR *xdrs, rmdir3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_rmdir3resok (xdrs, &objp->rmdir3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_rmdir3resfail (xdrs, &objp->rmdir3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_rename3args (XDR *xdrs, rename3args *objp)
+{
+ if (!xdr_diropargs3 (xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_diropargs3 (xdrs, &objp->to))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rename3resok (XDR *xdrs, rename3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rename3resfail (XDR *xdrs, rename3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_rename3res (XDR *xdrs, rename3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_rename3resok (xdrs, &objp->rename3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_rename3resfail (xdrs, &objp->rename3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_link3args (XDR *xdrs, link3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_diropargs3 (xdrs, &objp->link))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_link3resok (XDR *xdrs, link3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_link3resfail (XDR *xdrs, link3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_link3res (XDR *xdrs, link3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_link3resok (xdrs, &objp->link3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_link3resfail (xdrs, &objp->link3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_readdir3args (XDR *xdrs, readdir3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entry3 (XDR *xdrs, entry3 *objp)
+{
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entry3), (xdrproc_t) xdr_entry3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirlist3 (XDR *xdrs, dirlist3 *objp)
+{
+ if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entry3), (xdrproc_t) xdr_entry3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdir3resok (XDR *xdrs, readdir3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_dirlist3 (xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdir3resfail (XDR *xdrs, readdir3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdir3res (XDR *xdrs, readdir3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_readdir3resok (xdrs, &objp->readdir3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_readdir3resfail (xdrs, &objp->readdir3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_readdirp3args (XDR *xdrs, readdirp3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->dircount))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->maxcount))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entryp3 (XDR *xdrs, entryp3 *objp)
+{
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->name_attributes))
+ return FALSE;
+ if (!xdr_post_op_fh3 (xdrs, &objp->name_handle))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entryp3), (xdrproc_t) xdr_entryp3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirlistp3 (XDR *xdrs, dirlistp3 *objp)
+{
+ if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entryp3), (xdrproc_t) xdr_entryp3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdirp3resok (XDR *xdrs, readdirp3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_dirlistp3 (xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdirp3resfail (XDR *xdrs, readdirp3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdirp3res (XDR *xdrs, readdirp3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_readdirp3resok (xdrs, &objp->readdirp3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_readdirp3resfail (xdrs, &objp->readdirp3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_fsstat3args (XDR *xdrs, fsstat3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsstat3resok (XDR *xdrs, fsstat3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->tbytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->fbytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->abytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->tfiles))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->ffiles))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->afiles))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->invarsec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsstat3resfail (XDR *xdrs, fsstat3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsstat3res (XDR *xdrs, fsstat3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_fsstat3resok (xdrs, &objp->fsstat3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_fsstat3resfail (xdrs, &objp->fsstat3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_fsinfo3args (XDR *xdrs, fsinfo3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsinfo3resok (XDR *xdrs, fsinfo3resok *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->dtpref))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsinfo3resfail (XDR *xdrs, fsinfo3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fsinfo3res (XDR *xdrs, fsinfo3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_fsinfo3resok (xdrs, &objp->fsinfo3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_fsinfo3resfail (xdrs, &objp->fsinfo3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_pathconf3args (XDR *xdrs, pathconf3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_pathconf3resok (XDR *xdrs, pathconf3resok *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ IXDR_PUT_BOOL(buf, objp->no_trunc);
+ IXDR_PUT_BOOL(buf, objp->chown_restricted);
+ IXDR_PUT_BOOL(buf, objp->case_insensitive);
+ IXDR_PUT_BOOL(buf, objp->case_preserving);
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ objp->no_trunc = IXDR_GET_BOOL(buf);
+ objp->chown_restricted = IXDR_GET_BOOL(buf);
+ objp->case_insensitive = IXDR_GET_BOOL(buf);
+ objp->case_preserving = IXDR_GET_BOOL(buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_pathconf3resfail (XDR *xdrs, pathconf3resfail *objp)
+{
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_pathconf3res (XDR *xdrs, pathconf3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_pathconf3resok (xdrs, &objp->pathconf3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_pathconf3resfail (xdrs, &objp->pathconf3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_commit3args (XDR *xdrs, commit3args *objp)
+{
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_commit3resok (XDR *xdrs, commit3resok *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_writeverf3 (xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_commit3resfail (XDR *xdrs, commit3resfail *objp)
+{
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_commit3res (XDR *xdrs, commit3res *objp)
+{
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_commit3resok (xdrs, &objp->commit3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_commit3resfail (xdrs, &objp->commit3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
+{
+ if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirpath (XDR *xdrs, dirpath *objp)
+{
+ if (!xdr_string (xdrs, objp, MNTPATHLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_name (XDR *xdrs, name *objp)
+{
+ if (!xdr_string (xdrs, objp, MNTNAMLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
+{
+ if (!xdr_fhandle3 (xdrs, &objp->fhandle))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->auth_flavors.auth_flavors_val, (u_int *) &objp->auth_flavors.auth_flavors_len, ~0,
+ sizeof (int), (xdrproc_t) xdr_int))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountres3 (XDR *xdrs, mountres3 *objp)
+{
+ if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
+ return FALSE;
+ switch (objp->fhs_status) {
+ case MNT3_OK:
+ if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_mountlist (XDR *xdrs, mountlist *objp)
+{
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountbody (XDR *xdrs, mountbody *objp)
+{
+ if (!xdr_name (xdrs, &objp->ml_hostname))
+ return FALSE;
+ if (!xdr_dirpath (xdrs, &objp->ml_directory))
+ return FALSE;
+ if (!xdr_mountlist (xdrs, &objp->ml_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groups (XDR *xdrs, groups *objp)
+{
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groupnode (XDR *xdrs, groupnode *objp)
+{
+ if (!xdr_name (xdrs, &objp->gr_name))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->gr_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exports (XDR *xdrs, exports *objp)
+{
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exportnode (XDR *xdrs, exportnode *objp)
+{
+ if (!xdr_dirpath (xdrs, &objp->ex_dir))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->ex_groups))
+ return FALSE;
+ if (!xdr_exports (xdrs, &objp->ex_next))
+ return FALSE;
+ return TRUE;
+}
+
+void
+xdr_free_exports_list (struct exportnode *first)
+{
+ struct exportnode *elist = NULL;
+
+ if (!first)
+ return;
+
+ while (first) {
+ elist = first->ex_next;
+ if (first->ex_dir)
+ GF_FREE (first->ex_dir);
+
+ if (first->ex_groups) {
+ if (first->ex_groups->gr_name)
+ GF_FREE (first->ex_groups->gr_name);
+ GF_FREE (first->ex_groups);
+ }
+
+ GF_FREE (first);
+ first = elist;
+ }
+
+}
+
+
+void
+xdr_free_mountlist (mountlist ml)
+{
+ struct mountbody *next = NULL;
+
+ if (!ml)
+ return;
+
+ while (ml) {
+ GF_FREE (ml->ml_hostname);
+ GF_FREE (ml->ml_directory);
+ next = ml->ml_next;
+ GF_FREE (ml);
+ ml = next;
+ }
+
+ return;
+}
+
+
+/* Free statements are based on the way sunrpc xdr decoding
+ * code performs memory allocations.
+ */
+void
+xdr_free_write3args_nocopy (write3args *wa)
+{
+ if (!wa)
+ return;
+
+ FREE (wa->file.data.data_val);
+}
+
+
diff --git a/xlators/nfs/lib/src/xdr-nfs3.h b/xlators/nfs/lib/src/xdr-nfs3.h
new file mode 100644
index 000000000..0530876a8
--- /dev/null
+++ b/xlators/nfs/lib/src/xdr-nfs3.h
@@ -0,0 +1,1206 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _XDR_NFS3_H
+#define _XDR_NFS3_H
+
+#include <rpc/rpc.h>
+#include <sys/types.h>
+
+#define NFS3_FHSIZE 64
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
+
+#define NFS3_ENTRY3_FIXED_SIZE 24
+#define NFS3_POSTOPATTR_SIZE 88
+#define NFS3_READDIR_RESOK_SIZE (NFS3_POSTOPATTR_SIZE + sizeof (bool_t) + NFS3_COOKIEVERFSIZE)
+
+/* In size of post_op_fh3, the length of the file handle will have to be
+ * included separately since we have variable length fh. Here we only account
+ * for the field for handle_follows and for the file handle length field.
+ */
+#define NFS3_POSTOPFH3_FIXED_SIZE (sizeof (bool_t) + sizeof (uint32_t))
+
+/* Similarly, the size of the entry will have to include the variable length
+ * file handle and the length of the entry name.
+ */
+#define NFS3_ENTRYP3_FIXED_SIZE (NFS3_ENTRY3_FIXED_SIZE + NFS3_POSTOPATTR_SIZE + NFS3_POSTOPFH3_FIXED_SIZE)
+
+typedef uint64_t uint64;
+typedef int64_t int64;
+typedef uint32_t uint32;
+typedef int32_t int32;
+typedef char *filename3;
+typedef char *nfspath3;
+typedef uint64 fileid3;
+typedef uint64 cookie3;
+typedef char cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef char createverf3[NFS3_CREATEVERFSIZE];
+typedef char writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32 uid3;
+typedef uint32 gid3;
+typedef uint64 size3;
+typedef uint64 offset3;
+typedef uint32 mode3;
+typedef uint32 count3;
+
+#define NFS3MODE_SETXUID 0x00800
+#define NFS3MODE_SETXGID 0x00400
+#define NFS3MODE_SAVESWAPTXT 0x00200
+#define NFS3MODE_ROWNER 0x00100
+#define NFS3MODE_WOWNER 0x00080
+#define NFS3MODE_XOWNER 0x00040
+#define NFS3MODE_RGROUP 0x00020
+#define NFS3MODE_WGROUP 0x00010
+#define NFS3MODE_XGROUP 0x00008
+#define NFS3MODE_ROTHER 0x00004
+#define NFS3MODE_WOTHER 0x00002
+#define NFS3MODE_XOTHER 0x00001
+
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008,
+};
+typedef enum nfsstat3 nfsstat3;
+
+enum ftype3 {
+ NF3REG = 1,
+ NF3DIR = 2,
+ NF3BLK = 3,
+ NF3CHR = 4,
+ NF3LNK = 5,
+ NF3SOCK = 6,
+ NF3FIFO = 7,
+};
+typedef enum ftype3 ftype3;
+
+struct specdata3 {
+ uint32 specdata1;
+ uint32 specdata2;
+};
+typedef struct specdata3 specdata3;
+
+struct nfs_fh3 {
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct nfs_fh3 nfs_fh3;
+
+struct nfstime3 {
+ uint32 seconds;
+ uint32 nseconds;
+};
+typedef struct nfstime3 nfstime3;
+
+struct fattr3 {
+ ftype3 type;
+ mode3 mode;
+ uint32 nlink;
+ uid3 uid;
+ gid3 gid;
+ size3 size;
+ size3 used;
+ specdata3 rdev;
+ uint64 fsid;
+ fileid3 fileid;
+ nfstime3 atime;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+typedef struct fattr3 fattr3;
+
+struct post_op_attr {
+ bool_t attributes_follow;
+ union {
+ fattr3 attributes;
+ } post_op_attr_u;
+};
+typedef struct post_op_attr post_op_attr;
+
+struct wcc_attr {
+ size3 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+typedef struct wcc_attr wcc_attr;
+
+struct pre_op_attr {
+ bool_t attributes_follow;
+ union {
+ wcc_attr attributes;
+ } pre_op_attr_u;
+};
+typedef struct pre_op_attr pre_op_attr;
+
+struct wcc_data {
+ pre_op_attr before;
+ post_op_attr after;
+};
+typedef struct wcc_data wcc_data;
+
+struct post_op_fh3 {
+ bool_t handle_follows;
+ union {
+ nfs_fh3 handle;
+ } post_op_fh3_u;
+};
+typedef struct post_op_fh3 post_op_fh3;
+
+enum time_how {
+ DONT_CHANGE = 0,
+ SET_TO_SERVER_TIME = 1,
+ SET_TO_CLIENT_TIME = 2,
+};
+typedef enum time_how time_how;
+
+struct set_mode3 {
+ bool_t set_it;
+ union {
+ mode3 mode;
+ } set_mode3_u;
+};
+typedef struct set_mode3 set_mode3;
+
+struct set_uid3 {
+ bool_t set_it;
+ union {
+ uid3 uid;
+ } set_uid3_u;
+};
+typedef struct set_uid3 set_uid3;
+
+struct set_gid3 {
+ bool_t set_it;
+ union {
+ gid3 gid;
+ } set_gid3_u;
+};
+typedef struct set_gid3 set_gid3;
+
+struct set_size3 {
+ bool_t set_it;
+ union {
+ size3 size;
+ } set_size3_u;
+};
+typedef struct set_size3 set_size3;
+
+struct set_atime {
+ time_how set_it;
+ union {
+ nfstime3 atime;
+ } set_atime_u;
+};
+typedef struct set_atime set_atime;
+
+struct set_mtime {
+ time_how set_it;
+ union {
+ nfstime3 mtime;
+ } set_mtime_u;
+};
+typedef struct set_mtime set_mtime;
+
+struct sattr3 {
+ set_mode3 mode;
+ set_uid3 uid;
+ set_gid3 gid;
+ set_size3 size;
+ set_atime atime;
+ set_mtime mtime;
+};
+typedef struct sattr3 sattr3;
+
+struct diropargs3 {
+ nfs_fh3 dir;
+ filename3 name;
+};
+typedef struct diropargs3 diropargs3;
+
+struct getattr3args {
+ nfs_fh3 object;
+};
+typedef struct getattr3args getattr3args;
+
+struct getattr3resok {
+ fattr3 obj_attributes;
+};
+typedef struct getattr3resok getattr3resok;
+
+struct getattr3res {
+ nfsstat3 status;
+ union {
+ getattr3resok resok;
+ } getattr3res_u;
+};
+typedef struct getattr3res getattr3res;
+
+struct sattrguard3 {
+ bool_t check;
+ union {
+ nfstime3 obj_ctime;
+ } sattrguard3_u;
+};
+typedef struct sattrguard3 sattrguard3;
+
+struct setattr3args {
+ nfs_fh3 object;
+ sattr3 new_attributes;
+ sattrguard3 guard;
+};
+typedef struct setattr3args setattr3args;
+
+struct setattr3resok {
+ wcc_data obj_wcc;
+};
+typedef struct setattr3resok setattr3resok;
+
+struct setattr3resfail {
+ wcc_data obj_wcc;
+};
+typedef struct setattr3resfail setattr3resfail;
+
+struct setattr3res {
+ nfsstat3 status;
+ union {
+ setattr3resok resok;
+ setattr3resfail resfail;
+ } setattr3res_u;
+};
+typedef struct setattr3res setattr3res;
+
+struct lookup3args {
+ diropargs3 what;
+};
+typedef struct lookup3args lookup3args;
+
+struct lookup3resok {
+ nfs_fh3 object;
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+};
+typedef struct lookup3resok lookup3resok;
+
+struct lookup3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct lookup3resfail lookup3resfail;
+
+struct lookup3res {
+ nfsstat3 status;
+ union {
+ lookup3resok resok;
+ lookup3resfail resfail;
+ } lookup3res_u;
+};
+typedef struct lookup3res lookup3res;
+#define ACCESS3_READ 0x0001
+#define ACCESS3_LOOKUP 0x0002
+#define ACCESS3_MODIFY 0x0004
+#define ACCESS3_EXTEND 0x0008
+#define ACCESS3_DELETE 0x0010
+#define ACCESS3_EXECUTE 0x0020
+
+struct access3args {
+ nfs_fh3 object;
+ uint32 access;
+};
+typedef struct access3args access3args;
+
+struct access3resok {
+ post_op_attr obj_attributes;
+ uint32 access;
+};
+typedef struct access3resok access3resok;
+
+struct access3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct access3resfail access3resfail;
+
+struct access3res {
+ nfsstat3 status;
+ union {
+ access3resok resok;
+ access3resfail resfail;
+ } access3res_u;
+};
+typedef struct access3res access3res;
+
+struct readlink3args {
+ nfs_fh3 symlink;
+};
+typedef struct readlink3args readlink3args;
+
+struct readlink3resok {
+ post_op_attr symlink_attributes;
+ nfspath3 data;
+};
+typedef struct readlink3resok readlink3resok;
+
+struct readlink3resfail {
+ post_op_attr symlink_attributes;
+};
+typedef struct readlink3resfail readlink3resfail;
+
+struct readlink3res {
+ nfsstat3 status;
+ union {
+ readlink3resok resok;
+ readlink3resfail resfail;
+ } readlink3res_u;
+};
+typedef struct readlink3res readlink3res;
+
+struct read3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+typedef struct read3args read3args;
+
+struct read3resok {
+ post_op_attr file_attributes;
+ count3 count;
+ bool_t eof;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct read3resok read3resok;
+
+struct read3resfail {
+ post_op_attr file_attributes;
+};
+typedef struct read3resfail read3resfail;
+
+struct read3res {
+ nfsstat3 status;
+ union {
+ read3resok resok;
+ read3resfail resfail;
+ } read3res_u;
+};
+typedef struct read3res read3res;
+
+enum stable_how {
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2,
+};
+typedef enum stable_how stable_how;
+
+struct write3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+ stable_how stable;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct write3args write3args;
+
+/* Generally, the protocol allows the file handle to be less than 64 bytes but
+ * our server does not return file handles less than 64b so we can safely say
+ * sizeof (nfs_fh3) rather than first trying to extract the fh size of the
+ * network followed by a sized-read of the file handle.
+ */
+#define NFS3_WRITE3ARGS_SIZE (sizeof (uint32_t) + NFS3_FHSIZE + sizeof (offset3) + sizeof (count3) + sizeof (uint32_t))
+struct write3resok {
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ writeverf3 verf;
+};
+typedef struct write3resok write3resok;
+
+struct write3resfail {
+ wcc_data file_wcc;
+};
+typedef struct write3resfail write3resfail;
+
+struct write3res {
+ nfsstat3 status;
+ union {
+ write3resok resok;
+ write3resfail resfail;
+ } write3res_u;
+};
+typedef struct write3res write3res;
+
+enum createmode3 {
+ UNCHECKED = 0,
+ GUARDED = 1,
+ EXCLUSIVE = 2,
+};
+typedef enum createmode3 createmode3;
+
+struct createhow3 {
+ createmode3 mode;
+ union {
+ sattr3 obj_attributes;
+ createverf3 verf;
+ } createhow3_u;
+};
+typedef struct createhow3 createhow3;
+
+struct create3args {
+ diropargs3 where;
+ createhow3 how;
+};
+typedef struct create3args create3args;
+
+struct create3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct create3resok create3resok;
+
+struct create3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct create3resfail create3resfail;
+
+struct create3res {
+ nfsstat3 status;
+ union {
+ create3resok resok;
+ create3resfail resfail;
+ } create3res_u;
+};
+typedef struct create3res create3res;
+
+struct mkdir3args {
+ diropargs3 where;
+ sattr3 attributes;
+};
+typedef struct mkdir3args mkdir3args;
+
+struct mkdir3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct mkdir3resok mkdir3resok;
+
+struct mkdir3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct mkdir3resfail mkdir3resfail;
+
+struct mkdir3res {
+ nfsstat3 status;
+ union {
+ mkdir3resok resok;
+ mkdir3resfail resfail;
+ } mkdir3res_u;
+};
+typedef struct mkdir3res mkdir3res;
+
+struct symlinkdata3 {
+ sattr3 symlink_attributes;
+ nfspath3 symlink_data;
+};
+typedef struct symlinkdata3 symlinkdata3;
+
+struct symlink3args {
+ diropargs3 where;
+ symlinkdata3 symlink;
+};
+typedef struct symlink3args symlink3args;
+
+struct symlink3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct symlink3resok symlink3resok;
+
+struct symlink3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct symlink3resfail symlink3resfail;
+
+struct symlink3res {
+ nfsstat3 status;
+ union {
+ symlink3resok resok;
+ symlink3resfail resfail;
+ } symlink3res_u;
+};
+typedef struct symlink3res symlink3res;
+
+struct devicedata3 {
+ sattr3 dev_attributes;
+ specdata3 spec;
+};
+typedef struct devicedata3 devicedata3;
+
+struct mknoddata3 {
+ ftype3 type;
+ union {
+ devicedata3 device;
+ sattr3 pipe_attributes;
+ } mknoddata3_u;
+};
+typedef struct mknoddata3 mknoddata3;
+
+struct mknod3args {
+ diropargs3 where;
+ mknoddata3 what;
+};
+typedef struct mknod3args mknod3args;
+
+struct mknod3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct mknod3resok mknod3resok;
+
+struct mknod3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct mknod3resfail mknod3resfail;
+
+struct mknod3res {
+ nfsstat3 status;
+ union {
+ mknod3resok resok;
+ mknod3resfail resfail;
+ } mknod3res_u;
+};
+typedef struct mknod3res mknod3res;
+
+struct remove3args {
+ diropargs3 object;
+};
+typedef struct remove3args remove3args;
+
+struct remove3resok {
+ wcc_data dir_wcc;
+};
+typedef struct remove3resok remove3resok;
+
+struct remove3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct remove3resfail remove3resfail;
+
+struct remove3res {
+ nfsstat3 status;
+ union {
+ remove3resok resok;
+ remove3resfail resfail;
+ } remove3res_u;
+};
+typedef struct remove3res remove3res;
+
+struct rmdir3args {
+ diropargs3 object;
+};
+typedef struct rmdir3args rmdir3args;
+
+struct rmdir3resok {
+ wcc_data dir_wcc;
+};
+typedef struct rmdir3resok rmdir3resok;
+
+struct rmdir3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct rmdir3resfail rmdir3resfail;
+
+struct rmdir3res {
+ nfsstat3 status;
+ union {
+ rmdir3resok resok;
+ rmdir3resfail resfail;
+ } rmdir3res_u;
+};
+typedef struct rmdir3res rmdir3res;
+
+struct rename3args {
+ diropargs3 from;
+ diropargs3 to;
+};
+typedef struct rename3args rename3args;
+
+struct rename3resok {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+typedef struct rename3resok rename3resok;
+
+struct rename3resfail {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+typedef struct rename3resfail rename3resfail;
+
+struct rename3res {
+ nfsstat3 status;
+ union {
+ rename3resok resok;
+ rename3resfail resfail;
+ } rename3res_u;
+};
+typedef struct rename3res rename3res;
+
+struct link3args {
+ nfs_fh3 file;
+ diropargs3 link;
+};
+typedef struct link3args link3args;
+
+struct link3resok {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+typedef struct link3resok link3resok;
+
+struct link3resfail {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+typedef struct link3resfail link3resfail;
+
+struct link3res {
+ nfsstat3 status;
+ union {
+ link3resok resok;
+ link3resfail resfail;
+ } link3res_u;
+};
+typedef struct link3res link3res;
+
+struct readdir3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 count;
+};
+typedef struct readdir3args readdir3args;
+
+struct entry3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ struct entry3 *nextentry;
+};
+typedef struct entry3 entry3;
+
+struct dirlist3 {
+ entry3 *entries;
+ bool_t eof;
+};
+typedef struct dirlist3 dirlist3;
+
+struct readdir3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlist3 reply;
+};
+typedef struct readdir3resok readdir3resok;
+
+struct readdir3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct readdir3resfail readdir3resfail;
+
+struct readdir3res {
+ nfsstat3 status;
+ union {
+ readdir3resok resok;
+ readdir3resfail resfail;
+ } readdir3res_u;
+};
+typedef struct readdir3res readdir3res;
+
+struct readdirp3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 dircount;
+ count3 maxcount;
+};
+typedef struct readdirp3args readdirp3args;
+
+struct entryp3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ post_op_attr name_attributes;
+ post_op_fh3 name_handle;
+ struct entryp3 *nextentry;
+};
+typedef struct entryp3 entryp3;
+
+struct dirlistp3 {
+ entryp3 *entries;
+ bool_t eof;
+};
+typedef struct dirlistp3 dirlistp3;
+
+struct readdirp3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlistp3 reply;
+};
+typedef struct readdirp3resok readdirp3resok;
+
+struct readdirp3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct readdirp3resfail readdirp3resfail;
+
+struct readdirp3res {
+ nfsstat3 status;
+ union {
+ readdirp3resok resok;
+ readdirp3resfail resfail;
+ } readdirp3res_u;
+};
+typedef struct readdirp3res readdirp3res;
+
+struct fsstat3args {
+ nfs_fh3 fsroot;
+};
+typedef struct fsstat3args fsstat3args;
+
+struct fsstat3resok {
+ post_op_attr obj_attributes;
+ size3 tbytes;
+ size3 fbytes;
+ size3 abytes;
+ size3 tfiles;
+ size3 ffiles;
+ size3 afiles;
+ uint32 invarsec;
+};
+typedef struct fsstat3resok fsstat3resok;
+
+struct fsstat3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct fsstat3resfail fsstat3resfail;
+
+struct fsstat3res {
+ nfsstat3 status;
+ union {
+ fsstat3resok resok;
+ fsstat3resfail resfail;
+ } fsstat3res_u;
+};
+typedef struct fsstat3res fsstat3res;
+#define FSF3_LINK 0x0001
+#define FSF3_SYMLINK 0x0002
+#define FSF3_HOMOGENEOUS 0x0008
+#define FSF3_CANSETTIME 0x0010
+
+struct fsinfo3args {
+ nfs_fh3 fsroot;
+};
+typedef struct fsinfo3args fsinfo3args;
+
+struct fsinfo3resok {
+ post_op_attr obj_attributes;
+ uint32 rtmax;
+ uint32 rtpref;
+ uint32 rtmult;
+ uint32 wtmax;
+ uint32 wtpref;
+ uint32 wtmult;
+ uint32 dtpref;
+ size3 maxfilesize;
+ nfstime3 time_delta;
+ uint32 properties;
+};
+typedef struct fsinfo3resok fsinfo3resok;
+
+struct fsinfo3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct fsinfo3resfail fsinfo3resfail;
+
+struct fsinfo3res {
+ nfsstat3 status;
+ union {
+ fsinfo3resok resok;
+ fsinfo3resfail resfail;
+ } fsinfo3res_u;
+};
+typedef struct fsinfo3res fsinfo3res;
+
+struct pathconf3args {
+ nfs_fh3 object;
+};
+typedef struct pathconf3args pathconf3args;
+
+struct pathconf3resok {
+ post_op_attr obj_attributes;
+ uint32 linkmax;
+ uint32 name_max;
+ bool_t no_trunc;
+ bool_t chown_restricted;
+ bool_t case_insensitive;
+ bool_t case_preserving;
+};
+typedef struct pathconf3resok pathconf3resok;
+
+struct pathconf3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct pathconf3resfail pathconf3resfail;
+
+struct pathconf3res {
+ nfsstat3 status;
+ union {
+ pathconf3resok resok;
+ pathconf3resfail resfail;
+ } pathconf3res_u;
+};
+typedef struct pathconf3res pathconf3res;
+
+struct commit3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+typedef struct commit3args commit3args;
+
+struct commit3resok {
+ wcc_data file_wcc;
+ writeverf3 verf;
+};
+typedef struct commit3resok commit3resok;
+
+struct commit3resfail {
+ wcc_data file_wcc;
+};
+typedef struct commit3resfail commit3resfail;
+
+struct commit3res {
+ nfsstat3 status;
+ union {
+ commit3resok resok;
+ commit3resfail resfail;
+ } commit3res_u;
+};
+typedef struct commit3res commit3res;
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE3 NFS3_FHSIZE
+
+typedef struct {
+ u_int fhandle3_len;
+ char *fhandle3_val;
+} fhandle3;
+
+typedef char *dirpath;
+
+typedef char *name;
+
+enum mountstat3 {
+ MNT3_OK = 0,
+ MNT3ERR_PERM = 1,
+ MNT3ERR_NOENT = 2,
+ MNT3ERR_IO = 5,
+ MNT3ERR_ACCES = 13,
+ MNT3ERR_NOTDIR = 20,
+ MNT3ERR_INVAL = 22,
+ MNT3ERR_NAMETOOLONG = 63,
+ MNT3ERR_NOTSUPP = 10004,
+ MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
+
+struct mountres3_ok {
+ fhandle3 fhandle;
+ struct {
+ u_int auth_flavors_len;
+ int *auth_flavors_val;
+ } auth_flavors;
+};
+typedef struct mountres3_ok mountres3_ok;
+
+struct mountres3 {
+ mountstat3 fhs_status;
+ union {
+ mountres3_ok mountinfo;
+ } mountres3_u;
+};
+typedef struct mountres3 mountres3;
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+typedef struct groupnode groupnode;
+
+typedef struct exportnode *exports;
+
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+typedef struct exportnode exportnode;
+
+#define NFS_PROGRAM 100003
+#define NFS_V3 3
+
+#define NFS3_NULL 0
+#define NFS3_GETATTR 1
+#define NFS3_SETATTR 2
+#define NFS3_LOOKUP 3
+#define NFS3_ACCESS 4
+#define NFS3_READLINK 5
+#define NFS3_READ 6
+#define NFS3_WRITE 7
+#define NFS3_CREATE 8
+#define NFS3_MKDIR 9
+#define NFS3_SYMLINK 10
+#define NFS3_MKNOD 11
+#define NFS3_REMOVE 12
+#define NFS3_RMDIR 13
+#define NFS3_RENAME 14
+#define NFS3_LINK 15
+#define NFS3_READDIR 16
+#define NFS3_READDIRP 17
+#define NFS3_FSSTAT 18
+#define NFS3_FSINFO 19
+#define NFS3_PATHCONF 20
+#define NFS3_COMMIT 21
+#define NFS3_PROC_COUNT 22
+
+#define MOUNT_PROGRAM 100005
+#define MOUNT_V3 3
+#define MOUNT_V1 1
+
+#define MOUNT3_NULL 0
+#define MOUNT3_MNT 1
+#define MOUNT3_DUMP 2
+#define MOUNT3_UMNT 3
+#define MOUNT3_UMNTALL 4
+#define MOUNT3_EXPORT 5
+#define MOUNT3_PROC_COUNT 6
+
+#define MOUNT1_NULL 0
+#define MOUNT1_DUMP 2
+#define MOUNT1_UMNT 3
+#define MOUNT1_EXPORT 5
+#define MOUNT1_PROC_COUNT 6
+/* the xdr functions */
+
+extern bool_t xdr_uint64 (XDR *, uint64*);
+extern bool_t xdr_int64 (XDR *, int64*);
+extern bool_t xdr_uint32 (XDR *, uint32*);
+extern bool_t xdr_int32 (XDR *, int32*);
+extern bool_t xdr_filename3 (XDR *, filename3*);
+extern bool_t xdr_nfspath3 (XDR *, nfspath3*);
+extern bool_t xdr_fileid3 (XDR *, fileid3*);
+extern bool_t xdr_cookie3 (XDR *, cookie3*);
+extern bool_t xdr_cookieverf3 (XDR *, cookieverf3);
+extern bool_t xdr_createverf3 (XDR *, createverf3);
+extern bool_t xdr_writeverf3 (XDR *, writeverf3);
+extern bool_t xdr_uid3 (XDR *, uid3*);
+extern bool_t xdr_gid3 (XDR *, gid3*);
+extern bool_t xdr_size3 (XDR *, size3*);
+extern bool_t xdr_offset3 (XDR *, offset3*);
+extern bool_t xdr_mode3 (XDR *, mode3*);
+extern bool_t xdr_count3 (XDR *, count3*);
+extern bool_t xdr_nfsstat3 (XDR *, nfsstat3*);
+extern bool_t xdr_ftype3 (XDR *, ftype3*);
+extern bool_t xdr_specdata3 (XDR *, specdata3*);
+extern bool_t xdr_nfs_fh3 (XDR *, nfs_fh3*);
+extern bool_t xdr_nfstime3 (XDR *, nfstime3*);
+extern bool_t xdr_fattr3 (XDR *, fattr3*);
+extern bool_t xdr_post_op_attr (XDR *, post_op_attr*);
+extern bool_t xdr_wcc_attr (XDR *, wcc_attr*);
+extern bool_t xdr_pre_op_attr (XDR *, pre_op_attr*);
+extern bool_t xdr_wcc_data (XDR *, wcc_data*);
+extern bool_t xdr_post_op_fh3 (XDR *, post_op_fh3*);
+extern bool_t xdr_time_how (XDR *, time_how*);
+extern bool_t xdr_set_mode3 (XDR *, set_mode3*);
+extern bool_t xdr_set_uid3 (XDR *, set_uid3*);
+extern bool_t xdr_set_gid3 (XDR *, set_gid3*);
+extern bool_t xdr_set_size3 (XDR *, set_size3*);
+extern bool_t xdr_set_atime (XDR *, set_atime*);
+extern bool_t xdr_set_mtime (XDR *, set_mtime*);
+extern bool_t xdr_sattr3 (XDR *, sattr3*);
+extern bool_t xdr_diropargs3 (XDR *, diropargs3*);
+extern bool_t xdr_getattr3args (XDR *, getattr3args*);
+extern bool_t xdr_getattr3resok (XDR *, getattr3resok*);
+extern bool_t xdr_getattr3res (XDR *, getattr3res*);
+extern bool_t xdr_sattrguard3 (XDR *, sattrguard3*);
+extern bool_t xdr_setattr3args (XDR *, setattr3args*);
+extern bool_t xdr_setattr3resok (XDR *, setattr3resok*);
+extern bool_t xdr_setattr3resfail (XDR *, setattr3resfail*);
+extern bool_t xdr_setattr3res (XDR *, setattr3res*);
+extern bool_t xdr_lookup3args (XDR *, lookup3args*);
+extern bool_t xdr_lookup3resok (XDR *, lookup3resok*);
+extern bool_t xdr_lookup3resfail (XDR *, lookup3resfail*);
+extern bool_t xdr_lookup3res (XDR *, lookup3res*);
+extern bool_t xdr_access3args (XDR *, access3args*);
+extern bool_t xdr_access3resok (XDR *, access3resok*);
+extern bool_t xdr_access3resfail (XDR *, access3resfail*);
+extern bool_t xdr_access3res (XDR *, access3res*);
+extern bool_t xdr_readlink3args (XDR *, readlink3args*);
+extern bool_t xdr_readlink3resok (XDR *, readlink3resok*);
+extern bool_t xdr_readlink3resfail (XDR *, readlink3resfail*);
+extern bool_t xdr_readlink3res (XDR *, readlink3res*);
+extern bool_t xdr_read3args (XDR *, read3args*);
+extern bool_t xdr_read3resok (XDR *, read3resok*);
+extern bool_t xdr_read3resfail (XDR *, read3resfail*);
+extern bool_t xdr_read3res (XDR *, read3res*);
+extern bool_t xdr_read3res_nocopy (XDR *xdrs, read3res *objp);
+extern bool_t xdr_stable_how (XDR *, stable_how*);
+extern bool_t xdr_write3args (XDR *, write3args*);
+extern bool_t xdr_write3resok (XDR *, write3resok*);
+extern bool_t xdr_write3resfail (XDR *, write3resfail*);
+extern bool_t xdr_write3res (XDR *, write3res*);
+extern bool_t xdr_createmode3 (XDR *, createmode3*);
+extern bool_t xdr_createhow3 (XDR *, createhow3*);
+extern bool_t xdr_create3args (XDR *, create3args*);
+extern bool_t xdr_create3resok (XDR *, create3resok*);
+extern bool_t xdr_create3resfail (XDR *, create3resfail*);
+extern bool_t xdr_create3res (XDR *, create3res*);
+extern bool_t xdr_mkdir3args (XDR *, mkdir3args*);
+extern bool_t xdr_mkdir3resok (XDR *, mkdir3resok*);
+extern bool_t xdr_mkdir3resfail (XDR *, mkdir3resfail*);
+extern bool_t xdr_mkdir3res (XDR *, mkdir3res*);
+extern bool_t xdr_symlinkdata3 (XDR *, symlinkdata3*);
+extern bool_t xdr_symlink3args (XDR *, symlink3args*);
+extern bool_t xdr_symlink3resok (XDR *, symlink3resok*);
+extern bool_t xdr_symlink3resfail (XDR *, symlink3resfail*);
+extern bool_t xdr_symlink3res (XDR *, symlink3res*);
+extern bool_t xdr_devicedata3 (XDR *, devicedata3*);
+extern bool_t xdr_mknoddata3 (XDR *, mknoddata3*);
+extern bool_t xdr_mknod3args (XDR *, mknod3args*);
+extern bool_t xdr_mknod3resok (XDR *, mknod3resok*);
+extern bool_t xdr_mknod3resfail (XDR *, mknod3resfail*);
+extern bool_t xdr_mknod3res (XDR *, mknod3res*);
+extern bool_t xdr_remove3args (XDR *, remove3args*);
+extern bool_t xdr_remove3resok (XDR *, remove3resok*);
+extern bool_t xdr_remove3resfail (XDR *, remove3resfail*);
+extern bool_t xdr_remove3res (XDR *, remove3res*);
+extern bool_t xdr_rmdir3args (XDR *, rmdir3args*);
+extern bool_t xdr_rmdir3resok (XDR *, rmdir3resok*);
+extern bool_t xdr_rmdir3resfail (XDR *, rmdir3resfail*);
+extern bool_t xdr_rmdir3res (XDR *, rmdir3res*);
+extern bool_t xdr_rename3args (XDR *, rename3args*);
+extern bool_t xdr_rename3resok (XDR *, rename3resok*);
+extern bool_t xdr_rename3resfail (XDR *, rename3resfail*);
+extern bool_t xdr_rename3res (XDR *, rename3res*);
+extern bool_t xdr_link3args (XDR *, link3args*);
+extern bool_t xdr_link3resok (XDR *, link3resok*);
+extern bool_t xdr_link3resfail (XDR *, link3resfail*);
+extern bool_t xdr_link3res (XDR *, link3res*);
+extern bool_t xdr_readdir3args (XDR *, readdir3args*);
+extern bool_t xdr_entry3 (XDR *, entry3*);
+extern bool_t xdr_dirlist3 (XDR *, dirlist3*);
+extern bool_t xdr_readdir3resok (XDR *, readdir3resok*);
+extern bool_t xdr_readdir3resfail (XDR *, readdir3resfail*);
+extern bool_t xdr_readdir3res (XDR *, readdir3res*);
+extern bool_t xdr_readdirp3args (XDR *, readdirp3args*);
+extern bool_t xdr_entryp3 (XDR *, entryp3*);
+extern bool_t xdr_dirlistp3 (XDR *, dirlistp3*);
+extern bool_t xdr_readdirp3resok (XDR *, readdirp3resok*);
+extern bool_t xdr_readdirp3resfail (XDR *, readdirp3resfail*);
+extern bool_t xdr_readdirp3res (XDR *, readdirp3res*);
+extern bool_t xdr_fsstat3args (XDR *, fsstat3args*);
+extern bool_t xdr_fsstat3resok (XDR *, fsstat3resok*);
+extern bool_t xdr_fsstat3resfail (XDR *, fsstat3resfail*);
+extern bool_t xdr_fsstat3res (XDR *, fsstat3res*);
+extern bool_t xdr_fsinfo3args (XDR *, fsinfo3args*);
+extern bool_t xdr_fsinfo3resok (XDR *, fsinfo3resok*);
+extern bool_t xdr_fsinfo3resfail (XDR *, fsinfo3resfail*);
+extern bool_t xdr_fsinfo3res (XDR *, fsinfo3res*);
+extern bool_t xdr_pathconf3args (XDR *, pathconf3args*);
+extern bool_t xdr_pathconf3resok (XDR *, pathconf3resok*);
+extern bool_t xdr_pathconf3resfail (XDR *, pathconf3resfail*);
+extern bool_t xdr_pathconf3res (XDR *, pathconf3res*);
+extern bool_t xdr_commit3args (XDR *, commit3args*);
+extern bool_t xdr_commit3resok (XDR *, commit3resok*);
+extern bool_t xdr_commit3resfail (XDR *, commit3resfail*);
+extern bool_t xdr_commit3res (XDR *, commit3res*);
+extern bool_t xdr_fhandle3 (XDR *, fhandle3*);
+extern bool_t xdr_dirpath (XDR *, dirpath*);
+extern bool_t xdr_name (XDR *, name*);
+extern bool_t xdr_mountstat3 (XDR *, mountstat3*);
+extern bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern bool_t xdr_mountres3 (XDR *, mountres3*);
+extern bool_t xdr_mountlist (XDR *, mountlist*);
+extern bool_t xdr_mountbody (XDR *, mountbody*);
+extern bool_t xdr_groups (XDR *, groups*);
+extern bool_t xdr_groupnode (XDR *, groupnode*);
+extern bool_t xdr_exports (XDR *, exports*);
+extern bool_t xdr_exportnode (XDR *, exportnode*);
+
+extern void xdr_free_exports_list (struct exportnode *first);
+extern void xdr_free_mountlist (mountlist ml);
+
+extern void xdr_free_write3args_nocopy (write3args *wa);
+#endif
diff --git a/xlators/nfs/lib/src/xdr-rpc.c b/xlators/nfs/lib/src/xdr-rpc.c
new file mode 100644
index 000000000..274e118a3
--- /dev/null
+++ b/xlators/nfs/lib/src/xdr-rpc.c
@@ -0,0 +1,229 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <arpa/inet.h>
+#include <rpc/xdr.h>
+#include <sys/uio.h>
+#include <rpc/auth_unix.h>
+
+#include "mem-pool.h"
+#include "xdr-rpc.h"
+#include "xdr-common.h"
+#include "logging.h"
+
+/* Decodes the XDR format in msgbuf into rpc_msg.
+ * The remaining payload is returned into payload.
+ */
+int
+nfs_xdr_to_rpc_call (char *msgbuf, size_t len, struct rpc_msg *call,
+ struct iovec *payload, char *credbytes, char *verfbytes)
+{
+ XDR xdr;
+ char opaquebytes[MAX_AUTH_BYTES];
+ struct opaque_auth *oa = NULL;
+
+ if ((!msgbuf) || (!call))
+ return -1;
+
+ memset (call, 0, sizeof (*call));
+
+ oa = &call->rm_call.cb_cred;
+ if (!credbytes)
+ oa->oa_base = opaquebytes;
+ else
+ oa->oa_base = credbytes;
+
+ oa = &call->rm_call.cb_verf;
+ if (!verfbytes)
+ oa->oa_base = opaquebytes;
+ else
+ oa->oa_base = verfbytes;
+
+ xdrmem_create (&xdr, msgbuf, len, XDR_DECODE);
+ if (!xdr_callmsg (&xdr, call))
+ return -1;
+
+ if (payload) {
+ payload->iov_base = nfs_xdr_decoded_remaining_addr (xdr);
+ payload->iov_len = nfs_xdr_decoded_remaining_len (xdr);
+ }
+
+ return 0;
+}
+
+
+bool_t
+nfs_true_func (XDR *s, caddr_t *a)
+{
+ return TRUE;
+}
+
+
+int
+nfs_rpc_fill_empty_reply (struct rpc_msg *reply, uint32_t xid)
+{
+ if (!reply)
+ return -1;
+
+ /* Setting to 0 also results in reply verifier flavor to be
+ * set to AUTH_NULL which is what we want right now.
+ */
+ memset (reply, 0, sizeof (*reply));
+ reply->rm_xid = xid;
+ reply->rm_direction = REPLY;
+
+ return 0;
+}
+
+int
+nfs_rpc_fill_denied_reply (struct rpc_msg *reply, int rjstat, int auth_err)
+{
+ if (!reply)
+ return -1;
+
+ reply->rm_reply.rp_stat = MSG_DENIED;
+ reply->rjcted_rply.rj_stat = rjstat;
+ if (rjstat == RPC_MISMATCH) {
+ /* No problem with hardocoding
+ * RPC version numbers. We only support
+ * v2 anyway.
+ */
+ reply->rjcted_rply.rj_vers.low = 2;
+ reply->rjcted_rply.rj_vers.high = 2;
+ } else if (rjstat == AUTH_ERROR)
+ reply->rjcted_rply.rj_why = auth_err;
+
+ return 0;
+}
+
+
+int
+nfs_rpc_fill_accepted_reply (struct rpc_msg *reply, int arstat, int proglow,
+ int proghigh, int verf, int len, char *vdata)
+{
+ if (!reply)
+ return -1;
+
+ reply->rm_reply.rp_stat = MSG_ACCEPTED;
+ reply->acpted_rply.ar_stat = arstat;
+
+ reply->acpted_rply.ar_verf.oa_flavor = verf;
+ reply->acpted_rply.ar_verf.oa_length = len;
+ reply->acpted_rply.ar_verf.oa_base = vdata;
+ if (arstat == PROG_MISMATCH) {
+ reply->acpted_rply.ar_vers.low = proglow;
+ reply->acpted_rply.ar_vers.high = proghigh;
+ } else if (arstat == SUCCESS) {
+
+ /* This is a hack. I'd really like to build a custom
+ * XDR library because Sun RPC interface is not very flexible.
+ */
+ reply->acpted_rply.ar_results.proc = (xdrproc_t)nfs_true_func;
+ reply->acpted_rply.ar_results.where = NULL;
+ }
+
+ return 0;
+}
+
+int
+nfs_rpc_reply_to_xdr (struct rpc_msg *reply, char *dest, size_t len,
+ struct iovec *dst)
+{
+ XDR xdr;
+
+ if ((!dest) || (!reply) || (!dst))
+ return -1;
+
+ xdrmem_create (&xdr, dest, len, XDR_ENCODE);
+ if (!xdr_replymsg(&xdr, reply))
+ return -1;
+
+ dst->iov_base = dest;
+ dst->iov_len = nfs_xdr_encoded_length (xdr);
+
+ return 0;
+}
+
+
+int
+nfs_xdr_to_auth_unix_cred (char *msgbuf, int msglen, struct authunix_parms *au,
+ char *machname, gid_t *gids)
+{
+ XDR xdr;
+
+ if ((!msgbuf) || (!machname) || (!gids) || (!au))
+ return -1;
+
+ au->aup_machname = machname;
+#ifdef GF_DARWIN_HOST_OS
+ au->aup_gids = (int *)gids;
+#else
+ au->aup_gids = gids;
+#endif
+
+ xdrmem_create (&xdr, msgbuf, msglen, XDR_DECODE);
+
+ if (!xdr_authunix_parms (&xdr, au))
+ return -1;
+
+ return 0;
+}
+
+ssize_t
+nfs_xdr_length_round_up (size_t len, size_t bufsize)
+{
+ int roundup = 0;
+
+ roundup = len % NFS_XDR_BYTES_PER_UNIT;
+ if (roundup > 0)
+ roundup = NFS_XDR_BYTES_PER_UNIT - roundup;
+
+ if ((roundup > 0) && ((roundup + len) <= bufsize))
+ len += roundup;
+
+ return len;
+}
+
+int
+nfs_xdr_bytes_round_up (struct iovec *vec, size_t bufsize)
+{
+ vec->iov_len = nfs_xdr_length_round_up (vec->iov_len, bufsize);
+ return 0;
+}
+
+void
+nfs_xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count)
+{
+ uint32_t round_count = 0;
+
+ round_count = nfs_xdr_length_round_up (count, 1048576);
+ round_count -= count;
+ if (round_count == 0)
+ return;
+
+ vec[vcount-1].iov_len += round_count;
+}
diff --git a/xlators/nfs/lib/src/xdr-rpc.h b/xlators/nfs/lib/src/xdr-rpc.h
new file mode 100644
index 000000000..ddcbe6655
--- /dev/null
+++ b/xlators/nfs/lib/src/xdr-rpc.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _NFS_XDR_RPC_H
+#define _NFS_XDR_RPC_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <arpa/inet.h>
+#include <rpc/xdr.h>
+#include <sys/uio.h>
+
+/* Converts a given network buffer from its XDR format to a structure
+ * that contains everything an RPC call needs to work.
+ */
+extern int
+nfs_xdr_to_rpc_call (char *msgbuf, size_t len, struct rpc_msg *call,
+ struct iovec *payload, char *credbytes, char *verfbytes);
+
+extern int
+nfs_rpc_fill_empty_reply (struct rpc_msg *reply, uint32_t xid);
+
+extern int
+nfs_rpc_fill_denied_reply (struct rpc_msg *reply, int rjstat, int auth_err);
+
+extern int
+nfs_rpc_fill_accepted_reply (struct rpc_msg *reply, int arstat, int proglow,
+ int proghigh, int verf, int len, char *vdata);
+extern int
+nfs_rpc_reply_to_xdr (struct rpc_msg *reply, char *dest, size_t len,
+ struct iovec *dst);
+
+extern int
+nfs_xdr_to_auth_unix_cred (char *msgbuf, int msglen, struct authunix_parms *au,
+ char *machname, gid_t *gids);
+/* Macros that simplify accesing the members of an RPC call structure. */
+#define nfs_rpc_call_xid(call) ((call)->rm_xid)
+#define nfs_rpc_call_direction(call) ((call)->rm_direction)
+#define nfs_rpc_call_rpcvers(call) ((call)->ru.RM_cmb.cb_rpcvers)
+#define nfs_rpc_call_program(call) ((call)->ru.RM_cmb.cb_prog)
+#define nfs_rpc_call_progver(call) ((call)->ru.RM_cmb.cb_vers)
+#define nfs_rpc_call_progproc(call) ((call)->ru.RM_cmb.cb_proc)
+#define nfs_rpc_opaque_auth_flavour(oa) ((oa)->oa_flavor)
+#define nfs_rpc_opaque_auth_len(oa) ((oa)->oa_length)
+
+#define nfs_rpc_call_cred_flavour(call) (nfs_rpc_opaque_auth_flavour ((&(call)->ru.RM_cmb.cb_cred)))
+#define nfs_rpc_call_cred_len(call) (nfs_rpc_opaque_auth_len ((&(call)->ru.RM_cmb.cb_cred)))
+
+
+#define nfs_rpc_call_verf_flavour(call) (nfs_rpc_opaque_auth_flavour ((&(call)->ru.RM_cmb.cb_verf)))
+#define nfs_rpc_call_verf_len(call) (nfs_rpc_opaque_auth_len ((&(call)->ru.RM_cmb.cb_verf)))
+
+extern int
+nfs_xdr_bytes_round_up (struct iovec *vec, size_t bufsize);
+
+extern ssize_t
+nfs_xdr_length_round_up (size_t len, size_t bufsize);
+
+void
+nfs_xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count);
+#endif
diff --git a/xlators/nfs/server/src/Makefile.am b/xlators/nfs/server/src/Makefile.am
index ef3b67297..f8968916c 100644
--- a/xlators/nfs/server/src/Makefile.am
+++ b/xlators/nfs/server/src/Makefile.am
@@ -1,19 +1,13 @@
xlator_LTLIBRARIES = server.la
xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/nfs
-nfsrpclibdir = $(top_srcdir)/rpc/rpc-lib/src
+nfsrpclibdir = $(top_srcdir)/xlators/nfs/lib/src
server_la_LDFLAGS = -module -avoidversion
-server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c \
- nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c nlm4.c \
- nlmcbk_svc.c mount3udp_svc.c
+server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c $(nfsrpclibdir)/auth-null.c $(nfsrpclibdir)/auth-unix.c $(nfsrpclibdir)/msg-nfs3.c $(nfsrpclibdir)/rpc-socket.c $(nfsrpclibdir)/rpcsvc-auth.c $(nfsrpclibdir)/rpcsvc.c $(nfsrpclibdir)/xdr-nfs3.c $(nfsrpclibdir)/xdr-rpc.c
server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h \
- mount3.h nfs3-fh.h nfs3.h nfs3-helpers.h nfs-mem-types.h nlm4.h
-
+noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h mount3.h nfs3-fh.h nfs3.h nfs3-helpers.h nfs-mem-types.h $(nfsrpclibdir)/xdr-rpc.h $(nfsrpclibdir)/msg-nfs3.h $(nfsrpclibdir)/xdr-common.h $(nfsrpclibdir)/xdr-nfs3.h $(nfsrpclibdir)/rpc-socket.h $(nfsrpclibdir)/rpcsvc.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
- -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\
- -I$(nfsrpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree\
- -I$(top_srcdir)/rpc/xdr/src/
+ -I$(nfsrpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree
CLEANFILES =
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index aafabf4ae..295b4e830 100644
--- a/xlators/nfs/server/src/mount3.c
+++ b/xlators/nfs/server/src/mount3.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -47,9 +47,6 @@
typedef ssize_t (*mnt3_serializer) (struct iovec outmsg, void *args);
-extern void *
-mount3udp_thread (void *argv);
-
/* Generic reply function for MOUNTv3 specific replies. */
int
@@ -59,12 +56,11 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
struct iobuf *iob = NULL;
struct mount3_state *ms = NULL;
int ret = -1;
- struct iobref *iobref = NULL;
if (!req)
return -1;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found");
goto ret;
@@ -73,7 +69,6 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
- /* TODO: use 'xdrproc_t' instead of 'sfunc' to get the xdr-size */
iob = iobuf_get (ms->iobpool);
if (!iob) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobuf");
@@ -86,18 +81,9 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc)
*/
outmsg.iov_len = sfunc (outmsg, arg);
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- iobref_add (iobref, iob);
-
/* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
+ ret = nfs_rpcsvc_submit_message (req, outmsg, iob);
iobuf_unref (iob);
- iobref_unref (iobref);
if (ret == -1) {
gf_log (GF_MNT, GF_LOG_ERROR, "Reply submission failed");
goto ret;
@@ -195,7 +181,6 @@ mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req,
{
struct mountentry *me = NULL;
int ret = -1;
- char *colon = NULL;
if ((!ms) || (!req) || (!expname))
return -1;
@@ -210,14 +195,10 @@ mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req,
/* Must get the IP or hostname of the client so we
* can map it into the mount entry.
*/
- ret = rpcsvc_transport_peername (req->trans, me->hostname, MNTPATHLEN);
+ ret = nfs_rpcsvc_conn_peername (req->conn, me->hostname, MNTPATHLEN);
if (ret == -1)
goto free_err;
- colon = strrchr (me->hostname, ':');
- if (colon) {
- *colon = '\0';
- }
LOCK (&ms->mountlock);
{
list_add_tail (&me->mlist, &ms->mountlist);
@@ -279,17 +260,16 @@ mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie,
return -1;
mntxl = (xlator_t *)cookie;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found");
op_ret = -1;
op_errno = EINVAL;
}
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "error=%s", strerror (op_errno));
+ if (op_ret == -1)
status = mnt3svc_errno_to_mnterr (op_errno);
- }
+
if (status != MNT3_OK)
goto xmit_res;
@@ -307,9 +287,9 @@ xmit_res:
gf_log (GF_MNT, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr,
status);
if (op_ret == 0) {
- svc = rpcsvc_request_service (req);
- autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr,
- 10);
+ svc = nfs_rpcsvc_request_service (req);
+ autharrlen = nfs_rpcsvc_auth_array (svc, mntxl->name, autharr,
+ 10);
}
res = mnt3svc_set_mountres3 (status, &fh, autharr, autharrlen);
@@ -324,7 +304,7 @@ int
mnt3_match_dirpath_export (char *expname, char *dirpath)
{
int ret = 0;
- size_t dlen;
+ int dlen = 0;
if ((!expname) || (!dirpath))
return 0;
@@ -335,7 +315,7 @@ mnt3_match_dirpath_export (char *expname, char *dirpath)
* compare.
*/
dlen = strlen (dirpath);
- if (dlen && dirpath [dlen - 1] == '/')
+ if (dirpath [dlen - 1] == '/')
dirpath [dlen - 1] = '\0';
if (dirpath[0] != '/')
@@ -359,11 +339,11 @@ mnt3svc_mount_inode (rpcsvc_request_t *req, struct mount3_state *ms,
if ((!req) || (!xl) || (!ms) || (!exportinode))
return ret;
- ret = nfs_inode_loc_fill (exportinode, &exportloc, NFS_RESOLVE_EXIST);
+ ret = nfs_inode_loc_fill (exportinode, &exportloc);
if (ret < 0) {
gf_log (GF_MNT, GF_LOG_ERROR, "Loc fill failed for export inode"
- ": gfid %s, volume: %s",
- uuid_utoa (exportinode->gfid), xl->name);
+ ": ino %"PRIu64", volume: %s",
+ exportinode->ino, xl->name);
goto err;
}
@@ -400,7 +380,7 @@ mnt3svc_volume_mount (rpcsvc_request_t *req, struct mount3_state *ms,
rootgfid[15] = 1;
exportinode = inode_find (exp->vol->itable, rootgfid);
if (!exportinode) {
- gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get root inode");
+ gf_log (GF_MNT, GF_LOG_ERROR, "Faild to get root inode");
ret = -ENOENT;
goto err;
}
@@ -435,9 +415,6 @@ __volume_subdir (char *dirpath, char **volname)
if (!subdir)
goto out;
- if (!volname)
- goto out;
-
if (!*volname)
goto out;
@@ -525,8 +502,7 @@ __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres)
&mres->resolveloc, NFS_RESOLVE_CREATE);
if ((ret < 0) && (ret != -2)) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create "
- "inode: parent gfid %s, entry %s",
- uuid_utoa (mres->resolveloc.inode->gfid), nextcomp);
+ "inode: parent gfid %s, entry %s", uuid_utoa (mres->resolveloc.inode->gfid), nextcomp);
ret = -EFAULT;
goto err;
}
@@ -558,8 +534,6 @@ mnt3_resolve_subdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
mres = frame->local;
mntxl = (xlator_t *)cookie;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "path=%s (%s)",
- mres->resolveloc.path, strerror (op_errno));
mntstat = mnt3svc_errno_to_mnterr (op_errno);
goto err;
}
@@ -584,9 +558,9 @@ err:
if (op_ret == -1) {
gf_log (GF_MNT, GF_LOG_DEBUG, "Mount reply status: %d",
mntstat);
- svc = rpcsvc_request_service (mres->req);
- autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr,
- 10);
+ svc = nfs_rpcsvc_request_service (mres->req);
+ autharrlen = nfs_rpcsvc_auth_array (svc, mntxl->name, autharr,
+ 10);
res = mnt3svc_set_mountres3 (mntstat, &fh, autharr, autharrlen);
mnt3svc_submit_reply (mres->req, (void *)&res,
@@ -698,7 +672,7 @@ mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms,
if (!volume_subdir)
goto err;
- ret = mnt3_resolve_subdir (req, ms, exp, volume_subdir);
+ ret = mnt3_resolve_subdir (req, ms, exp, exp->expname);
if (ret < 0) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s"
, exp->expname);
@@ -761,38 +735,24 @@ int
mnt3_check_client_net (struct mount3_state *ms, rpcsvc_request_t *req,
xlator_t *targetxl)
{
-
- rpcsvc_t *svc = NULL;
- rpc_transport_t *trans = NULL;
- struct sockaddr_storage sastorage = {0,};
- char peer[RPCSVC_PEER_STRLEN] = {0,};
- int ret = -1;
+ rpcsvc_t *svc = NULL;
+ int ret = -1;
if ((!ms) || (!req) || (!targetxl))
return -1;
- svc = rpcsvc_request_service (req);
-
- trans = rpcsvc_request_transport (req);
- ret = rpcsvc_transport_peeraddr (trans, peer, RPCSVC_PEER_STRLEN,
- &sastorage, sizeof (sastorage));
- if (ret != 0) {
- gf_log (GF_MNT, GF_LOG_WARNING, "Failed to get peer addr: %s",
- gai_strerror (ret));
- }
-
- ret = rpcsvc_transport_peer_check (svc->options, targetxl->name,
- trans);
+ svc = nfs_rpcsvc_request_service (req);
+ ret = nfs_rpcsvc_conn_peer_check (svc->options, targetxl->name,
+ nfs_rpcsvc_request_conn (req));
if (ret == RPCSVC_AUTH_REJECT) {
- gf_log (GF_MNT, GF_LOG_INFO, "Peer %s not allowed", peer);
+ gf_log (GF_MNT, GF_LOG_TRACE, "Peer not allowed");
goto err;
}
- ret = rpcsvc_transport_privport_check (svc, targetxl->name,
- rpcsvc_request_transport (req));
+ ret = nfs_rpcsvc_conn_privport_check (svc, targetxl->name,
+ nfs_rpcsvc_request_conn (req));
if (ret == RPCSVC_AUTH_REJECT) {
- gf_log (GF_MNT, GF_LOG_INFO, "Peer %s rejected. Unprivileged "
- "port not allowed", peer);
+ gf_log (GF_MNT, GF_LOG_TRACE, "Unprivileged port not allowed");
goto err;
}
@@ -841,17 +801,19 @@ mnt3_find_export (rpcsvc_request_t *req, char *path, struct mnt3_export **e)
int ret = -EFAULT;
struct mount3_state *ms = NULL;
struct mnt3_export *exp = NULL;
+ struct nfs_state *nfs = NULL;
if ((!req) || (!path) || (!e))
return -1;
- ms = (struct mount3_state *) rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
goto err;
}
+ nfs = (struct nfs_state *)ms->nfsx->private;
gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s", path);
exp = mnt3_mntpath_to_export (ms, path);
if (exp) {
@@ -892,17 +854,17 @@ mnt3svc_mnt (rpcsvc_request_t *req)
pvec.iov_base = path;
pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
+ ret = xdr_to_mountpath (pvec, req->msg);
if (ret == -1) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed to decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = -1;
goto rpcerr;
}
@@ -959,7 +921,8 @@ mnt3svc_null (rpcsvc_request_t *req)
gf_log (GF_MNT, GF_LOG_ERROR, "Got NULL request!");
return 0;
}
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
+
+ nfs_rpcsvc_submit_generic (req, dummyvec, NULL);
return 0;
}
@@ -1065,19 +1028,19 @@ mnt3svc_dump (rpcsvc_request_t *req)
if (!req)
return -1;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
goto rpcerr;
}
sfunc = (mnt3_serializer)xdr_serialize_mountlist;
mlist = mnt3svc_build_mountlist (ms, &ret);
- arg = &mlist;
-
+ arg = mlist;
+
if (!mlist) {
if (ret != 0) {
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = -1;
goto rpcerr;
} else {
@@ -1171,7 +1134,6 @@ mnt3svc_umnt (rpcsvc_request_t *req)
int ret = -1;
struct mount3_state *ms = NULL;
mountstat3 mstat = MNT3_OK;
- char *colon = NULL;
if (!req)
return -1;
@@ -1179,43 +1141,56 @@ mnt3svc_umnt (rpcsvc_request_t *req)
/* Remove the mount point from the exports list. */
pvec.iov_base = dirpath;
pvec.iov_len = MNTPATHLEN;
- ret = xdr_to_mountpath (pvec, req->msg[0]);
+ ret = xdr_to_mountpath (pvec, req->msg);;
if (ret == -1) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed decode args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = -1;
goto rpcerr;
}
- ret = rpcsvc_transport_peername (req->trans, hostname, MNTPATHLEN);
+ ret = nfs_rpcsvc_conn_peername (req->conn, hostname, MNTPATHLEN);
if (ret != 0) {
gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote name: %s",
gai_strerror (ret));
- goto rpcerr;
+ goto try_umount_with_addr;
}
- colon = strrchr (hostname, ':');
- if (colon) {
- *colon= '\0';
- }
gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s, hostname: %s", dirpath,
hostname);
ret = mnt3svc_umount (ms, dirpath, hostname);
- if (ret == -1) {
- ret = 0;
- mstat = MNT3ERR_NOENT;
+ /* Unmount succeeded with the given hostname. */
+ if (ret == 0)
+ goto snd_reply;
+
+try_umount_with_addr:
+ if (ret != 0)
+ ret = nfs_rpcsvc_conn_peeraddr (req->conn, hostname, MNTPATHLEN,
+ NULL, 0);
+
+ if (ret != 0) {
+ gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote addr: %s",
+ gai_strerror (ret));
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
+ goto rpcerr;
}
- /* FIXME: also take care of the corner case where the
- * client was resolvable at mount but not at the umount - vice-versa.
- */
+
+ gf_log (GF_MNT, GF_LOG_DEBUG, "dirpath: %s, hostname: %s", dirpath,
+ hostname);
+ ret = mnt3svc_umount (ms, dirpath, hostname);
+ if (ret == -1)
+ mstat = MNT3ERR_INVAL;
+
+ ret = 0;
+snd_reply:
mnt3svc_submit_reply (req, &mstat,
(mnt3_serializer)xdr_serialize_mountstat3);
@@ -1272,10 +1247,10 @@ mnt3svc_umntall (rpcsvc_request_t *req)
if (!req)
return ret;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
goto rpcerr;
}
@@ -1331,8 +1306,8 @@ mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms)
strcpy (elist->ex_dir, ent->expname);
- addrstr = rpcsvc_volume_allowed (svc->options,
- ent->vol->name);
+ addrstr = nfs_rpcsvc_volume_allowed (svc->options,
+ ent->vol->name);
if (addrstr)
addrstr = gf_strdup (addrstr);
else
@@ -1379,15 +1354,15 @@ mnt3svc_export (rpcsvc_request_t *req)
if (!req)
return -1;
- ms = (struct mount3_state *)rpcsvc_request_program_private (req);
+ ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req);
if (!ms) {
gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
goto err;
}
/* Using the children translator names, build the export list */
- elist = mnt3_xlchildren_to_exports (rpcsvc_request_service (req),
+ elist = mnt3_xlchildren_to_exports (nfs_rpcsvc_request_service (req),
ms);
/* Do not return error when exports list is empty. An exports list can
* be empty when no subvolumes have come up. No point returning error
@@ -1409,87 +1384,6 @@ err:
return ret;
}
-/* just declaring, definition is way down below */
-rpcsvc_program_t mnt3prog;
-
-/* nfs3_rootfh used by mount3udp thread needs to access mount3prog.private
- * directly as we don't have nfs xlator pointer to dereference it. But thats OK
- */
-
-struct nfs3_fh *
-nfs3_rootfh (char* path)
-{
- struct mount3_state *ms = NULL;
- struct nfs3_fh *fh = NULL;
- struct mnt3_export *exp = NULL;
- inode_t *inode = NULL;
- char *tmp = NULL;
-
- ms = mnt3prog.private;
- exp = mnt3_mntpath_to_export (ms, path);
- if (exp == NULL)
- goto err;
-
- tmp = (char *)path;
- tmp = strchr (tmp, '/');
- if (tmp == NULL)
- tmp = "/";
-
- inode = inode_from_path (exp->vol->itable, tmp);
- if (inode == NULL)
- goto err;
-
- fh = GF_CALLOC (1, sizeof(*fh), gf_nfs_mt_nfs3_fh);
- if (fh == NULL)
- goto err;
- nfs3_build_fh (inode, exp->volumeid, fh);
-
-err:
- if (inode)
- inode_unref (inode);
- return fh;
-}
-
-int
-mount3udp_add_mountlist (char *host, dirpath *expname)
-{
- struct mountentry *me = NULL;
- struct mount3_state *ms = NULL;
- char *export = NULL;
-
- ms = mnt3prog.private;
- me = GF_CALLOC (1, sizeof (*me), gf_nfs_mt_mountentry);
- if (!me)
- return -1;
- export = (char *)expname;
- while (*export == '/')
- export++;
-
- strcpy (me->exname, export);
- strcpy (me->hostname, host);
- INIT_LIST_HEAD (&me->mlist);
- LOCK (&ms->mountlock);
- {
- list_add_tail (&me->mlist, &ms->mountlist);
- }
- UNLOCK (&ms->mountlock);
- return 0;
-}
-
-int
-mount3udp_delete_mountlist (char *hostname, dirpath *expname)
-{
- struct mount3_state *ms = NULL;
- char *export = NULL;
-
- ms = mnt3prog.private;
- export = (char *)expname;
- while (*export == '/')
- export++;
- __mnt3svc_umount (ms, export, hostname);
- return 0;
-}
-
struct mnt3_export *
mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath,
@@ -1534,10 +1428,7 @@ mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath,
exp->exptype = MNT3_EXPTYPE_VOLUME;
ret = snprintf (exp->expname, alloclen, "/%s", xl->name);
}
- if (ret < 0) {
- gf_log (xl->name, GF_LOG_WARNING,
- "failed to get the export name");
- }
+
/* Just copy without discrimination, we'll determine whether to
* actually use it when a mount request comes in and a file handle
* needs to be built.
@@ -1584,7 +1475,8 @@ __mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator,
ret = 0;
err:
- GF_FREE (dupopt);
+ if (dupopt)
+ GF_FREE (dupopt);
return ret;
}
@@ -1821,35 +1713,13 @@ mnt3_init_state (xlator_t *nfsx)
return ms;
}
-int
-mount_init_state (xlator_t *nfsx)
-{
- int ret = -1;
- struct nfs_state *nfs = NULL;
-
- if (!nfsx)
- goto out;
-
- nfs = (struct nfs_state *)nfs_state (nfsx);
- /*Maintaining global state for MOUNT1 and MOUNT3*/
- nfs->mstate = mnt3_init_state (nfsx);
- if (!nfs->mstate) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocate"
- "mount state");
- goto out;
- }
- ret = 0;
-out:
- return ret;
-}
-
rpcsvc_actor_t mnt3svc_actors[MOUNT3_PROC_COUNT] = {
- {"NULL", MOUNT3_NULL, mnt3svc_null, NULL, NULL, 0},
- {"MNT", MOUNT3_MNT, mnt3svc_mnt, NULL, NULL, 0},
- {"DUMP", MOUNT3_DUMP, mnt3svc_dump, NULL, NULL, 0},
- {"UMNT", MOUNT3_UMNT, mnt3svc_umnt, NULL, NULL, 0},
- {"UMNTALL", MOUNT3_UMNTALL, mnt3svc_umntall, NULL, NULL, 0},
- {"EXPORT", MOUNT3_EXPORT, mnt3svc_export, NULL, NULL, 0}
+ {"NULL", MOUNT3_NULL, mnt3svc_null, NULL, NULL},
+ {"MNT", MOUNT3_MNT, mnt3svc_mnt, NULL, NULL},
+ {"DUMP", MOUNT3_DUMP, mnt3svc_dump, NULL, NULL},
+ {"UMNT", MOUNT3_UMNT, mnt3svc_umnt, NULL, NULL},
+ {"UMNTALL", MOUNT3_UMNTALL, mnt3svc_umntall, NULL, NULL},
+ {"EXPORT", MOUNT3_EXPORT, mnt3svc_export, NULL, NULL}
};
@@ -1862,74 +1732,30 @@ rpcsvc_program_t mnt3prog = {
.prognum = MOUNT_PROGRAM,
.progver = MOUNT_V3,
.progport = GF_MOUNTV3_PORT,
+ .progaddrfamily = AF_INET,
+ .proghost = NULL,
.actors = mnt3svc_actors,
.numactors = MOUNT3_PROC_COUNT,
- .min_auth = AUTH_NULL,
};
-
rpcsvc_program_t *
mnt3svc_init (xlator_t *nfsx)
{
struct mount3_state *mstate = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- char *portstr = NULL;
- int ret = -1;
- pthread_t udp_thread;
- if (!nfsx || !nfsx->private)
+ if (!nfsx)
return NULL;
- nfs = (struct nfs_state *)nfsx->private;
-
gf_log (GF_MNT, GF_LOG_DEBUG, "Initing Mount v3 state");
- mstate = (struct mount3_state *)nfs->mstate;
+ mstate = mnt3_init_state (nfsx);
if (!mstate) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount v3 state init failed");
goto err;
}
mnt3prog.private = mstate;
- options = dict_new ();
- ret = gf_asprintf (&portstr, "%d", GF_MOUNTV3_PORT);
- if (ret == -1)
- goto err;
-
- ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr);
- if (ret == -1)
- goto err;
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- if (nfs->allow_insecure) {
- ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- }
-
- rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners");
- dict_unref (options);
- goto err;
- }
-
- if (nfs->mount_udp) {
- pthread_create (&udp_thread, NULL, mount3udp_thread, NULL);
- }
return &mnt3prog;
err:
return NULL;
@@ -1937,12 +1763,12 @@ err:
rpcsvc_actor_t mnt1svc_actors[MOUNT1_PROC_COUNT] = {
- {"NULL", MOUNT1_NULL, mnt3svc_null, NULL, NULL, 0},
- {{0, 0}, },
- {"DUMP", MOUNT1_DUMP, mnt3svc_dump, NULL, NULL, 0},
- {"UMNT", MOUNT1_UMNT, mnt3svc_umnt, NULL, NULL, 0},
- {{0, 0}, },
- {"EXPORT", MOUNT1_EXPORT, mnt3svc_export, NULL, NULL, 0}
+ {"NULL", MOUNT1_NULL, mnt3svc_null, NULL, NULL},
+ {{0}, },
+ {"DUMP", MOUNT1_DUMP, mnt3svc_dump, NULL, NULL},
+ {"UMNT", MOUNT1_UMNT, mnt3svc_umnt, NULL, NULL},
+ {{0}, },
+ {"EXPORT", MOUNT1_EXPORT, mnt3svc_export, NULL, NULL}
};
rpcsvc_program_t mnt1prog = {
@@ -1950,9 +1776,10 @@ rpcsvc_program_t mnt1prog = {
.prognum = MOUNT_PROGRAM,
.progver = MOUNT_V1,
.progport = GF_MOUNTV1_PORT,
+ .progaddrfamily = AF_INET,
+ .proghost = NULL,
.actors = mnt1svc_actors,
.numactors = MOUNT1_PROC_COUNT,
- .min_auth = AUTH_NULL,
};
@@ -1960,18 +1787,12 @@ rpcsvc_program_t *
mnt1svc_init (xlator_t *nfsx)
{
struct mount3_state *mstate = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- char *portstr = NULL;
- int ret = -1;
- if (!nfsx || !nfsx->private)
+ if (!nfsx)
return NULL;
- nfs = (struct nfs_state *)nfsx->private;
-
gf_log (GF_MNT, GF_LOG_DEBUG, "Initing Mount v1 state");
- mstate = (struct mount3_state *)nfs->mstate;
+ mstate = mnt3_init_state (nfsx);
if (!mstate) {
gf_log (GF_MNT, GF_LOG_ERROR, "Mount v3 state init failed");
goto err;
@@ -1979,42 +1800,9 @@ mnt1svc_init (xlator_t *nfsx)
mnt1prog.private = mstate;
- options = dict_new ();
-
- ret = gf_asprintf (&portstr, "%d", GF_MOUNTV1_PORT);
- if (ret == -1)
- goto err;
-
- ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr);
- if (ret == -1)
- goto err;
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- if (nfs->allow_insecure) {
- ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- }
-
- rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners");
- dict_unref (options);
- goto err;
- }
-
return &mnt1prog;
err:
return NULL;
}
+
+
diff --git a/xlators/nfs/server/src/mount3.h b/xlators/nfs/server/src/mount3.h
index c0eae3644..ad4f21c98 100644
--- a/xlators/nfs/server/src/mount3.h
+++ b/xlators/nfs/server/src/mount3.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -50,10 +50,7 @@ mnt3svc_init (xlator_t *nfsx);
extern rpcsvc_program_t *
mnt1svc_init (xlator_t *nfsx);
-extern int
-mount_init_state (xlator_t *nfsx);
-
-/* Data structure used to store the list of mounts points currently
+/* Data structureused to store the list of mounts points currently
* in use by NFS clients.
*/
struct mountentry {
diff --git a/xlators/nfs/server/src/mount3udp_svc.c b/xlators/nfs/server/src/mount3udp_svc.c
deleted file mode 100644
index aa38b1cc4..000000000
--- a/xlators/nfs/server/src/mount3udp_svc.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "xdr-nfs3.h"
-#include "logging.h"
-#include "mem-pool.h"
-#include "nfs-mem-types.h"
-#include "mount3.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <rpc/pmap_clnt.h>
-#include <string.h>
-#include <memory.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-
-extern struct nfs3_fh* nfs3_rootfh (char *dp);
-extern mountres3 mnt3svc_set_mountres3 (mountstat3 stat, struct nfs3_fh *fh,
- int *authflavor, u_int aflen);
-extern int
-mount3udp_add_mountlist (char *host, dirpath *expname);
-
-extern int
-mount3udp_delete_mountlist (char *host, dirpath *expname);
-
-
-/* only this thread will use this, no locking needed */
-char mnthost[INET_ADDRSTRLEN+1];
-
-mountres3 *
-mountudpproc3_mnt_3_svc(dirpath **dpp, struct svc_req *req)
-{
- struct mountres3 *res = NULL;
- int *autharr = NULL;
- struct nfs3_fh *fh = NULL;
- char *tmp = NULL;
-
- tmp = (char *)*dpp;
- while (*tmp == '/')
- tmp++;
- fh = nfs3_rootfh (tmp);
- if (fh == NULL) {
- gf_log (GF_MNT, GF_LOG_DEBUG, "unable to get fh for %s", tmp);
- goto err;
- }
-
- res = GF_CALLOC (1, sizeof(*res), gf_nfs_mt_mountres3);
- if (res == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
- goto err;
- }
- autharr = GF_CALLOC (1, sizeof(*autharr), gf_nfs_mt_int);
- if (autharr == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
- goto err;
- }
- autharr[0] = AUTH_UNIX;
- *res = mnt3svc_set_mountres3 (MNT3_OK, fh, autharr, 1);
- mount3udp_add_mountlist (mnthost, *dpp);
- return res;
-
- err:
- GF_FREE (fh);
- GF_FREE (res);
- GF_FREE (autharr);
- return NULL;
-}
-
-mountstat3 *
-mountudpproc3_umnt_3_svc(dirpath **dp, struct svc_req *req)
-{
- mountstat3 *stat = NULL;
-
- stat = GF_CALLOC (1, sizeof(mountstat3), gf_nfs_mt_mountstat3);
- if (stat == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to allocate memory");
- return NULL;
- }
- *stat = MNT3_OK;
- mount3udp_delete_mountlist (mnthost, *dp);
- return stat;
-}
-
-static void
-mountudp_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
-{
- union {
- dirpath mountudpproc3_mnt_3_arg;
- } argument;
- char *result = NULL;
- xdrproc_t _xdr_argument = NULL, _xdr_result = NULL;
- char *(*local)(char *, struct svc_req *) = NULL;
- mountres3 *res = NULL;
- struct sockaddr_in *sin = NULL;
-
- sin = svc_getcaller (transp);
- inet_ntop (AF_INET, &sin->sin_addr, mnthost, INET_ADDRSTRLEN+1);
-
- switch (rqstp->rq_proc) {
- case NULLPROC:
- (void) svc_sendreply (transp, (xdrproc_t) xdr_void,
- (char *)NULL);
- return;
-
- case MOUNT3_MNT:
- _xdr_argument = (xdrproc_t) xdr_dirpath;
- _xdr_result = (xdrproc_t) xdr_mountres3;
- local = (char *(*)(char *,
- struct svc_req *)) mountudpproc3_mnt_3_svc;
- break;
-
- case MOUNT3_UMNT:
- _xdr_argument = (xdrproc_t) xdr_dirpath;
- _xdr_result = (xdrproc_t) xdr_mountstat3;
- local = (char *(*)(char *,
- struct svc_req *)) mountudpproc3_umnt_3_svc;
- break;
-
- default:
- svcerr_noproc (transp);
- return;
- }
- memset ((char *)&argument, 0, sizeof (argument));
- if (!svc_getargs (transp, (xdrproc_t) _xdr_argument,
- (caddr_t) &argument)) {
- svcerr_decode (transp);
- return;
- }
- result = (*local)((char *)&argument, rqstp);
- if (result == NULL) {
- gf_log (GF_MNT, GF_LOG_DEBUG, "PROC returned error");
- svcerr_systemerr (transp);
- }
- if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result,
- result)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "svc_sendreply returned error");
- svcerr_systemerr (transp);
- }
- if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument,
- (caddr_t) &argument)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "unable to free arguments");
- }
- if (result == NULL)
- return;
- /* free the result */
- switch (rqstp->rq_proc) {
- case MOUNT3_MNT:
- res = (mountres3 *) result;
- GF_FREE (res->mountres3_u.mountinfo.fhandle.fhandle3_val);
- GF_FREE (res->mountres3_u.mountinfo.auth_flavors.auth_flavors_val);
- GF_FREE (res);
- break;
-
- case MOUNT3_UMNT:
- GF_FREE (result);
- break;
- }
- return;
-}
-
-void *
-mount3udp_thread (void *argv)
-{
- register SVCXPRT *transp = NULL;
-
- transp = svcudp_create(RPC_ANYSOCK);
- if (transp == NULL) {
- gf_log (GF_MNT, GF_LOG_ERROR, "svcudp_create error");
- return NULL;
- }
- if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3,
- mountudp_program_3, IPPROTO_UDP)) {
- gf_log (GF_MNT, GF_LOG_ERROR, "svc_register error");
- return NULL;
- }
-
- svc_run ();
- gf_log (GF_MNT, GF_LOG_ERROR, "svc_run returned");
- return NULL;
-}
diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c
index d35df87bc..f109cdde5 100644
--- a/xlators/nfs/server/src/nfs-common.c
+++ b/xlators/nfs/server/src/nfs-common.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -88,7 +88,7 @@ nfs_mntpath_to_xlator (xlator_list_t *cl, char *path)
{
char volname[MNTPATHLEN];
char *volptr = NULL;
- size_t pathlen;
+ int pathlen = 0;
xlator_t *targetxl = NULL;
if ((!cl) || (!path))
@@ -102,7 +102,7 @@ nfs_mntpath_to_xlator (xlator_list_t *cl, char *path)
else
volptr = &volname[0];
- if (pathlen && volname[pathlen - 1] == '/')
+ if (volname[pathlen - 1] == '/')
volname[pathlen - 1] = '\0';
while (cl) {
@@ -131,7 +131,7 @@ nfs_zero_filled_stat (struct iatt *buf)
* we've already mapped the root ino to 1 so it is not guaranteed to be
* 0.
*/
- if ((buf->ia_nlink == 0) && (buf->ia_ctime == 0))
+ if ((buf->ia_nlink == 0) && (buf->ia_type == 0))
return 1;
return 0;
@@ -141,18 +141,61 @@ nfs_zero_filled_stat (struct iatt *buf)
void
nfs_loc_wipe (loc_t *loc)
{
- loc_wipe (loc);
+ if (!loc)
+ return;
+
+ if (loc->path) {
+ GF_FREE ((char *)loc->path);
+ loc->path = NULL;
+ }
+
+ if (loc->parent) {
+ inode_unref (loc->parent);
+ loc->parent = NULL;
+ }
+
+ if (loc->inode) {
+ inode_unref (loc->inode);
+ loc->inode = NULL;
+ }
+
+ loc->ino = 0;
}
int
nfs_loc_copy (loc_t *dst, loc_t *src)
{
- int ret = -1;
+ int ret = -1;
- ret = loc_copy (dst, src);
+ dst->ino = src->ino;
- return ret;
+ if (src->inode)
+ dst->inode = inode_ref (src->inode);
+
+ if (src->parent)
+ dst->parent = inode_ref (src->parent);
+
+ dst->path = gf_strdup (src->path);
+
+ if (!dst->path)
+ goto out;
+
+ dst->name = strrchr (dst->path, '/');
+ if (dst->name)
+ dst->name++;
+
+ ret = 0;
+out:
+ if (ret == -1) {
+ if (dst->inode)
+ inode_unref (dst->inode);
+
+ if (dst->parent)
+ inode_unref (dst->parent);
+ }
+
+ return ret;
}
@@ -166,24 +209,24 @@ nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
if (inode) {
loc->inode = inode_ref (inode);
- if (!uuid_is_null (inode->gfid))
- uuid_copy (loc->gfid, inode->gfid);
+ loc->ino = inode->ino;
}
if (parent)
loc->parent = inode_ref (parent);
- if (path) {
- loc->path = gf_strdup (path);
- if (!loc->path) {
- gf_log (GF_NFS, GF_LOG_ERROR, "strdup failed");
- goto loc_wipe;
- }
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
+ loc->path = gf_strdup (path);
+ if (!loc->path) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "strdup failed");
+ goto loc_wipe;
}
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+ else
+ goto loc_wipe;
+
ret = 0;
loc_wipe:
if (ret < 0)
@@ -194,7 +237,7 @@ loc_wipe:
int
-nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how)
+nfs_inode_loc_fill (inode_t *inode, loc_t *loc)
{
char *resolvedpath = NULL;
inode_t *parent = NULL;
@@ -203,45 +246,34 @@ nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how)
if ((!inode) || (!loc))
return ret;
- /* If gfid is not null, then the inode is already linked to
- * the inode table, and not a newly created one. For newly
- * created inode, inode_path returns null gfid as the path.
- */
- if (!uuid_is_null (inode->gfid)) {
- ret = inode_path (inode, NULL, &resolvedpath);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "path resolution failed "
- "%s", resolvedpath);
- goto err;
- }
- }
+ if ((inode) && (inode->ino == 1))
+ goto ignore_parent;
- if (resolvedpath == NULL) {
- char tmp_path[GFID_STR_PFX_LEN + 1] = {0,};
- snprintf (tmp_path, sizeof (tmp_path), "<gfid:%s>",
- uuid_utoa (loc->gfid));
- resolvedpath = gf_strdup (tmp_path);
- }
+ parent = inode_parent (inode, 0, NULL);
+ if (!parent)
+ goto err;
+
+ignore_parent:
+ ret = inode_path (inode, NULL, &resolvedpath);
+ if (ret < 0)
+ goto err;
ret = nfs_loc_fill (loc, inode, parent, resolvedpath);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "loc fill resolution failed %s",
- resolvedpath);
+ if (ret < 0)
goto err;
- }
- ret = 0;
err:
if (parent)
inode_unref (parent);
- GF_FREE (resolvedpath);
+ if (resolvedpath)
+ GF_FREE (resolvedpath);
return ret;
}
int
-nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how)
+nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc)
{
int ret = -EFAULT;
inode_t *inode = NULL;
@@ -251,33 +283,11 @@ nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how)
inode = inode_find (itable, gfid);
if (!inode) {
- gf_log (GF_NFS, GF_LOG_TRACE, "Inode not found in itable, will try to create one.");
- if (how == NFS_RESOLVE_CREATE) {
- gf_log (GF_NFS, GF_LOG_TRACE, "Inode needs to be created.");
- inode = inode_new (itable);
- if (!inode) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to "
- "allocate memory");
- ret = -ENOMEM;
- goto err;
- }
-
- } else {
- gf_log (GF_NFS, GF_LOG_ERROR, "Inode not found in itable and no creation was requested.");
- ret = -ENOENT;
- goto err;
- }
- } else {
- gf_log (GF_NFS, GF_LOG_TRACE, "Inode was found in the itable.");
- }
-
- uuid_copy (loc->gfid, gfid);
+ ret = -ENOENT;
+ goto err;
+ }
- ret = nfs_inode_loc_fill (inode, loc, how);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Inode loc filling failed.: %s", strerror (-ret));
- goto err;
- }
+ ret = nfs_inode_loc_fill (inode, loc);
err:
if (inode)
@@ -292,7 +302,7 @@ nfs_root_loc_fill (inode_table_t *itable, loc_t *loc)
uuid_t rootgfid = {0, };
rootgfid[15] = 1;
- return nfs_gfid_loc_fill (itable, rootgfid, loc, NFS_RESOLVE_EXIST);
+ return nfs_gfid_loc_fill (itable, rootgfid, loc);
}
@@ -308,14 +318,11 @@ nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry,
return ret;
ret = inode_path (parent, entry, &path);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "path resolution failed %s",
- path);
+ if (ret < 0)
goto err;
- }
ret = nfs_loc_fill (loc, entryinode, parent, path);
- GF_FREE (path);
+
err:
return ret;
}
@@ -347,8 +354,6 @@ nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry,
if (!parent)
goto err;
- uuid_copy (loc->pargfid, pargfid);
-
ret = -2;
entryinode = inode_grep (itable, parent, entry);
if (!entryinode) {
@@ -376,18 +381,13 @@ nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry,
ret = inode_path (parent, entry, &resolvedpath);
if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "path resolution failed %s",
- resolvedpath);
ret = -3;
goto err;
}
ret = nfs_loc_fill (loc, entryinode, parent, resolvedpath);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "loc_fill failed %s",
- resolvedpath);
+ if (ret < 0)
ret = -3;
- }
err:
if (parent)
@@ -396,7 +396,8 @@ err:
if (entryinode)
inode_unref (entryinode);
- GF_FREE (resolvedpath);
+ if (resolvedpath)
+ GF_FREE (resolvedpath);
return ret;
}
diff --git a/xlators/nfs/server/src/nfs-common.h b/xlators/nfs/server/src/nfs-common.h
index 88fc14961..deca5d422 100644
--- a/xlators/nfs/server/src/nfs-common.h
+++ b/xlators/nfs/server/src/nfs-common.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -37,7 +37,7 @@
#define NFS_PATH_MAX 4096
#define NFS_NAME_MAX NAME_MAX
-#define NFS_DEFAULT_CREATE_MODE 0600
+#define NFS_DEFAULT_CREATE_MODE 0644
extern xlator_t *
nfs_xlid_to_xlator (xlator_list_t *cl, uint8_t xlid);
@@ -67,7 +67,7 @@ nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path);
#define NFS_RESOLVE_CREATE 2
extern int
-nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how);
+nfs_inode_loc_fill (inode_t *inode, loc_t *loc);
extern int
nfs_ino_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *l);
@@ -81,7 +81,4 @@ nfs_root_loc_fill (inode_table_t *itable, loc_t *loc);
extern uint32_t
nfs_hash_gfid (uuid_t gfid);
-
-extern int
-nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how);
#endif
diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c
index e2eedf433..ff055aa51 100644
--- a/xlators/nfs/server/src/nfs-fops.c
+++ b/xlators/nfs/server/src/nfs-fops.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -22,9 +22,6 @@
#include "config.h"
#endif
-#include <grp.h>
-#include <pwd.h>
-
#include "dict.h"
#include "xlator.h"
#include "iobuf.h"
@@ -34,80 +31,10 @@
#include "nfs-fops.h"
#include "inode.h"
#include "nfs-common.h"
-#include "nfs3-helpers.h"
-#include "nfs-mem-types.h"
+
#include <libgen.h>
#include <semaphore.h>
-void
-nfs_fix_groups (xlator_t *this, call_stack_t *root)
-{
- struct passwd mypw;
- char mystrs[1024];
- struct passwd *result;
- gid_t mygroups[GF_MAX_AUX_GROUPS];
- int ngroups;
- int i;
- struct nfs_state *priv = this->private;
- const gid_list_t *agl;
- gid_list_t gl;
-
- if (!priv->server_aux_gids) {
- return;
- }
-
- agl = gid_cache_lookup(&priv->gid_cache, root->uid);
- if (agl) {
- for (ngroups = 0; ngroups < agl->gl_count; ngroups++)
- root->groups[ngroups] = agl->gl_list[ngroups];
- root->ngrps = ngroups;
- gid_cache_release(&priv->gid_cache, agl);
- return;
- }
-
- /* No cached list found. */
- if (getpwuid_r(root->uid,&mypw,mystrs,sizeof(mystrs),&result) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "getpwuid_r(%u) failed", root->uid);
- return;
- }
-
- if (!result) {
- gf_log (this->name, GF_LOG_ERROR,
- "getpwuid_r(%u) found nothing", root->uid);
- return;
- }
-
- gf_log (this->name, GF_LOG_TRACE, "mapped %u => %s",
- root->uid, result->pw_name);
-
- ngroups = GF_MAX_AUX_GROUPS;
- if (getgrouplist(result->pw_name,root->gid,mygroups,&ngroups) == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "could not map %s to group list", result->pw_name);
- return;
- }
-
- /* Add the group data to the cache. */
- gl.gl_list = GF_CALLOC(ngroups, sizeof(gid_t), gf_nfs_mt_aux_gids);
- if (gl.gl_list) {
- /* It's not fatal if the alloc failed. */
- gl.gl_id = root->uid;
- gl.gl_count = ngroups;
- memcpy(gl.gl_list, mygroups, sizeof(gid_t) * ngroups);
- if (gid_cache_add(&priv->gid_cache, &gl) != 1)
- GF_FREE(gl.gl_list);
- }
-
- /* Copy data to the frame. */
- for (i = 0; i < ngroups; ++i) {
- gf_log (this->name, GF_LOG_TRACE,
- "%s is in group %u", result->pw_name, mygroups[i]);
- root->groups[i] = mygroups[i];
- }
- root->ngrps = ngroups;
-}
-
struct nfs_fop_local *
nfs_fop_local_init (xlator_t *nfsx)
{
@@ -125,9 +52,13 @@ nfs_fop_local_init (xlator_t *nfsx)
void
nfs_fop_local_wipe (xlator_t *nfsx, struct nfs_fop_local *l)
{
+ struct nfs_state *nfs = NULL;
+
if ((!nfsx) || (!l))
return;
+ nfs = nfsx->private;
+
if (l->iobref)
iobref_unref (l->iobref);
@@ -143,7 +74,7 @@ nfs_fop_local_wipe (xlator_t *nfsx, struct nfs_fop_local *l)
if (l->dictgfid)
dict_unref (l->dictgfid);
- mem_put (l);
+ mem_put (nfs->foppool, l);
return;
}
@@ -163,7 +94,7 @@ unsigned int cval = 1;
int
nfs_frame_getctr ()
{
- uint64_t val = 0;
+ int val = 0;
pthread_mutex_lock (&ctr);
{
@@ -194,24 +125,18 @@ nfs_create_frame (xlator_t *xl, nfs_user_t *nfu)
frame->root->pid = NFS_PID;
frame->root->uid = nfu->uid;
frame->root->gid = nfu->gids[NFS_PRIMGID_IDX];
- frame->root->lk_owner = nfu->lk_owner;
+ if (nfu->ngrps == 1)
+ goto err; /* Done, we only got primary gid */
- if (nfu->ngrps != 1) {
- frame->root->ngrps = nfu->ngrps - 1;
+ frame->root->ngrps = nfu->ngrps - 1;
- gf_log (GF_NFS, GF_LOG_TRACE,"uid: %d, gid %d, gids: %d",
- frame->root->uid, frame->root->gid, frame->root->ngrps);
- for(y = 0, x = 1; y < frame->root->ngrps; x++,y++) {
- gf_log (GF_NFS, GF_LOG_TRACE, "gid: %d", nfu->gids[x]);
- frame->root->groups[y] = nfu->gids[x];
- }
+ gf_log (GF_NFS, GF_LOG_TRACE,"uid: %d, gid %d, gids: %d",
+ frame->root->uid, frame->root->gid, frame->root->ngrps);
+ for(y = 0, x = 1; y < frame->root->ngrps; x++,y++) {
+ gf_log (GF_NFS, GF_LOG_TRACE, "gid: %d", nfu->gids[x]);
+ frame->root->groups[y] = nfu->gids[x];
}
-
- /*
- * It's tempting to do this *instead* of using nfu above, but we need
- * to have those values in case nfs_fix_groups doesn't do anything.
- */
- nfs_fix_groups(xl,frame->root);
+ frame->root->lk_owner = nfs_frame_getctr ();
err:
return frame;
@@ -219,7 +144,7 @@ err:
#define nfs_fop_handle_frame_create(fram, xla, nfuser, retval, errlabel) \
do { \
- fram = nfs_create_frame (xla, (nfuser)); \
+ fram = nfs_create_frame (xla, (nfuser)); \
if (!fram) { \
retval = (-ENOMEM); \
gf_log (GF_NFS, GF_LOG_ERROR,"Frame creation failed");\
@@ -231,22 +156,21 @@ err:
* for us to determine in the callback whether to funge the ino in the stat buf
* with 1 for the parent.
*/
-#define nfs_fop_save_root_ino(locl, loc) \
- do { \
- if (((loc)->inode) && \
- __is_root_gfid ((loc)->inode->gfid)) \
- (locl)->rootinode = 1; \
- else if (((loc)->parent) && \
- __is_root_gfid ((loc)->parent->gfid)) \
- (locl)->rootparentinode = 1; \
- } while (0)
+#define nfs_fop_save_root_ino(locl, loc) \
+ do { \
+ if ((loc)->ino == 1) \
+ (locl)->rootinode = 1; \
+ else if (((loc)->parent) && ((loc)->parent->ino == 1)) \
+ (locl)->rootparentinode = 1; \
+ } while (0) \
/* Do the same for an fd */
-#define nfs_fop_save_root_fd_ino(locl, fdesc) \
- do { \
- if (__is_root_gfid ((fdesc)->inode->gfid)) \
- (locl)->rootinode = 1; \
- } while (0)
+#define nfs_fop_save_root_fd_ino(locl, fdesc) \
+ do { \
+ if ((fdesc)->inode->ino == 1) \
+ (locl)->rootinode = 1; \
+ } while (0) \
+
/* Use the state saved by the previous macro to funge the ino in the appropriate
@@ -280,15 +204,14 @@ err:
/* If the newly created, inode's parent is root, we'll need to funge the ino
* in the parent attr when we receive them in the callback.
*/
-#define nfs_fop_newloc_save_root_ino(locl, newloc) \
- do { \
- if (((newloc)->inode) && \
- __is_root_gfid ((newloc)->inode->gfid)) \
- (locl)->newrootinode = 1; \
- else if (((newloc)->parent) && \
- __is_root_gfid ((newloc)->parent->gfid)) \
- (locl)->newrootparentinode = 1; \
- } while (0)
+#define nfs_fop_newloc_save_root_ino(locl, newloc) \
+ do { \
+ if ((newloc)->ino == 1) \
+ (locl)->newrootinode = 1; \
+ else if (((newloc)->parent) && ((newloc)->parent->ino == 1)) \
+ (locl)->newrootparentinode = 1; \
+ } while (0) \
+
#define nfs_fop_newloc_restore_root_ino(locl, fopret, preattr, postattr, prepar, postpar) \
do { \
@@ -430,55 +353,10 @@ err:
return ret;
}
-int32_t
-nfs_fop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_access_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, xdata);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-int
-nfs_fop_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t accesstest, fop_access_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
- uint32_t accessbits = 0;
-
- if ((!xl) || (!loc) || (!nfu))
- return ret;
-
- gf_log (GF_NFS, GF_LOG_TRACE, "Access: %s", loc->path);
- nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
- nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
- nfs_fop_save_root_ino (nfl, loc);
-
- accessbits = nfs3_request_to_accessbits (accesstest);
- STACK_WIND_COOKIE (frame, nfs_fop_access_cbk, xl, xl, xl->fops->access,
- loc, accessbits, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
int32_t
nfs_fop_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
struct nfs_fop_local *nfl = NULL;
fop_stat_cbk_t progcbk = NULL;
@@ -486,7 +364,7 @@ nfs_fop_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, buf, NULL, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, buf);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -510,7 +388,7 @@ nfs_fop_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
nfs_fop_save_root_ino (nfl, loc);
STACK_WIND_COOKIE (frame, nfs_fop_stat_cbk, xl, xl, xl->fops->stat,
- loc, NULL);
+ loc);
ret = 0;
err:
if (ret < 0) {
@@ -524,8 +402,7 @@ err:
int32_t
nfs_fop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
struct nfs_fop_local *nfl = NULL;
fop_fstat_cbk_t progcbk = NULL;
@@ -533,7 +410,7 @@ nfs_fop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, buf, NULL, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, buf);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -557,7 +434,7 @@ nfs_fop_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
nfs_fop_save_root_fd_ino (nfl, fd);
STACK_WIND_COOKIE (frame, nfs_fop_fstat_cbk, xl, xl, xl->fops->fstat,
- fd, NULL);
+ fd);
ret = 0;
err:
@@ -572,14 +449,14 @@ err:
int32_t
nfs_fop_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct nfs_fop_local *nfl = NULL;
fop_opendir_cbk_t progcbk = NULL;
nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, fd);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -601,7 +478,7 @@ nfs_fop_opendir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_opendir_cbk, xl, xl,
- xl->fops->opendir, pathloc, dirfd, NULL);
+ xl->fops->opendir, pathloc, dirfd);
ret = 0;
err:
@@ -615,14 +492,14 @@ err:
int
nfs_fop_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
struct nfs_fop_local *nfl = NULL;
fop_flush_cbk_t progcbk = NULL;
nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -644,7 +521,7 @@ nfs_fop_flush (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_flush_cbk, xl, xl, xl->fops->flush,
- fd, NULL);
+ fd);
ret = 0;
err:
if (ret < 0) {
@@ -658,15 +535,14 @@ err:
int32_t
nfs_fop_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
struct nfs_fop_local *nfl = NULL;
fop_readdirp_cbk_t progcbk = NULL;
nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, entries, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, entries);
nfs_stack_destroy (nfl, frame);
@@ -691,7 +567,7 @@ nfs_fop_readdirp (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_readdirp_cbk, xl, xl,
- xl->fops->readdirp, dirfd, bufsize, offset, 0);
+ xl->fops->readdirp, dirfd, bufsize, offset);
ret = 0;
err:
@@ -706,8 +582,7 @@ err:
int32_t
nfs_fop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
struct nfs_fop_local *nfl = NULL;
@@ -715,7 +590,7 @@ nfs_fop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, buf, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, buf);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -738,7 +613,7 @@ nfs_fop_statfs (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_statfs_cbk, xl, xl,
- xl->fops->statfs, pathloc, NULL);
+ xl->fops->statfs, pathloc);
ret = 0;
err:
if (ret < 0) {
@@ -754,7 +629,7 @@ int32_t
nfs_fop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_create_cbk_t progcbk = NULL;
@@ -764,7 +639,7 @@ nfs_fop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, NULL);
+ preparent, postparent);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -790,7 +665,7 @@ nfs_fop_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_gfid_setup (nfl, pathloc->inode, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_create_cbk, xl, xl, xl->fops->create,
- pathloc, flags, mode, 0, fd, nfl->dictgfid);
+ pathloc, flags, mode, fd, nfl->dictgfid);
ret = 0;
err:
@@ -806,7 +681,7 @@ err:
int32_t
nfs_fop_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *pre,
- struct iatt *post, dict_t *xdata)
+ struct iatt *post)
{
struct nfs_fop_local *nfl = NULL;
fop_setattr_cbk_t progcbk = NULL;
@@ -814,8 +689,7 @@ nfs_fop_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, pre, post, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, pre, post,
- xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, pre, post);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -840,7 +714,7 @@ nfs_fop_setattr (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_save_root_ino (nfl, pathloc);
STACK_WIND_COOKIE (frame, nfs_fop_setattr_cbk, xl, xl,
- xl->fops->setattr, pathloc, buf, valid, NULL);
+ xl->fops->setattr, pathloc, buf, valid);
ret = 0;
err:
if (ret < 0) {
@@ -856,7 +730,7 @@ int32_t
nfs_fop_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_mkdir_cbk_t progcbk = NULL;
@@ -865,7 +739,7 @@ nfs_fop_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs_fop_restore_root_ino (nfl, op_ret, buf, NULL,preparent, postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -889,7 +763,7 @@ nfs_fop_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_gfid_setup (nfl, pathloc->inode, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_mkdir_cbk, xl, xl, xl->fops->mkdir,
- pathloc, mode, 0, nfl->dictgfid);
+ pathloc, mode, nfl->dictgfid);
ret = 0;
err:
if (ret < 0) {
@@ -905,7 +779,7 @@ int32_t
nfs_fop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_symlink_cbk_t progcbk = NULL;
@@ -914,7 +788,7 @@ nfs_fop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs_fop_restore_root_ino (nfl, op_ret,buf, NULL, preparent, postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -937,8 +811,7 @@ nfs_fop_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target,
nfs_fop_gfid_setup (nfl, pathloc->inode, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_symlink_cbk, xl, xl,
- xl->fops->symlink, target, pathloc,
- 0, nfl->dictgfid);
+ xl->fops->symlink, target, pathloc, nfl->dictgfid);
ret = 0;
err:
if (ret < 0) {
@@ -953,7 +826,7 @@ err:
int32_t
nfs_fop_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
struct nfs_fop_local *nfl = NULL;
fop_readlink_cbk_t progcbk = NULL;
@@ -961,8 +834,7 @@ nfs_fop_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, buf, NULL, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, path, buf,
- xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, path, buf);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -985,7 +857,7 @@ nfs_fop_readlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_save_root_ino (nfl, pathloc);
STACK_WIND_COOKIE (frame, nfs_fop_readlink_cbk, xl, xl,
- xl->fops->readlink, pathloc, size, NULL);
+ xl->fops->readlink, pathloc, size);
ret = 0;
err:
if (ret < 0) {
@@ -1001,7 +873,7 @@ int32_t
nfs_fop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_mknod_cbk_t progcbk = NULL;
@@ -1010,7 +882,7 @@ nfs_fop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs_fop_restore_root_ino (nfl, op_ret,buf, NULL, preparent, postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -1034,7 +906,7 @@ nfs_fop_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_gfid_setup (nfl, pathloc->inode, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_mknod_cbk, xl, xl, xl->fops->mknod,
- pathloc, mode, dev, 0, nfl->dictgfid);
+ pathloc, mode, dev, nfl->dictgfid);
ret = 0;
err:
if (ret < 0) {
@@ -1048,7 +920,7 @@ err:
int32_t
nfs_fop_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = frame->local;
fop_rmdir_cbk_t progcbk = NULL;
@@ -1058,7 +930,7 @@ nfs_fop_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, NULL);
+ postparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -1082,7 +954,7 @@ nfs_fop_rmdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_save_root_ino (nfl, pathloc);
STACK_WIND_COOKIE (frame, nfs_fop_rmdir_cbk, xl, xl, xl->fops->rmdir,
- pathloc, 0, NULL);
+ pathloc, 0);
ret = 0;
err:
if (ret < 0) {
@@ -1098,7 +970,7 @@ err:
int32_t
nfs_fop_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = frame->local;
fop_unlink_cbk_t progcbk = NULL;
@@ -1108,7 +980,7 @@ nfs_fop_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -1131,7 +1003,7 @@ nfs_fop_unlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
nfs_fop_save_root_ino (nfl, pathloc);
STACK_WIND_COOKIE (frame, nfs_fop_unlink_cbk, xl, xl,
- xl->fops->unlink, pathloc, 0, NULL);
+ xl->fops->unlink, pathloc);
ret = 0;
err:
if (ret < 0) {
@@ -1148,7 +1020,7 @@ int32_t
nfs_fop_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_link_cbk_t progcbk = NULL;
@@ -1158,7 +1030,7 @@ nfs_fop_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
postparent);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -1183,7 +1055,7 @@ nfs_fop_link (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
nfs_fop_save_root_ino (nfl, newloc);
STACK_WIND_COOKIE (frame, nfs_fop_link_cbk, xl, xl, xl->fops->link,
- oldloc, newloc, NULL);
+ oldloc, newloc);
ret = 0;
err:
if (ret < 0) {
@@ -1199,8 +1071,7 @@ int32_t
nfs_fop_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
struct nfs_fop_local *nfl = NULL;
@@ -1209,7 +1080,7 @@ nfs_fop_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
/* The preattr arg needs to be NULL instead of @buf because it is
* possible that the new parent is not root whereas the source dir
- * could have been. That is handled in the next macro.
+ * could've been. That is handled in the next macro.
*/
nfs_fop_restore_root_ino (nfl, op_ret, NULL, NULL, preoldparent,
postoldparent);
@@ -1218,7 +1089,7 @@ nfs_fop_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, buf,
preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
+ postnewparent);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -1243,7 +1114,7 @@ nfs_fop_rename (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
nfs_fop_newloc_save_root_ino (nfl, newloc);
STACK_WIND_COOKIE (frame, nfs_fop_rename_cbk, xl, xl,
- xl->fops->rename, oldloc, newloc, NULL);
+ xl->fops->rename, oldloc, newloc);
ret = 0;
err:
if (ret < 0) {
@@ -1257,14 +1128,14 @@ err:
int32_t
nfs_fop_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct nfs_fop_local *nfl = NULL;
fop_open_cbk_t progcbk = NULL;
nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, fd);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -1272,7 +1143,7 @@ nfs_fop_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
nfs_fop_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t flags, fd_t *fd, fop_open_cbk_t cbk,
+ int32_t flags, fd_t *fd, int32_t wbflags, fop_open_cbk_t cbk,
void *local)
{
call_frame_t *frame = NULL;
@@ -1287,7 +1158,7 @@ nfs_fop_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
STACK_WIND_COOKIE (frame, nfs_fop_open_cbk, xl, xl, xl->fops->open,
- loc, flags, fd, NULL);
+ loc, flags, fd, wbflags);
ret = 0;
err:
if (ret < 0) {
@@ -1302,7 +1173,7 @@ err:
int32_t
nfs_fop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
struct nfs_fop_local *nfl = NULL;
fop_writev_cbk_t progcbk = NULL;
@@ -1310,8 +1181,7 @@ nfs_fop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, prebuf, postbuf, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, prebuf,postbuf);
nfs_stack_destroy (nfl, frame);
@@ -1321,20 +1191,20 @@ nfs_fop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- struct iobref *srciobref, struct iovec *vector, int32_t count,
+ struct iobuf *srciob, struct iovec *vector, int32_t count,
off_t offset, fop_writev_cbk_t cbk, void *local)
{
call_frame_t *frame = NULL;
int ret = -EFAULT;
struct nfs_fop_local *nfl = NULL;
- if ((!nfsx) || (!xl) || (!fd) || (!vector) || (!nfu) || (!srciobref))
+ if ((!nfsx) || (!xl) || (!fd) || (!vector) || (!nfu) || (!srciob))
return ret;
nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
nfs_fop_save_root_fd_ino (nfl, fd);
-/*
+
nfl->iobref = iobref_new ();
if (!nfl->iobref) {
gf_log (GF_NFS, GF_LOG_ERROR, "iobref creation failed");
@@ -1343,9 +1213,8 @@ nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
}
iobref_add (nfl->iobref, srciob);
-*/
- STACK_WIND_COOKIE (frame, nfs_fop_writev_cbk, xl, xl,xl->fops->writev,
- fd, vector, count, offset, 0, srciobref, NULL);
+ STACK_WIND_COOKIE (frame, nfs_fop_writev_cbk, xl, xl,xl->fops->writev
+ , fd, vector, count, offset, nfl->iobref);
ret = 0;
err:
if (ret < 0) {
@@ -1360,7 +1229,7 @@ err:
int32_t
nfs_fop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
struct nfs_fop_local *nfl = NULL;
fop_fsync_cbk_t progcbk = NULL;
@@ -1368,9 +1237,7 @@ nfs_fop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, prebuf, postbuf, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, prebuf,
- postbuf, xdata);
-
+ progcbk (frame, cookie, this, op_ret, op_errno, prebuf,postbuf);
nfs_stack_destroy (nfl, frame);
return 0;
}
@@ -1393,7 +1260,7 @@ nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
nfs_fop_save_root_fd_ino (nfl, fd);
STACK_WIND_COOKIE (frame, nfs_fop_fsync_cbk, xl, xl,
- xl->fops->fsync, fd, datasync, NULL);
+ xl->fops->fsync, fd, datasync);
ret = 0;
err:
if (ret < 0) {
@@ -1408,8 +1275,7 @@ err:
int32_t
nfs_fop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
struct nfs_fop_local *nfl = NULL;
fop_readv_cbk_t progcbk = NULL;
@@ -1418,7 +1284,7 @@ nfs_fop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs_fop_restore_root_ino (nfl, op_ret, stbuf, NULL, NULL, NULL);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -1441,60 +1307,7 @@ nfs_fop_read (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
nfs_fop_save_root_fd_ino (nfl, fd);
STACK_WIND_COOKIE (frame, nfs_fop_readv_cbk, xl, xl, xl->fops->readv,
- fd, size, offset, 0, NULL);
- ret = 0;
-err:
- if (ret < 0) {
- if (frame)
- nfs_stack_destroy (nfl, frame);
- }
-
- return ret;
-}
-
-int32_t
-nfs_fop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
-{
- struct nfs_fop_local *nfl = NULL;
- fop_lk_cbk_t progcbk = NULL;
-
- nfl_to_prog_data (nfl, progcbk, frame);
-
- if (!op_ret)
- fd_lk_insert_and_merge (nfl->fd, nfl->cmd, &nfl->flock);
-
- fd_unref (nfl->fd);
-
- if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, flock, xdata);
-
- nfs_stack_destroy (nfl, frame);
- return 0;
-}
-
-
-int
-nfs_fop_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local)
-{
- call_frame_t *frame = NULL;
- int ret = -EFAULT;
- struct nfs_fop_local *nfl = NULL;
-
- if ((!xl) || (!fd) || (!nfu))
- return ret;
-
- nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err);
- nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err);
-
- nfl->cmd = cmd;
- nfl->fd = fd_ref (fd);
- nfl->flock = *flock;
-
- STACK_WIND_COOKIE (frame, nfs_fop_lk_cbk, xl, xl, xl->fops->lk,
- fd, cmd, flock, NULL);
+ fd, size, offset);
ret = 0;
err:
if (ret < 0) {
@@ -1509,7 +1322,7 @@ err:
int32_t
nfs_fop_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
struct nfs_fop_local *nfl = NULL;
fop_truncate_cbk_t progcbk = NULL;
@@ -1517,8 +1330,7 @@ nfs_fop_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfl_to_prog_data (nfl, progcbk, frame);
nfs_fop_restore_root_ino (nfl, op_ret, prebuf, postbuf, NULL, NULL);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, prebuf,postbuf);
nfs_stack_destroy (nfl, frame);
return 0;
@@ -1541,7 +1353,7 @@ nfs_fop_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
nfs_fop_save_root_ino (nfl, loc);
STACK_WIND_COOKIE (frame, nfs_fop_truncate_cbk, xl, xl,
- xl->fops->truncate, loc, offset, NULL);
+ xl->fops->truncate, loc, offset);
ret = 0;
err:
diff --git a/xlators/nfs/server/src/nfs-fops.h b/xlators/nfs/server/src/nfs-fops.h
index b82805939..d010db282 100644
--- a/xlators/nfs/server/src/nfs-fops.h
+++ b/xlators/nfs/server/src/nfs-fops.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -96,14 +96,10 @@ struct nfs_fop_local {
*/
int rootparentinode;
- char path[NFS_NAME_MAX + 1];
- char newpath[NFS_NAME_MAX + 1];
+ char path[NFS_NAME_MAX];
+ char newpath[NFS_NAME_MAX];
xlator_t *nfsx;
dict_t *dictgfid;
-
- fd_t *fd;
- int cmd;
- struct gf_flock flock;
};
extern struct nfs_fop_local *
@@ -138,7 +134,7 @@ nfs_fop_local_wipe (xlator_t *xl, struct nfs_fop_local *l);
#define nfs_fop_handle_local_init(fram,nfx, nfloc, cbck,prgloc,retval,lab) \
do { \
- prog_data_to_nfl (nfx, nfloc, fram, cbck, prgloc); \
+ prog_data_to_nfl (nfx, nfloc, fram, cbck, prgloc); \
if (!nfloc) { \
gf_log (GF_NFS,GF_LOG_ERROR,"Failed to init local");\
retval = -ENOMEM; \
@@ -184,12 +180,12 @@ nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
extern int
nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- struct iobref *srciobref, struct iovec *vector, int32_t count,
+ struct iobuf *srciob, struct iovec *vector, int32_t count,
off_t offset, fop_writev_cbk_t cbk, void *local);
extern int
nfs_fop_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t flags, fd_t *fd, fop_open_cbk_t cbk,
+ int32_t flags, fd_t *fd, int32_t wbflags, fop_open_cbk_t cbk,
void *local);
extern int
@@ -237,12 +233,4 @@ extern int
nfs_fop_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
fop_stat_cbk_t cbk, void *local);
-extern int
-nfs_fop_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t accesstest, fop_access_cbk_t cbk, void *local);
-
-extern int
-nfs_fop_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local);
-
#endif
diff --git a/xlators/nfs/server/src/nfs-generics.c b/xlators/nfs/server/src/nfs-generics.c
index 553cc7f39..0ebba689a 100644
--- a/xlators/nfs/server/src/nfs-generics.c
+++ b/xlators/nfs/server/src/nfs-generics.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -46,19 +46,6 @@ nfs_fstat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
return ret;
}
-int
-nfs_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int32_t accesstest, fop_access_cbk_t cbk, void *local)
-{
- int ret = -EFAULT;
-
- if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
- return ret;
-
- ret = nfs_fop_access (nfsx, xl, nfu, pathloc, accesstest, cbk, local);
-
- return ret;
-}
int
nfs_stat (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
@@ -151,6 +138,7 @@ nfs_truncate (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
return ret;
}
+
int
nfs_read (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size,
off_t offset, fop_readv_cbk_t cbk, void *local)
@@ -158,12 +146,6 @@ nfs_read (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size,
return nfs_fop_read (nfsx, xl, nfu, fd, size, offset, cbk, local);
}
-int
-nfs_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local)
-{
- return nfs_fop_lk ( nfsx, xl, nfu, fd, cmd, flock, cbk, local);
-}
int
nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
@@ -175,11 +157,11 @@ nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
int
nfs_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- struct iobref *srciobref, struct iovec *vector, int32_t count,
+ struct iobuf *srciob, struct iovec *vector, int32_t count,
off_t offset, fop_writev_cbk_t cbk, void *local)
{
- return nfs_fop_write (nfsx, xl, nfu, fd, srciobref, vector, count,
- offset, cbk, local);
+ return nfs_fop_write (nfsx, xl, nfu, fd, srciob, vector, count, offset,
+ cbk, local);
}
@@ -192,7 +174,7 @@ nfs_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
if ((!nfsx) || (!xl) || (!pathloc) || (!nfu))
return ret;
- ret = nfs_inode_open (nfsx, xl, nfu, pathloc, flags, cbk,
+ ret = nfs_inode_open (nfsx, xl, nfu, pathloc, flags, GF_OPEN_NOWB, cbk,
local);
return ret;
}
@@ -335,4 +317,3 @@ nfs_opendir (xlator_t *nfsx, xlator_t *fopxl, nfs_user_t *nfu, loc_t *pathloc,
return nfs_inode_opendir (nfsx, fopxl, nfu, pathloc, cbk, local);
}
-
diff --git a/xlators/nfs/server/src/nfs-generics.h b/xlators/nfs/server/src/nfs-generics.h
index 11f191f5f..91915f120 100644
--- a/xlators/nfs/server/src/nfs-generics.h
+++ b/xlators/nfs/server/src/nfs-generics.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -43,7 +43,7 @@ struct nfs_direntcache {
* different NFS versions can simply call a standard interface and have fop
* interface dependent functions be handled internally.
* This structure is part of such an abstraction. The fops layer stores any
- * state is requires in the fd. E.g. the dirent cache for a directory fd_t.
+ * state is requires in the fd. For eg, the dirent cache for a directory fd_t.
*/
typedef struct nfs_fop_fdcontext {
pthread_mutex_t lock;
@@ -92,7 +92,7 @@ nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
extern int
nfs_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- struct iobref *srciobref, struct iovec *vector, int32_t count,
+ struct iobuf *srciob, struct iovec *vector, int32_t count,
off_t offset, fop_writev_cbk_t cbk, void *local);
extern int
@@ -157,11 +157,4 @@ nfs_read_sync (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size,
extern int
nfs_opendir (xlator_t *nfsx, xlator_t *fopxl, nfs_user_t *nfu, loc_t *pathloc,
fop_opendir_cbk_t cbk, void *local);
-
-extern int
-nfs_access (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
- int32_t accesstest, fop_access_cbk_t cbk, void *local);
-extern int
-nfs_lk (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
- int cmd, struct gf_flock *flock, fop_lk_cbk_t cbk, void *local);
#endif
diff --git a/xlators/nfs/server/src/nfs-inodes.c b/xlators/nfs/server/src/nfs-inodes.c
index c9bf37206..ddc1a9c0d 100644
--- a/xlators/nfs/server/src/nfs-inodes.c
+++ b/xlators/nfs/server/src/nfs-inodes.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -70,7 +70,7 @@ int32_t
nfs_inode_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode
, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = frame->local;
fop_create_cbk_t progcbk = NULL;
@@ -90,7 +90,7 @@ do_not_link:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (linked_inode) {
inode_lookup (linked_inode);
@@ -142,7 +142,7 @@ int32_t
nfs_inode_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = frame->local;
fop_mkdir_cbk_t progcbk = NULL;
@@ -157,7 +157,7 @@ do_not_link:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (linked_inode) {
inode_lookup (linked_inode);
@@ -193,7 +193,7 @@ err:
int32_t
nfs_inode_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct nfs_fop_local *nfl = NULL;
@@ -209,14 +209,14 @@ nfs_inode_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
+ progcbk (frame, cookie, this, op_ret, op_errno, fd);
return 0;
}
int
nfs_inode_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t flags, fop_open_cbk_t cbk, void *local)
+ int32_t flags, int32_t wbflags, fop_open_cbk_t cbk, void *local)
{
struct nfs_fop_local *nfl = NULL;
fd_t *newfd = NULL;
@@ -233,7 +233,7 @@ nfs_inode_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
}
nfs_fop_handle_local_init (NULL, nfsx, nfl, cbk, local, ret, fd_err);
- ret = nfs_fop_open (nfsx, xl, nfu, loc, flags, newfd,
+ ret = nfs_fop_open (nfsx, xl, nfu, loc, flags, newfd, wbflags,
nfs_inode_open_cbk, nfl);
if (ret < 0)
@@ -255,8 +255,7 @@ int32_t
nfs_inode_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
struct nfs_fop_local *nfl = NULL;
fop_rename_cbk_t progcbk = NULL;
@@ -273,7 +272,7 @@ do_not_link:
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, buf,
preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
+ postnewparent);
return 0;
}
@@ -306,7 +305,7 @@ int32_t
nfs_inode_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_link_cbk_t progcbk = NULL;
@@ -322,7 +321,7 @@ do_not_link:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (linked_inode) {
inode_lookup (linked_inode);
@@ -359,7 +358,7 @@ err:
int32_t
nfs_inode_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_unlink_cbk_t progcbk = NULL;
@@ -376,7 +375,7 @@ do_not_unlink:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
return 0;
}
@@ -407,7 +406,7 @@ err:
int32_t
nfs_inode_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_rmdir_cbk_t progcbk = NULL;
@@ -424,7 +423,7 @@ do_not_unlink:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
return 0;
}
@@ -457,7 +456,7 @@ int32_t
nfs_inode_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_mknod_cbk_t progcbk = NULL;
@@ -474,7 +473,7 @@ do_not_link:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (linked_inode) {
inode_lookup (linked_inode);
@@ -514,7 +513,7 @@ int32_t
nfs_inode_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
struct nfs_fop_local *nfl = NULL;
fop_symlink_cbk_t progcbk = NULL;
@@ -530,7 +529,7 @@ do_not_link:
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
progcbk (frame, cookie, this, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
if (linked_inode) {
inode_lookup (linked_inode);
@@ -566,7 +565,7 @@ err:
int32_t
nfs_inode_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
struct nfs_fop_local *nfl = NULL;
@@ -580,8 +579,7 @@ nfs_inode_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inodes_nfl_to_prog_data (nfl, progcbk, frame);
if (progcbk)
- progcbk (frame, cookie, this, op_ret, op_errno, fd, xdata);
-
+ progcbk (frame, cookie, this, op_ret, op_errno, fd);
return 0;
}
diff --git a/xlators/nfs/server/src/nfs-inodes.h b/xlators/nfs/server/src/nfs-inodes.h
index 7c962b339..a34a26738 100644
--- a/xlators/nfs/server/src/nfs-inodes.h
+++ b/xlators/nfs/server/src/nfs-inodes.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -48,7 +48,7 @@ nfs_inode_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
extern int
nfs_inode_open (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
- int32_t flags, fop_open_cbk_t cbk,
+ int32_t flags, int32_t wbflags, fop_open_cbk_t cbk,
void *local);
extern int
diff --git a/xlators/nfs/server/src/nfs-mem-types.h b/xlators/nfs/server/src/nfs-mem-types.h
index de25b08a8..0909a7fb8 100644
--- a/xlators/nfs/server/src/nfs-mem-types.h
+++ b/xlators/nfs/server/src/nfs-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -37,22 +37,12 @@ enum gf_nfs_mem_types_ {
gf_nfs_mt_entry3,
gf_nfs_mt_entryp3,
gf_nfs_mt_nfs3_fd_entry,
- gf_nfs_mt_nfs3_fh,
gf_nfs_mt_nfs_initer_list,
gf_nfs_mt_xlator_t,
gf_nfs_mt_list_head,
gf_nfs_mt_mnt3_resolve,
gf_nfs_mt_mnt3_export,
- gf_nfs_mt_int,
- gf_nfs_mt_mountres3,
- gf_nfs_mt_mountstat3,
gf_nfs_mt_inode_q,
- gf_nfs_mt_nlm4_state,
- gf_nfs_mt_nlm4_cm,
- gf_nfs_mt_nlm4_fde,
- gf_nfs_mt_nlm4_nlmclnt,
- gf_nfs_mt_nlm4_share,
- gf_nfs_mt_aux_gids,
gf_nfs_mt_end
};
#endif
diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c
index 0a5a9d1e3..081414607 100644
--- a/xlators/nfs/server/src/nfs.c
+++ b/xlators/nfs/server/src/nfs.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -39,12 +39,6 @@
#include "mount3.h"
#include "nfs3.h"
#include "nfs-mem-types.h"
-#include "nfs3-helpers.h"
-#include "nlm4.h"
-#include "options.h"
-
-#define OPT_SERVER_AUX_GIDS "nfs.server-aux-gids"
-#define OPT_SERVER_GID_CACHE_TIMEOUT "nfs.server.aux-gid-timeout"
/* Every NFS version must call this function with the init function
* for its particular version.
@@ -87,8 +81,8 @@ nfs_deinit_versions (struct list_head *versions, xlator_t *this)
version->deinit (this);
*/
if (version->program)
- rpcsvc_program_unregister (nfs->rpcsvc,
- (version->program));
+ nfs_rpcsvc_program_unregister (nfs->rpcsvc,
+ *(version->program));
list_del (&version->list);
GF_FREE (version);
@@ -97,6 +91,7 @@ nfs_deinit_versions (struct list_head *versions, xlator_t *this)
return 0;
}
+
int
nfs_init_versions (struct nfs_state *nfs, xlator_t *this)
{
@@ -122,26 +117,17 @@ nfs_init_versions (struct nfs_state *nfs, xlator_t *this)
ret = -1;
goto err;
}
-// prog->actorxl = this;
+ prog->actorxl = this;
version->program = prog;
if (nfs->override_portnum)
prog->progport = nfs->override_portnum;
gf_log (GF_NFS, GF_LOG_DEBUG, "Starting program: %s",
prog->progname);
-
- ret = rpcsvc_program_register (nfs->rpcsvc, prog);
+ ret = nfs_rpcsvc_program_register (nfs->rpcsvc, *prog);
if (ret == -1) {
gf_log (GF_NFS, GF_LOG_ERROR, "Program init failed");
goto err;
}
- if (rpcsvc_register_portmap_enabled(nfs->rpcsvc)) {
- ret = rpcsvc_program_register_portmap (prog,
- prog->progport);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Program registration failed");
- goto err;
- }
- }
}
ret = 0;
@@ -177,15 +163,6 @@ nfs_add_all_initiators (struct nfs_state *nfs)
goto ret;
}
- if (nfs->enable_nlm == _gf_true) {
- ret = nfs_add_initer (&nfs->versions, nlm4svc_init);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add protocol"
- " initializer");
- goto ret;
- }
- }
-
ret = 0;
ret:
return ret;
@@ -288,7 +265,7 @@ nfs_startup_subvolume (xlator_t *nfsx, xlator_t *xl)
goto err;
}
- ret = nfs_root_loc_fill (xl->itable, &rootloc);
+ ret = nfs_inode_loc_fill (xl->itable->root, &rootloc);
if (ret == -1) {
gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init root loc");
goto err;
@@ -389,7 +366,7 @@ nfs_init_subvolumes (struct nfs_state *nfs, xlator_list_t *cl)
}
LOCK_INIT (&nfs->svinitlock);
- nfs->initedxl = GF_CALLOC (svcount, sizeof (xlator_t *),
+ nfs->initedxl = GF_CALLOC (svcount, sizeof (xlator_t *),
gf_nfs_mt_xlator_t );
if (!nfs->initedxl) {
gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocated inited xls");
@@ -462,30 +439,13 @@ nfs_request_user_init (nfs_user_t *nfu, rpcsvc_request_t *req)
if ((!req) || (!nfu))
return;
- gidarr = rpcsvc_auth_unix_auxgids (req, &gids);
- nfs_user_create (nfu, rpcsvc_request_uid (req),
- rpcsvc_request_gid (req), gidarr, gids);
+ gidarr = nfs_rpcsvc_auth_unix_auxgids (req, &gids);
+ nfs_user_create (nfu, nfs_rpcsvc_request_uid (req),
+ nfs_rpcsvc_request_gid (req), gidarr, gids);
return;
}
-void
-nfs_request_primary_user_init (nfs_user_t *nfu, rpcsvc_request_t *req,
- uid_t uid, gid_t gid)
-{
- gid_t *gidarr = NULL;
- int gids = 0;
-
- if ((!req) || (!nfu))
- return;
-
- gidarr = rpcsvc_auth_unix_auxgids (req, &gids);
- nfs_user_create (nfu, uid, gid, gidarr, gids);
-
- return;
-}
-
-
int32_t
mem_acct_init (xlator_t *this)
{
@@ -495,7 +455,7 @@ mem_acct_init (xlator_t *this)
return ret;
ret = xlator_mem_acct_init (this, gf_nfs_mt_end + 1);
-
+
if (ret != 0) {
gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
"failed");
@@ -514,7 +474,6 @@ nfs_init_state (xlator_t *this)
unsigned int fopspoolsize = 0;
char *optstr = NULL;
gf_boolean_t boolt = _gf_false;
- struct stat stbuf = {0,};
if (!this)
return NULL;
@@ -531,20 +490,28 @@ nfs_init_state (xlator_t *this)
return NULL;
}
+ /* RPC service needs to be started before NFS versions can be
+ * inited. */
+ nfs->rpcsvc = nfs_rpcsvc_init (this->ctx, this->options);
+ if (!nfs->rpcsvc) {
+ gf_log (GF_NFS, GF_LOG_ERROR, "RPC service init failed");
+ goto free_nfs;
+ }
+
nfs->memfactor = GF_NFS_DEFAULT_MEMFACTOR;
if (dict_get (this->options, "nfs.mem-factor")) {
ret = dict_get_str (this->options, "nfs.mem-factor",
&optstr);
if (ret < 0) {
gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_rpcsvc;
+ goto free_foppool;
}
ret = gf_string2uint (optstr, &nfs->memfactor);
if (ret < 0) {
gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse uint "
"string");
- goto free_rpcsvc;
+ goto free_foppool;
}
}
@@ -577,22 +544,6 @@ nfs_init_state (xlator_t *this)
nfs->dynamicvolumes = GF_NFS_DVM_ON;
}
- nfs->enable_nlm = _gf_true;
- if (!dict_get_str (this->options, "nfs.nlm", &optstr)) {
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse"
- " bool string");
- goto free_foppool;
- }
-
- if (boolt == _gf_false) {
- gf_log (GF_NFS, GF_LOG_INFO, "NLM is manually disabled");
- nfs->enable_nlm = _gf_false;
- }
- }
-
nfs->enable_ino32 = 0;
if (dict_get (this->options, "nfs.enable-ino32")) {
ret = dict_get_str (this->options, "nfs.enable-ino32",
@@ -613,6 +564,7 @@ nfs_init_state (xlator_t *this)
nfs->enable_ino32 = 1;
}
+ nfs->override_portnum = 0;
if (dict_get (this->options, "nfs.port")) {
ret = dict_get_str (this->options, "nfs.port",
&optstr);
@@ -629,134 +581,6 @@ nfs_init_state (xlator_t *this)
}
}
- if (dict_get(this->options, "transport.socket.listen-port") == NULL) {
- if (nfs->override_portnum)
- ret = gf_asprintf (&optstr, "%d",
- nfs->override_portnum);
- else
- ret = gf_asprintf (&optstr, "%d", GF_NFS3_PORT);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "failed mem-allocation");
- goto free_foppool;
- }
- ret = dict_set_dynstr (this->options,
- "transport.socket.listen-port", optstr);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_dynstr error");
- goto free_foppool;
- }
- }
-
- if (dict_get(this->options, "transport-type") == NULL) {
- ret = dict_set_str (this->options, "transport-type", "socket");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto free_foppool;
- }
- }
-
- nfs->mount_udp = 0;
- if (dict_get(this->options, "nfs.mount-udp")) {
- ret = dict_get_str (this->options, "nfs.mount-udp", &optstr);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_foppool;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
- "string");
- goto free_foppool;
- }
-
- if (boolt == _gf_true)
- nfs->mount_udp = 1;
- }
-
- /* support both options rpc-auth.ports.insecure and
- * rpc-auth-allow-insecure for backward compatibility
- */
- nfs->allow_insecure = 1;
- if (dict_get(this->options, "rpc-auth.ports.insecure")) {
- ret = dict_get_str (this->options, "rpc-auth.ports.insecure",
- &optstr);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_foppool;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
- "string");
- goto free_foppool;
- }
-
- if (boolt == _gf_false)
- nfs->allow_insecure = 0;
- }
-
- if (dict_get(this->options, "rpc-auth-allow-insecure")) {
- ret = dict_get_str (this->options, "rpc-auth-allow-insecure",
- &optstr);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict");
- goto free_foppool;
- }
-
- ret = gf_string2boolean (optstr, &boolt);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool "
- "string");
- goto free_foppool;
- }
-
- if (boolt == _gf_false)
- nfs->allow_insecure = 0;
- }
-
- if (nfs->allow_insecure) {
- /* blindly set both the options */
- dict_del (this->options, "rpc-auth-allow-insecure");
- ret = dict_set_str (this->options,
- "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto free_foppool;
- }
- dict_del (this->options, "rpc-auth.ports.insecure");
- ret = dict_set_str (this->options,
- "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error");
- goto free_foppool;
- }
- }
-
- GF_OPTION_INIT (OPT_SERVER_AUX_GIDS, nfs->server_aux_gids,
- bool, free_foppool);
- GF_OPTION_INIT (OPT_SERVER_GID_CACHE_TIMEOUT, nfs->server_aux_gids_max_age,
- uint32, free_foppool);
-
- if (gid_cache_init(&nfs->gid_cache, nfs->server_aux_gids_max_age) < 0) {
- gf_log(GF_NFS, GF_LOG_ERROR, "Failed to initialize group cache.");
- goto free_foppool;
- }
-
- if (stat("/sbin/rpc.statd", &stbuf) == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING, "/sbin/rpc.statd not found. "
- "Disabling NLM");
- nfs->enable_nlm = _gf_false;
- }
-
- nfs->rpcsvc = rpcsvc_init (this, this->ctx, this->options, 0);
- if (!nfs->rpcsvc) {
- ret = -1;
- gf_log (GF_NFS, GF_LOG_ERROR, "RPC service init failed");
- goto free_foppool;
- }
-
this->private = (void *)nfs;
INIT_LIST_HEAD (&nfs->versions);
@@ -769,6 +593,7 @@ free_foppool:
free_rpcsvc:
/*
* rpcsvc_deinit */
+free_nfs:
if (ret < 0) {
GF_FREE (nfs);
nfs = NULL;
@@ -777,6 +602,35 @@ free_rpcsvc:
return nfs;
}
+int
+validate_options (xlator_t *this, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
+
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
+
+out:
+ return ret;
+
+}
+
int
init (xlator_t *this) {
@@ -806,20 +660,6 @@ init (xlator_t *this) {
goto err;
}
- ret = mount_init_state (this);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init Mount"
- "state");
- goto err;
- }
-
- ret = nlm4_init_state (this);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init NLM"
- "state");
- goto err;
- }
-
ret = nfs_init_versions (nfs, this);
if (ret == -1) {
gf_log (GF_NFS, GF_LOG_ERROR, "Failed to initialize "
@@ -842,8 +682,10 @@ err:
int
notify (xlator_t *this, int32_t event, void *data, ...)
{
+ struct nfs_state *nfs = NULL;
xlator_t *subvol = NULL;
+ nfs = (struct nfs_state *)this->private;
subvol = (xlator_t *)data;
gf_log (GF_NFS, GF_LOG_TRACE, "Notification received: %d",
@@ -879,127 +721,9 @@ fini (xlator_t *this)
return 0;
}
-int32_t
-nfs_forget (xlator_t *this, inode_t *inode)
-{
- uint64_t ctx = 0;
- struct list_head *head = NULL;
-
- if (inode_ctx_del (inode, this, &ctx))
- return -1;
-
- head = (struct list_head *)ctx;
- GF_FREE (head);
-
- return 0;
-}
-
-gf_boolean_t
-_nfs_export_is_for_vol (char *exname, char *volname)
-{
- gf_boolean_t ret = _gf_false;
- char *tmp = NULL;
-
- tmp = exname;
- if (tmp[0] == '/')
- tmp++;
-
- if (!strcmp (tmp, volname))
- ret = _gf_true;
-
- return ret;
-}
-
-int
-nfs_priv_to_dict (xlator_t *this, dict_t *dict)
-{
- int ret = -1;
- struct nfs_state *priv = NULL;
- struct mountentry *mentry = NULL;
- char *volname = NULL;
- char key[1024] = {0,};
- int count = 0;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (THIS->name, dict, out);
-
- priv = this->private;
- GF_ASSERT (priv);
-
- ret = dict_get_str (dict, "volname", &volname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "Could not get volname");
- goto out;
- }
-
- list_for_each_entry (mentry, &priv->mstate->mountlist, mlist) {
- if (!_nfs_export_is_for_vol (mentry->exname, volname))
- continue;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.hostname", count);
- ret = dict_set_str (dict, key, mentry->hostname);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error writing hostname to dict");
- goto out;
- }
-
- /* No connection data available yet in nfs server.
- * Hence, setting to 0 to prevent cli failing
- */
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.bytesread", count);
- ret = dict_set_uint64 (dict, key, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error writing bytes read to dict");
- goto out;
- }
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.byteswrite", count);
- ret = dict_set_uint64 (dict, key, 0);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error writing bytes write to dict");
- goto out;
- }
-
- count++;
- }
-
- ret = dict_set_int32 (dict, "clientcount", count);
- if (ret)
- gf_log (this->name, GF_LOG_ERROR,
- "Error writing client count to dict");
-
-out:
- gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
- return ret;
-}
-
-extern int32_t
-nlm_priv (xlator_t *this);
-
-int32_t
-nfs_priv (xlator_t *this)
-{
- return nlm_priv (this);
-}
-
-
-struct xlator_cbks cbks = {
- .forget = nfs_forget,
-};
-
+struct xlator_cbks cbks = { };
struct xlator_fops fops = { };
-struct xlator_dumpops dumpops = {
- .priv = nfs_priv,
- .priv_to_dict = nfs_priv_to_dict,
-};
-
/* TODO: If needed, per-volume options below can be extended to be export
+ * specific also because after export-dir is introduced, a volume is not
+ * neccessarily an export whereas different subdirectories within that volume
@@ -1010,13 +734,13 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_SIZET,
.description = "Size in which the client should issue read requests"
" to the Gluster NFSv3 server. Must be a multiple of"
- " 4KB."
+ " 4KiB."
},
{ .key = {"nfs3.write-size"},
.type = GF_OPTION_TYPE_SIZET,
.description = "Size in which the client should issue write requests"
" to the Gluster NFSv3 server. Must be a multiple of"
- " 4KB."
+ " 4KiB."
},
{ .key = {"nfs3.readdir-size"},
.type = GF_OPTION_TYPE_SIZET,
@@ -1053,7 +777,7 @@ struct volume_options options[] = {
},
{ .key = {"nfs3.*.export-dir"},
- .type = GF_OPTION_TYPE_PATH,
+ .type = GF_OPTION_TYPE_STR,
.description = "By default, all subvolumes of nfs are exported as "
"individual exports. There are cases where a "
"subdirectory or subdirectories in the volume need to "
@@ -1094,16 +818,7 @@ struct volume_options options[] = {
{ .key = {"rpc-auth.auth-unix.*"},
.type = GF_OPTION_TYPE_BOOL,
.description = "Disable or enable the AUTH_UNIX authentication type "
- "for a particular exported volume overriding defaults"
- " and general setting for AUTH_UNIX scheme. Must "
- "always be enabled for better interoperability."
- "However, can be disabled if needed. Enabled by"
- "default."
- },
- { .key = {"rpc-auth.auth-unix.*.allow"},
- .type = GF_OPTION_TYPE_STR,
- .description = "Disable or enable the AUTH_UNIX authentication type "
- "for a particular exported volume overriding defaults"
+ "for a particular exported volume over-riding defaults"
" and general setting for AUTH_UNIX scheme. Must "
"always be enabled for better interoperability."
"However, can be disabled if needed. Enabled by"
@@ -1112,37 +827,37 @@ struct volume_options options[] = {
{ .key = {"rpc-auth.auth-null.*"},
.type = GF_OPTION_TYPE_BOOL,
.description = "Disable or enable the AUTH_NULL authentication type "
- "for a particular exported volume overriding defaults"
+ "for a particular exported volume over-riding defaults"
" and general setting for AUTH_NULL. Must always be "
"enabled. This option is here only to avoid "
"unrecognized option warnings."
},
{ .key = {"rpc-auth.addr.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .type = GF_OPTION_TYPE_STR,
.description = "Allow a comma separated list of addresses and/or"
" hostnames to connect to the server. By default, all"
- " connections are allowed. This allows users to "
+ " connections are disallowed. This allows users to "
"define a general rule for all exported volumes."
},
{ .key = {"rpc-auth.addr.reject"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .type = GF_OPTION_TYPE_STR,
.description = "Reject a comma separated list of addresses and/or"
" hostnames from connecting to the server. By default,"
- " all connections are allowed. This allows users to"
+ " all connections are disallowed. This allows users to"
"define a general rule for all exported volumes."
},
{ .key = {"rpc-auth.addr.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .type = GF_OPTION_TYPE_STR,
.description = "Allow a comma separated list of addresses and/or"
" hostnames to connect to the server. By default, all"
- " connections are allowed. This allows users to "
+ " connections are disallowed. This allows users to "
"define a rule for a specific exported volume."
},
{ .key = {"rpc-auth.addr.*.reject"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
+ .type = GF_OPTION_TYPE_STR,
.description = "Reject a comma separated list of addresses and/or"
" hostnames from connecting to the server. By default,"
- " all connections are allowed. This allows users to"
+ " all connections are disallowed. This allows users to"
"define a rule for a specific exported volume."
},
{ .key = {"rpc-auth.ports.insecure"},
@@ -1156,20 +871,20 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_BOOL,
.description = "Allow client connections from unprivileged ports. By "
"default only privileged ports are allowed. Use this"
- " option to enable or disable insecure ports for "
- "a specific subvolume and to override the global setting "
+ " option to set enable or disable insecure ports for "
+ "a specific subvolume and to over-ride global setting "
" set by the previous option."
},
{ .key = {"rpc-auth.addr.namelookup"},
.type = GF_OPTION_TYPE_BOOL,
- .description = "Users have the option of turning on name lookup for"
- " incoming client connections using this option. Use this "
- "option to turn on name lookups during address-based "
- "authentication. Turning this on will enable you to"
- " use hostnames in rpc-auth.addr.* filters. In some "
+ .description = "Users have the option of turning off name lookup for"
+ " incoming client connections using this option. In some "
"setups, the name server can take too long to reply to DNS "
- "queries resulting in timeouts of mount requests. By default, "
- " name lookup is off"
+ "queries resulting in timeouts of mount requests. Use this "
+ "option to turn off name lookups during address "
+ "authentication. Note, turning this off will prevent you from"
+ " using hostnames in rpc-auth.addr.* filters. By default, "
+ " name lookup is on."
},
{ .key = {"nfs.dynamic-volumes"},
.type = GF_OPTION_TYPE_BOOL,
@@ -1189,27 +904,23 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_BOOL,
.description = "For nfs clients or apps that do not support 64-bit "
"inode numbers, use this option to make NFS return "
- "32-bit inode numbers instead. Disabled by default, so "
- "NFS returns 64-bit inode numbers."
+ "32-bit inode numbers instead. Disabled by default so "
+ "NFS returns 64-bit inode numbers by default."
},
{ .key = {"rpc.register-with-portmap"},
.type = GF_OPTION_TYPE_BOOL,
- .description = "For systems that need to run multiple nfs servers, "
- "only one registration is possible with "
+ .description = "For systems that need to run multiple nfs servers, we"
+ "need to prevent more than one from registering with "
"portmap service. Use this option to turn off portmap "
"registration for Gluster NFS. On by default"
},
{ .key = {"nfs.port"},
.type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = 0xffff,
.description = "Use this option on systems that need Gluster NFS to "
"be associated with a non-default port number."
},
{ .key = {"nfs.mem-factor"},
.type = GF_OPTION_TYPE_INT,
- .min = 1,
- .max = 1024,
.description = "Use this option to make NFS be faster on systems by "
"using more memory. This option specifies a multiple "
"that determines the total amount of memory used. "
@@ -1223,39 +934,6 @@ struct volume_options options[] = {
.description = "This option is used to start or stop NFS server"
"for individual volume."
},
-
- { .key = {"nfs.nlm"},
- .type = GF_OPTION_TYPE_BOOL,
- .description = "This option, if set to 'off', disables NLM server "
- "by not registering the service with the portmapper."
- " Set it to 'on' to re-enable it. Default value: 'on'"
- },
-
- { .key = {"nfs.mount-udp"},
- .type = GF_OPTION_TYPE_BOOL,
- .description = "set the option to 'on' to enable mountd on UDP. "
- "Needed by Solaris NFS clients if NLM support is"
- "needed"
- },
- { .key = {OPT_SERVER_AUX_GIDS},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- .description = "Let the server look up which groups a user belongs "
- "to, overwriting the list passed from the client. "
- "This enables support for group lists longer than "
- "can be passed through the NFS protocol, but is not "
- "secure unless users and groups are well synchronized "
- "between clients and servers."
- },
- { .key = {OPT_SERVER_GID_CACHE_TIMEOUT},
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = 3600,
- .default_value = "5",
- .description = "Number of seconds to cache auxiliary-GID data, when "
- OPT_SERVER_AUX_GIDS " is set."
- },
-
{ .key = {NULL} },
};
diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h
index c3deba00a..7b93cd56e 100644
--- a/xlators/nfs/server/src/nfs.h
+++ b/xlators/nfs/server/src/nfs.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -28,8 +28,6 @@
#include "rpcsvc.h"
#include "dict.h"
#include "xlator.h"
-#include "lkowner.h"
-#include "gidcache.h"
#define GF_NFS "nfs"
@@ -47,12 +45,6 @@
#define GF_NFS_DVM_ON 1
#define GF_NFS_DVM_OFF 2
-/* This corresponds to the max 16 number of group IDs that are sent through an
- * RPC request. Since NFS is the only one going to set this, we can be safe
- * in keeping this size hardcoded.
- */
-#define GF_REQUEST_MAXGROUPS 16
-
/* Callback into a version-specific NFS protocol.
* The return type is used by the nfs.c code to register the protocol.
* with the RPC service.
@@ -66,12 +58,10 @@ struct nfs_initer_list {
rpcsvc_program_t *program;
};
+
struct nfs_state {
rpcsvc_t *rpcsvc;
struct list_head versions;
- struct mount3_state *mstate;
- struct nfs3_state *nfs3state;
- struct nlm4_state *nlm4state;
struct mem_pool *foppool;
unsigned int memfactor;
xlator_list_t *subvols;
@@ -84,13 +74,6 @@ struct nfs_state {
int dynamicvolumes;
int enable_ino32;
unsigned int override_portnum;
- int allow_insecure;
- int enable_nlm;
- int mount_udp;
- struct rpc_clnt *rpc_clnt;
- gf_boolean_t server_aux_gids;
- uint32_t server_aux_gids_max_age;
- gid_cache_t gid_cache;
};
#define gf_nfs_dvm_on(nfsstt) (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_ON)
@@ -111,7 +94,6 @@ typedef struct nfs_user_info {
uid_t uid;
gid_t gids[NFS_NGROUPS];
int ngrps;
- gf_lkowner_t lk_owner;
} nfs_user_t;
extern int
@@ -124,12 +106,6 @@ nfs_user_create (nfs_user_t *newnfu, uid_t uid, gid_t gid, gid_t *auxgids,
extern void
nfs_request_user_init (nfs_user_t *nfu, rpcsvc_request_t *req);
-extern void
-nfs_request_primary_user_init (nfs_user_t *nfu, rpcsvc_request_t *req,
- uid_t uid, gid_t gid);
extern int
nfs_subvolume_started (struct nfs_state *nfs, xlator_t *xl);
-
-extern void
-nfs_fix_groups (xlator_t *this, call_stack_t *root);
#endif
diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c
index eb8223924..971bea8a3 100644
--- a/xlators/nfs/server/src/nfs3-fh.c
+++ b/xlators/nfs/server/src/nfs3-fh.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -59,6 +59,7 @@ nfs3_fh_init (struct nfs3_fh *fh, struct iatt *buf)
fh->ident[0] = GF_NFSFH_IDENT0;
fh->ident[1] = GF_NFSFH_IDENT1;
+ fh->hashcount = 0;
uuid_copy (fh->gfid, buf->ia_gfid);
}
@@ -111,6 +112,66 @@ nfs3_fh_is_root_fh (struct nfs3_fh *fh)
}
+nfs3_hash_entry_t
+nfs3_fh_hash_entry (uuid_t gfid)
+{
+ nfs3_hash_entry_t hash = 0;
+ int shiftsize = 48;
+ uint64_t ino = 0;
+ uint64_t gen = 0;
+ nfs3_hash_entry_t inomsb = 0;
+ nfs3_hash_entry_t inolsb = 0;
+ nfs3_hash_entry_t inols23b = 0;
+
+ nfs3_hash_entry_t genmsb = 0;
+ nfs3_hash_entry_t genlsb = 0;
+ nfs3_hash_entry_t genls23b = 0;
+
+ memcpy (&ino, &gfid[8], 8);
+ hash = ino;
+ while (shiftsize != 0) {
+ hash ^= (ino >> shiftsize);
+ shiftsize -= 16;
+ }
+/*
+ gf_log ("FILEHANDLE", GF_LOG_TRACE, "INO %"PRIu64, ino);
+ gf_log ("FILEHANDLE",GF_LOG_TRACE, "PRI HASH %d", hash);
+*/
+ inomsb = (ino >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inomsb %d", inomsb);
+
+ inolsb = ((ino << 56) >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb %d", inolsb);
+
+ inolsb = (inolsb << 8);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb to inomsb %d", inolsb);
+ inols23b = ((ino << 40) >> 48);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ inols23b = (inols23b << 8);
+// gf_log ("FILEHDNALE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ memcpy (&gen, &gfid[0], 8);
+ genmsb = (gen >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inomsb %d", inomsb);
+
+ genlsb = ((gen << 56) >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb %d", inolsb);
+
+ genlsb = (genlsb << 8);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb to inomsb %d", inolsb);
+
+ genls23b = ((gen << 40) >> 48);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ genls23b = (genls23b << 8);
+// gf_log ("FILEHDNALE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ hash ^= inolsb ^ inomsb ^ inols23b ^ genmsb ^ genlsb ^ genls23b;
+ return hash;
+
+}
+
void
nfs3_fh_to_str (struct nfs3_fh *fh, char *str)
{
@@ -120,24 +181,30 @@ nfs3_fh_to_str (struct nfs3_fh *fh, char *str)
if ((!fh) || (!str))
return;
- sprintf (str, "FH: exportid %s, gfid %s",
- uuid_utoa_r (fh->exportid, exportid),
+ sprintf (str, "FH: hashcount %d, exportid %s, gfid %s",
+ fh->hashcount, uuid_utoa_r (fh->exportid, exportid),
uuid_utoa_r (fh->gfid, gfid));
}
void
nfs3_log_fh (struct nfs3_fh *fh)
{
+// int x = 0;
char gfidstr[512];
char exportidstr[512];
if (!fh)
return;
- gf_log ("nfs3-fh", GF_LOG_TRACE, "filehandle: exportid "
- "0x%s, gfid 0x%s",
+ gf_log ("nfs3-fh", GF_LOG_TRACE, "filehandle: hashcount %d, exportid "
+ "0x%s, gfid 0x%s", fh->hashcount,
uuid_utoa_r (fh->exportid, exportidstr),
uuid_utoa_r (fh->gfid, gfidstr));
+/*
+ for (; x < fh->hashcount; ++x)
+ gf_log ("FILEHANDLE", GF_LOG_TRACE, "Hash %d: %d", x,
+ fh->entryhash[x]);
+*/
}
int
@@ -149,33 +216,53 @@ nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,
nfs3_fh_init (newfh, newstat);
uuid_copy (newfh->exportid, child->exportid);
+ if (newstat->ia_ino == 1)
+ goto done;
- return 0;
-}
+ newfh->hashcount = child->hashcount - 1;
+ memcpy (newfh->entryhash, child->entryhash,
+ newfh->hashcount * GF_NFSFH_ENTRYHASH_SIZE);
-int
-nfs3_build_fh (inode_t *inode, uuid_t exportid, struct nfs3_fh *newfh)
-{
- if (!newfh || !inode)
- return -1;
+done:
+// nfs3_log_fh (newfh);
- newfh->ident[0] = GF_NFSFH_IDENT0;
- newfh->ident[1] = GF_NFSFH_IDENT1;
- uuid_copy (newfh->gfid, inode->gfid);
- uuid_copy (newfh->exportid, exportid);
return 0;
}
+
int
nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
struct nfs3_fh *newfh)
{
+ int hashcount = 0;
+ int entry = 0;
+
if ((!parent) || (!newstat) || (!newfh))
return -1;
nfs3_fh_init (newfh, newstat);
uuid_copy (newfh->exportid, parent->exportid);
+ newfh->hashcount = parent->hashcount + 1;
+ /* Only copy the hashes that are available in the parent file
+ * handle. */
+ if (parent->hashcount > GF_NFSFH_MAXHASHES)
+ hashcount = GF_NFSFH_MAXHASHES;
+ else
+ hashcount = parent->hashcount;
+
+ memcpy (newfh->entryhash, parent->entryhash,
+ hashcount * GF_NFSFH_ENTRYHASH_SIZE);
+
+ /* Do not insert parent dir hash if there is no space left in the hash
+ * array of the child entry. */
+ if (newfh->hashcount <= GF_NFSFH_MAXHASHES) {
+ entry = newfh->hashcount - 1;
+ newfh->entryhash[entry] = nfs3_fh_hash_entry (parent->gfid);
+ }
+
+// nfs3_log_fh (newfh);
+
return 0;
}
@@ -183,5 +270,34 @@ nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
uint32_t
nfs3_fh_compute_size (struct nfs3_fh *fh)
{
- return GF_NFSFH_STATIC_SIZE;
+ uint32_t fhlen = 0;
+
+ if (!fh)
+ return 0;
+
+ if (fh->hashcount <= GF_NFSFH_MAXHASHES)
+ fhlen = nfs3_fh_hashcounted_size (fh->hashcount);
+ else
+ fhlen = nfs3_fh_hashcounted_size (GF_NFSFH_MAXHASHES);
+
+ return fhlen;
}
+
+
+/* There is no point searching at a directory level which is beyond that of
+ * the hashcount given in the file handle.
+ */
+int
+nfs3_fh_hash_index_is_beyond (struct nfs3_fh *fh, int hashidx)
+{
+ if (!fh)
+ return 1;
+
+ if (fh->hashcount >= hashidx)
+ return 0;
+ else
+ return 1;
+
+ return 1;
+}
+
diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h
index a9002afe7..f52c36ecf 100644
--- a/xlators/nfs/server/src/nfs3-fh.h
+++ b/xlators/nfs/server/src/nfs3-fh.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -36,7 +36,16 @@
#define GF_NFSFH_IDENT0 ':'
#define GF_NFSFH_IDENT1 'O'
#define GF_NFSFH_IDENT_SIZE (sizeof(char) * 2)
-#define GF_NFSFH_STATIC_SIZE (GF_NFSFH_IDENT_SIZE + (2*sizeof (uuid_t)))
+#define GF_NFSFH_STATIC_SIZE (GF_NFSFH_IDENT_SIZE + (2*sizeof (uuid_t)) + sizeof (uint16_t))
+#define GF_NFSFH_MAX_HASH_BYTES (NFS3_FHSIZE - GF_NFSFH_STATIC_SIZE)
+
+/* Each hash element in the file handle is of 2 bytes thus giving
+ * us theoretically 65536 unique entries in a directory.
+ */
+typedef uint16_t nfs3_hash_entry_t;
+#define GF_NFSFH_ENTRYHASH_SIZE (sizeof (nfs3_hash_entry_t))
+#define GF_NFSFH_MAXHASHES ((int)(GF_NFSFH_MAX_HASH_BYTES / GF_NFSFH_ENTRYHASH_SIZE))
+#define nfs3_fh_hashcounted_size(hcount) (GF_NFSFH_STATIC_SIZE + (hcount * GF_NFSFH_ENTRYHASH_SIZE))
#define nfs3_fh_exportid_to_index(exprtid) ((uint16_t)exprtid[15])
/* ATTENTION: Change in size of the structure below should be reflected in the
@@ -63,6 +72,11 @@ struct nfs3_fh {
/* File/dir gfid. */
uuid_t gfid;
+
+ /* Number of file/ino hash elements that follow the ino. */
+ uint16_t hashcount;
+
+ nfs3_hash_entry_t entryhash[GF_NFSFH_MAXHASHES];
} __attribute__((__packed__));
#define GF_NFS3FH_STATIC_INITIALIZER {{0},}
@@ -70,6 +84,9 @@ struct nfs3_fh {
extern uint32_t
nfs3_fh_compute_size (struct nfs3_fh *fh);
+extern int
+nfs3_fh_hash_index_is_beyond (struct nfs3_fh *fh, int hashidx);
+
extern uint16_t
nfs3_fh_hash_entry (uuid_t gfid);
@@ -98,8 +115,4 @@ nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,
extern struct nfs3_fh
nfs3_fh_build_uuid_root_fh (uuid_t volumeid);
-
-extern int
-nfs3_build_fh (inode_t *inode, uuid_t exportid, struct nfs3_fh *newfh);
-
#endif
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c
index e2c16ef0e..468f8f7af 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -102,18 +102,21 @@ struct nfs3stat_strerror nfs3stat_strerror_table[] = {
uint64_t
nfs3_iatt_gfid_to_ino (struct iatt *buf)
{
- uint64_t ino = 0;
+ uuid_t gfid = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+ uint64_t ino = 0;
if (!buf)
return 0;
- if (gf_nfs_enable_ino32()) {
- ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid);
- goto hashout;
- }
+ if ((buf->ia_ino != 1) && (uuid_compare (buf->ia_gfid, gfid) != 0)) {
+ if (gf_nfs_enable_ino32()) {
+ ino = (uint32_t )nfs_hash_gfid (buf->ia_gfid);
+ goto hashout;
+ }
- /* from posix its guaranteed to send unique ino */
- ino = buf->ia_ino;
+ memcpy (&ino, &buf->ia_gfid[8], sizeof (uint64_t));
+ } else
+ ino = 1;
hashout:
return ino;
@@ -343,15 +346,25 @@ nfs3_stat_to_fattr3 (struct iatt *buf)
fa.fsid = buf->ia_dev;
fa.fileid = nfs3_iatt_gfid_to_ino (buf);
+ /* FIXME: Handle time resolutions for sub-second granularity */
+ if (buf->ia_atime == 9669) {
+ fa.mtime.seconds = 0;
+ fa.mtime.nseconds = 0;
+ fa.atime.seconds = 0;
+ fa.atime.nseconds = 0;
+ } else {
+ fa.mtime.seconds = buf->ia_mtime;
+ fa.mtime.nseconds = 0;
+ fa.atime.seconds = buf->ia_atime;
+ fa.atime.seconds = 0;
+ fa.atime.nseconds = 0;
+ }
fa.atime.seconds = buf->ia_atime;
- fa.atime.nseconds = buf->ia_atime_nsec;
+ fa.atime.nseconds = 0;
fa.ctime.seconds = buf->ia_ctime;
- fa.ctime.nseconds = buf->ia_ctime_nsec;
-
- fa.mtime.seconds = buf->ia_mtime;
- fa.mtime.nseconds = buf->ia_mtime_nsec;
+ fa.ctime.nseconds = 0;
return fa;
}
@@ -395,10 +408,11 @@ nfs3_stat_to_pre_op_attr (struct iatt *pre)
poa.attributes_follow = TRUE;
poa.pre_op_attr_u.attributes.size = pre->ia_size;
- poa.pre_op_attr_u.attributes.mtime.seconds = pre->ia_mtime;
- poa.pre_op_attr_u.attributes.mtime.nseconds = pre->ia_mtime_nsec;
+ if (pre->ia_atime == 9669)
+ poa.pre_op_attr_u.attributes.mtime.seconds = 0;
+ else
+ poa.pre_op_attr_u.attributes.mtime.seconds = pre->ia_mtime;
poa.pre_op_attr_u.attributes.ctime.seconds = pre->ia_ctime;
- poa.pre_op_attr_u.attributes.ctime.nseconds = pre->ia_ctime_nsec;
out:
return poa;
@@ -551,48 +565,171 @@ nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh)
args->object.data.data_val = (void *)fh;
}
-#define POSIX_READ 4
-#define POSIX_WRITE 2
-#define POSIX_EXEC 1
uint32_t
-nfs3_accessbits (int32_t accbits)
+nfs3_owner_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request)
{
- uint32_t accresult = 0;
+ uint32_t accresult = 0;
- if (accbits & POSIX_READ)
+ if (IA_PROT_RUSR (prot) && (request & ACCESS3_READ))
accresult |= ACCESS3_READ;
- if (accbits & POSIX_WRITE)
- accresult |= (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE);
+ if (request & ACCESS3_LOOKUP)
+ if ((IA_ISDIR (type)) && (IA_PROT_XUSR (prot)))
+ accresult |= ACCESS3_LOOKUP;
+
+ if ((IA_PROT_WUSR (prot) && (request & ACCESS3_MODIFY)))
+ accresult |= ACCESS3_MODIFY;
+
+ if ((IA_PROT_WUSR (prot) && (request & ACCESS3_EXTEND)))
+ accresult |= ACCESS3_EXTEND;
+
+ /* ACCESS3_DELETE is ignored for now since that requires
+ * knowing the permissions on the parent directory.
+ */
+
+ if (request & ACCESS3_EXECUTE)
+ if (IA_PROT_XUSR (prot) && (!IA_ISDIR (type)))
+ accresult |= ACCESS3_EXECUTE;
+
+ return accresult;
+}
+
+
+uint32_t
+nfs3_group_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request)
+{
+ uint32_t accresult = 0;
+
+ if (IA_PROT_RGRP (prot) && (request & ACCESS3_READ))
+ accresult |= ACCESS3_READ;
+
+ if (request & ACCESS3_LOOKUP)
+ if ((IA_ISDIR (type)) && IA_PROT_RGRP (prot))
+ accresult |= ACCESS3_LOOKUP;
+
+ if (IA_PROT_WGRP (prot) && (request & ACCESS3_MODIFY))
+ accresult |= ACCESS3_MODIFY;
+
+ if (IA_PROT_WGRP (prot) && (request & ACCESS3_EXTEND))
+ accresult |= ACCESS3_EXTEND;
+
+ /* ACCESS3_DELETE is ignored for now since that requires
+ * knowing the permissions on the parent directory.
+ */
+
+ if (request & ACCESS3_EXECUTE)
+ if (IA_PROT_XGRP (prot) && (!IA_ISDIR (type)))
+ accresult |= ACCESS3_EXECUTE;
+
+ return accresult;
+}
+
+
+uint32_t
+nfs3_other_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request)
+{
+ uint32_t accresult = 0;
+
+ if (IA_PROT_ROTH (prot) && (request & ACCESS3_READ))
+ accresult |= ACCESS3_READ;
+
+ if (request & ACCESS3_LOOKUP)
+ if (IA_ISDIR (type) && IA_PROT_ROTH (prot))
+ accresult |= ACCESS3_LOOKUP;
+
+ if (IA_PROT_WOTH (prot) && (request & ACCESS3_MODIFY))
+ accresult |= ACCESS3_MODIFY;
+
+ if (IA_PROT_WOTH (prot) && (request & ACCESS3_EXTEND))
+ accresult |= ACCESS3_EXTEND;
+
+ /* ACCESS3_DELETE is ignored for now since that requires
+ * knowing the permissions on the parent directory.
+ */
- /* lookup on directory allowed only in case of execute permission */
- if (accbits & POSIX_EXEC)
- accresult |= (ACCESS3_EXECUTE | ACCESS3_LOOKUP);
+ if (request & ACCESS3_EXECUTE)
+ if (IA_PROT_XOTH (prot) && (!IA_ISDIR (type)))
+ accresult |= ACCESS3_EXECUTE;
return accresult;
}
+
uint32_t
-nfs3_request_to_accessbits (int32_t accbits)
+nfs3_superuser_accessbits (ia_prot_t prot, ia_type_t type, uint32_t request)
{
- uint32_t acc_request = 0;
+ uint32_t accresult = 0;
+
+ if (request & ACCESS3_READ)
+ accresult |= ACCESS3_READ;
+
+ if (request & ACCESS3_LOOKUP)
+ if (IA_ISDIR (type))
+ accresult |= ACCESS3_LOOKUP;
+
+ if (request & ACCESS3_MODIFY)
+ accresult |= ACCESS3_MODIFY;
- if (accbits & ACCESS3_READ)
- acc_request |= POSIX_READ;
+ if (request & ACCESS3_EXTEND)
+ accresult |= ACCESS3_EXTEND;
- if (accbits & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE))
- acc_request |= POSIX_WRITE;
+ /* ACCESS3_DELETE is ignored for now since that requires
+ * knowing the permissions on the parent directory.
+ */
+
+ if (request & ACCESS3_EXECUTE)
+ if ((IA_PROT_XOTH (prot) || IA_PROT_XUSR (prot) ||
+ IA_PROT_XGRP (prot)) && (!IA_ISDIR (type)))
+ accresult |= ACCESS3_EXECUTE;
+
+ return accresult;
+}
- /* For lookup on directory check for execute permission */
- if (accbits & (ACCESS3_EXECUTE | ACCESS3_LOOKUP))
- acc_request |= POSIX_EXEC;
- return acc_request;
+uint32_t
+nfs3_stat_to_accessbits (struct iatt *buf, uint32_t request, uid_t uid,
+ gid_t gid, gid_t *auxgids, int gids)
+{
+ uint32_t accresult = 0;
+ ia_prot_t prot = {0, };
+ ia_type_t type = 0;
+ int testgid = -1;
+ int x = 0;
+
+ prot = buf->ia_prot;
+ type = buf->ia_type;
+
+ if (buf->ia_gid == gid)
+ testgid = gid;
+ else {
+ for (; x < gids; ++x) {
+ if (buf->ia_gid == auxgids[x]) {
+ testgid = buf->ia_gid;
+ break;
+ }
+ }
+ }
+
+ if (uid == 0)
+ accresult = nfs3_superuser_accessbits (prot, type, request);
+ else if (buf->ia_uid == uid)
+ accresult = nfs3_owner_accessbits (prot, type, request);
+ else if ((testgid != -1) && (buf->ia_gid == testgid))
+ accresult = nfs3_group_accessbits (prot, type, request);
+ else
+ accresult = nfs3_other_accessbits (prot, type, request);
+
+ return accresult;
}
+
+
void
-nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits)
+nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf,
+ uint32_t accbits, uid_t uid, gid_t gid,
+ uint64_t deviceid, gid_t *gidarr, int gids)
{
+ post_op_attr objattr;
uint32_t accres = 0;
memset (res, 0, sizeof (*res));
@@ -600,8 +737,11 @@ nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits)
if (status != NFS3_OK)
return;
- accres = nfs3_accessbits (accbits);
+ nfs3_map_deviceid_to_statdev (buf, deviceid);
+ objattr = nfs3_stat_to_post_op_attr (buf);
+ accres = nfs3_stat_to_accessbits (buf, accbits, uid, gid, gidarr, gids);
+ res->access3res_u.resok.obj_attributes = objattr;
res->access3res_u.resok.access = accres;
}
@@ -680,7 +820,7 @@ nfs3_fill_entry3 (gf_dirent_t *entry, struct nfs3_fh *dfh)
/* If the entry is . or .., we need to replace the physical ino and gen
* with 1 and 0 respectively if the directory is root. This funging is
* needed because there is no parent directory of the root. In that
- * sense the behavior we provide is similar to the output of the
+ * sense the behavious we provide is similar to the output of the
* command: "stat /.."
*/
entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat);
@@ -749,7 +889,7 @@ nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh, uint64_t devid)
/* If the entry is . or .., we need to replace the physical ino and gen
* with 1 and 0 respectively if the directory is root. This funging is
* needed because there is no parent directory of the root. In that
- * sense the behavior we provide is similar to the output of the
+ * sense the behavious we provide is similar to the output of the
* command: "stat /.."
*/
entry->d_ino = nfs3_iatt_gfid_to_ino (&entry->d_stat);
@@ -1603,1804 +1743,694 @@ err:
}
-void
-nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat,
- char *errstr)
-{
- if ((!op) || (!errstr))
- return;
-
- sprintf (errstr, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", xid, op,
- stat, nfsstat3_strerror (stat), pstat, strerror (pstat));
-}
-
-void
-nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh)
-{
- char fhstr[1024];
-
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
-
- nfs3_fh_to_str (fh, fhstr);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s", xid, op,
- fhstr);
-}
-
-
-void
-nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh,
- char *name)
+/* When remove a file, we need to unref the cached fd for an inode but this
+ * needs to happen only when the file was in fact opened. However, it is
+ * possible that fd_lookup on a file returns an fd because the file was in
+ * process of being created(which also returns an fd) but since this fd was not
+ * opened through this path, in the NFS3 remove path, we'll end up removing the
+ * reference that belongs to someone else. That means, nfs3 remove path should
+ * not unref unless it is sure that the file was cached open also. If it was,
+ * only then perform the fd_unref, else not.
+ *
+ * We determine that using a flag in the inode context.
+ */
+int
+nfs3_set_inode_opened (xlator_t *nfsxl, inode_t *inode)
{
- char fhstr[1024];
-
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, name: %s", xid,
- op, fhstr, name);
-}
+ if ((!nfsxl) || (!inode))
+ return -1;
+ inode_ctx_put (inode, nfsxl, GF_NFS3_FD_CACHED);
-void
-nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname,
- struct nfs3_fh *dst, char *dname)
-{
- char sfhstr[1024];
- char dfhstr[1024];
-
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (src, sfhstr);
- nfs3_fh_to_str (dst, dfhstr);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, RENAME: args: Src: %s, "
- "name: %s, Dst: %s, name: %s", xid, sfhstr, sname, dfhstr,
- dname);
+ return 0;
}
-
-void
-nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name,
- createmode3 mode)
+/* Returns 1 if inode was cached open, otherwise 0 */
+int
+nfs3_cached_inode_opened (xlator_t *nfsxl, inode_t *inode)
{
- char fhstr[1024];
- char *modestr = NULL;
- char exclmode[] = "EXCLUSIVE";
- char unchkd[] = "UNCHECKED";
- char guarded[] = "GUARDED";
-
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr);
- if (mode == EXCLUSIVE)
- modestr = exclmode;
- else if (mode == GUARDED)
- modestr = guarded;
- else
- modestr = unchkd;
-
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, CREATE: args: %s, name: %s,"
- " mode: %s", xid, fhstr, name, modestr);
-}
-
+ int ret = -1;
+ uint64_t cflag = 0;
-void
-nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type)
-{
- char fhstr[1024];
- char *modestr = NULL;
- char chr[] = "CHAR";
- char blk[] = "BLK";
- char sock[] = "SOCK";
- char fifo[] = "FIFO";
+ if ((!nfsxl) || (!inode))
+ return -1;
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr);
- if (type == NF3CHR)
- modestr = chr;
- else if (type == NF3BLK)
- modestr = blk;
- else if (type == NF3SOCK)
- modestr = sock;
- else
- modestr = fifo;
+ ret = inode_ctx_get (inode, nfsxl, &cflag);
+ if (ret == -1)
+ ret = 0;
+ else if (cflag == GF_NFS3_FD_CACHED)
+ ret = 1;
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, MKNOD: args: %s, name: %s,"
- " type: %s", xid, fhstr, name, modestr);
+ return ret;
}
-
-void
-nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt)
+int32_t
+nfs3_dir_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- char fhstr[1024];
-
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, SYMLINK: args: %s, name: %s,"
- " target: %s", xid, fhstr, name, tgt);
-}
-
+ nfs3_call_state_t *cs = NULL;
-void
-nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name,
- struct nfs3_fh *tgt)
-{
- char dfhstr[1024];
- char tfhstr[1024];
+ cs = frame->local;
+ if (op_ret == -1) {
+ cs->resolve_ret = -1;
+ cs->resolve_errno = op_errno;
+ nfs3_call_resume (cs);
+ goto err;
+ }
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, dfhstr);
- nfs3_fh_to_str (tgt, tfhstr);
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, LINK: args: %s, name: %s,"
- " target: %s", xid, dfhstr, name, tfhstr);
+ cs->fd = fd; /* Gets unrefd when the call state is wiped. */
+ nfs3_set_inode_opened (cs->nfsx, cs->resolvedloc.inode);
+ gf_log (GF_NFS3, GF_LOG_TRACE, "FD_REF: %d", fd->refcount);
+ nfs3_call_resume (cs);
+err:
+ return 0;
}
-void
-nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt,
- count3 count, int stablewrite)
+int
+__nfs3_dir_open_and_resume (nfs3_call_state_t *cs)
{
- char fhstr[1024];
+ nfs_user_t nfu = {0, };
+ int ret = -EFAULT;
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
- nfs3_fh_to_str (fh, fhstr);
- if (stablewrite == -1)
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:"
- " %"PRIu64", count: %"PRIu32, xid, op, fhstr, offt,
- count);
- else
- gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:"
- " %"PRIu64", count: %"PRIu32", %s", xid, op, fhstr,
- offt, count,
- (stablewrite == UNSTABLE)?"UNSTABLE":"STABLE");
+ if (!cs)
+ return ret;
+ nfs_user_root_create (&nfu);
+ ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_dir_open_cbk, cs);
+ return ret;
}
int
-nfs3_getattr_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_PERM:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ACCES:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+nfs3_dir_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume)
+{
+ fd_t *fd = NULL;
+ int ret = -EFAULT;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if ((!cs))
+ return ret;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ cs->resume_fn = resume;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening: %s", cs->resolvedloc.path);
+ fd = fd_lookup (cs->resolvedloc.inode, 0);
+ if (fd) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: ref: %d", fd->refcount);
+ cs->fd = fd; /* Gets unrefd when the call state is wiped. */
+ cs->resolve_ret = 0;
+ nfs3_call_resume (cs);
+ ret = 0;
+ goto err;
}
- return ll;
-}
-
-
-int
-nfs3_setattr_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
+ ret = __nfs3_dir_open_and_resume (cs);
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
-
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
-
- return ll;
+err:
+ return ret;
}
int
-nfs3_lookup_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_PERM:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ACCES:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+nfs3_flush_call_state (nfs3_call_state_t *cs, fd_t *openedfd)
+{
+ if ((!cs))
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Calling resume");
+ if (openedfd) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd done: %d",
+ openedfd->refcount);
+ cs->fd = fd_ref (openedfd);
+ /* Set resove_ret to 0 so that the error checking in the resume
+ * callback results in a successful read reply when the fd was
+ * opened. If the fd opening failed, the resolve_ret is already
+ * set to -1 in nfs3_file_open_cbk, so that will result in an
+ * error being returned to the nfs client' read request.
+ */
+ cs->resolve_ret = 0;
}
+ list_del (&cs->openwait_q);
+ nfs3_call_resume (cs);
- return ll;
+ return 0;
}
int
-nfs3_access_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+nfs3_flush_inode_queue (struct inode_op_queue *inode_q, fd_t *openedfd)
+{
+ nfs3_call_state_t *cstmp = NULL;
+ nfs3_call_state_t *cs = NULL;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if (!inode_q)
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
+ list_for_each_entry_safe (cs, cstmp, &inode_q->opq, openwait_q)
+ nfs3_flush_call_state (cs, openedfd);
- return ll;
+ return 0;
}
int
-nfs3_readlink_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+nfs3_flush_open_wait_call_states (nfs3_call_state_t *cs, fd_t *openedfd)
+{
+ struct inode_op_queue *inode_q = NULL;
+ uint64_t ctxaddr = 0;
+ int ret = 0;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if (!cs)
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Flushing call state");
+ ret = inode_ctx_get (cs->resolvedloc.inode, cs->nfsx, &ctxaddr);
+ if (ret == -1) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "No inode queue present");
+ goto out;
}
- return ll;
-}
-
-int
-nfs3_read_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ inode_q = (struct inode_op_queue *)(long)ctxaddr;
+ if (!inode_q)
+ goto out;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ pthread_mutex_lock (&inode_q->qlock);
+ {
+ nfs3_flush_inode_queue (inode_q, openedfd);
}
+ pthread_mutex_unlock (&inode_q->qlock);
- return ll;
+out:
+ return 0;
}
int
-nfs3_write_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+__nfs3_fdcache_update_entry (struct nfs3_state *nfs3, fd_t *fd)
+{
+ uint64_t ctxaddr = 0;
+ struct nfs3_fd_entry *fde = NULL;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if ((!nfs3) || (!fd))
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Updating fd: 0x%lx", (long int)fd);
+ fd_ctx_get (fd, nfs3->nfsx, &ctxaddr);
+ fde = (struct nfs3_fd_entry *)(long)ctxaddr;
+ if (fde) {
+ list_del (&fde->list);
+ list_add_tail (&fde->list, &nfs3->fdlru);
}
- return ll;
+ return 0;
}
int
-nfs3_create_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+nfs3_fdcache_update (struct nfs3_state *nfs3, fd_t *fd)
+{
+ if ((!nfs3) || (!fd))
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ LOCK (&nfs3->fdlrulock);
+ {
+ __nfs3_fdcache_update_entry (nfs3, fd);
}
+ UNLOCK (&nfs3->fdlrulock);
- return ll;
+ return 0;
}
int
-nfs3_mkdir_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+__nfs3_fdcache_remove_entry (struct nfs3_state *nfs3, struct nfs3_fd_entry *fde)
+{
+ if ((!fde) || (!nfs3))
+ return 0;
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Removing fd: 0x%lx: %d",
+ (long int)fde->cachedfd, fde->cachedfd->refcount);
+ list_del (&fde->list);
+ fd_ctx_del (fde->cachedfd, nfs3->nfsx, NULL);
+ fd_unref (fde->cachedfd);
+ GF_FREE (fde);
+ --nfs3->fdcount;
- return ll;
+ return 0;
}
int
-nfs3_symlink_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+nfs3_fdcache_remove (struct nfs3_state *nfs3, fd_t *fd)
+{
+ struct nfs3_fd_entry *fde = NULL;
+ uint64_t ctxaddr = 0;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if ((!nfs3) || (!fd))
+ return -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ LOCK (&nfs3->fdlrulock);
+ {
+ fd_ctx_get (fd, nfs3->nfsx, &ctxaddr);
+ fde = (struct nfs3_fd_entry *)(long)ctxaddr;
+ __nfs3_fdcache_remove_entry (nfs3, fde);
}
+ UNLOCK (&nfs3->fdlrulock);
- return ll;
+ return 0;
}
int
-nfs3_mknod_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
+__nfs3_fdcache_replace (struct nfs3_state *nfs3)
+{
+ struct nfs3_fd_entry *fde = NULL;
+ struct nfs3_fd_entry *tmp = NULL;
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
+ if (!nfs3)
+ return -1;
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
+ if (nfs3->fdcount <= GF_NFS3_FDCACHE_SIZE)
+ return 0;
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
+ list_for_each_entry_safe (fde, tmp, &nfs3->fdlru, list)
break;
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
+ __nfs3_fdcache_remove_entry (nfs3, fde);
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
+ return 0;
+}
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
+int
+nfs3_fdcache_add (struct nfs3_state *nfs3, fd_t *fd)
+{
+ struct nfs3_fd_entry *fde = NULL;
+ int ret = -1;
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
+ if ((!nfs3) || (!fd))
+ return -1;
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+ fde = GF_CALLOC (1, sizeof (*fd), gf_nfs_mt_nfs3_fd_entry);
+ if (!fde) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "fd entry allocation failed");
+ goto out;
+ }
- default:
- ll = GF_LOG_DEBUG;
- break;
+ /* Already refd by caller. */
+ fde->cachedfd = fd;
+ INIT_LIST_HEAD (&fde->list);
+
+ LOCK (&nfs3->fdlrulock);
+ {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Adding fd: 0x%lx",
+ (long int) fd);
+ fd_ctx_set (fd, nfs3->nfsx, (uintptr_t)fde);
+ fd_bind (fd);
+ list_add_tail (&fde->list, &nfs3->fdlru);
+ ++nfs3->fdcount;
+ __nfs3_fdcache_replace (nfs3);
}
+ UNLOCK (&nfs3->fdlrulock);
- return ll;
+out:
+ return ret;
}
-int
-nfs3_remove_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+int32_t
+nfs3_file_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
+{
+ nfs3_call_state_t *cs = NULL;
+ struct nfs3_state *nfs3 = NULL;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ cs = frame->local;
+ if (op_ret == -1) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd failed: "
+ "%s", strerror(op_errno));
+ cs->resolve_ret = -1;
+ cs->resolve_errno = op_errno;
+ fd = NULL;
+ } else {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd done: %d",
+ fd->refcount);
}
- return ll;
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
+ /* Call states are flushed even when the opening of the file failed.
+ * This allows returning an error for each one of the file io requests
+ * that are currently queued waiting for the open to succeed.
+ */
+ nfs3_flush_open_wait_call_states (cs, fd);
+ if (fd)
+ nfs3_fdcache_add (nfs3, fd);
+ return 0;
}
-int
-nfs3_rmdir_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
+struct inode_op_queue *
+__nfs3_get_inode_queue (nfs3_call_state_t *cs)
+{
+ struct inode_op_queue *inode_q = NULL;
+ int ret = -1;
+ uint64_t ctxaddr = 0;
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
+ ret = __inode_ctx_get (cs->resolvedloc.inode, cs->nfsx, &ctxaddr);
+ if (ret == 0) {
+ inode_q = (struct inode_op_queue *)(long)ctxaddr;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Inode queue already inited");
+ goto err;
+ }
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
+ inode_q = GF_CALLOC (1, sizeof (*inode_q), gf_nfs_mt_inode_q);
+ if (!inode_q) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Memory allocation failed");
+ goto err;
+ }
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Initing inode queue");
+ INIT_LIST_HEAD (&inode_q->opq);
+ pthread_mutex_init (&inode_q->qlock, NULL);
+ __inode_ctx_put (cs->resolvedloc.inode, cs->nfsx, (uintptr_t)inode_q);
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
+err:
+ return inode_q;
+}
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+struct inode_op_queue *
+nfs3_get_inode_queue (nfs3_call_state_t *cs)
+{
+ struct inode_op_queue *inode_q = NULL;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ LOCK (&cs->resolvedloc.inode->lock);
+ {
+ inode_q = __nfs3_get_inode_queue (cs);
}
+ UNLOCK (&cs->resolvedloc.inode->lock);
- return ll;
+ return inode_q;
}
-int
-nfs3_rename_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
+#define GF_NFS3_FD_OPEN_INPROGRESS 1
+#define GF_NFS3_FD_NEEDS_OPEN 0
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
+int
+__nfs3_queue_call_state (struct inode_op_queue *inode_q, nfs3_call_state_t *cs)
+{
+ int ret = -1;
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+ if (!inode_q)
+ goto err;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ pthread_mutex_lock (&inode_q->qlock);
+ {
+ if (list_empty (&inode_q->opq)) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "First call in queue");
+ ret = GF_NFS3_FD_NEEDS_OPEN;
+ } else
+ ret = GF_NFS3_FD_OPEN_INPROGRESS;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Queueing call state");
+ list_add_tail (&cs->openwait_q, &inode_q->opq);
}
+ pthread_mutex_unlock (&inode_q->qlock);
- return ll;
+err:
+ return ret;
}
+/* Returns GF_NFS3_FD_NEEDS_OPEN if the current call is the first one to be
+ * queued. If so, the caller will need to send the open fop. If this is a
+ * non-first call to be queued, it means the fd opening is in progress and
+ * GF_NFS3_FD_OPEN_INPROGRESS is returned.
+ *
+ * Returns -1 on error.
+ */
int
-nfs3_link_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+nfs3_queue_call_state (nfs3_call_state_t *cs)
+{
+ struct inode_op_queue *inode_q = NULL;
+ int ret = -1;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ inode_q = nfs3_get_inode_queue (cs);
+ if (!inode_q) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get inode op queue");
+ goto err;
}
- return ll;
+ ret = __nfs3_queue_call_state (inode_q, cs);
+
+err:
+ return ret;
}
int
-nfs3_readdir_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+__nfs3_file_open_and_resume (nfs3_call_state_t *cs)
+{
+ nfs_user_t nfu = {0, };
+ int ret = -EFAULT;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ if (!cs)
+ return ret;
- default:
- ll = GF_LOG_DEBUG;
- break;
+ ret = nfs3_queue_call_state (cs);
+ if (ret == -1) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Error queueing call state");
+ ret = -EFAULT;
+ goto out;
+ } else if (ret == GF_NFS3_FD_OPEN_INPROGRESS) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Open in progress. Will wait.");
+ ret = 0;
+ goto out;
}
- return ll;
+ nfs_user_root_create (&nfu);
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening uncached fd");
+ ret = nfs_open (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, O_RDWR,
+ nfs3_file_open_cbk, cs);
+out:
+ return ret;
}
-int
-nfs3_fsstat_loglevel (nfsstat3 stat) {
-
- int ll = GF_LOG_DEBUG;
-
- switch (stat) {
-
- case NFS3ERR_PERM:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOENT:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_ACCES:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_EXIST:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_XDEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NODEV:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_IO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NXIO:
- ll = GF_LOG_WARNING;
- break;
-
- case NFS3ERR_NOTDIR:
- ll = GF_LOG_WARNING;
- break;
+fd_t *
+nfs3_fdcache_getfd (struct nfs3_state *nfs3, inode_t *inode)
+{
+ fd_t *fd = NULL;
- case NFS3ERR_ISDIR:
- ll = GF_LOG_WARNING;
- break;
+ if ((!nfs3) || (!inode))
+ return NULL;
- case NFS3ERR_INVAL:
- ll = GF_LOG_WARNING;
- break;
+ fd = fd_lookup (inode, 0);
+ if (fd) {
+ /* Already refd by fd_lookup, so no need to ref again. */
+ gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: %d",
+ fd->refcount);
+ nfs3_fdcache_update (nfs3, fd);
+ } else
+ gf_log (GF_NFS3, GF_LOG_TRACE, "fd not found in state");
- case NFS3ERR_NOSPC:
- ll = GF_LOG_WARNING;
- break;
+ return fd;
+}
- case NFS3ERR_ROFS:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_FBIG:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_MLINK:
- ll = GF_LOG_WARNING;
- break;
+int
+nfs3_file_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume)
+{
+ fd_t *fd = NULL;
+ int ret = -EFAULT;
- case NFS3ERR_NAMETOOLONG:
- ll = GF_LOG_WARNING;
- break;
+ if (!cs)
+ return ret;
- case NFS3ERR_NOTEMPTY:
- ll = GF_LOG_WARNING;
- break;
+ cs->resume_fn = resume;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Opening: %s", cs->resolvedloc.path);
+ fd = nfs3_fdcache_getfd (cs->nfs3state, cs->resolvedloc.inode);
+ if (fd) {
+ cs->fd = fd; /* Gets unrefd when the call state is wiped. */
+ cs->resolve_ret = 0;
+ nfs3_call_resume (cs);
+ ret = 0;
+ goto err;
+ }
- case NFS3ERR_SERVERFAULT:
- ll = GF_LOG_WARNING;
- break;
+ ret = __nfs3_file_open_and_resume (cs);
- case NFS3ERR_NOTSUPP:
- ll = GF_LOG_WARNING;
- break;
+err:
+ return ret;
+}
- case NFS3ERR_BADHANDLE:
- ll = GF_LOG_WARNING;
- break;
- case NFS3ERR_STALE:
- ll = GF_LOG_WARNING;
- break;
+void
+nfs3_stat_to_errstr (uint32_t xid, char *op, nfsstat3 stat, int pstat,
+ char *errstr)
+{
+ if ((!op) || (!errstr))
+ return;
- case NFS3ERR_DQUOT:
- ll = GF_LOG_WARNING;
- break;
+ sprintf (errstr, "XID: %x, %s: NFS: %d(%s), POSIX: %d(%s)", xid, op,
+ stat, nfsstat3_strerror (stat), pstat, strerror (pstat));
+}
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
+void
+nfs3_log_common_call (uint32_t xid, char *op, struct nfs3_fh *fh)
+{
+ char fhstr[1024];
- return ll;
+ nfs3_fh_to_str (fh, fhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s", xid, op,
+ fhstr);
}
-struct nfs3op_str {
- int op;
- char str[100];
-};
-struct nfs3op_str nfs3op_strings[] = {
- { NFS3_NULL, "NULL"},
- { NFS3_GETATTR, "GETATTR"},
- { NFS3_SETATTR, "SETATTR"},
- { NFS3_LOOKUP, "LOOKUP"},
- { NFS3_ACCESS, "ACCESS"},
- { NFS3_READLINK, "READLINK"},
- { NFS3_READ, "READ"},
- { NFS3_WRITE, "WRITE"},
- { NFS3_CREATE, "CREATE"},
- { NFS3_MKDIR, "MKDIR"},
- { NFS3_SYMLINK, "SYMLINK"},
- { NFS3_MKNOD, "MKNOD"},
- { NFS3_REMOVE, "REMOVE"},
- { NFS3_RMDIR, "RMDIR"},
- { NFS3_RENAME, "RENAME"},
- { NFS3_LINK, "LINK"},
- { NFS3_READDIR, "READDIR"},
- { NFS3_READDIRP, "READDIRP"},
- { NFS3_FSSTAT, "FSSTAT"},
- { NFS3_FSINFO, "FSINFO"},
- { NFS3_PATHCONF, "PATHCONF"},
- { NFS3_COMMIT, "COMMIT"},
-};
-
-int
-nfs3_loglevel (int nfs_op, nfsstat3 stat) {
+void
+nfs3_log_fh_entry_call (uint32_t xid, char *op, struct nfs3_fh *fh,
+ char *name)
+{
+ char fhstr[1024];
- int ll = GF_LOG_DEBUG;
+ nfs3_fh_to_str (fh, fhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, name: %s", xid,
+ op, fhstr, name);
+}
- switch (nfs_op) {
- case NFS3_GETATTR:
- ll = nfs3_getattr_loglevel (stat);
- break;
- case NFS3_SETATTR:
- ll = nfs3_setattr_loglevel (stat);
- break;
+void
+nfs3_log_rename_call (uint32_t xid, struct nfs3_fh *src, char *sname,
+ struct nfs3_fh *dst, char *dname)
+{
+ char sfhstr[1024];
+ char dfhstr[1024];
- case NFS3_LOOKUP:
- ll = nfs3_lookup_loglevel (stat);
- break;
+ nfs3_fh_to_str (src, sfhstr);
+ nfs3_fh_to_str (dst, dfhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, RENAME: args: Src: %s, "
+ "name: %s, Dst: %s, name: %s", xid, sfhstr, sname, dfhstr,
+ dname);
+}
- case NFS3_ACCESS:
- ll = nfs3_access_loglevel (stat);
- break;
- case NFS3_READLINK:
- ll = nfs3_readlink_loglevel (stat);
- break;
- case NFS3_READ:
- ll = nfs3_read_loglevel (stat);
- break;
+void
+nfs3_log_create_call (uint32_t xid, struct nfs3_fh *fh, char *name,
+ createmode3 mode)
+{
+ char fhstr[1024];
+ char *modestr = NULL;
+ char exclmode[] = "EXCLUSIVE";
+ char unchkd[] = "UNCHECKED";
+ char guarded[] = "GUARDED";
- case NFS3_WRITE:
- ll = nfs3_write_loglevel (stat);
- break;
+ nfs3_fh_to_str (fh, fhstr);
+ if (mode == EXCLUSIVE)
+ modestr = exclmode;
+ else if (mode == GUARDED)
+ modestr = guarded;
+ else
+ modestr = unchkd;
- case NFS3_CREATE:
- ll = nfs3_create_loglevel (stat);
- break;
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, CREATE: args: %s, name: %s,"
+ " mode: %s", xid, fhstr, name, modestr);
+}
- case NFS3_MKDIR:
- ll = nfs3_mkdir_loglevel (stat);
- break;
- case NFS3_SYMLINK:
- ll = nfs3_symlink_loglevel (stat);
- break;
+void
+nfs3_log_mknod_call (uint32_t xid, struct nfs3_fh *fh, char *name, int type)
+{
+ char fhstr[1024];
+ char *modestr = NULL;
+ char chr[] = "CHAR";
+ char blk[] = "BLK";
+ char sock[] = "SOCK";
+ char fifo[] = "FIFO";
- case NFS3_MKNOD:
- ll = nfs3_mknod_loglevel (stat);
- break;
+ nfs3_fh_to_str (fh, fhstr);
+ if (type == NF3CHR)
+ modestr = chr;
+ else if (type == NF3BLK)
+ modestr = blk;
+ else if (type == NF3SOCK)
+ modestr = sock;
+ else
+ modestr = fifo;
- case NFS3_REMOVE:
- ll = nfs3_remove_loglevel (stat);
- break;
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, MKNOD: args: %s, name: %s,"
+ " type: %s", xid, fhstr, name, modestr);
+}
- case NFS3_RMDIR:
- ll = nfs3_rmdir_loglevel (stat);
- break;
- case NFS3_RENAME:
- ll = nfs3_rename_loglevel (stat);
- break;
- case NFS3_LINK:
- ll = nfs3_link_loglevel (stat);
- break;
+void
+nfs3_log_symlink_call (uint32_t xid, struct nfs3_fh *fh, char *name, char *tgt)
+{
+ char fhstr[1024];
- case NFS3_READDIR:
- ll = nfs3_readdir_loglevel (stat);
- break;
+ nfs3_fh_to_str (fh, fhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, SYMLINK: args: %s, name: %s,"
+ " target: %s", xid, fhstr, name, tgt);
+}
- case NFS3_READDIRP:
- ll = nfs3_readdir_loglevel (stat);
- break;
- case NFS3_FSSTAT:
- ll = nfs3_fsstat_loglevel (stat);
- break;
+void
+nfs3_log_link_call (uint32_t xid, struct nfs3_fh *fh, char *name,
+ struct nfs3_fh *tgt)
+{
+ char dfhstr[1024];
+ char tfhstr[1024];
- case NFS3_FSINFO:
- ll = nfs3_fsstat_loglevel (stat);
- break;
+ nfs3_fh_to_str (fh, dfhstr);
+ nfs3_fh_to_str (tgt, tfhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, LINK: args: %s, name: %s,"
+ " target: %s", xid, dfhstr, name, tfhstr);
+}
- case NFS3_PATHCONF:
- ll = nfs3_fsstat_loglevel (stat);
- break;
- case NFS3_COMMIT:
- ll = nfs3_write_loglevel (stat);
- break;
+void
+nfs3_log_rw_call (uint32_t xid, char *op, struct nfs3_fh *fh, offset3 offt,
+ count3 count, int stablewrite)
+{
+ char fhstr[1024];
- default:
- ll = GF_LOG_DEBUG;
- break;
- }
+ nfs3_fh_to_str (fh, fhstr);
+ if (stablewrite == -1)
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:"
+ " %"PRIu64", count: %"PRIu32, xid, op, fhstr, offt,
+ count);
+ else
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "XID: %x, %s: args: %s, offset:"
+ " %"PRIu64", count: %"PRIu32", %s", xid, op, fhstr,
+ offt, count,
+ (stablewrite == UNSTABLE)?"UNSTABLE":"STABLE");
- return ll;
}
+
void
-nfs3_log_common_res (uint32_t xid, int op, nfsstat3 stat, int pstat)
+nfs3_log_common_res (uint32_t xid, char *op, nfsstat3 stat, int pstat)
{
char errstr[1024];
- int ll = nfs3_loglevel (op, stat);
- if (gf_log_loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s", errstr);
+ nfs3_stat_to_errstr (xid, op, stat, pstat, errstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s", errstr);
}
void
nfs3_log_readlink_res (uint32_t xid, nfsstat3 stat, int pstat, char *linkpath)
{
char errstr[1024];
- int ll = nfs3_loglevel (NFS3_READLINK, stat);
-
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "READLINK", stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s, target: %s",
- errstr, linkpath);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, target: %s", errstr, linkpath);
}
@@ -3409,18 +2439,14 @@ nfs3_log_read_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count,
int is_eof, struct iovec *vec, int32_t veccount)
{
char errstr[1024];
- int ll = GF_LOG_DEBUG;
- ll = nfs3_loglevel (NFS3_READ, stat);
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "READ", stat, pstat, errstr);
if (vec)
- gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", is_eof:"
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", is_eof:"
" %d, vector: count: %d, len: %zd", errstr, count,
is_eof, veccount, vec->iov_len);
else
- gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", is_eof:"
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", is_eof:"
" %d", errstr, count, is_eof);
}
@@ -3430,32 +2456,25 @@ nfs3_log_write_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count,
int stable, uint64_t wverf)
{
char errstr[1024];
- int ll = nfs3_loglevel (NFS3_WRITE, stat);
-
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "WRITE", stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", %s,wverf: %"PRIu64
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", %s,wverf: %"PRIu64
, errstr, count, (stable == UNSTABLE)?"UNSTABLE":"STABLE",
wverf);
}
void
-nfs3_log_newfh_res (uint32_t xid, int op, nfsstat3 stat, int pstat,
+nfs3_log_newfh_res (uint32_t xid, char *op, nfsstat3 stat, int pstat,
struct nfs3_fh *newfh)
{
char errstr[1024];
char fhstr[1024];
- int ll = nfs3_loglevel (op, stat);
- if (gf_log_loglevel < ll)
- return;
- nfs3_stat_to_errstr (xid, nfs3op_strings[op].str, stat, pstat, errstr);
+ nfs3_stat_to_errstr (xid, op, stat, pstat, errstr);
nfs3_fh_to_str (newfh, fhstr);
- gf_log (GF_NFS3, nfs3_loglevel (op, stat), "%s, %s", errstr, fhstr);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, %s", errstr, fhstr);
}
@@ -3464,12 +2483,9 @@ nfs3_log_readdir_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf,
count3 count, int is_eof)
{
char errstr[1024];
- int ll = nfs3_loglevel (NFS3_READDIR, stat);
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "READDIR", stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s, count: %"PRIu32", cverf: %"PRIu64
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, count: %"PRIu32", cverf: %"PRIu64
", is_eof: %d", errstr, count, cverf, is_eof);
}
@@ -3479,12 +2495,9 @@ nfs3_log_readdirp_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t cverf,
count3 dircount, count3 maxcount, int is_eof)
{
char errstr[1024];
- int ll = nfs3_loglevel (NFS3_READDIRP, stat);
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "READDIRPLUS", stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s, dircount: %"PRIu32", maxcount: %"
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, dircount: %"PRIu32", maxcount: %"
PRIu32", cverf: %"PRIu64", is_eof: %d", errstr, dircount,
maxcount, cverf, is_eof);
}
@@ -3494,12 +2507,9 @@ void
nfs3_log_commit_res (uint32_t xid, nfsstat3 stat, int pstat, uint64_t wverf)
{
char errstr[1024];
- int ll = nfs3_loglevel (NFS3_COMMIT, stat);
- if (gf_log_loglevel < ll)
- return;
nfs3_stat_to_errstr (xid, "COMMIT", stat, pstat, errstr);
- gf_log (GF_NFS3, ll, "%s, wverf: %"PRIu64, errstr, wverf);
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "%s, wverf: %"PRIu64, errstr, wverf);
}
@@ -3509,9 +2519,6 @@ nfs3_log_readdir_call (uint32_t xid, struct nfs3_fh *fh, count3 dircount,
{
char fhstr[1024];
- if (gf_log_loglevel < GF_LOG_DEBUG)
- return;
-
nfs3_fh_to_str (fh, fhstr);
if (maxcount == 0)
@@ -3533,11 +2540,9 @@ nfs3_fh_resolve_inode_done (nfs3_call_state_t *cs, inode_t *inode)
return ret;
gf_log (GF_NFS3, GF_LOG_TRACE, "FH inode resolved");
- ret = nfs_inode_loc_fill (inode, &cs->resolvedloc, NFS_RESOLVE_EXIST);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "inode loc fill failed");
+ ret = nfs_inode_loc_fill (inode, &cs->resolvedloc);
+ if (ret < 0)
goto err;
- }
nfs3_call_resume (cs);
@@ -3545,6 +2550,55 @@ err:
return ret;
}
+#define GF_NFS3_FHRESOLVE_FOUND 1
+#define GF_NFS3_FHRESOLVE_NOTFOUND 2
+#define GF_NFS3_FHRESOLVE_DIRFOUND 3
+
+int
+nfs3_fh_resolve_check_entry (struct nfs3_fh *fh, gf_dirent_t *candidate,
+ int hashidx)
+{
+ struct iatt *ia = NULL;
+ int ret = GF_NFS3_FHRESOLVE_NOTFOUND;
+ nfs3_hash_entry_t entryhash = 0;
+
+ if ((!fh) || (!candidate))
+ return ret;
+
+ if ((strcmp (candidate->d_name, ".") == 0) ||
+ (strcmp (candidate->d_name, "..") == 0))
+ goto found_entry;
+
+ ia = &candidate->d_stat;
+ if ((uuid_compare (candidate->d_stat.ia_gfid, fh->gfid)) == 0) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Found entry: gfid: %s, "
+ "name: %s, hashcount %d",
+ uuid_utoa (candidate->d_stat.ia_gfid),
+ candidate->d_name, hashidx);
+ ret = GF_NFS3_FHRESOLVE_FOUND;
+ goto found_entry;
+ }
+
+ /* This condition ensures that we never have to be afraid of having
+ * a directory hash conflict with a file hash. The consequence of
+ * this condition is that we can now have unlimited files in a directory
+ * and upto 65536 sub-directories in a directory.
+ */
+ if (!IA_ISDIR (candidate->d_stat.ia_type))
+ goto found_entry;
+ entryhash = fh->entryhash[hashidx];
+ if (entryhash == nfs3_fh_hash_entry (ia->ia_gfid)) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Found hash match: %s: %d, "
+ "hashidx: %d", candidate->d_name, entryhash, hashidx);
+ ret = GF_NFS3_FHRESOLVE_DIRFOUND;
+ goto found_entry;
+ }
+
+found_entry:
+
+ return ret;
+}
+
int32_t
nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie,
@@ -3561,16 +2615,13 @@ nfs3_fh_resolve_entry_lookup_cbk (call_frame_t *frame, void *cookie,
cs->resolve_errno = op_errno;
if (op_ret == -1) {
- gf_log (GF_NFS3, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR),
- "Lookup failed: %s: %s",
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Lookup failed: %s: %s",
cs->resolvedloc.path, strerror (op_errno));
goto err;
} else
gf_log (GF_NFS3, GF_LOG_TRACE, "Entry looked up: %s",
cs->resolvedloc.path);
- memcpy (&cs->stbuf, buf, sizeof (*buf));
- memcpy (&cs->postparent, postparent, sizeof (*postparent));
linked_inode = inode_link (inode, cs->resolvedloc.parent,
cs->resolvedloc.name, buf);
if (linked_inode) {
@@ -3583,8 +2634,44 @@ err:
}
+
+int32_t
+nfs3_fh_resolve_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries);
+
+int
+nfs3_fh_resolve_found_entry (nfs3_call_state_t *cs, gf_dirent_t *candidate)
+{
+ int ret = 0;
+ nfs_user_t nfu = {0, };
+ uuid_t gfid = {0, };
+
+ if ((!cs) || (!candidate))
+ return -EFAULT;
+
+ uuid_copy (gfid, cs->resolvedloc.inode->gfid);
+ nfs_loc_wipe (&cs->resolvedloc);
+ ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name,
+ &cs->resolvedloc, NFS_RESOLVE_CREATE);
+ if (ret == -ENOENT) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Entry not in itable, needs"
+ " lookup");
+ nfs_user_root_create (&nfu);
+ ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_entry_lookup_cbk,
+ cs);
+ } else {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Entry got from itable");
+ nfs3_call_resume (cs);
+ }
+
+ return ret;
+}
+
+
int32_t
-nfs3_fh_resolve_inode_lookup_cbk (call_frame_t *frame, void *cookie,
+nfs3_fh_resolve_parent_lookup_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
int32_t op_errno, inode_t *inode,
struct iatt *buf, dict_t *xattr,
@@ -3598,37 +2685,332 @@ nfs3_fh_resolve_inode_lookup_cbk (call_frame_t *frame, void *cookie,
cs->resolve_errno = op_errno;
if (op_ret == -1) {
- gf_log (GF_NFS3, (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_ERROR),
- "Lookup failed: %s: %s",
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Lookup failed: %s: %s",
cs->resolvedloc.path, strerror (op_errno));
nfs3_call_resume (cs);
goto err;
- }
+ } else
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Entry looked up: %s",
+ cs->resolvedloc.path);
- memcpy (&cs->stbuf, buf, sizeof(*buf));
- memcpy (&cs->postparent, buf, sizeof(*postparent));
linked_inode = inode_link (inode, cs->resolvedloc.parent,
cs->resolvedloc.name, buf);
if (linked_inode) {
inode_lookup (linked_inode);
- inode_unref (cs->resolvedloc.inode);
- cs->resolvedloc.inode = linked_inode;
+ inode_unref (linked_inode);
}
+ nfs3_fh_resolve_entry_hard (cs);
- /* If it is an entry lookup and we landed in the callback for hard
- * inode resolution, it means the parent inode was not available and
- * had to be resolved first. Now that is done, lets head back into
- * entry resolution.
- */
- if (cs->resolventry)
+err:
+ return 0;
+}
+
+
+int
+nfs3_fh_resolve_found_parent (nfs3_call_state_t *cs, gf_dirent_t *candidate)
+{
+ int ret = 0;
+ nfs_user_t nfu = {0, };
+ uuid_t gfid = {0, };
+
+ if ((!cs) || (!candidate))
+ return -EFAULT;
+
+ uuid_copy (gfid, cs->resolvedloc.inode->gfid);
+ nfs_loc_wipe (&cs->resolvedloc);
+ ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name,
+ &cs->resolvedloc, NFS_RESOLVE_CREATE);
+ if (ret == -ENOENT) {
+ nfs_user_root_create (&nfu);
+ ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_parent_lookup_cbk,
+ cs);
+ } else
nfs3_fh_resolve_entry_hard (cs);
- else
- nfs3_call_resume (cs);
+
+ return ret;
+}
+
+
+int
+nfs3_fh_resolve_found (nfs3_call_state_t *cs, gf_dirent_t *candidate)
+{
+ int ret = 0;
+
+ if ((!cs) || (!candidate))
+ return -EFAULT;
+
+ if (!cs->resolventry) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate entry was found");
+ ret = nfs3_fh_resolve_found_entry (cs, candidate);
+ } else {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Entry's parent was found");
+ ret = nfs3_fh_resolve_found_parent (cs, candidate);
+ }
+
+ return ret;
+}
+
+
+int32_t
+nfs3_fh_resolve_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
+{
+ nfs3_call_state_t *cs = NULL;
+ int ret = -EFAULT;
+ nfs_user_t nfu = {0, };
+
+ cs = frame->local;
+ cs->resolve_ret = op_ret;
+ cs->resolve_errno = op_errno;
+
+ if (op_ret == -1) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir open failed: %s: %s",
+ cs->resolvedloc.path, strerror (op_errno));
+ nfs3_call_resume (cs);
+ goto err;
+ } else
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Reading directory: %s",
+ cs->resolvedloc.path);
+
+ nfs_user_root_create (&nfu);
+ /* Keep this directory fd_t around till we have either:
+ * a. found the entry,
+ * b. exhausted all the entries,
+ * c. decide to step into a child directory.
+ *
+ * This decision is made in nfs3_fh_resolve_check_response.
+ */
+ cs->resolve_dir_fd = fd;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "resolve new fd refed: 0x%lx, ref: %d",
+ (long)cs->resolve_dir_fd, cs->resolve_dir_fd->refcount);
+ ret = nfs_readdirp (cs->nfsx, cs->vol, &nfu, fd, GF_NFS3_DTPREF, 0,
+ nfs3_fh_resolve_readdir_cbk, cs);
+
err:
+ return ret;
+}
+
+int32_t
+nfs3_fh_resolve_dir_lookup_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ nfs3_call_state_t *cs = NULL;
+ nfs_user_t nfu = {0, };
+ inode_t *linked_inode = NULL;
+
+ cs = frame->local;
+ cs->resolve_ret = op_ret;
+ cs->resolve_errno = op_errno;
+
+ if (op_ret == -1) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Lookup failed: %s: %s",
+ cs->resolvedloc.path, strerror (op_errno));
+ nfs3_call_resume (cs);
+ goto err;
+ } else
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s",
+ cs->resolvedloc.path);
+
+ nfs_user_root_create (&nfu);
+ linked_inode = inode_link (inode, cs->resolvedloc.parent,
+ cs->resolvedloc.name, buf);
+ if (linked_inode) {
+ inode_lookup (linked_inode);
+ inode_unref (linked_inode);
+ }
+
+ nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_opendir_cbk, cs);
+
+err:
+ return 0;
+}
+
+
+/* Validate the depth of the dir such that we do not end up opening and
+ * reading directories beyond those that are needed for resolving the file
+ * handle.
+ * Returns 1 if fh resolution can continue, 0 otherwise.
+ */
+int
+nfs3_fh_resolve_validate_dirdepth (nfs3_call_state_t *cs)
+{
+ int ret = 1;
+
+ if (!cs)
+ return 0;
+
+ /* This condition will generally never be hit because the
+ * hash-matching scheme will prevent us from going into a
+ * directory that is not part of the hash-array.
+ */
+ if (nfs3_fh_hash_index_is_beyond (&cs->resolvefh, cs->hashidx)) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index is beyond: idx %d,"
+ " fh idx: %d", cs->hashidx, cs->resolvefh.hashcount);
+ ret = 0;
+ goto out;
+ }
+
+ if (cs->hashidx >= GF_NFSFH_MAXHASHES) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index beyond max hashes:"
+ " hashidx %d, max: %d", cs->hashidx,
+ GF_NFSFH_MAXHASHES);
+ ret = 0;
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+int
+nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uuid_t dirgfid, char *entry)
+{
+ int ret = -EFAULT;
+ nfs_user_t nfu = {0, };
+
+ if (!cs)
+ return ret;
+
+ cs->hashidx++;
+ nfs_loc_wipe (&cs->resolvedloc);
+ if (!nfs3_fh_resolve_validate_dirdepth (cs)) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed");
+ nfs3_call_resume_estale (cs);
+ ret = 0;
+ goto out;
+ }
+
+ nfs_user_root_create (&nfu);
+ gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard dir resolution: gfid: %s, "
+ "entry: %s, next hashcount: %d", uuid_utoa (dirgfid), entry,
+ cs->hashidx);
+ ret = nfs_entry_loc_fill (cs->vol->itable, dirgfid, entry,
+ &cs->resolvedloc, NFS_RESOLVE_CREATE);
+
+ if (ret == 0) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s",
+ cs->resolvedloc.path);
+ ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_opendir_cbk, cs);
+ } else if (ret == -ENOENT) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir needs lookup: %s",
+ cs->resolvedloc.path);
+ ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_dir_lookup_cbk, cs);
+ }
+out:
+ return ret;
+}
+
+
+/*
+ * Called in a recursive code path, so if another
+ * directory was opened in an earlier call during fh resolution, we must unref
+ * through this reference before opening another fd_t.
+ */
+#define nfs3_fh_resolve_close_cwd(cst) \
+ do { \
+ if ((cst)->resolve_dir_fd) { \
+ gf_log (GF_NFS3, GF_LOG_TRACE, "resolve fd " \
+ "unrefing: 0x%lx, ref: %d", \
+ (long)(cst)->resolve_dir_fd, \
+ (cst)->resolve_dir_fd->refcount); \
+ fd_unref ((cst)->resolve_dir_fd); \
+ } \
+ } while (0) \
+
+
+int
+nfs3_fh_resolve_check_response (nfs3_call_state_t *cs, gf_dirent_t *candidate,
+ int response, off_t last_offt)
+{
+ int ret = -EFAULT;
+ nfs_user_t nfu = {0, };
+
+ if (!cs)
+ return ret;
+
+ switch (response) {
+
+ case GF_NFS3_FHRESOLVE_DIRFOUND:
+ nfs3_fh_resolve_close_cwd (cs);
+ nfs3_fh_resolve_dir_hard (cs, cs->resolvedloc.inode->gfid,
+ candidate->d_name);
+ break;
+
+ case GF_NFS3_FHRESOLVE_FOUND:
+ nfs3_fh_resolve_close_cwd (cs);
+ nfs3_fh_resolve_found (cs, candidate);
+ break;
+
+ case GF_NFS3_FHRESOLVE_NOTFOUND:
+ nfs_user_root_create (&nfu);
+ nfs_readdirp (cs->nfsx, cs->vol, &nfu, cs->resolve_dir_fd,
+ GF_NFS3_DTPREF, last_offt,
+ nfs3_fh_resolve_readdir_cbk, cs);
+ break;
+ }
+
return 0;
}
+int
+nfs3_fh_resolve_search_dir (nfs3_call_state_t *cs, gf_dirent_t *entries)
+{
+ gf_dirent_t *candidate = NULL;
+ int ret = GF_NFS3_FHRESOLVE_NOTFOUND;
+ off_t lastoff = 0;
+
+ if ((!cs) || (!entries))
+ return -EFAULT;
+
+ if (list_empty (&entries->list))
+ goto not_found;
+
+ list_for_each_entry (candidate, &entries->list, list) {
+ lastoff = candidate->d_off;
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate: %s, gfid: %s",
+ candidate->d_name,
+ uuid_utoa (candidate->d_stat.ia_gfid));
+ ret = nfs3_fh_resolve_check_entry (&cs->resolvefh, candidate,
+ cs->hashidx);
+ if (ret != GF_NFS3_FHRESOLVE_NOTFOUND)
+ break;
+ }
+
+not_found:
+ nfs3_fh_resolve_check_response (cs, candidate, ret, lastoff);
+ return ret;
+}
+
+
+int32_t
+nfs3_fh_resolve_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ gf_dirent_t *entries)
+{
+ nfs3_call_state_t *cs = NULL;
+
+ cs = frame->local;
+ if (op_ret <= 0) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Directory read done: %s: %s",
+ cs->resolvedloc.path, strerror (op_ret));
+ cs->resolve_ret = -1;
+ cs->resolve_errno = ESTALE;
+ nfs3_call_resume (cs);
+ goto err;
+ }
+
+ nfs3_fh_resolve_search_dir (cs, entries);
+err:
+ return 0;
+}
/* Needs no extra argument since it knows that the fh to be resolved is in
* resolvefh and that it needs to start looking from the root.
@@ -3642,21 +3024,33 @@ nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs)
if (!cs)
return ret;
- gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: gfid 0x%s",
- uuid_utoa (cs->resolvefh.gfid));
- cs->hardresolved = 1;
+ cs->hashidx++;
nfs_loc_wipe (&cs->resolvedloc);
- ret = nfs_gfid_loc_fill (cs->vol->itable, cs->resolvefh.gfid,
- &cs->resolvedloc, NFS_RESOLVE_CREATE);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to fill loc using gfid: "
- "%s", strerror (-ret));
+ if (!nfs3_fh_resolve_validate_dirdepth (cs)) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed");
+ nfs3_call_resume_estale (cs);
+ ret = 0;
goto out;
}
nfs_user_root_create (&nfu);
- ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3_fh_resolve_inode_lookup_cbk, cs);
+ gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: gfid 0x%s"
+ ", hashcount: %d, current hashidx %d",
+ uuid_utoa (cs->resolvefh.gfid),
+ cs->resolvefh.hashcount, cs->hashidx);
+ ret = nfs_root_loc_fill (cs->vol->itable, &cs->resolvedloc);
+
+ if (ret == 0) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s",
+ cs->resolvedloc.path);
+ ret = nfs_opendir (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_opendir_cbk, cs);
+ } else if (ret == -ENOENT) {
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Dir needs lookup: %s",
+ cs->resolvedloc.path);
+ ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3_fh_resolve_dir_lookup_cbk, cs);
+ }
out:
return ret;
@@ -3675,8 +3069,8 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
nfs_loc_wipe (&cs->resolvedloc);
nfs_user_root_create (&nfu);
gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution: gfid: %s "
- ", entry: %s", uuid_utoa (cs->resolvefh.gfid),
- cs->resolventry);
+ ", entry: %s, hashidx: %d", uuid_utoa (cs->resolvefh.gfid),
+ cs->resolventry, cs->hashidx);
ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.gfid,
cs->resolventry, &cs->resolvedloc,
@@ -3685,22 +3079,13 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
if (ret == -2) {
gf_log (GF_NFS3, GF_LOG_TRACE, "Entry needs lookup: %s",
cs->resolvedloc.path);
- /* If the NFS op is lookup, let the resume callback
- * handle the sending of the lookup fop. Similarly,
- * if the NFS op is create, let the create call
- * go ahead in the resume callback so that an EEXIST gets
- * handled at posix without an extra fop at this point.
- */
- if (nfs3_lookup_op (cs) ||
- (nfs3_create_op (cs) && !nfs3_create_exclusive_op (cs))) {
+ if (nfs3_lookup_op (cs)) {
cs->lookuptype = GF_NFS3_FRESH;
cs->resolve_ret = 0;
nfs3_call_resume (cs);
- } else {
- cs->hardresolved = 1;
+ } else
nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
nfs3_fh_resolve_entry_lookup_cbk, cs);
- }
ret = 0;
} else if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_TRACE, "Entry needs parent lookup: %s",
@@ -3724,7 +3109,6 @@ nfs3_fh_resolve_inode (nfs3_call_state_t *cs)
return ret;
gf_log (GF_NFS3, GF_LOG_TRACE, "FH needs inode resolution");
- uuid_copy (cs->resolvedloc.gfid, cs->resolvefh.gfid);
inode = inode_find (cs->vol->itable, cs->resolvefh.gfid);
if (!inode)
ret = nfs3_fh_resolve_inode_hard (cs);
@@ -3791,7 +3175,7 @@ nfs3_fh_resolve_root_lookup_cbk (call_frame_t *frame, void *cookie,
cs->resolve_errno = op_errno;
if (op_ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Root lookup failed: %s",
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Root lookup failed: %s",
strerror (op_errno));
goto err;
} else
@@ -3822,11 +3206,6 @@ nfs3_fh_resolve_root (nfs3_call_state_t *cs)
nfs_user_root_create (&nfu);
gf_log (GF_NFS3, GF_LOG_TRACE, "Root needs lookup");
ret = nfs_root_loc_fill (cs->vol->itable, &cs->resolvedloc);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to lookup root from itable: %s",
- strerror (-ret));
- goto out;
- }
ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
nfs3_fh_resolve_root_lookup_cbk, cs);
diff --git a/xlators/nfs/server/src/nfs3-helpers.h b/xlators/nfs/server/src/nfs3-helpers.h
index 67935d143..8fb11ff15 100644
--- a/xlators/nfs/server/src/nfs3-helpers.h
+++ b/xlators/nfs/server/src/nfs3-helpers.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -99,7 +99,9 @@ extern void
nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh);
extern void
-nfs3_fill_access3res (access3res *res, nfsstat3 status, int32_t accbits);
+nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf,
+ uint32_t accbits, uid_t uid, gid_t gid,
+ uint64_t deviceid, gid_t *auxgids, int gids);
extern char *
nfs3_fhcache_getpath (struct nfs3_state *nfs3, struct nfs3_fh *fh);
@@ -255,7 +257,7 @@ extern int
nfs3_cached_inode_opened (xlator_t *nfsxl, inode_t *inode);
extern void
-nfs3_log_common_res (uint32_t xid, int op, nfsstat3 stat, int pstat);
+nfs3_log_common_res (uint32_t xid, char *op, nfsstat3 stat, int pstat);
extern void
nfs3_log_readlink_res (uint32_t xid, nfsstat3 stat, int pstat, char *linkpath);
@@ -269,7 +271,7 @@ nfs3_log_write_res (uint32_t xid, nfsstat3 stat, int pstat, count3 count,
int stable, uint64_t wverf);
extern void
-nfs3_log_newfh_res (uint32_t xid, int op, nfsstat3 stat, int pstat,
+nfs3_log_newfh_res (uint32_t xid, char *op, nfsstat3 stat, int pstat,
struct nfs3_fh *newfh);
extern void
@@ -330,13 +332,18 @@ nfs3_fh_resolve_and_resume (nfs3_call_state_t *cs, struct nfs3_fh *fh,
char *entry, nfs3_resume_fn_t resum_fn);
extern int
+nfs3_file_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume);
+
+extern int
+nfs3_dir_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume);
+
+extern int
nfs3_verify_dircookie (struct nfs3_state *nfs3, fd_t *dirfd, cookie3 cookie,
uint64_t cverf, nfsstat3 *stat);
extern int
-nfs3_is_parentdir_entry (char *entry);
-
-uint32_t
-nfs3_request_to_accessbits (int32_t accbits);
+nfs3_fdcache_remove (struct nfs3_state *nfs3, fd_t *fd);
+extern int
+nfs3_is_parentdir_entry (char *entry);
#endif
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index 9b8af7df8..13eb1c0eb 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -38,8 +38,7 @@
#include "nfs3-helpers.h"
#include "nfs-mem-types.h"
#include "nfs.h"
-#include "xdr-rpc.h"
-#include "xdr-generic.h"
+
#include <sys/socket.h>
#include <sys/uio.h>
@@ -50,8 +49,6 @@
do { \
if ((str)) { \
if (strlen ((str)) > (len)) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "strlen "\
- "too long"); \
status = NFS3ERR_NAMETOOLONG; \
retval = -ENAMETOOLONG; \
goto label; \
@@ -61,8 +58,8 @@
#define nfs3_validate_nfs3_state(request, state, status, label, retval) \
do { \
- state = rpcsvc_request_program_private (request); \
- if (!state) { \
+ state = nfs_rpcsvc_request_program_private (request); \
+ if (!nfs3) { \
gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state " \
"missing from RPC request"); \
status = NFS3ERR_SERVERFAULT; \
@@ -88,7 +85,6 @@ __nfs3_get_export_by_index (struct nfs3_state *nfs3, uuid_t exportid)
}
exp = NULL;
- gf_log (GF_NFS, GF_LOG_ERROR, "searchindex=%d not found", searchindex);
found:
return exp;
}
@@ -133,7 +129,8 @@ nfs3_export_access (struct nfs3_state *nfs3, uuid_t exportid)
int ret = GF_NFS3_VOLACCESS_RO;
struct nfs3_export *exp = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err);
+ if (!nfs3)
+ return ret;
exp = __nfs3_get_export_by_exportid (nfs3, exportid);
@@ -151,7 +148,7 @@ err:
#define nfs3_check_rw_volaccess(nfs3state, exid, status, label) \
do { \
if (nfs3_export_access (nfs3state,exid)!=GF_NFS3_VOLACCESS_RW){\
- gf_log (GF_NFS3, GF_LOG_ERROR, "No read-write access");\
+ gf_log (GF_NFS3, GF_LOG_TRACE, "No read-write access");\
status = NFS3ERR_ROFS; \
goto label; \
} \
@@ -165,8 +162,8 @@ nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh)
xlator_t *vol = NULL;
struct nfs3_export *exp = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out);
+ if ((!nfs3) || (!fh))
+ return vol;
exp = __nfs3_get_export_by_exportid (nfs3, fh->exportid);
if (!exp)
@@ -184,8 +181,8 @@ nfs3_is_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh)
struct nfs3_export *exp = NULL;
int ret = 0;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, rootfh, out);
+ if ((!nfs3) || (!rootfh))
+ return 0;
exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid);
if (!exp)
@@ -203,8 +200,8 @@ nfs3_set_root_looked_up (struct nfs3_state *nfs3, struct nfs3_fh *rootfh)
struct nfs3_export *exp = NULL;
int ret = 0;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, rootfh, out);
+ if ((!nfs3) || (!rootfh))
+ return 0;
exp = __nfs3_get_export_by_exportid (nfs3, rootfh->exportid);
if (!exp)
@@ -216,29 +213,18 @@ out:
}
-#define nfs3_map_fh_to_volume(nfs3state, handle, req, volume, status, label) \
+#define nfs3_map_fh_to_volume(nfs3state, handle, rqst, volume, status, label) \
do { \
- char exportid[256], gfid[256]; \
- rpc_transport_t *trans = NULL; \
volume = nfs3_fh_to_xlator ((nfs3state), handle); \
if (!volume) { \
- uuid_unparse (handle->exportid, exportid); \
- uuid_unparse (handle->gfid, gfid); \
- trans = rpcsvc_request_transport (req); \
gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to map " \
- "FH to vol: client=%s, exportid=%s, gfid=%s",\
- trans->peerinfo.identifier, exportid, \
- gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, \
- "Stale nfs client %s must be trying to "\
- "connect to a deleted volume, please " \
- "unmount it.", trans->peerinfo.identifier);\
+ "FH to vol"); \
status = NFS3ERR_STALE; \
goto label; \
} else { \
gf_log (GF_NFS3, GF_LOG_TRACE, "FH to Volume: %s"\
,volume->name); \
- rpcsvc_request_set_private (req, volume); \
+ nfs_rpcsvc_request_set_private (req, volume); \
} \
} while (0); \
@@ -247,7 +233,6 @@ out:
do { \
if ((handle)) { \
if (!nfs3_fh_validate (handle)) { \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Bad Handle");\
status = NFS3ERR_BADHANDLE; \
goto errlabel; \
} \
@@ -256,18 +241,7 @@ out:
#define nfs3_check_fh_resolve_status(cst, nfstat, erlabl) \
do { \
- xlator_t *xlatorp = NULL; \
- char buf[256], gfid[256]; \
- rpc_transport_t *trans = NULL; \
if ((cst)->resolve_ret < 0) { \
- trans = rpcsvc_request_transport (cst->req); \
- xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \
- &cst->resolvefh); \
- uuid_unparse (cst->resolvefh.gfid, gfid); \
- sprintf (buf, "(%s) %s : %s", trans->peerinfo.identifier,\
- xlatorp ? xlatorp->name : "ERR", gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
nfstat = nfs3_errno_to_nfsstat3 (cst->resolve_errno);\
goto erlabl; \
} \
@@ -275,19 +249,8 @@ out:
#define nfs3_check_new_fh_resolve_status(cst, nfstat, erlabl) \
do { \
- xlator_t *xlatorp = NULL; \
- char buf[256], gfid[256]; \
- rpc_transport_t *trans = NULL; \
if (((cst)->resolve_ret < 0) && \
((cst)->resolve_errno != ENOENT)) { \
- trans = rpcsvc_request_transport (cst->req); \
- xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \
- &cst->resolvefh); \
- uuid_unparse (cst->resolvefh.gfid, gfid); \
- sprintf (buf, "(%s) %s : %s", trans->peerinfo.identifier,\
- xlatorp ? xlatorp->name : "ERR", gfid); \
- gf_log (GF_NFS3, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
nfstat = nfs3_errno_to_nfsstat3 (cs->resolve_errno);\
goto erlabl; \
} \
@@ -301,8 +264,8 @@ __nfs3_get_volume_id (struct nfs3_state *nfs3, xlator_t *xl,
int ret = -1;
struct nfs3_export *exp = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, xl, out);
+ if ((!nfs3) || (!xl))
+ return ret;
list_for_each_entry (exp, &nfs3->exports, explist) {
if (exp->subvol == xl) {
@@ -358,7 +321,8 @@ nfs3_export_sync_trusted (struct nfs3_state *nfs3, uuid_t exportid)
struct nfs3_export *exp = NULL;
int ret = 0;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err);
+ if (!nfs3)
+ return ret;
exp = __nfs3_get_export_by_exportid (nfs3, exportid);
if (!exp)
@@ -376,7 +340,8 @@ nfs3_export_write_trusted (struct nfs3_state *nfs3, uuid_t exportid)
struct nfs3_export *exp = NULL;
int ret = 0;
- GF_VALIDATE_OR_GOTO (GF_NFS3, nfs3, err);
+ if (!nfs3)
+ return ret;
exp = __nfs3_get_export_by_exportid (nfs3, exportid);
if (!exp)
@@ -414,15 +379,12 @@ nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v)
{
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, s, err);
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, err);
- GF_VALIDATE_OR_GOTO (GF_NFS3, v, err);
+ if ((!s) || (!req) || (!v))
+ return NULL;
cs = (nfs3_call_state_t *) mem_get (s->localpool);
- if (!cs) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "out of memory");
+ if (!cs)
return NULL;
- }
memset (cs, 0, sizeof (*cs));
INIT_LIST_HEAD (&cs->entries.list);
@@ -432,25 +394,29 @@ nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v)
cs->vol = v;
cs->nfsx = s->nfsx;
cs->nfs3state = s;
-err:
+
return cs;
}
void
nfs3_call_state_wipe (nfs3_call_state_t *cs)
{
+ struct nfs3_state *nfs3 = NULL;
if (!cs)
return;
+ nfs3 = cs->nfs3state;
if (cs->fd) {
gf_log (GF_NFS3, GF_LOG_TRACE, "fd 0x%lx ref: %d",
(long)cs->fd, cs->fd->refcount);
fd_unref (cs->fd);
}
- GF_FREE (cs->resolventry);
+ if (cs->resolventry)
+ GF_FREE (cs->resolventry);
- GF_FREE (cs->pathname);
+ if (cs->pathname)
+ GF_FREE (cs->pathname);
if (!list_empty (&cs->entries.list))
gf_dirent_free (&cs->entries);
@@ -459,12 +425,8 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs)
nfs_loc_wipe (&cs->resolvedloc);
if (cs->iob)
iobuf_unref (cs->iob);
- if (cs->iobref)
- iobref_unref (cs->iobref);
- if (cs->trans)
- rpc_transport_unref (cs->trans);
memset (cs, 0, sizeof (*cs));
- mem_put (cs);
+ mem_put (nfs3->localpool, cs);
/* Already refd by fd_lookup, so no need to ref again. */
}
@@ -490,7 +452,7 @@ nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc,
struct iobuf *iob = NULL;
ssize_t retlen = -1;
- nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req);
+ nfs3 = (struct nfs3_state *)nfs_rpcsvc_request_program_private (req);
if (!nfs3) {
gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state not found in RPC"
" request");
@@ -500,8 +462,6 @@ nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc,
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
- /* TODO: get rid of 'sfunc' and use 'xdrproc_t' so we
- can have 'xdr_sizeof' */
iob = iobuf_get (nfs3->iobpool);
if (!iob) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get iobuf");
@@ -540,7 +500,6 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc)
struct iovec outmsg = {0, };
struct iobuf *iob = NULL;
int ret = -1;
- struct iobref *iobref = NULL;
if (!req)
return -1;
@@ -551,25 +510,14 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc)
goto ret;
}
- iobref = iobref_new ();
- if (!iobref) {
- iobuf_unref (iob);
- gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new()");
- goto ret;
- }
-
- iobref_add (iobref, iob);
-
/* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
+ ret = nfs_rpcsvc_submit_message (req, outmsg, iob);
/* Now that we've done our job of handing the message to the RPC layer
* we can safely unref the iob in the hope that RPC layer must have
* ref'ed the iob on receiving into the txlist.
*/
iobuf_unref (iob);
- iobref_unref (iobref);
-
if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
goto ret;
@@ -584,12 +532,11 @@ ret:
int
nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg,
nfs3_serializer sfunc, struct iovec *payload,
- int vcount, struct iobref *iobref)
+ int vcount, struct iobref *piobref)
{
struct iovec outmsg = {0, };
struct iobuf *iob = NULL;
int ret = -1;
- int new_iobref = 0;
if (!req)
return -1;
@@ -597,40 +544,25 @@ nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg,
iob = nfs3_serialize_reply (req, arg, sfunc, &outmsg);
if (!iob) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to serialize reply");
- goto ret;
- }
- if (iobref == NULL) {
- iobref = iobref_new ();
- if (!iobref) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new");
- goto ret;
- }
- new_iobref = 1;
+ goto err;
}
- iobref_add (iobref, iob);
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, payload, vcount, iobref);
-
- /* Now that we've done our job of handing the message to the RPC layer
- * we can safely unref the iob in the hope that RPC layer must have
- * ref'ed the iob on receiving into the txlist.
- */
+ ret = nfs_rpcsvc_request_attach_vector (req, outmsg, iob, NULL, 0);
iobuf_unref (iob);
- if (new_iobref)
- iobref_unref (iobref);
- if (ret == -1) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
+ if (piobref)
+ ret = nfs_rpcsvc_request_attach_vectors (req, payload, vcount,
+ piobref);
+
+ if (ret == -1)
+ goto err;
+ ret = nfs_rpcsvc_submit_vectors (req);
+err:
- ret = 0;
-ret:
return ret;
}
+
uint64_t
nfs3_request_xlator_deviceid (rpcsvc_request_t *rq)
{
@@ -642,8 +574,8 @@ nfs3_request_xlator_deviceid (rpcsvc_request_t *rq)
if (!rq)
return 0;
- xl = rpcsvc_request_private (rq);
- nfs3 = rpcsvc_request_program_private (rq);
+ xl = nfs_rpcsvc_request_private (rq);
+ nfs3 = nfs_rpcsvc_request_program_private (rq);
if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx)))
devid = (uint64_t)nfs_xlator_to_xlid (nfs3->exportslist, xl);
else {
@@ -661,7 +593,8 @@ nfs3svc_null (rpcsvc_request_t *req)
struct iovec dummyvec = {0, };
if (!req)
return RPCSVC_ACTOR_ERROR;
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
+
+ nfs_rpcsvc_submit_generic (req, dummyvec, NULL);
return RPCSVC_ACTOR_SUCCESS;
}
@@ -692,14 +625,10 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
status = nfs3_errno_to_nfsstat3 (op_errno);
- }
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR",
status, op_errno);
nfs3_getattr_reply (cs->req, status, buf);
@@ -711,22 +640,17 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
nfs3svc_getattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
nfsstat3 status = NFS3_OK;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
status = nfs3_errno_to_nfsstat3 (op_errno);
- }
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_GETATTR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR",
status, op_errno);
nfs3_getattr_reply (cs->req, status, buf);
@@ -755,22 +679,13 @@ nfs3_getattr_resume (void *carg)
* for the root to have been looked up when the getattr on the root is
* sent. AND, this causes a problem for stat-prefetch in that it
* expects even the root inode to have been looked up.
-
- if (__is_root_gfid (cs->resolvedloc.inode->gfid))
+ */
+ if (cs->resolvedloc.inode->ino == 1)
ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
nfs3svc_getattr_lookup_cbk, cs);
else
ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- */
-
- if (cs->hardresolved) {
- ret = -EFAULT;
- stat = NFS3_OK;
- goto nfs3err;
- }
-
- ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- nfs3svc_getattr_stat_cbk, cs);
+ nfs3svc_getattr_stat_cbk, cs);
if (ret < 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Stat fop failed: %s: %s",
@@ -780,9 +695,9 @@ nfs3_getattr_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_GETATTR, stat, -ret);
- nfs3_getattr_reply (cs->req, stat, &cs->stbuf);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "GETATTR", stat, -ret);
+ nfs3_getattr_reply (cs->req, stat, NULL);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -800,10 +715,10 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh)
struct nfs3_state *nfs3 = NULL;
nfs3_call_state_t *cstate = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out);
+ if ((!req) || (!fh))
+ return -1;
- nfs3_log_common_call (rpcsvc_request_xid (req), "GETATTR", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "GETATTR", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -816,7 +731,7 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_GETATTR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "GETATTR",
stat, -ret);
nfs3_getattr_reply (req, stat, NULL);
ret = 0;
@@ -838,16 +753,16 @@ nfs3svc_getattr (rpcsvc_request_t *req)
return ret;
nfs3_prep_getattr3args (&args, &fh);
- if (xdr_to_getattr3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_getattr3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_getattr (req, &fh);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "GETATTR procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -874,7 +789,7 @@ nfs3_setattr_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preop,
int32_t
nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
struct iatt *prestat = NULL;
@@ -882,9 +797,6 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -900,7 +812,7 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_SETATTR, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "SETATTR", stat,
op_errno);
nfs3_setattr_reply (cs->req, stat, prestat, postbuf);
nfs3_call_state_wipe (cs);
@@ -912,7 +824,7 @@ nfs3err:
int32_t
nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preop,
- struct iatt *postop, dict_t *xdata)
+ struct iatt *postop)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -1;
@@ -922,18 +834,22 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
- prebuf = preop;
- /* Store the current preop in case we need to send a truncate,
- * in which case the preop to be returned will be this one.
+ /* If the first stat was got from the guarded setattr callback, then
+ * we'll need to use that stat instead of the preop returned here.
*/
- cs->preparent = *preop;
+ if (cs->preparent.ia_ino != 0)
+ prebuf = &cs->preparent;
+ else {
+ prebuf = preop;
+ /* Store the current preop in case we need to send a truncate,
+ * in which case the preop to be returned will be this one.
+ */
+ cs->preparent = *preop;
+ }
/* Only truncate if the size is not already same as the requested
* truncation and also only if this is not a directory.
@@ -953,8 +869,8 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SETATTR, stat, op_errno);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "SETATTR", stat, op_errno);
nfs3_setattr_reply (cs->req, stat, prebuf, postop);
nfs3_call_state_wipe (cs);
}
@@ -966,8 +882,7 @@ nfs3err:
int32_t
nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
int ret = -EFAULT;
@@ -977,15 +892,12 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
if (buf->ia_ctime != cs->timestamp.seconds) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Timestamps not in sync");
+ gf_log (GF_NFS3, GF_LOG_TRACE, "Timestamps not in sync");
stat = NFS3ERR_NOT_SYNC;
goto nfs3err;
}
@@ -1000,8 +912,8 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SETATTR, stat, op_errno);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "SETATTR", stat, op_errno);
nfs3_setattr_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1024,17 +936,22 @@ nfs3_setattr_resume (void *carg)
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
nfs_request_user_init (&nfu, cs->req);
- ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- &cs->stbuf, cs->setattr_valid,
- nfs3svc_setattr_cbk, cs);
+ /* If no ctime check is required, head straight to setting the attrs. */
+ if (cs->sattrguardcheck)
+ ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3svc_setattr_stat_cbk, cs);
+ else
+ ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ &cs->stbuf, cs->setattr_valid,
+ nfs3svc_setattr_cbk, cs);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SETATTR, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "SETATTR", stat, -ret);
nfs3_setattr_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1053,12 +970,12 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
struct nfs3_state *nfs3 = NULL;
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, sattr, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, guard, out);
+ if ((!req) || (!fh) || (!sattr) || (!guard)) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
+ return -1;
+ }
- nfs3_log_common_call (rpcsvc_request_xid (req), "SETATTR", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "SETATTR", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -1080,7 +997,6 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
if (!cs->setattr_valid) {
ret = -EINVAL; /* Force a reply */
stat = NFS3_OK;
- gf_log (GF_NFS3, GF_LOG_ERROR, "cs->setattr_valid is invalid");
goto nfs3err;
}
@@ -1090,7 +1006,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SETATTR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SETATTR",
stat, -ret);
nfs3_setattr_reply (req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -1112,19 +1028,20 @@ nfs3svc_setattr (rpcsvc_request_t *req)
setattr3args args;
int ret = RPCSVC_ACTOR_ERROR;
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, rpcerr);
+ if (!req)
+ return ret;
nfs3_prep_setattr3args (&args, &fh);
- if (xdr_to_setattr3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_setattr3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_setattr (req, &fh, &args.new_attributes, &args.guard);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "SETATTR procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -1157,7 +1074,9 @@ nfs3_fresh_lookup (nfs3_call_state_t *cs)
int ret = -EFAULT;
char *oldresolventry = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, cs, err);
+ if (!cs)
+ return -1;
+
gf_log (GF_NFS3, GF_LOG_DEBUG, "inode needs fresh lookup");
inode_unlink (cs->resolvedloc.inode, cs->resolvedloc.parent,
cs->resolventry);
@@ -1174,7 +1093,7 @@ nfs3_fresh_lookup (nfs3_call_state_t *cs)
* same call_state.
*/
GF_FREE (oldresolventry);
-err:
+
return ret;
}
@@ -1190,17 +1109,12 @@ nfs3svc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS,
- (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_WARNING),
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
status = nfs3_errno_to_nfsstat3 (op_errno);
goto xmit_res;
}
nfs3_fh_build_child_fh (&cs->parent, buf, &newfh);
- oldinode = inode_link (inode, cs->resolvedloc.parent,
- cs->resolvedloc.name, buf);
+ oldinode = inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf);
xmit_res:
/* Only send fresh lookup if it was a revalidate that failed. */
if ((op_ret == -1) && (nfs3_is_revalidate_lookup (cs))) {
@@ -1208,7 +1122,7 @@ xmit_res:
goto out;
}
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status,
op_errno, &newfh);
nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent);
nfs3_call_state_wipe (cs);
@@ -1235,9 +1149,6 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
status = nfs3_errno_to_nfsstat3 (op_errno);
goto xmit_res;
}
@@ -1261,7 +1172,7 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
xmit_res:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP, status,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status,
op_errno, &newfh);
nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent);
nfs3_call_state_wipe (cs);
@@ -1280,7 +1191,8 @@ nfs3_lookup_parentdir_resume (void *carg)
nfs3_call_state_t *cs = NULL;
inode_t *parent = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ if (!carg)
+ return ret;
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
@@ -1311,14 +1223,10 @@ nfs3_lookup_parentdir_resume (void *carg)
if (!nfs3_fh_is_root_fh (&cs->fh)) {
parent = inode_ref (cs->resolvedloc.parent);
nfs_loc_wipe (&cs->resolvedloc);
- ret = nfs_inode_loc_fill (parent, &cs->resolvedloc,
- NFS_RESOLVE_CREATE);
+ ret = nfs_inode_loc_fill (parent, &cs->resolvedloc);
- if (ret < 0) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "nfs_inode_loc_fill"
- " error");
+ if (ret < 0)
goto errtostat;
- }
}
ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
@@ -1329,7 +1237,7 @@ errtostat:
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP",
stat, -ret);
nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -1349,21 +1257,14 @@ nfs3_lookup_resume (void *carg)
int ret = -EFAULT;
nfs_user_t nfu = {0, };
nfs3_call_state_t *cs = NULL;
- struct nfs3_fh newfh = {{0},};
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ if (!carg)
+ return ret;
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- cs->parent = cs->resolvefh;
-
- if (cs->hardresolved) {
- stat = NFS3_OK;
- nfs3_fh_build_child_fh (&cs->parent, &cs->stbuf, &newfh);
- goto nfs3err;
- }
-
nfs_request_user_init (&nfu, cs->req);
+ cs->parent = cs->resolvefh;
ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
nfs3svc_lookup_cbk, cs);
if (ret < 0)
@@ -1371,10 +1272,9 @@ nfs3_lookup_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LOOKUP,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP",
stat, -ret);
- nfs3_lookup_reply (cs->req, stat, &newfh, &cs->stbuf,
- &cs->postparent);
+ nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1391,11 +1291,12 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)
struct nfs3_state *nfs3 = NULL;
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, req, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, fh, out);
- GF_VALIDATE_OR_GOTO (GF_NFS3, name, out);
+ if ((!req) || (!fh) || (!name)) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Bad arguments");
+ return -1;
+ }
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh,
+ nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "LOOKUP", fh,
name);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
if (nfs3_solaris_zerolen_fh (fh, fhlen))
@@ -1408,17 +1309,19 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name)
nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
cs->lookuptype = GF_NFS3_REVALIDATE;
- ret = nfs3_fh_resolve_and_resume (cs, fh, name,
- nfs3_lookup_resume);
+ if (!nfs3_is_parentdir_entry (name))
+ ret = nfs3_fh_resolve_and_resume (cs, fh, name,
+ nfs3_lookup_resume);
+ else
+ ret = nfs3_fh_resolve_and_resume (cs, fh, NULL,
+ nfs3_lookup_parentdir_resume);
- if (ret < 0) {
- gf_log (GF_NFS, GF_LOG_ERROR, "failed to start hard reslove");
+ if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
- }
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LOOKUP,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LOOKUP",
stat,
-ret);
nfs3_lookup_reply (req, stat, NULL, NULL, NULL);
@@ -1441,19 +1344,20 @@ nfs3svc_lookup (rpcsvc_request_t *req)
lookup3args args;
int ret = RPCSVC_ACTOR_ERROR;
- GF_VALIDATE_OR_GOTO (GF_NFS, req, rpcerr);
+ if (!req)
+ return ret;
nfs3_prep_lookup3args (&args, &fh, name);
- if (xdr_to_lookup3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_lookup3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_lookup (req, &fh, args.what.dir.data.data_len, name);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "LOOKUP procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -1463,11 +1367,20 @@ rpcerr:
int
-nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits)
+nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf,
+ uint32_t accbits)
{
access3res res;
+ uint64_t deviceid = 0;
+ gid_t *gidarr = NULL;
+ int gids = 0;
- nfs3_fill_access3res (&res, status, accbits);
+ deviceid = nfs3_request_xlator_deviceid (req);
+ gidarr = nfs_rpcsvc_auth_unix_auxgids (req, &gids);
+ nfs3_fill_access3res (&res, status, buf, accbits,
+ nfs_rpcsvc_request_uid (req),
+ nfs_rpcsvc_request_gid (req), deviceid, gidarr,
+ gids);
nfs3svc_submit_reply (req, &res,
(nfs3_serializer)xdr_serialize_access3res);
return 0;
@@ -1476,22 +1389,19 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, int32_t accbits)
int32_t
nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
nfsstat3 status = NFS3_OK;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
status = nfs3_errno_to_nfsstat3 (op_errno);
- }
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS, status,
+
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", status,
op_errno);
- nfs3_access_reply (cs->req, status, op_errno);
+ nfs3_access_reply (cs->req, status, buf, cs->accessbits);
nfs3_call_state_wipe (cs);
return 0;
@@ -1505,22 +1415,23 @@ nfs3_access_resume (void *carg)
nfs_user_t nfu = {0, };
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS3, carg, nfs3err);
+ if (!carg)
+ return ret;
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
cs->fh = cs->resolvefh;
nfs_request_user_init (&nfu, cs->req);
- ret = nfs_access (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
- cs->accessbits, nfs3svc_access_cbk, cs);
+ ret = nfs_stat (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ nfs3svc_access_cbk, cs);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_ACCESS,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS",
stat, -ret);
- nfs3_access_reply (cs->req, stat, 0);
+ nfs3_access_reply (cs->req, stat, NULL, 0);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -1538,9 +1449,10 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits)
int ret = -EFAULT;
nfs3_call_state_t *cs = NULL;
- GF_VALIDATE_OR_GOTO (GF_NFS, req, out);
- GF_VALIDATE_OR_GOTO (GF_NFS, fh, out);
- nfs3_log_common_call (rpcsvc_request_xid (req), "ACCESS", fh);
+ if ((!req) || (!fh))
+ return -1;
+
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "ACCESS", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -1554,9 +1466,9 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_ACCESS,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "ACCESS",
stat, -ret);
- nfs3_access_reply (req, stat, 0);
+ nfs3_access_reply (req, stat, NULL, 0);
nfs3_call_state_wipe (cs);
ret = 0;
}
@@ -1576,16 +1488,16 @@ nfs3svc_access (rpcsvc_request_t *req)
return ret;
nfs3_prep_access3args (&args, &fh);
- if (xdr_to_access3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_access3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_access (req, &fh, args.access);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "ACCESS procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -1613,16 +1525,13 @@ nfs3_readlink_reply (rpcsvc_request_t *req, nfsstat3 stat, char *path,
int32_t
nfs3svc_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *buf, dict_t *xdata)
+ struct iatt *buf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -1630,7 +1539,7 @@ nfs3svc_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
- nfs3_log_readlink_res (rpcsvc_request_xid (cs->req), stat, op_errno,
+ nfs3_log_readlink_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno,
(char *)path);
nfs3_readlink_reply (cs->req, stat, (char *)path, buf);
nfs3_call_state_wipe (cs);
@@ -1660,8 +1569,8 @@ nfs3_readlink_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READLINK, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READLINK", stat, -ret);
nfs3_readlink_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -1684,7 +1593,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh)
return -1;
}
- nfs3_log_common_call (rpcsvc_request_xid (req), "READLINK", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "READLINK", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -1697,7 +1606,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READLINK,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READLINK",
stat, -ret);
nfs3_readlink_reply (req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -1722,16 +1631,16 @@ nfs3svc_readlink (rpcsvc_request_t *req)
return ret;
nfs3_prep_readlink3args (&args, &fh);
- if (xdr_to_readlink3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_readlink3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_readlink (req, &fh);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "READLINK procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -1751,19 +1660,17 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,
deviceid = nfs3_request_xlator_deviceid (req);
nfs3_fill_read3res (&res, stat, count, poststat, is_eof, deviceid);
if (stat == NFS3_OK) {
- xdr_vector_round_up (vec, vcount, count);
+ nfs_xdr_vector_round_up (vec, vcount, count);
/* iob can be zero if the file size was zero. If so, op_ret
* would be 0 and count = 0.
*/
-
if (count != 0) {
nfs3svc_submit_vector_reply (req, (void *)&res,
(nfs3_serializer)
xdr_serialize_read3res_nocopy,
vec, vcount, iobref);
} else
-
- nfs3svc_submit_reply (req, (void *)&res,
+ nfs3svc_submit_reply (req, (void *)&res,
(nfs3_serializer)
xdr_serialize_read3res_nocopy);
} else
@@ -1778,8 +1685,7 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,
int32_t
nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int is_eof = 0;
@@ -1787,9 +1693,6 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto err;
} else
@@ -1799,7 +1702,7 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
is_eof = 1;
err:
- nfs3_log_read_res (rpcsvc_request_xid (cs->req), stat, op_errno,
+ nfs3_log_read_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno,
op_ret, is_eof, vector, count);
nfs3_read_reply (cs->req, stat, op_ret, vector, count, iobref, stbuf,
is_eof);
@@ -1829,7 +1732,7 @@ nfs3_read_fd_resume (void *carg)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_READ,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ",
stat, -ret);
nfs3_read_reply (cs->req, stat, 0, NULL, 0, NULL, NULL, 0);
nfs3_call_state_wipe (cs);
@@ -1845,25 +1748,19 @@ nfs3_read_resume (void *carg)
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
nfs3_call_state_t *cs = NULL;
- fd_t *fd = NULL;
if (!carg)
return ret;
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- fd = fd_anonymous (cs->resolvedloc.inode);
- if (!fd) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd");
- goto nfs3err;
- }
+ ret = nfs3_file_open_and_resume (cs, nfs3_read_fd_resume);
+ if (ret < 0)
+ stat = nfs3_errno_to_nfsstat3 (-ret);
- cs->fd = fd;
- nfs3_read_fd_resume (cs);
- ret = 0;
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_READ,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ",
stat, -ret);
nfs3_read_reply (cs->req, stat, 0, NULL,0, NULL, NULL, 0);
nfs3_call_state_wipe (cs);
@@ -1887,7 +1784,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
return -1;
}
- nfs3_log_rw_call (rpcsvc_request_xid (req), "READ", fh, offset,
+ nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "READ", fh, offset,
count, -1);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -1903,7 +1800,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_READ, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READ", stat,
-ret);
nfs3_read_reply (req, stat, 0, NULL,0, NULL, NULL, 0);
nfs3_call_state_wipe (cs);
@@ -1925,16 +1822,16 @@ nfs3svc_read (rpcsvc_request_t *req)
return ret;
nfs3_prep_read3args (&args, &fh);
- if (xdr_to_read3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_read3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_read (req, &fh, args.offset, args.count);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "READ procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -1963,24 +1860,21 @@ nfs3_write_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count,
int32_t
nfs3svc_write_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
struct nfs3_state *nfs3 = NULL;
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- nfs3 = rpcsvc_request_program_private (cs->req);
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else
+ else
stat = NFS3_OK;
- nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat, op_errno,
+ nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno,
cs->maxcount, cs->writetype, nfs3->serverstart);
nfs3_write_reply (cs->req, stat, cs->maxcount, cs->writetype,
nfs3->serverstart, &cs->stbuf, postbuf);
@@ -2059,7 +1953,7 @@ err:
int32_t
nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
@@ -2070,11 +1964,8 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int sync_trusted = 0;
cs = frame->local;
- nfs3 = rpcsvc_request_program_private (cs->req);
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto err;
}
@@ -2103,7 +1994,7 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
err:
if (ret < 0) {
- nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat,
+ nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat,
op_errno, cs->maxcount, cs->writetype,
nfs3->serverstart);
nfs3_write_reply (cs->req, stat, cs->maxcount,
@@ -2138,9 +2029,8 @@ __nfs3_write_resume (nfs3_call_state_t *cs)
* opaque data buffers to multiples of 4 bytes.
*/
cs->datavec.iov_len = cs->datacount;
- ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iobref,
- &cs->datavec, 1, cs->dataoffset, nfs3svc_write_cbk,
- cs);
+ ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iob, &cs->datavec,
+ 1, cs->dataoffset, nfs3svc_write_cbk, cs);
return ret;
}
@@ -2152,26 +2042,19 @@ nfs3_write_resume (void *carg)
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
nfs3_call_state_t *cs = NULL;
- fd_t *fd = NULL;
if (!carg)
return ret;
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- fd = fd_anonymous (cs->resolvedloc.inode);
- if (!fd) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd");
- goto nfs3err;
- }
- cs->fd = fd; /* Gets unrefd when the call state is wiped. */
ret = __nfs3_write_resume (cs);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_WRITE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE",
stat, -ret);
nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL,
NULL);
@@ -2182,9 +2065,37 @@ nfs3err:
int
+nfs3_write_open_resume (void *carg)
+{
+ nfsstat3 stat = NFS3ERR_SERVERFAULT;
+ int ret = -EFAULT;
+ nfs3_call_state_t *cs = NULL;
+
+ if (!carg)
+ return ret;
+
+ cs = (nfs3_call_state_t *)carg;
+ nfs3_check_fh_resolve_status (cs, stat, nfs3err);
+ ret = nfs3_file_open_and_resume (cs, nfs3_write_resume);
+ if (ret < 0)
+ stat = nfs3_errno_to_nfsstat3 (-ret);
+nfs3err:
+ if (ret < 0) {
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE",
+ stat, -ret);
+ nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL,
+ NULL);
+ nfs3_call_state_wipe (cs);
+ }
+ return ret;
+}
+
+
+
+int
nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
count3 count, stable_how stable, struct iovec payload,
- struct iobref *iobref)
+ struct iobuf *iob)
{
xlator_t *vol = NULL;
nfsstat3 stat = NFS3ERR_SERVERFAULT;
@@ -2197,7 +2108,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
return -1;
}
- nfs3_log_rw_call (rpcsvc_request_xid (req), "WRITE", fh, offset,
+ nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "WRITE", fh, offset,
count, stable);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -2208,17 +2119,17 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
cs->datacount = count;
cs->dataoffset = offset;
cs->writetype = stable;
- cs->iobref = iobref;
+ cs->iob = iob;
cs->datavec = payload;
- ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_write_resume);
+ ret = nfs3_fh_resolve_and_resume (cs, fh, NULL, nfs3_write_open_resume);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_WRITE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "WRITE",
stat, -ret);
nfs3_write_reply (req, stat, 0, stable, 0, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2236,47 +2147,99 @@ out:
int
-nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *base_addr,
- char *curr_addr)
+nfs3svc_write_vecsizer (rpcsvc_request_t *req, ssize_t *readsize, int *newbuf)
{
- int ret = 0;
- uint32_t fhlen = 0;
- uint32_t fhlen_n = 0;
+ ssize_t ret = RPCSVC_ACTOR_ERROR;
+ int state = 0;
+ uint32_t fhlen = 0;
+ uint32_t fhlen_n = 0;
+ write3args *args = NULL;
+ if (!req)
+ return ret;
+
+ state = (long)nfs_rpcsvc_request_private (req);
+ *newbuf = 0;
if (state == 0) {
- ret = NFS3_VECWRITE_READFHLEN;
+ nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFHLEN);
*readsize = 4;
+ ret = 0;
} else if (state == NFS3_VECWRITE_READFHLEN) {
- fhlen_n = *(uint32_t *)(curr_addr - 4);
+ fhlen_n = *(uint32_t *)req->msg.iov_base;
fhlen = ntohl (fhlen_n);
- *readsize = xdr_length_round_up (fhlen, NFS3_FHSIZE);
- ret = NFS3_VECWRITE_READFH;
+ *readsize = nfs_xdr_length_round_up (fhlen, NFS3_FHSIZE);
+ nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFH);
+ ret = 0;
} else if (state == NFS3_VECWRITE_READFH) {
*readsize = NFS3_WRITE_POSTFH_SIZE;
- ret = NFS3_VECWRITE_READREST;
+ nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READREST);
+ ret = 0;
} else if (state == NFS3_VECWRITE_READREST) {
+ args = GF_CALLOC (1, sizeof (*args), gf_nfs_mt_write3args);
+ if (!args)
+ goto rpcerr;
+
+ if (xdr_to_write3args_nocopy (req->msg, args, NULL) <= 0) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ goto rpcerr;
+ }
+ nfs_rpcsvc_request_set_private (req, args);
+ ret = nfs_xdr_length_round_up (args->data.data_len, 1048576);
+ *readsize = ret;
+ *newbuf = 1;
ret = 0;
- *readsize = 0;
- } else
- gf_log ("nfs", GF_LOG_ERROR, "state wrong");
+ }
+
+rpcerr:
+ return ret;
+}
+
+
+int
+nfs3svc_write_vec (rpcsvc_request_t *req, struct iobuf *iob)
+{
+ write3args *args = NULL;
+ int ret = RPCSVC_ACTOR_ERROR;
+ struct iovec payload = {0, };
+ struct nfs3_fh fh = {{0}, };
+
+ if ((!req) || (!iob))
+ return ret;
+
+ args = nfs_rpcsvc_request_private (req);
+ iobuf_to_iovec (iob, &payload);
+ iobuf_ref (iob);
+ memcpy (&fh, args->file.data.data_val, args->file.data.data_len);
+ ret = nfs3_write (req, &fh, args->offset, args->count, args->stable,
+ payload,iob);
+ xdr_free_write3args_nocopy (args);
+ GF_FREE (args);
+ if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
+ gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed");
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
+ ret = RPCSVC_ACTOR_ERROR;
+ }
return ret;
}
+
int
nfs3svc_write (rpcsvc_request_t *req)
{
struct nfs3_fh fh = {{0}, };
write3args args;
int ret = RPCSVC_ACTOR_ERROR;
+ struct iovec payload = {0, };
if (!req)
return ret;
nfs3_prep_write3args (&args, &fh);
- if (xdr_to_write3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_write3args_nocopy (req->msg, &args, &payload) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
@@ -2285,12 +2248,12 @@ nfs3svc_write (rpcsvc_request_t *req)
* ourselves because the RPC call handler who called us will unref its
* own ref of the record's iobuf when it is done handling the request.
*/
-
+ nfs_rpcsvc_request_record_ref (req);
ret = nfs3_write (req, &fh, args.offset, args.count, args.stable,
- req->msg[1], rpcsvc_request_iobref_ref (req));
+ payload, nfs_rpcsvc_request_record_iob (req));
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -2298,12 +2261,6 @@ rpcerr:
return ret;
}
-int
-nfs3svc_write_vec (rpcsvc_request_t *req, struct iovec *payload,
- int payload_count, struct iobref *iobref)
-{
- return nfs3svc_write (req);
-}
int
nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,
@@ -2325,23 +2282,20 @@ nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh,
int32_t
nfs3svc_create_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_CREATE, stat,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", stat,
op_errno, &cs->fh);
nfs3_create_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
&cs->postparent);
@@ -2355,26 +2309,20 @@ int32_t
nfs3svc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
nfs_user_t nfu = {0, };
nfs3_call_state_t *cs = NULL;
- inode_t *oldinode = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh);
- oldinode = inode_link (inode, cs->resolvedloc.parent,
- cs->resolvedloc.name, buf);
/* Means no attributes were required to be set. */
if (!cs->setattr_valid) {
@@ -2386,20 +2334,14 @@ nfs3svc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs->preparent = *preparent;
cs->postparent = *postparent;
nfs_request_user_init (&nfu, cs->req);
- uuid_copy (cs->resolvedloc.gfid, inode->gfid);
ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,&cs->stbuf,
cs->setattr_valid, nfs3svc_create_setattr_cbk, cs);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
- if (oldinode) {
- inode_lookup (oldinode);
- inode_unref (oldinode);
- }
-
if (ret < 0) {
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_CREATE,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE",
stat, op_errno, &cs->fh);
nfs3_create_reply (cs->req, stat, &cs->fh, buf, preparent,
postparent);
@@ -2415,30 +2357,16 @@ nfs3_create_common (nfs3_call_state_t *cs)
int ret = -EFAULT;
int flags = 0;
nfs_user_t nfu = {0, };
- uid_t uid = 0;
- gid_t gid = 0;
if (!cs)
return ret;
- if (cs->createmode == GUARDED)
- flags = (O_RDWR | O_EXCL);
- else
+ if (cs->createmode == UNCHECKED)
flags = O_RDWR;
+ else if (cs->createmode == GUARDED)
+ flags = (O_RDWR | O_EXCL);
- if (gf_attr_uid_set (cs->setattr_valid)) {
- uid = cs->stbuf.ia_uid;
- cs->setattr_valid &= ~GF_SET_ATTR_UID;
- } else
- uid = rpcsvc_request_uid (cs->req);
-
- if (gf_attr_gid_set (cs->setattr_valid)) {
- gid = cs->stbuf.ia_gid;
- cs->setattr_valid &= ~GF_SET_ATTR_GID;
- } else
- gid = rpcsvc_request_gid (cs->req);
-
- nfs_request_primary_user_init (&nfu, cs->req, uid, gid);
+ nfs_request_user_init (&nfu, cs->req);
/* We can avoid sending the setattr call later if only the mode is
* required to be set. This is possible because the create fop allows
* us to specify a mode arg.
@@ -2458,8 +2386,7 @@ nfs3_create_common (nfs3_call_state_t *cs)
int32_t
nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
int ret = -EFAULT;
nfsstat3 stat = NFS3ERR_SERVERFAULT;
@@ -2469,9 +2396,6 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
nfs_request_user_init (&nfu, cs->req);
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
ret = -op_errno;
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
@@ -2479,23 +2403,20 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((cs->stbuf.ia_mtime == buf->ia_mtime) &&
(cs->stbuf.ia_atime == buf->ia_atime)) {
- gf_log (GF_NFS3, GF_LOG_DEBUG,
- "Create req retransmitted verf %x %x",
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "Create req retransmitted verf %x %x",
cs->stbuf.ia_mtime, cs->stbuf.ia_atime);
stat = NFS3_OK;
nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh);
} else {
- gf_log (GF_NFS3, GF_LOG_DEBUG,
- "File already exist new_verf %x %x"
- "old_verf %x %x", cs->stbuf.ia_mtime,
- cs->stbuf.ia_atime,
+ gf_log (GF_NFS3, GF_LOG_DEBUG, "File already exist new_verf %x %x"
+ "old_verf %x %x", cs->stbuf.ia_mtime, cs->stbuf.ia_atime,
buf->ia_mtime, buf->ia_atime);
stat = NFS3ERR_EXIST;
}
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE",
stat, op_errno);
nfs3_create_reply (cs->req, stat, &cs->fh, buf, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2516,11 +2437,8 @@ nfs3_create_exclusive (nfs3_call_state_t *cs)
/* Storing verifier as a mtime and atime attribute, to store it
* in stable storage */
- memcpy (&cs->stbuf.ia_atime, &cs->cookieverf,
- sizeof (cs->stbuf.ia_atime));
- memcpy (&cs->stbuf.ia_mtime,
- ((char *) &cs->cookieverf) + sizeof (cs->stbuf.ia_atime),
- sizeof (cs->stbuf.ia_mtime));
+ cs->stbuf.ia_atime = (cs->cookieverf & 0xFFFFFFFF00000000);
+ cs->stbuf.ia_mtime = (cs->cookieverf & 0x00000000FFFFFFFF);
cs->setattr_valid |= GF_SET_ATTR_ATIME;
cs->setattr_valid |= GF_SET_ATTR_MTIME;
nfs_request_user_init (&nfu, cs->req);
@@ -2536,7 +2454,15 @@ nfs3_create_exclusive (nfs3_call_state_t *cs)
goto nfs3err;
}
- ret = nfs3_create_common (cs);
+ if (cs->setattr_valid & GF_SET_ATTR_MODE) {
+ cs->setattr_valid &= ~GF_SET_ATTR_MODE;
+ ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
+ O_RDWR, cs->mode, nfs3svc_create_cbk, cs);
+ } else
+ ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->oploc, O_RDWR,
+ NFS_DEFAULT_CREATE_MODE, nfs3svc_create_cbk,
+ cs);
+
nfs3err:
return ret;
}
@@ -2565,7 +2491,7 @@ nfs3_create_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_CREATE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE",
stat, -ret);
nfs3_create_reply (cs->req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2587,7 +2513,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
if ((!req) || (!dirfh) || (!name) || (!sattr))
return -1;
- nfs3_log_create_call (rpcsvc_request_xid (req), dirfh, name, mode);
+ nfs3_log_create_call (nfs_rpcsvc_request_xid (req), dirfh, name, mode);
nfs3_validate_gluster_fh (dirfh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret);
@@ -2597,12 +2523,8 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
cs->cookieverf = cverf;
- /*In Exclusive create client is supposed to send cverf instead of
- * sattr*/
- if (mode != EXCLUSIVE)
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr,
- &cs->stbuf,
- &cs->mode);
+ cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
+ &cs->mode);
cs->createmode = mode;
cs->parent = *dirfh;
@@ -2612,7 +2534,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_CREATE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "CREATE",
stat, -ret);
nfs3_create_reply (req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2637,9 +2559,9 @@ nfs3svc_create (rpcsvc_request_t *req)
return ret;
nfs3_prep_create3args (&args, &dirfh, name);
- if (xdr_to_create3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_create3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
@@ -2647,8 +2569,7 @@ nfs3svc_create (rpcsvc_request_t *req)
if (cval)
cverf = *cval;
else {
- gf_log(GF_NFS3, GF_LOG_ERROR,
- "Error getting createverf3 from args");
+ gf_log(GF_NFS3, GF_LOG_ERROR, "Error getting createverf3 from args");
goto rpcerr;
}
@@ -2656,7 +2577,7 @@ nfs3svc_create (rpcsvc_request_t *req)
&args.how.createhow3_u.obj_attributes, cverf);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "CREATE procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -2684,23 +2605,20 @@ nfs3_mkdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,
int32_t
nfs3svc_mkdir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR, stat,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", stat,
op_errno, &cs->fh);
nfs3_mkdir_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
&cs->postparent);
@@ -2714,7 +2632,7 @@ int32_t
nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
@@ -2723,9 +2641,6 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -2748,7 +2663,7 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
nfs3err:
if (ret < 0) {
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR",
stat, op_errno, &cs->fh);
nfs3_mkdir_reply (cs->req, stat, &cs->fh, buf, preparent,
postparent);
@@ -2787,7 +2702,7 @@ nfs3_mkdir_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_MKDIR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR",
stat, -ret);
nfs3_mkdir_reply (cs->req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2813,7 +2728,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
return -1;
}
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "MKDIR", dirfh,
+ nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "MKDIR", dirfh,
name);
nfs3_validate_gluster_fh (dirfh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -2832,7 +2747,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKDIR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKDIR",
stat, -ret);
nfs3_mkdir_reply (req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -2854,16 +2769,16 @@ nfs3svc_mkdir (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_mkdir3args (&args, &dirfh, name);
- if (xdr_to_mkdir3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_mkdir3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_mkdir (req, &dirfh, name, &args.attributes);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "MKDIR procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -2894,16 +2809,13 @@ int32_t
nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -2912,7 +2824,7 @@ nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_SYMLINK, stat,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "SYMLINK", stat,
op_errno, &cs->fh);
nfs3_symlink_reply (cs->req, stat, &cs->fh, buf, preparent,
postparent);
@@ -2942,8 +2854,8 @@ nfs3_symlink_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_SYMLINK, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "SYMLINK", stat, -ret);
nfs3_symlink_reply (cs->req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
}
@@ -2967,7 +2879,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
return -1;
}
- nfs3_log_symlink_call (rpcsvc_request_xid (req), dirfh, name,
+ nfs3_log_symlink_call (nfs_rpcsvc_request_xid (req), dirfh, name,
target);
nfs3_validate_gluster_fh (dirfh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -2991,7 +2903,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_SYMLINK,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SYMLINK",
stat, -ret);
nfs3_symlink_reply (req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3017,9 +2929,9 @@ nfs3svc_symlink (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_symlink3args (&args, &dirfh, name, target);
- if (xdr_to_symlink3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_symlink3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
@@ -3027,7 +2939,7 @@ nfs3svc_symlink (rpcsvc_request_t *req)
&args.symlink.symlink_attributes);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "SYMLINK procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -3056,23 +2968,20 @@ nfs3_mknod_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh,
int32_t
nfs3svc_mknod_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
stat = NFS3_OK;
nfs3err:
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD, stat,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", stat,
op_errno, &cs->fh);
nfs3_mknod_reply (cs->req, stat, &cs->fh, postop, &cs->preparent,
&cs->postparent);
@@ -3086,7 +2995,7 @@ int32_t
nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -1;
@@ -3095,9 +3004,6 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -3120,7 +3026,7 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD,
+ nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD",
stat,
op_errno, &cs->fh);
nfs3_mknod_reply (cs->req, stat, &cs->fh, buf, preparent,
@@ -3219,7 +3125,7 @@ nfs3_mknod_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_MKNOD,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD",
stat, -ret);
nfs3_mknod_reply (cs->req, stat, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3246,7 +3152,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,
return -1;
}
- nfs3_log_mknod_call (rpcsvc_request_xid (req), fh, name,
+ nfs3_log_mknod_call (nfs_rpcsvc_request_xid (req), fh, name,
nodedata->type);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -3262,15 +3168,13 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,
case NF3BLK:
cs->devnums = nodedata->mknoddata3_u.device.spec;
sattr = &nodedata->mknoddata3_u.device.dev_attributes;
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr,
- &cs->stbuf,
+ cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
&cs->mode);
break;
case NF3SOCK:
case NF3FIFO:
sattr = &nodedata->mknoddata3_u.pipe_attributes;
- cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr,
- &cs->stbuf,
+ cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
&cs->mode);
break;
default:
@@ -3285,7 +3189,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_MKNOD,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKNOD",
stat, -ret);
nfs3_mknod_reply (req, stat, NULL, NULL, NULL, NULL);
/* Ret must be 0 after this so that the caller does not
@@ -3310,16 +3214,16 @@ nfs3svc_mknod (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_mknod3args (&args, &fh, name);
- if (xdr_to_mknod3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_mknod3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_mknod (req, &fh, name, &args.what);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "MKNOD procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -3346,23 +3250,31 @@ nfs3_remove_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent
int32_t
nfs3svc_remove_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
+ fd_t *openfd = NULL;
nfs3_call_state_t *cs = NULL;
+ struct nfs3_state *nfs3 = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
+ goto do_not_unref_cached_fd;
}
-
- if (op_ret == 0)
- stat = NFS3_OK;
-
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE, stat,
+ stat = NFS3_OK;
+ /* Close any cached fds so that when any currently active write
+ * finishes, the file is finally removed.
+ */
+ openfd = fd_lookup (cs->resolvedloc.inode, 0);
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
+ if (openfd) {
+ fd_unref (openfd);
+ nfs3_fdcache_remove (nfs3, openfd);
+ }
+
+do_not_unref_cached_fd:
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE", stat,
op_errno);
nfs3_remove_reply (cs->req, stat, preparent, postparent);
nfs3_call_state_wipe (cs);
@@ -3411,7 +3323,7 @@ nfs3_remove_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_REMOVE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE",
stat, -ret);
nfs3_remove_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3435,7 +3347,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
return -1;
}
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "REMOVE", fh,
+ nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "REMOVE", fh,
name);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -3451,7 +3363,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_REMOVE,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "REMOVE",
stat, -ret);
nfs3_remove_reply (req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3476,16 +3388,16 @@ nfs3svc_remove (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_remove3args (&args, &fh, name);
- if (xdr_to_remove3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_remove3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_remove (req, &fh, name);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "REMOVE procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -3512,22 +3424,19 @@ nfs3_rmdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent,
int32_t
nfs3svc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else {
+ else {
stat = NFS3_OK;
}
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RMDIR, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR", stat,
op_errno);
nfs3_rmdir_reply (cs->req, stat, preparent, postparent);
nfs3_call_state_wipe (cs);
@@ -3556,7 +3465,7 @@ nfs3_rmdir_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RMDIR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR",
stat, -ret);
nfs3_rmdir_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3581,7 +3490,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
return -1;
}
- nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "RMDIR", fh,
+ nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "RMDIR", fh,
name);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -3597,7 +3506,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RMDIR,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RMDIR",
stat, -ret);
nfs3_rmdir_reply (req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3622,16 +3531,16 @@ nfs3svc_rmdir (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_rmdir3args (&args, &fh, name);
- if (xdr_to_rmdir3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_rmdir3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_rmdir (req, &fh, name);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "RMDIR procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -3664,26 +3573,34 @@ int32_t
nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
int ret = -EFAULT;
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
+ fd_t *openfd = NULL;
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: rename %s -> %s => -1 (%s)",
- rpcsvc_request_xid (cs->req), cs->oploc.path,
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
stat = NFS3_OK;
+ /* Close any cached fds so that when any currently active writes to the
+ * dst finish, the file is finally removed.
+ *
+ * This logic works because we know resolvedloc contains dst, which is
+ * resolved after src
+ */
+ openfd = fd_lookup (cs->resolvedloc.inode, 0);
+ if (openfd) {
+ fd_unref (openfd);
+ nfs3_fdcache_remove (cs->nfs3state, openfd);
+ }
+
nfs3err:
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", stat,
-ret);
nfs3_rename_reply (cs->req, stat, buf, preoldparent, postoldparent,
prenewparent, postnewparent);
@@ -3714,7 +3631,7 @@ nfs3_rename_resume_dst (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME",
stat, -ret);
nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3742,7 +3659,6 @@ nfs3_rename_resume_src (void *carg)
*/
nfs_loc_copy (&cs->oploc, &cs->resolvedloc);
nfs_loc_wipe (&cs->resolvedloc);
- GF_FREE (cs->resolventry);
ret = nfs3_fh_resolve_and_resume (cs, &cs->fh, cs->pathname,
nfs3_rename_resume_dst);
@@ -3751,7 +3667,7 @@ nfs3_rename_resume_src (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_RENAME,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME",
stat, -ret);
nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3776,7 +3692,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname,
return -1;
}
- nfs3_log_rename_call (rpcsvc_request_xid (req), olddirfh, oldname,
+ nfs3_log_rename_call (nfs_rpcsvc_request_xid (req), olddirfh, oldname,
newdirfh, newname);
nfs3_validate_gluster_fh (olddirfh, stat, nfs3err);
nfs3_validate_gluster_fh (newdirfh, stat, nfs3err);
@@ -3806,7 +3722,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_RENAME,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RENAME",
stat, -ret);
nfs3_rename_reply (req, stat, NULL, NULL, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3833,16 +3749,16 @@ nfs3svc_rename (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_rename3args (&args, &olddirfh, oldname, &newdirfh, newname);
- if (xdr_to_rename3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_rename3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_rename (req, &olddirfh, oldname, &newdirfh, newname);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "RENAME procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -3871,22 +3787,18 @@ int32_t
nfs3svc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: link %s <- %s => -1 (%s)",
- rpcsvc_request_xid (cs->req), cs->oploc.path,
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else
+ else
stat = NFS3_OK;
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", stat,
op_errno);
nfs3_link_reply (cs->req, stat, buf, preparent, postparent);
nfs3_call_state_wipe (cs);
@@ -3917,7 +3829,7 @@ nfs3_link_resume_lnk (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK",
stat, -ret);
nfs3_link_reply (cs->req, stat, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3948,7 +3860,7 @@ nfs3_link_resume_tgt (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_LINK,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK",
stat, -ret);
nfs3_link_reply (cs->req, stat, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -3997,7 +3909,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_LINK, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LINK", stat,
-ret);
nfs3_link_reply (req, stat, NULL, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -4022,16 +3934,16 @@ nfs3svc_link (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_link3args (&args, &targetfh, &dirfh, newpath);
- if (xdr_to_link3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_link3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_link (req, &targetfh, &dirfh, newpath);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "LINK procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4080,8 +3992,7 @@ nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh,
int32_t
nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int is_eof = 0;
@@ -4089,9 +4000,6 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto nfs3err;
}
@@ -4107,14 +4015,14 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
nfs3err:
if (cs->maxcount == 0) {
- nfs3_log_readdir_res (rpcsvc_request_xid (cs->req), stat,
+ nfs3_log_readdir_res (nfs_rpcsvc_request_xid (cs->req), stat,
op_errno, (uintptr_t)cs->fd,
cs->dircount, is_eof);
nfs3_readdir_reply (cs->req, stat, &cs->parent,
(uintptr_t)cs->fd, buf, &cs->entries,
cs->dircount, is_eof);
} else {
- nfs3_log_readdirp_res (rpcsvc_request_xid (cs->req), stat,
+ nfs3_log_readdirp_res (nfs_rpcsvc_request_xid (cs->req), stat,
op_errno, (uintptr_t)cs->fd,
cs->dircount, cs->maxcount, is_eof);
nfs3_readdirp_reply (cs->req, stat, &cs->parent,
@@ -4134,8 +4042,7 @@ nfs3err:
int32_t
nfs3svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
int ret = -EFAULT;
@@ -4144,9 +4051,6 @@ nfs3svc_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto err;
}
@@ -4167,12 +4071,12 @@ err:
goto ret;
if (cs->maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIR, stat, op_errno);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIR", stat, op_errno);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0);
} else {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIRP, stat, op_errno);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIRP", stat, op_errno);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4215,7 +4119,7 @@ nfs3_readdir_read_resume (void *carg)
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- nfs3 = rpcsvc_request_program_private (cs->req);
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
ret = nfs3_verify_dircookie (nfs3, cs->fd, cs->cookie, cs->cookieverf,
&stat);
if (ret < 0) /* Stat already set by verifier function above. */
@@ -4227,13 +4131,13 @@ nfs3_readdir_read_resume (void *carg)
nfs3err:
if (ret < 0) {
if (cs->maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIR, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIR", stat, -ret);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0);
} else {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIRP, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIRP", stat, -ret);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4256,26 +4160,20 @@ nfs3_readdir_open_resume (void *carg)
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- cs->fd = fd_anonymous (cs->resolvedloc.inode);
- if (!cs->fd) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Faile to create anonymous fd");
- goto nfs3err;
- }
-
- ret = nfs3_readdir_read_resume (cs);
+ ret = nfs3_dir_open_and_resume (cs, nfs3_readdir_read_resume);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
if (cs->maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIR, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIR", stat, -ret);
nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0);
} else {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_READDIRP, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "READDIRP", stat, -ret);
nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL,
0, 0, 0);
}
@@ -4302,7 +4200,7 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
return -1;
}
- nfs3_log_readdir_call (rpcsvc_request_xid (req), fh, dircount,
+ nfs3_log_readdir_call (nfs_rpcsvc_request_xid (req), fh, dircount,
maxcount);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -4323,13 +4221,13 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie,
nfs3err:
if (ret < 0) {
if (maxcount == 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req),
- NFS3_READDIR, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req),
+ "READDIR", stat, -ret);
nfs3_readdir_reply (req, stat, NULL, 0, NULL, NULL, 0,
0);
} else {
- nfs3_log_common_res (rpcsvc_request_xid (req),
- NFS3_READDIRP, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req),
+ "READDIRP", stat, -ret);
nfs3_readdirp_reply (req, stat, NULL, 0, NULL, NULL, 0,
0, 0);
}
@@ -4356,9 +4254,9 @@ nfs3svc_readdir (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_readdir3args (&ra, &fh);
- if (xdr_to_readdir3args (req->msg[0], &ra) <= 0) {
+ if (xdr_to_readdir3args (req->msg, &ra) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
@@ -4367,15 +4265,14 @@ nfs3svc_readdir (rpcsvc_request_t *req)
if (cval)
verf = *cval;
else {
- gf_log(GF_NFS3, GF_LOG_ERROR,
- "Error getting cookieverf from readdir args");
+ gf_log(GF_NFS3, GF_LOG_ERROR, "Error getting cookieverf from readdir args");
goto rpcerr;
}
ret = nfs3_readdir (req, &fh, ra.cookie, verf, ra.count, 0);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "READDIR procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4396,9 +4293,9 @@ nfs3svc_readdirp (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_readdirp3args (&ra, &fh);
- if (xdr_to_readdirp3args (req->msg[0], &ra) <= 0) {
+ if (xdr_to_readdirp3args (req->msg, &ra) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
@@ -4407,8 +4304,7 @@ nfs3svc_readdirp (rpcsvc_request_t *req)
if (cval)
cverf = *cval;
else {
- gf_log (GF_NFS3, GF_LOG_ERROR,
- "Error getting cookieverf from readdirp args");
+ gf_log (GF_NFS3, GF_LOG_ERROR, "Error getting cookieverf from readdirp args");
goto rpcerr;
}
@@ -4416,7 +4312,7 @@ nfs3svc_readdirp (rpcsvc_request_t *req)
ra.maxcount);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "READDIRP procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4442,22 +4338,18 @@ nfs3_fsstat_reply (rpcsvc_request_t *req, nfsstat3 stat, struct statvfs *fsbuf,
int32_t
nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else
+ else
stat = NFS3_OK;
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", stat,
op_errno);
nfs3_fsstat_reply (cs->req, stat, &cs->fsstat, buf);
nfs3_call_state_wipe (cs);
@@ -4467,8 +4359,7 @@ nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
nfs_user_t nfu = {0, };
int ret = -EFAULT;
@@ -4477,9 +4368,6 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
cs = frame->local;
if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
ret = -op_errno;
stat = nfs3_errno_to_nfsstat3 (op_errno);
goto err;
@@ -4497,7 +4385,7 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT",
stat, -ret);
nfs3_fsstat_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -4529,7 +4417,7 @@ nfs3_fsstat_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSSTAT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT",
stat, -ret);
nfs3_fsstat_reply (cs->req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -4554,7 +4442,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh)
return -1;
}
- nfs3_log_common_call (rpcsvc_request_xid (req), "FSSTAT", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSSTAT", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -4567,7 +4455,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSSTAT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSTAT",
stat, -ret);
nfs3_fsstat_reply (req, stat, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -4591,16 +4479,16 @@ nfs3svc_fsstat (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_fsstat3args (&args, &fh);
- if (xdr_to_fsstat3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_fsstat3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_fsstat (req, &fh);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "FSTAT procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4617,7 +4505,7 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot)
uint64_t deviceid = 0;
deviceid = nfs3_request_xlator_deviceid (req);
- nfs3 = rpcsvc_request_program_private (req);
+ nfs3 = nfs_rpcsvc_request_program_private (req);
nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid);
nfs3svc_submit_reply (req, &res,
@@ -4628,23 +4516,19 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot)
int32_t
nfs3svc_fsinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
nfsstat3 status = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
status = nfs3_errno_to_nfsstat3 (op_errno);
- }else
+ else
status = NFS3_OK;
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSINFO, status,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO", status,
op_errno);
nfs3_fsinfo_reply (cs->req, status, buf);
@@ -4677,7 +4561,7 @@ nfs3_fsinfo_resume (void *carg)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_FSINFO,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO",
stat, -ret);
nfs3_fsinfo_reply (cs->req, stat, NULL);
nfs3_call_state_wipe (cs);
@@ -4701,7 +4585,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh)
return -1;
}
- nfs3_log_common_call (rpcsvc_request_xid (req), "FSINFO", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSINFO", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -4714,7 +4598,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_FSINFO,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSINFO",
stat, -ret);
nfs3_fsinfo_reply (req, stat, NULL);
nfs3_call_state_wipe (cs);
@@ -4736,16 +4620,16 @@ nfs3svc_fsinfo (rpcsvc_request_t *req)
return ret;
nfs3_prep_fsinfo3args (&args, &root);
- if (xdr_to_fsinfo3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_fsinfo3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding arguments");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_fsinfo (req, &root);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "FSINFO procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4770,20 +4654,16 @@ nfs3_pathconf_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf)
int32_t
nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
struct iatt *sbuf = NULL;
nfs3_call_state_t *cs = NULL;
nfsstat3 stat = NFS3ERR_SERVERFAULT;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else {
+ else {
/* If stat fop failed, we can still send the other components
* in a pathconf reply.
*/
@@ -4791,7 +4671,7 @@ nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
stat = NFS3_OK;
}
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_PATHCONF, stat,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "PATHCONF", stat,
op_errno);
nfs3_pathconf_reply (cs->req, stat, sbuf);
nfs3_call_state_wipe (cs);
@@ -4820,8 +4700,8 @@ nfs3_pathconf_resume (void *carg)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req),
- NFS3_PATHCONF, stat, -ret);
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req),
+ "PATHCONF", stat, -ret);
nfs3_pathconf_reply (cs->req, stat, NULL);
nfs3_call_state_wipe (cs);
}
@@ -4843,7 +4723,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh)
return -1;
}
- nfs3_log_common_call (rpcsvc_request_xid (req), "PATHCONF", fh);
+ nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "PATHCONF", fh);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err);
@@ -4856,7 +4736,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh)
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_PATHCONF,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "PATHCONF",
stat, -ret);
nfs3_pathconf_reply (req, stat, NULL);
nfs3_call_state_wipe (cs);
@@ -4880,16 +4760,16 @@ nfs3svc_pathconf (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_pathconf3args (&args, &fh);
- if (xdr_to_pathconf3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_pathconf3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_pathconf (req, &fh);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "PATHCONF procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -4915,25 +4795,23 @@ nfs3_commit_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t wverf,
int32_t
nfs3svc_commit_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
nfsstat3 stat = NFS3ERR_SERVERFAULT;
nfs3_call_state_t *cs = NULL;
struct nfs3_state *nfs3 = NULL;
cs = frame->local;
- if (op_ret == -1) {
- gf_log (GF_NFS, GF_LOG_WARNING,
- "%x: %s => -1 (%s)", rpcsvc_request_xid (cs->req),
- cs->resolvedloc.path, strerror (op_errno));
+ if (op_ret == -1)
stat = nfs3_errno_to_nfsstat3 (op_errno);
- } else
+ else
stat = NFS3_OK;
- nfs3 = rpcsvc_request_program_private (cs->req);
- nfs3_log_commit_res (rpcsvc_request_xid (cs->req), stat, op_errno,
+ nfs3 = nfs_rpcsvc_request_program_private (cs->req);
+ nfs3_log_commit_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno,
nfs3->serverstart);
- nfs3_commit_reply (cs->req, stat, nfs3->serverstart, NULL, NULL);
+ nfs3_commit_reply (cs->req, stat, nfs3->serverstart, prebuf, postbuf);
nfs3_call_state_wipe (cs);
return 0;
@@ -4960,14 +4838,14 @@ nfs3_commit_resume (void *carg)
}
nfs_request_user_init (&nfu, cs->req);
- ret = nfs_flush (cs->nfsx, cs->vol, &nfu, cs->fd,
+ ret = nfs_fsync (cs->nfsx, cs->vol, &nfu, cs->fd, 0,
nfs3svc_commit_cbk, cs);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_COMMIT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT",
stat, -ret);
nfs3_commit_reply (cs->req, stat, cs->nfs3state->serverstart,
NULL, NULL);
@@ -4975,7 +4853,7 @@ nfs3err:
ret = 0;
}
- return 0;
+ return ret;
}
@@ -4991,18 +4869,13 @@ nfs3_commit_open_resume (void *carg)
cs = (nfs3_call_state_t *)carg;
nfs3_check_fh_resolve_status (cs, stat, nfs3err);
- cs->fd = fd_anonymous (cs->resolvedloc.inode);
- if (!cs->fd) {
- gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to create anonymous fd.");
- goto nfs3err;
- }
- ret = nfs3_commit_resume (cs);
+ ret = nfs3_file_open_and_resume (cs, nfs3_commit_resume);
if (ret < 0)
stat = nfs3_errno_to_nfsstat3 (-ret);
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (cs->req), NFS3_COMMIT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT",
stat, -ret);
nfs3_commit_reply (cs->req, stat, 0, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -5028,7 +4901,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
return -1;
}
- nfs3_log_rw_call (rpcsvc_request_xid (req), "COMMIT", fh, offset,
+ nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "COMMIT", fh, offset,
count, -1);
nfs3_validate_gluster_fh (fh, stat, nfs3err);
nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret);
@@ -5046,7 +4919,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset,
nfs3err:
if (ret < 0) {
- nfs3_log_common_res (rpcsvc_request_xid (req), NFS3_COMMIT,
+ nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "COMMIT",
stat, -ret);
nfs3_commit_reply (req, stat, 0, NULL, NULL);
nfs3_call_state_wipe (cs);
@@ -5068,16 +4941,16 @@ nfs3svc_commit (rpcsvc_request_t *req)
if (!req)
return ret;
nfs3_prep_commit3args (&args, &fh);
- if (xdr_to_commit3args (req->msg[0], &args) <= 0) {
+ if (xdr_to_commit3args (req->msg, &args) <= 0) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
+ nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS);
goto rpcerr;
}
ret = nfs3_commit (req, &fh, args.offset, args.count);
if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) {
gf_log (GF_NFS3, GF_LOG_ERROR, "COMMIT procedure failed");
- rpcsvc_request_seterr (req, SYSTEM_ERR);
+ nfs_rpcsvc_request_seterr (req, SYSTEM_ERR);
ret = RPCSVC_ACTOR_ERROR;
}
@@ -5087,28 +4960,28 @@ rpcerr:
rpcsvc_actor_t nfs3svc_actors[NFS3_PROC_COUNT] = {
- {"NULL", NFS3_NULL, nfs3svc_null, NULL, NULL, 0},
- {"GETATTR", NFS3_GETATTR, nfs3svc_getattr,NULL, NULL, 0},
- {"SETATTR", NFS3_SETATTR, nfs3svc_setattr,NULL, NULL, 0},
- {"LOOKUP", NFS3_LOOKUP, nfs3svc_lookup, NULL, NULL, 0},
- {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, NULL, 0},
- {"READLINK", NFS3_READLINK, nfs3svc_readlink,NULL, NULL, 0},
- {"READ", NFS3_READ, nfs3svc_read, NULL, NULL, 0},
- {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vec, nfs3svc_write_vecsizer, 0},
- {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, NULL, 0},
- {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, NULL, 0},
- {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink,NULL, NULL, 0},
- {"MKNOD", NFS3_MKNOD, nfs3svc_mknod, NULL, NULL, 0},
- {"REMOVE", NFS3_REMOVE, nfs3svc_remove, NULL, NULL, 0},
- {"RMDIR", NFS3_RMDIR, nfs3svc_rmdir, NULL, NULL, 0},
- {"RENAME", NFS3_RENAME, nfs3svc_rename, NULL, NULL, 0},
- {"LINK", NFS3_LINK, nfs3svc_link, NULL, NULL, 0},
- {"READDIR", NFS3_READDIR, nfs3svc_readdir,NULL, NULL, 0},
- {"READDIRPLUS", NFS3_READDIRP, nfs3svc_readdirp,NULL, NULL, 0},
- {"FSSTAT", NFS3_FSSTAT, nfs3svc_fsstat, NULL, NULL, 0},
- {"FSINFO", NFS3_FSINFO, nfs3svc_fsinfo, NULL, NULL, 0},
- {"PATHCONF", NFS3_PATHCONF, nfs3svc_pathconf,NULL, NULL, 0},
- {"COMMIT", NFS3_COMMIT, nfs3svc_commit, NULL, NULL, 0}
+ {"NULL", NFS3_NULL, nfs3svc_null, NULL, NULL},
+ {"GETATTR", NFS3_GETATTR, nfs3svc_getattr,NULL, NULL},
+ {"SETATTR", NFS3_SETATTR, nfs3svc_setattr,NULL, NULL},
+ {"LOOKUP", NFS3_LOOKUP, nfs3svc_lookup, NULL, NULL},
+ {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, NULL},
+ {"READLINK", NFS3_READLINK, nfs3svc_readlink,NULL, NULL},
+ {"READ", NFS3_READ, nfs3svc_read, NULL, NULL},
+ {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vec, nfs3svc_write_vecsizer},
+ {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, NULL},
+ {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, NULL},
+ {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink,NULL, NULL},
+ {"MKNOD", NFS3_MKNOD, nfs3svc_mknod, NULL, NULL},
+ {"REMOVE", NFS3_REMOVE, nfs3svc_remove, NULL, NULL},
+ {"RMDIR", NFS3_RMDIR, nfs3svc_rmdir, NULL, NULL},
+ {"RENAME", NFS3_RENAME, nfs3svc_rename, NULL, NULL},
+ {"LINK", NFS3_LINK, nfs3svc_link, NULL, NULL},
+ {"READDIR", NFS3_READDIR, nfs3svc_readdir,NULL, NULL},
+ {"READDIRPLUS", NFS3_READDIRP, nfs3svc_readdirp,NULL, NULL},
+ {"FSSTAT", NFS3_FSSTAT, nfs3svc_fsstat, NULL, NULL},
+ {"FSINFO", NFS3_FSINFO, nfs3svc_fsinfo, NULL, NULL},
+ {"PATHCONF", NFS3_PATHCONF, nfs3svc_pathconf,NULL, NULL},
+ {"COMMIT", NFS3_COMMIT, nfs3svc_commit, NULL, NULL}
};
@@ -5117,6 +4990,8 @@ rpcsvc_program_t nfs3prog = {
.prognum = NFS_PROGRAM,
.progver = NFS_V3,
.progport = GF_NFS3_PORT,
+ .progaddrfamily = AF_INET,
+ .proghost = NULL,
.actors = nfs3svc_actors,
.numactors = NFS3_PROC_COUNT,
@@ -5209,7 +5084,7 @@ nfs3_init_options (struct nfs3_state *nfs3, xlator_t *nfsx)
nfs3->iobsize = nfs3->readdirsize;
/* But this is the true size of each iobuf. We need this size to
- * accommodate the NFS headers also in the same buffer. */
+ * accomodate the NFS headers also in the same buffer. */
nfs3->iobsize = nfs3->iobsize * 2;
/* mem-factor */
@@ -5454,7 +5329,7 @@ nfs3_init_state (xlator_t *nfsx)
struct nfs3_state *nfs3 = NULL;
int ret = -1;
unsigned int localpool = 0;
- struct nfs_state *nfs = NULL;
+
if (!nfsx)
return NULL;
@@ -5466,7 +5341,6 @@ nfs3_init_state (xlator_t *nfsx)
return NULL;
}
- nfs = nfsx->private;
ret = nfs3_init_options (nfs3, nfsx);
if (ret == -1) {
gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init options");
@@ -5499,13 +5373,6 @@ nfs3_init_state (xlator_t *nfsx)
LOCK_INIT (&nfs3->fdlrulock);
nfs3->fdcount = 0;
- rpcsvc_create_listeners (nfs->rpcsvc, nfsx->options, nfsx->name);
- if (ret == -1) {
- gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners");
- goto free_localpool;
- }
-
- nfs->nfs3state = nfs3;
ret = 0;
free_localpool:
diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h
index 78eb01b60..bf4371a8a 100644
--- a/xlators/nfs/server/src/nfs3.h
+++ b/xlators/nfs/server/src/nfs3.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -34,11 +34,11 @@
#include "nfs-common.h"
#include "xdr-nfs3.h"
#include "mem-pool.h"
-#include "nlm4.h"
#include <sys/statvfs.h>
#define GF_NFS3 GF_NFS"-nfsv3"
+#define GF_NFS3_PORT 38467
#define GF_NFS3_DEFAULT_MEMFACTOR 15
#define GF_NFS3_IOBPOOL_MULT GF_NFS_CONCURRENT_OPS_MULT
@@ -94,7 +94,7 @@ struct nfs3_export {
#define GF_NFS3_DEFAULT_VOLACCESS (GF_NFS3_VOLACCESS_RW)
/* The NFSv3 protocol state */
-typedef struct nfs3_state {
+struct nfs3_state {
/* The NFS xlator pointer. The NFS xlator can be running
* multiple versions of the NFS protocol.
@@ -133,31 +133,13 @@ typedef struct nfs3_state {
struct list_head fdlru;
gf_lock_t fdlrulock;
int fdcount;
-} nfs3_state_t;
+};
typedef enum nfs3_lookup_type {
GF_NFS3_REVALIDATE = 1,
GF_NFS3_FRESH,
} nfs3_lookup_type_t;
-typedef union args_ {
- nlm4_stat nlm4_stat;
- nlm4_holder nlm4_holder;
- nlm4_lock nlm4_lock;
- nlm4_share nlm4_share;
- nlm4_testrply nlm4_testrply;
- nlm4_testres nlm4_testres;
- nlm4_testargs nlm4_testargs;
- nlm4_res nlm4_res;
- nlm4_lockargs nlm4_lockargs;
- nlm4_cancargs nlm4_cancargs;
- nlm4_unlockargs nlm4_unlockargs;
- nlm4_shareargs nlm4_shareargs;
- nlm4_shareres nlm4_shareres;
- nlm4_freeallargs nlm4_freeallargs;
-} args;
-
-
typedef int (*nfs3_resume_fn_t) (void *cs);
/* Structure used to communicate state between a fop and its callback.
* Not all members are used at all times. Usage is fop and NFS request
@@ -202,7 +184,6 @@ struct nfs3_local {
count3 datacount;
offset3 dataoffset;
struct iobuf *iob;
- struct iobref *iobref;
createmode3 createmode;
uint64_t cookieverf;
int sattrguardcheck;
@@ -214,7 +195,6 @@ struct nfs3_local {
mode_t mode;
/* NFSv3 FH resolver state */
- int hardresolved;
struct nfs3_fh resolvefh;
loc_t resolvedloc;
int resolve_ret;
@@ -223,24 +203,10 @@ struct nfs3_local {
fd_t *resolve_dir_fd;
char *resolventry;
nfs3_lookup_type_t lookuptype;
- gf_dirent_t *hashmatch;
- gf_dirent_t *entrymatch;
- off_t lastentryoffset;
- struct flock flock;
- args args;
- nlm4_lkowner_t lkowner;
- char cookiebytes[1024];
- struct nfs3_fh lockfh;
- int monitor;
- rpc_transport_t *trans;
- call_frame_t *frame;
};
#define nfs3_is_revalidate_lookup(cst) ((cst)->lookuptype == GF_NFS3_REVALIDATE)
-#define nfs3_lookup_op(cst) (rpcsvc_request_procnum(cst->req) == NFS3_LOOKUP)
-#define nfs3_create_op(cst) (rpcsvc_request_procnum(cst->req) == NFS3_CREATE)
-#define nfs3_create_exclusive_op(cst) ((cst)->createmode == EXCLUSIVE)
-
+#define nfs3_lookup_op(cst) (nfs_rpcsvc_request_procnum(cst->req) == NFS3_LOOKUP)
typedef struct nfs3_local nfs3_call_state_t;
/* Queue of ops waiting for open fop to return. */
diff --git a/xlators/nfs/server/src/nlm4.c b/xlators/nfs/server/src/nlm4.c
deleted file mode 100644
index 6399cb043..000000000
--- a/xlators/nfs/server/src/nlm4.c
+++ /dev/null
@@ -1,2472 +0,0 @@
-/*
- Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "defaults.h"
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "nfs.h"
-#include "mem-pool.h"
-#include "logging.h"
-#include "nfs-fops.h"
-#include "inode.h"
-#include "mount3.h"
-#include "nfs3.h"
-#include "nfs-mem-types.h"
-#include "nfs3-helpers.h"
-#include "nfs3-fh.h"
-#include "nlm4.h"
-#include "nlm4-xdr.h"
-#include "msg-nfs3.h"
-#include "nfs-generics.h"
-#include "rpc-clnt.h"
-#include "nsm-xdr.h"
-#include "nlmcbk-xdr.h"
-#include "run.h"
-#include <unistd.h>
-#include <rpc/pmap_clnt.h>
-#include <rpc/rpc.h>
-#include <rpc/xdr.h>
-#include <statedump.h>
-
-/* TODO:
- * 1) 2 opens racing .. creating an fd leak.
- * 2) use mempool for nlmclnt - destroy if no fd exists, create during 1st call
- */
-
-typedef ssize_t (*nlm4_serializer) (struct iovec outmsg, void *args);
-
-extern void nfs3_call_state_wipe (nfs3_call_state_t *cs);
-
-struct list_head nlm_client_list;
-gf_lock_t nlm_client_list_lk;
-
-/* race on this is harmless */
-int nlm_grace_period = 50;
-
-#define nlm4_validate_nfs3_state(request, state, status, label, retval) \
- do { \
- state = rpcsvc_request_program_private (request); \
- if (!state) { \
- gf_log (GF_NLM, GF_LOG_ERROR, "NFSv3 state " \
- "missing from RPC request"); \
- rpcsvc_request_seterr (req, SYSTEM_ERR); \
- status = nlm4_failed; \
- goto label; \
- } \
- } while (0); \
-
-nfs3_call_state_t *
-nfs3_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req, xlator_t *v);
-
-#define nlm4_handle_call_state_init(nfs3state, calls, rq, opstat, errlabel)\
- do { \
- calls = nlm4_call_state_init ((nfs3state), (rq)); \
- if (!calls) { \
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to " \
- "init call state"); \
- opstat = nlm4_failed; \
- rpcsvc_request_seterr (req, SYSTEM_ERR); \
- goto errlabel; \
- } \
- } while (0) \
-
-#define nlm4_validate_gluster_fh(handle, status, errlabel) \
- do { \
- if (!nfs3_fh_validate (handle)) { \
- status = nlm4_stale_fh; \
- goto errlabel; \
- } \
- } while (0) \
-
-xlator_t *
-nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh);
-
-#define nlm4_map_fh_to_volume(nfs3state, handle, req, volume, status, label) \
- do { \
- char exportid[256], gfid[256]; \
- rpc_transport_t *trans = NULL; \
- volume = nfs3_fh_to_xlator ((nfs3state), &handle); \
- if (!volume) { \
- uuid_unparse (handle.exportid, exportid); \
- uuid_unparse (handle.gfid, gfid); \
- trans = rpcsvc_request_transport (req); \
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to map " \
- "FH to vol: client=%s, exportid=%s, gfid=%s",\
- trans->peerinfo.identifier, exportid, \
- gfid); \
- gf_log (GF_NLM, GF_LOG_ERROR, \
- "Stale nfs client %s must be trying to "\
- "connect to a deleted volume, please " \
- "unmount it.", trans->peerinfo.identifier);\
- status = nlm4_stale_fh; \
- goto label; \
- } else { \
- gf_log (GF_NLM, GF_LOG_TRACE, "FH to Volume: %s"\
- ,volume->name); \
- rpcsvc_request_set_private (req, volume); \
- } \
- } while (0); \
-
-#define nlm4_volume_started_check(nfs3state, vlm, rtval, erlbl) \
- do { \
- if ((!nfs_subvolume_started (nfs_state (nfs3state->nfsx), vlm))){\
- gf_log (GF_NLM, GF_LOG_ERROR, "Volume is disabled: %s",\
- vlm->name); \
- rtval = RPCSVC_ACTOR_IGNORE; \
- goto erlbl; \
- } \
- } while (0) \
-
-#define nlm4_check_fh_resolve_status(cst, nfstat, erlabl) \
- do { \
- xlator_t *xlatorp = NULL; \
- char buf[256], gfid[256]; \
- rpc_transport_t *trans = NULL; \
- if ((cst)->resolve_ret < 0) { \
- trans = rpcsvc_request_transport (cst->req); \
- xlatorp = nfs3_fh_to_xlator (cst->nfs3state, \
- &cst->resolvefh); \
- uuid_unparse (cst->resolvefh.gfid, gfid); \
- sprintf (buf, "(%s) %s : %s", trans->peerinfo.identifier,\
- xlatorp ? xlatorp->name : "ERR", gfid); \
- gf_log (GF_NLM, GF_LOG_ERROR, "Unable to resolve FH"\
- ": %s", buf); \
- nfstat = nlm4_errno_to_nlm4stat (cst->resolve_errno);\
- goto erlabl; \
- } \
- } while (0) \
-
-
-void
-nlm4_prep_nlm4_testargs (nlm4_testargs *args, struct nfs3_fh *fh,
- nlm4_lkowner_t *oh, char *cookiebytes)
-{
- memset (args, 0, sizeof (*args));
- args->alock.fh.n_bytes = (void *)fh;
- args->alock.oh.n_bytes = (void *)oh;
- args->cookie.n_bytes = (void *)cookiebytes;
-}
-
-void
-nlm4_prep_nlm4_lockargs (nlm4_lockargs *args, struct nfs3_fh *fh,
- nlm4_lkowner_t *oh, char *cookiebytes)
-{
- memset (args, 0, sizeof (*args));
- args->alock.fh.n_bytes = (void *)fh;
- args->alock.oh.n_bytes = (void *)oh;
- args->cookie.n_bytes = (void *)cookiebytes;
-}
-
-void
-nlm4_prep_nlm4_cancargs (nlm4_cancargs *args, struct nfs3_fh *fh,
- nlm4_lkowner_t *oh, char *cookiebytes)
-{
- memset (args, 0, sizeof (*args));
- args->alock.fh.n_bytes = (void *)fh;
- args->alock.oh.n_bytes = (void *)oh;
- args->cookie.n_bytes = (void *)cookiebytes;
-}
-
-void
-nlm4_prep_nlm4_unlockargs (nlm4_unlockargs *args, struct nfs3_fh *fh,
- nlm4_lkowner_t *oh, char *cookiebytes)
-{
- memset (args, 0, sizeof (*args));
- args->alock.fh.n_bytes = (void *)fh;
- args->alock.oh.n_bytes = (void *)oh;
- args->cookie.n_bytes = (void *)cookiebytes;
-}
-
-void
-nlm4_prep_shareargs (nlm4_shareargs *args, struct nfs3_fh *fh,
- nlm4_lkowner_t *oh, char *cookiebytes)
-{
- memset (args, 0, sizeof (*args));
- args->share.fh.n_bytes = (void *)fh;
- args->share.oh.n_bytes = (void *)oh;
- args->cookie.n_bytes = (void *)cookiebytes;
-}
-
-void
-nlm4_prep_freeallargs (nlm4_freeallargs *args, nlm4_lkowner_t *oh)
-{
- memset (args, 0, sizeof (*args));
- args->name = (void *)oh;
-}
-
-void
-nlm_copy_lkowner (gf_lkowner_t *dst, netobj *src)
-{
- dst->len = src->n_len;
- memcpy (dst->data, src->n_bytes, dst->len);
-}
-
-int
-nlm_is_oh_same_lkowner (gf_lkowner_t *a, netobj *b)
-{
- if (!a || !b) {
- gf_log (GF_NLM, GF_LOG_ERROR, "invalid args");
- return -1;
- }
-
- return (a->len == b->n_len &&
- !memcmp (a->data, b->n_bytes, a->len));
-}
-
-nfsstat3
-nlm4_errno_to_nlm4stat (int errnum)
-{
- nlm4_stats stat = nlm4_denied;
-
- switch (errnum) {
- case 0:
- stat = nlm4_granted;
- break;
- case EROFS:
- stat = nlm4_rofs;
- break;
- case ESTALE:
- stat = nlm4_stale_fh;
- break;
- case ENOLCK:
- stat = nlm4_failed;
- break;
- default:
- stat = nlm4_denied;
- break;
- }
-
- return stat;
-}
-
-nfs3_call_state_t *
-nlm4_call_state_init (struct nfs3_state *s, rpcsvc_request_t *req)
-{
- nfs3_call_state_t *cs = NULL;
-
- if ((!s) || (!req))
- return NULL;
-
- cs = (nfs3_call_state_t *) mem_get (s->localpool);
- if (!cs)
- return NULL;
-
- memset (cs, 0, sizeof (*cs));
- INIT_LIST_HEAD (&cs->entries.list);
- INIT_LIST_HEAD (&cs->openwait_q);
- cs->operrno = EINVAL;
- cs->req = req;
- cs->nfsx = s->nfsx;
- cs->nfs3state = s;
- cs->monitor = 1;
-
- return cs;
-}
-
-int
-nlm_monitor (char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
- int monitor = -1;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- monitor = nlmclnt->nsm_monitor;
- nlmclnt->nsm_monitor = 1;
- break;
- }
- }
- UNLOCK (&nlm_client_list_lk);
-
- if (monitor == -1)
- gf_log (GF_NLM, GF_LOG_ERROR, "%s was not found in "
- "the nlmclnt list", caller_name);
-
- return monitor;
-}
-
-rpc_clnt_t *
-nlm_get_rpc_clnt (char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- rpc_clnt_t *rpc_clnt = NULL;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
- if (!nlmclnt_found)
- goto ret;
- if (nlmclnt->rpc_clnt)
- rpc_clnt = rpc_clnt_ref (nlmclnt->rpc_clnt);
-ret:
- UNLOCK (&nlm_client_list_lk);
- return rpc_clnt;
-}
-
-int
-nlm_set_rpc_clnt (rpc_clnt_t *rpc_clnt, char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- int ret = -1;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
- if (!nlmclnt_found) {
- nlmclnt = GF_CALLOC (1, sizeof(*nlmclnt),
- gf_nfs_mt_nlm4_nlmclnt);
- if (nlmclnt == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "mem-alloc error");
- goto ret;
- }
-
- INIT_LIST_HEAD(&nlmclnt->fdes);
- INIT_LIST_HEAD(&nlmclnt->nlm_clients);
- INIT_LIST_HEAD(&nlmclnt->shares);
-
- list_add (&nlmclnt->nlm_clients, &nlm_client_list);
- nlmclnt->caller_name = gf_strdup (caller_name);
- }
- if (nlmclnt->rpc_clnt == NULL) {
- nlmclnt->rpc_clnt = rpc_clnt_ref (rpc_clnt);
- }
- ret = 0;
-ret:
- UNLOCK (&nlm_client_list_lk);
- return ret;
-}
-
-int
-nlm_unset_rpc_clnt (rpc_clnt_t *rpc)
-{
- nlm_client_t *nlmclnt = NULL;
- rpc_clnt_t *rpc_clnt = NULL;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (rpc == nlmclnt->rpc_clnt) {
- rpc_clnt = nlmclnt->rpc_clnt;
- nlmclnt->rpc_clnt = NULL;
- break;
- }
- }
- UNLOCK (&nlm_client_list_lk);
- if (rpc_clnt == NULL) {
- return -1;
- }
- if (rpc_clnt) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&rpc_clnt->conn);
-
- rpc_clnt_unref (rpc_clnt);
- }
- return 0;
-}
-
-int
-nlm_add_nlmclnt (char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- int ret = -1;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
- if (!nlmclnt_found) {
- nlmclnt = GF_CALLOC (1, sizeof(*nlmclnt),
- gf_nfs_mt_nlm4_nlmclnt);
- if (nlmclnt == NULL) {
- gf_log (GF_NLM, GF_LOG_DEBUG, "malloc error");
- goto ret;
- }
-
- INIT_LIST_HEAD(&nlmclnt->fdes);
- INIT_LIST_HEAD(&nlmclnt->nlm_clients);
- INIT_LIST_HEAD(&nlmclnt->shares);
-
- list_add (&nlmclnt->nlm_clients, &nlm_client_list);
- nlmclnt->caller_name = gf_strdup (caller_name);
- }
- ret = 0;
-ret:
- UNLOCK (&nlm_client_list_lk);
- return ret;
-}
-
-int
-nlm4svc_submit_reply (rpcsvc_request_t *req, void *arg, nlm4_serializer sfunc)
-{
- struct iovec outmsg = {0, };
- struct iobuf *iob = NULL;
- struct nfs3_state *nfs3 = NULL;
- int ret = -1;
- struct iobref *iobref = NULL;
-
- if (!req)
- return -1;
-
- nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req);
- if (!nfs3) {
- gf_log (GF_NLM, GF_LOG_ERROR, "mount state not found");
- goto ret;
- }
-
- /* First, get the io buffer into which the reply in arg will
- * be serialized.
- */
- iob = iobuf_get (nfs3->iobpool);
- if (!iob) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to get iobuf");
- goto ret;
- }
-
- iobuf_to_iovec (iob, &outmsg);
- /* Use the given serializer to translate the give C structure in arg
- * to XDR format which will be written into the buffer in outmsg.
- */
- outmsg.iov_len = sfunc (outmsg, arg);
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- iobref_add (iobref, iob);
-
- /* Then, submit the message for transmission. */
- ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Reply submission failed");
- goto ret;
- }
-
- ret = 0;
-ret:
- if (iob)
- iobuf_unref (iob);
- if (iobref)
- iobref_unref (iobref);
-
- return ret;
-}
-
-typedef int (*nlm4_resume_fn_t) (void *cs);
-
-int32_t
-nlm4_file_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
-{
- nfs3_call_state_t *cs = frame->local;
-
- if (op_ret == 0)
- fd_bind (cs->fd);
- cs->resolve_ret = op_ret;
- cs->resume_fn (cs);
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-void *
-nsm_monitor(void *arg)
-{
- CLIENT *clnt = NULL;
- enum clnt_stat ret;
- struct mon nsm_mon;
- struct sm_stat_res res;
- struct timeval tout = { 5, 0 };
- char *host = NULL;
-
- host = arg;
- nsm_mon.mon_id.mon_name = gf_strdup(host);
- nsm_mon.mon_id.my_id.my_name = gf_strdup("localhost");
- nsm_mon.mon_id.my_id.my_prog = NLMCBK_PROGRAM;
- nsm_mon.mon_id.my_id.my_vers = NLMCBK_V1;
- nsm_mon.mon_id.my_id.my_proc = NLMCBK_SM_NOTIFY;
- /* nothing to put in the private data */
-#define SM_PROG 100024
-#define SM_VERS 1
-#define SM_MON 2
-
- /* create a connection to nsm on the localhost */
- clnt = clnt_create("localhost", SM_PROG, SM_VERS, "tcp");
- if(!clnt)
- {
- gf_log (GF_NLM, GF_LOG_ERROR, "%s",
- clnt_spcreateerror ("Clnt_create()"));
- goto out;
- }
-
- ret = clnt_call(clnt, SM_MON,
- (xdrproc_t) xdr_mon, (caddr_t) & nsm_mon,
- (xdrproc_t) xdr_sm_stat_res, (caddr_t) & res, tout);
- if(ret != RPC_SUCCESS)
- {
- gf_log (GF_NLM, GF_LOG_ERROR, "clnt_call(): %s",
- clnt_sperrno(ret));
- goto out;
- }
- if(res.res_stat != STAT_SUCC)
- {
- gf_log (GF_NLM, GF_LOG_ERROR, "clnt_call(): %s",
- clnt_sperrno(ret));
- goto out;
- }
-
-out:
- GF_FREE(nsm_mon.mon_id.mon_name);
- GF_FREE(nsm_mon.mon_id.my_id.my_name);
- if (clnt != NULL)
- clnt_destroy(clnt);
- return NULL;
-}
-
-nlm_client_t *
-__nlm_get_uniq (char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
-
- if (!caller_name)
- return NULL;
-
- list_for_each_entry (nlmclnt, &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name))
- return nlmclnt;
- }
-
- return NULL;
-}
-
-nlm_client_t *
-nlm_get_uniq (char *caller_name)
-{
- nlm_client_t *nlmclnt = NULL;
-
- LOCK (&nlm_client_list_lk);
- nlmclnt = __nlm_get_uniq (caller_name);
- UNLOCK (&nlm_client_list_lk);
-
- return nlmclnt;
-}
-
-
-int
-nlm4_file_open_and_resume(nfs3_call_state_t *cs, nlm4_resume_fn_t resume)
-{
- fd_t *fd = NULL;
- int ret = -1;
- nlm_client_t *nlmclnt = NULL;
- call_frame_t *frame = NULL;
-
- nlmclnt = nlm_get_uniq (cs->args.nlm4_lockargs.alock.caller_name);
- if (nlmclnt == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "nlm_get_uniq() returned NULL");
- ret = -ENOLCK;
- goto err;
- }
- cs->resume_fn = resume;
- fd = fd_lookup_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt);
- if (fd) {
- cs->fd = fd;
- cs->resolve_ret = 0;
- cs->resume_fn(cs);
- ret = 0;
- goto err;
- }
-
- fd = fd_create_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt);
- if (fd == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "fd_create_uint64() returned NULL");
- ret = -ENOLCK;
- goto err;
- }
-
- cs->fd = fd;
-
- frame = create_frame (cs->nfsx, cs->nfsx->ctx->pool);
- if (!frame) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to create frame");
- ret = -ENOMEM;
- goto err;
- }
-
- frame->root->pid = NFS_PID;
- frame->root->uid = 0;
- frame->root->gid = 0;
- frame->local = cs;
- /*
- * This is the only place that we call STACK_WIND without nfs_fix_groups,
- * because in this particular case the relevant identify is in lk_owner and
- * we don't care about the fields that nfs_fix_groups would set up.
- */
- STACK_WIND_COOKIE (frame, nlm4_file_open_cbk, cs->vol, cs->vol,
- cs->vol->fops->open, &cs->resolvedloc, O_RDWR,
- cs->fd, NULL);
- ret = 0;
-err:
- return ret;
-}
-
-int
-nlm4_generic_reply (rpcsvc_request_t *req, netobj cookie, nlm4_stats stat)
-{
- nlm4_res res;
-
- memset (&res, 0, sizeof (res));
- res.cookie = cookie;
- res.stat.stat = stat;
-
- nlm4svc_submit_reply (req, (void *)&res,
- (nlm4_serializer)xdr_serialize_nlm4_res);
- return 0;
-}
-
-int
-nlm4svc_null (rpcsvc_request_t *req)
-{
- struct iovec dummyvec = {0, };
-
- if (!req) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Got NULL request!");
- return 0;
- }
- rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL);
- return 0;
-}
-
-int
-nlm4_gf_flock_to_holder (nlm4_holder *holder, struct gf_flock *flock)
-{
- switch (flock->l_type) {
- case GF_LK_F_WRLCK:
- holder->exclusive = 1;
- break;
- }
-
- holder->svid = flock->l_pid;
- holder->l_offset = flock->l_start;
- holder->l_len = flock->l_len;
- return 0;
-}
-
-int
-nlm4_lock_to_gf_flock (struct gf_flock *flock, nlm4_lock *lock, int excl)
-{
- flock->l_pid = lock->svid;
- flock->l_start = lock->l_offset;
- flock->l_len = lock->l_len;
- if (excl)
- flock->l_type = F_WRLCK;
- else
- flock->l_type = F_RDLCK;
- flock->l_whence = SEEK_SET;
- nlm_copy_lkowner (&flock->l_owner, &lock->oh);
- return 0;
-}
-
-rpc_clnt_procedure_t nlm4_clnt_actors[NLM4_PROC_COUNT] = {
- [NLM4_NULL] = {"NULL", NULL},
- [NLM4_GRANTED] = {"GRANTED", NULL},
-};
-
-char *nlm4_clnt_names[NLM4_PROC_COUNT] = {
- [NLM4_NULL] = "NULL",
- [NLM4_GRANTED] = "GRANTED",
-};
-
-rpc_clnt_prog_t nlm4clntprog = {
- .progname = "NLMv4",
- .prognum = NLM_PROGRAM,
- .progver = NLM_V4,
- .numproc = NLM4_PROC_COUNT,
- .proctable = nlm4_clnt_actors,
- .procnames = nlm4_clnt_names,
-};
-
-int
-nlm4_test_reply (nfs3_call_state_t *cs, nlm4_stats stat, struct gf_flock *flock)
-{
- nlm4_testres res;
-
- memset (&res, 0, sizeof (res));
- res.cookie = cs->args.nlm4_testargs.cookie;
- res.stat.stat = stat;
- if (stat == nlm4_denied)
- nlm4_gf_flock_to_holder (&res.stat.nlm4_testrply_u.holder,
- flock);
-
- nlm4svc_submit_reply (cs->req, (void *)&res,
- (nlm4_serializer)xdr_serialize_nlm4_testres);
- return 0;
-}
-
-int
-nlm4svc_test_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
-{
- nlm4_stats stat = nlm4_denied;
- nfs3_call_state_t *cs = NULL;
-
- cs = frame->local;
- if (op_ret == -1) {
- stat = nlm4_errno_to_nlm4stat (op_errno);
- goto err;
- } else if (flock->l_type == F_UNLCK)
- stat = nlm4_granted;
-
-err:
- nlm4_test_reply (cs, stat, flock);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-int
-nlm4_test_fd_resume (void *carg)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- struct gf_flock flock = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs_request_user_init (&nfu, cs->req);
- nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_testargs.alock,
- cs->args.nlm4_testargs.exclusive);
- nlm_copy_lkowner (&nfu.lk_owner, &cs->args.nlm4_testargs.alock.oh);
- ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_GETLK, &flock,
- nlm4svc_test_cbk, cs);
-
- return ret;
-}
-
-
-int
-nlm4_test_resume (void *carg)
-{
- nlm4_stats stat = nlm4_failed;
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
- fd_t *fd = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nlm4_check_fh_resolve_status (cs, stat, nlm4err);
- fd = fd_anonymous (cs->resolvedloc.inode);
- if (!fd)
- goto nlm4err;
- cs->fd = fd;
- ret = nlm4_test_fd_resume (cs);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to open_and_resume");
- stat = nlm4_errno_to_nlm4stat (-ret);
- nlm4_test_reply (cs, stat, NULL);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nlm4svc_test (rpcsvc_request_t *req)
-{
- xlator_t *vol = NULL;
- nlm4_stats stat = nlm4_failed;
- struct nfs_state *nfs = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- int ret = RPCSVC_ACTOR_ERROR;
- struct nfs3_fh fh = {{0}, };
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_nlm4_testargs (&cs->args.nlm4_testargs, &fh, &cs->lkowner,
- cs->cookiebytes);
- if (xdr_to_nlm4_testargs(req->msg[0], &cs->args.nlm4_testargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req, vol, stat, nlm4err);
-
- if (nlm_grace_period) {
- gf_log (GF_NLM, GF_LOG_WARNING, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_test_reply (cs, stat, NULL);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh,
- NULL, nlm4_test_resume);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to resolve and resume");
- nlm4_test_reply (cs, stat, NULL);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
-rpcerr:
- if (ret < 0)
- nfs3_call_state_wipe (cs);
-
- return ret;
-}
-
-int
-nlm4svc_send_granted_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- STACK_DESTROY (((call_frame_t*)myframe)->root);
- return 0;
-}
-
-int nlm_rpcclnt_notify (struct rpc_clnt *rpc, void *mydata,
- rpc_clnt_event_t fn, void *data)
-{
- nlm_condmutex_t *cm = NULL;
- int ret;
- cm = mydata;
- switch (fn) {
- case RPC_CLNT_CONNECT:
- ret = pthread_cond_broadcast (&cm->cond);
- if (ret!=0)
- gf_log (GF_NLM, GF_LOG_ERROR, "cond_broadcast error %s",
- strerror (errno));
- break;
- case RPC_CLNT_MSG:
- break;
- case RPC_CLNT_DISCONNECT:
- nlm_unset_rpc_clnt(rpc);
- break;
- }
- return 0;
-}
-
-void
-nlm4svc_send_granted (nfs3_call_state_t *cs);
-
-void *
-nlm4_establish_callback (void *csarg)
-{
- nfs3_call_state_t *cs = NULL;
- struct sockaddr_storage sa;
- struct sockaddr *sockaddr = NULL;
- dict_t *options = NULL;
- char peerip[INET6_ADDRSTRLEN+1], *portstr = NULL;
- rpc_clnt_t *rpc_clnt = NULL;
- int port = -1;
- int ret = -1;
- char *caller_name = NULL;
-
- cs = (nfs3_call_state_t *) csarg;
- glusterfs_this_set (cs->nfsx);
-
- caller_name = cs->args.nlm4_lockargs.alock.caller_name;
-
- rpc_transport_get_peeraddr (cs->trans, NULL, 0, &sa, sizeof (sa));
- sockaddr = (struct sockaddr*) &sa;
- switch (sockaddr->sa_family) {
- case AF_INET6:
- /* can not come here as NLM listens on IPv4 */
- gf_log (GF_NLM, GF_LOG_ERROR, "NLM is not supported on IPv6 in"
- " this release");
- goto err;
-/*
- inet_ntop (AF_INET6,
- &((struct sockaddr_in6 *)sockaddr)->sin6_addr,
- peerip, INET6_ADDRSTRLEN+1);
- break;
-*/
- case AF_INET:
- inet_ntop (AF_INET,
- &((struct sockaddr_in *)sockaddr)->sin_addr,
- peerip, INET6_ADDRSTRLEN+1);
- break;
- default:
- break;
- /* FIXME: handle the error */
- }
-
- /* looks like libc rpc supports only ipv4 */
- port = pmap_getport ((struct sockaddr_in*)sockaddr, NLM_PROGRAM,
- NLM_V4, IPPROTO_TCP);
-
- if (port == 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Unable to get NLM port of the "
- "client. Is the firewall running on client?");
- goto err;
- }
-
- options = dict_new();
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- ret = dict_set_dynstr (options, "remote-host", gf_strdup (peerip));
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- ret = gf_asprintf (&portstr, "%d", port);
- if (ret == -1)
- goto err;
-
- ret = dict_set_dynstr (options, "remote-port",
- portstr);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_dynstr error");
- goto err;
- }
- ret = dict_set_str (options, "auth-null", "on");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_dynstr error");
- goto err;
- }
-
- /* TODO: is 32 frames in transit enough ? */
- rpc_clnt = rpc_clnt_new (options, cs->nfsx->ctx, "NLM-client", 32);
- if (rpc_clnt == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "rpc_clnt NULL");
- goto err;
- }
- nlm_condmutex_t *cm;
- cm = GF_CALLOC (1, sizeof(*cm), gf_nfs_mt_nlm4_cm);
- pthread_mutex_init (&cm->mutex, NULL);
- pthread_cond_init (&cm->cond, NULL);
- ret = rpc_clnt_register_notify (rpc_clnt, nlm_rpcclnt_notify,
- cm);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR,"rpc_clnt_register_connect error");
- goto err;
- }
- ret = rpc_transport_connect (rpc_clnt->conn.trans, port);
- pthread_cond_wait (&cm->cond, &cm->mutex);
- pthread_mutex_destroy (&cm->mutex);
- GF_FREE (cm);
- rpc_clnt_set_connected (&rpc_clnt->conn);
- ret = nlm_set_rpc_clnt (rpc_clnt, caller_name);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_ptr error");
- goto err;
- }
- nlm4svc_send_granted (cs);
-err:
- if (rpc_clnt) {
- rpc_clnt_unref (rpc_clnt);
- }
- return NULL;
-}
-
-void
-nlm4svc_send_granted (nfs3_call_state_t *cs)
-{
- int ret = -1;
- rpc_clnt_t *rpc_clnt = NULL;
- struct iovec outmsg = {0, };
- nlm4_testargs testargs;
- struct iobuf *iobuf = NULL;
- struct iobref *iobref = NULL;
- char peerip[INET6_ADDRSTRLEN+1];
- pthread_t thr;
- struct sockaddr_storage sa;
- struct sockaddr *sockaddr = NULL;
-
-
- rpc_transport_get_peeraddr (cs->trans, NULL, 0, &sa, sizeof (sa));
- sockaddr = (struct sockaddr*) &sa;
- switch (sockaddr->sa_family) {
- case AF_INET6:
- inet_ntop (AF_INET6,
- &((struct sockaddr_in6 *)sockaddr)->sin6_addr,
- peerip, INET6_ADDRSTRLEN+1);
- break;
- case AF_INET:
- inet_ntop (AF_INET,
- &((struct sockaddr_in *)sockaddr)->sin_addr,
- peerip, INET6_ADDRSTRLEN+1);
- default:
- break;
- /* FIXME: handle the error */
- }
-
- rpc_clnt = nlm_get_rpc_clnt (cs->args.nlm4_lockargs.alock.caller_name);
- if (rpc_clnt == NULL) {
- pthread_create (&thr, NULL, nlm4_establish_callback, (void*)cs);
- return;
- }
-
- testargs.cookie = cs->args.nlm4_lockargs.cookie;
- testargs.exclusive = cs->args.nlm4_lockargs.exclusive;
- testargs.alock = cs->args.nlm4_lockargs.alock;
-
- iobuf = iobuf_get (cs->nfs3state->iobpool);
- if (!iobuf) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to get iobuf");
- goto ret;
- }
-
- iobuf_to_iovec (iobuf, &outmsg);
- /* Use the given serializer to translate the give C structure in arg
- * to XDR format which will be written into the buffer in outmsg.
- */
- outmsg.iov_len = xdr_serialize_nlm4_testargs (outmsg, &testargs);
-
- iobref = iobref_new ();
- if (iobref == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Failed to get iobref");
- goto ret;
- }
-
- iobref_add (iobref, iobuf);
-
- ret = rpc_clnt_submit (rpc_clnt, &nlm4clntprog, NLM4_GRANTED,
- nlm4svc_send_granted_cbk,
- &outmsg, 1,
- NULL,
- 0, iobref, cs->frame, NULL, 0,
- NULL, 0, NULL);
-
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "rpc_clnt_submit error");
- goto ret;
- }
-ret:
- if (iobref)
- iobref_unref (iobref);
- if (iobuf)
- iobuf_unref (iobuf);
-
- rpc_clnt_unref (rpc_clnt);
- nfs3_call_state_wipe (cs);
- return;
-}
-
-int
-nlm_cleanup_fds (char *caller_name)
-{
- int nlmclnt_found = 0;
- nlm_fde_t *fde = NULL, *tmp = NULL;
- nlm_client_t *nlmclnt = NULL;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt,
- &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
-
- if (!nlmclnt_found)
- goto ret;
-
- if (list_empty (&nlmclnt->fdes))
- goto ret;
-
- list_for_each_entry_safe (fde, tmp, &nlmclnt->fdes, fde_list) {
- fd_unref (fde->fd);
- list_del (&fde->fde_list);
- GF_FREE (fde);
- }
-
-ret:
- UNLOCK (&nlm_client_list_lk);
- return 0;
-}
-
-void
-nlm_search_and_delete (fd_t *fd, char *caller_name)
-{
- nlm_fde_t *fde = NULL;
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- int fde_found = 0;
- int transit_cnt = 0;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt,
- &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
-
- if (!nlmclnt_found)
- goto ret;
-
- list_for_each_entry (fde, &nlmclnt->fdes, fde_list) {
- if (fde->fd == fd) {
- fde_found = 1;
- break;
- }
- }
-
- if (!fde_found)
- goto ret;
- transit_cnt = fde->transit_cnt;
- if (transit_cnt)
- goto ret;
- list_del (&fde->fde_list);
-
-ret:
- UNLOCK (&nlm_client_list_lk);
-
- if (fde_found && !transit_cnt) {
- fd_unref (fde->fd);
- GF_FREE (fde);
- }
- return;
-}
-
-int
-nlm_dec_transit_count (fd_t *fd, char *caller_name)
-{
- nlm_fde_t *fde = NULL;
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- int fde_found = 0;
- int transit_cnt = -1;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt,
- &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
-
- if (!nlmclnt_found) {
- gf_log (GF_NLM, GF_LOG_ERROR, "nlmclnt not found");
- nlmclnt = NULL;
- goto ret;
- }
-
- list_for_each_entry (fde, &nlmclnt->fdes, fde_list) {
- if (fde->fd == fd) {
- fde_found = 1;
- break;
- }
- }
-
- if (fde_found) {
- transit_cnt = --fde->transit_cnt;
- goto ret;
- }
-ret:
-
- UNLOCK (&nlm_client_list_lk);
- return transit_cnt;
-}
-
-
-nlm_client_t *
-nlm_search_and_add (fd_t *fd, char *caller_name)
-{
- nlm_fde_t *fde = NULL;
- nlm_client_t *nlmclnt = NULL;
- int nlmclnt_found = 0;
- int fde_found = 0;
-
- LOCK (&nlm_client_list_lk);
- list_for_each_entry (nlmclnt,
- &nlm_client_list, nlm_clients) {
- if (!strcmp(caller_name, nlmclnt->caller_name)) {
- nlmclnt_found = 1;
- break;
- }
- }
-
- if (!nlmclnt_found) {
- gf_log (GF_NLM, GF_LOG_ERROR, "nlmclnt not found");
- nlmclnt = NULL;
- goto ret;
- }
-
- list_for_each_entry (fde, &nlmclnt->fdes, fde_list) {
- if (fde->fd == fd) {
- fde_found = 1;
- break;
- }
- }
-
- if (fde_found)
- goto ret;
-
- fde = GF_CALLOC (1, sizeof (*fde), gf_nfs_mt_nlm4_fde);
-
- fde->fd = fd_ref (fd);
- list_add (&fde->fde_list, &nlmclnt->fdes);
-ret:
- if (nlmclnt_found && fde)
- fde->transit_cnt++;
- UNLOCK (&nlm_client_list_lk);
- return nlmclnt;
-}
-
-int
-nlm4svc_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
-{
- nlm4_stats stat = nlm4_denied;
- int transit_cnt = -1;
- char *caller_name = NULL;
- nfs3_call_state_t *cs = NULL;
- pthread_t thr;
-
- cs = frame->local;
- caller_name = cs->args.nlm4_lockargs.alock.caller_name;
- transit_cnt = nlm_dec_transit_count (cs->fd,
- caller_name);
- if (op_ret == -1) {
- if (transit_cnt == 0)
- nlm_search_and_delete (cs->fd,
- caller_name);
- stat = nlm4_errno_to_nlm4stat (op_errno);
- goto err;
- } else {
- stat = nlm4_granted;
- if (cs->monitor && !nlm_monitor (caller_name)) {
- /* FIXME: handle nsm_monitor failure */
- pthread_create (&thr, NULL, nsm_monitor, (void*)caller_name);
- }
- }
-
-err:
- if (cs->args.nlm4_lockargs.block) {
- cs->frame = copy_frame (frame);
- nlm4svc_send_granted (cs);
- } else {
- nlm4_generic_reply (cs->req, cs->args.nlm4_lockargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- }
- return 0;
-}
-
-int
-nlm4_lock_fd_resume (void *carg)
-{
- nlm4_stats stat = nlm4_denied;
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- struct gf_flock flock = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nlm4_check_fh_resolve_status (cs, stat, nlm4err);
- (void) nlm_search_and_add (cs->fd,
- cs->args.nlm4_lockargs.alock.caller_name);
- nfs_request_user_init (&nfu, cs->req);
- nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_lockargs.alock,
- cs->args.nlm4_lockargs.exclusive);
- nlm_copy_lkowner (&nfu.lk_owner, &cs->args.nlm4_lockargs.alock.oh);
- if (cs->args.nlm4_lockargs.block) {
- nlm4_generic_reply (cs->req, cs->args.nlm4_lockargs.cookie,
- nlm4_blocked);
- ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLKW,
- &flock, nlm4svc_lock_cbk, cs);
- /* FIXME: handle error from nfs_lk() specially by just
- * cleaning up cs and unblock the client lock request.
- */
- ret = 0;
- } else
- ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLK,
- &flock, nlm4svc_lock_cbk, cs);
-
-nlm4err:
- if (ret < 0) {
- stat = nlm4_errno_to_nlm4stat (-ret);
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to call lk()");
- nlm4_generic_reply (cs->req, cs->args.nlm4_lockargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-
-int
-nlm4_lock_resume (void *carg)
-{
- nlm4_stats stat = nlm4_failed;
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nlm4_check_fh_resolve_status (cs, stat, nlm4err);
- ret = nlm4_file_open_and_resume (cs, nlm4_lock_fd_resume);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to open and resume");
- stat = nlm4_errno_to_nlm4stat (-ret);
- nlm4_generic_reply (cs->req, cs->args.nlm4_lockargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nlm4svc_lock_common (rpcsvc_request_t *req, int mon)
-{
- int ret = RPCSVC_ACTOR_ERROR;
- nlm4_stats stat = nlm4_failed;
- struct nfs3_fh fh = {{0}, };
- xlator_t *vol = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- struct nfs_state *nfs = NULL;
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_nlm4_lockargs (&cs->args.nlm4_lockargs, &cs->lockfh,
- &cs->lkowner, cs->cookiebytes);
- if (xdr_to_nlm4_lockargs(req->msg[0], &cs->args.nlm4_lockargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- fh = cs->lockfh;
- cs->monitor = mon;
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req, vol, stat, nlm4err);
-
- if (nlm_grace_period && !cs->args.nlm4_lockargs.reclaim) {
- gf_log (GF_NLM, GF_LOG_WARNING, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_generic_reply (req, cs->args.nlm4_unlockargs.cookie, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- cs->trans = rpcsvc_request_transport_ref(req);
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nlm_add_nlmclnt (cs->args.nlm4_lockargs.alock.caller_name);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh,
- NULL, nlm4_lock_resume);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to resolve and resume");
- nlm4_generic_reply (cs->req, cs->args.nlm4_lockargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
-rpcerr:
- if (ret < 0) {
- nfs3_call_state_wipe (cs);
- }
-
- return ret;
-}
-
-int
-nlm4svc_lock (rpcsvc_request_t *req)
-{
- return nlm4svc_lock_common (req, 1);
-}
-
-int
-nlm4svc_nm_lock (rpcsvc_request_t *req)
-{
- return nlm4svc_lock_common (req, 0);
-}
-
-int
-nlm4svc_cancel_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
-{
- nlm4_stats stat = nlm4_denied;
- nfs3_call_state_t *cs = NULL;
-
- cs = frame->local;
- if (op_ret == -1) {
- stat = nlm4_errno_to_nlm4stat (op_errno);
- goto err;
- } else
- stat = nlm4_granted;
-
-err:
- nlm4_generic_reply (cs->req, cs->args.nlm4_cancargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-int
-nlm4_cancel_fd_resume (void *carg)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- struct gf_flock flock = {0, };
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nfs_request_user_init (&nfu, cs->req);
- nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_cancargs.alock,
- cs->args.nlm4_cancargs.exclusive);
- nlm_copy_lkowner (&nfu.lk_owner, &cs->args.nlm4_cancargs.alock.oh);
- flock.l_type = F_UNLCK;
- ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLK,
- &flock, nlm4svc_cancel_cbk, cs);
-
- return ret;
-}
-
-int
-nlm4_cancel_resume (void *carg)
-{
- nlm4_stats stat = nlm4_failed;
- int ret = -EFAULT;
- nfs3_call_state_t *cs = NULL;
- nlm_client_t *nlmclnt = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nlm4_check_fh_resolve_status (cs, stat, nlm4err);
-
- nlmclnt = nlm_get_uniq (cs->args.nlm4_cancargs.alock.caller_name);
- if (nlmclnt == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "nlm_get_uniq() returned NULL");
- goto nlm4err;
- }
- cs->fd = fd_lookup_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt);
- if (cs->fd == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "fd_lookup_uint64 retrned NULL");
- goto nlm4err;
- }
- ret = nlm4_cancel_fd_resume (cs);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_WARNING, "unable to unlock_fd_resume()");
- stat = nlm4_errno_to_nlm4stat (-ret);
- nlm4_generic_reply (cs->req, cs->args.nlm4_cancargs.cookie,
- stat);
-
- nfs3_call_state_wipe (cs);
- }
- /* clean up is taken care of */
- return 0;
-}
-
-int
-nlm4svc_cancel (rpcsvc_request_t *req)
-{
- xlator_t *vol = NULL;
- nlm4_stats stat = nlm4_failed;
- struct nfs_state *nfs = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- int ret = RPCSVC_ACTOR_ERROR;
- struct nfs3_fh fh = {{0}, };
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_nlm4_cancargs (&cs->args.nlm4_cancargs, &fh, &cs->lkowner,
- cs->cookiebytes);
- if (xdr_to_nlm4_cancelargs(req->msg[0], &cs->args.nlm4_cancargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req, vol, stat, nlm4err);
-
- if (nlm_grace_period) {
- gf_log (GF_NLM, GF_LOG_WARNING, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_generic_reply (req, cs->args.nlm4_unlockargs.cookie, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh,
- NULL, nlm4_cancel_resume);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to resolve and resume");
- nlm4_generic_reply (cs->req, cs->args.nlm4_cancargs.cookie,
- stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
-rpcerr:
- if (ret < 0) {
- nfs3_call_state_wipe (cs);
- }
- return ret;
-}
-
-int
-nlm4svc_unlock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
-{
- nlm4_stats stat = nlm4_denied;
- nfs3_call_state_t *cs = NULL;
-
- cs = frame->local;
- if (op_ret == -1) {
- stat = nlm4_errno_to_nlm4stat (op_errno);
- goto err;
- } else {
- stat = nlm4_granted;
- if (flock->l_type == F_UNLCK)
- nlm_search_and_delete (cs->fd,
- cs->args.nlm4_unlockargs.alock.caller_name);
- }
-
-err:
- nlm4_generic_reply (cs->req, cs->args.nlm4_unlockargs.cookie, stat);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-int
-nlm4_unlock_fd_resume (void *carg)
-{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
- nfs3_call_state_t *cs = NULL;
- struct gf_flock flock = {0, };
-
- if (!carg)
- return ret;
- cs = (nfs3_call_state_t *)carg;
- nfs_request_user_init (&nfu, cs->req);
- nlm4_lock_to_gf_flock (&flock, &cs->args.nlm4_unlockargs.alock, 0);
- nlm_copy_lkowner (&nfu.lk_owner, &cs->args.nlm4_unlockargs.alock.oh);
- flock.l_type = F_UNLCK;
- ret = nfs_lk (cs->nfsx, cs->vol, &nfu, cs->fd, F_SETLK,
- &flock, nlm4svc_unlock_cbk, cs);
-
- return ret;
-}
-
-int
-nlm4_unlock_resume (void *carg)
-{
- nlm4_stats stat = nlm4_failed;
- int ret = -1;
- nfs3_call_state_t *cs = NULL;
- nlm_client_t *nlmclnt = NULL;
-
- if (!carg)
- return ret;
-
- cs = (nfs3_call_state_t *)carg;
- nlm4_check_fh_resolve_status (cs, stat, nlm4err);
-
- nlmclnt = nlm_get_uniq (cs->args.nlm4_unlockargs.alock.caller_name);
- if (nlmclnt == NULL) {
- stat = nlm4_granted;
- gf_log (GF_NLM, GF_LOG_WARNING, "nlm_get_uniq() returned NULL");
- goto nlm4err;
- }
- cs->fd = fd_lookup_uint64 (cs->resolvedloc.inode, (uint64_t)nlmclnt);
- if (cs->fd == NULL) {
- stat = nlm4_granted;
- gf_log (GF_NLM, GF_LOG_WARNING, "fd_lookup_uint64() returned "
- "NULL");
- goto nlm4err;
- }
- ret = nlm4_unlock_fd_resume (cs);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_WARNING, "unable to unlock_fd_resume");
- stat = nlm4_errno_to_nlm4stat (-ret);
- nlm4_generic_reply (cs->req, cs->args.nlm4_unlockargs.cookie,
- stat);
-
- nfs3_call_state_wipe (cs);
- }
- /* we have already taken care of cleanup */
- return 0;
-}
-
-int
-nlm4svc_unlock (rpcsvc_request_t *req)
-{
- xlator_t *vol = NULL;
- nlm4_stats stat = nlm4_failed;
- struct nfs_state *nfs = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- int ret = RPCSVC_ACTOR_ERROR;
- struct nfs3_fh fh = {{0}, };
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_nlm4_unlockargs (&cs->args.nlm4_unlockargs, &fh, &cs->lkowner,
- cs->cookiebytes);
- if (xdr_to_nlm4_unlockargs(req->msg[0], &cs->args.nlm4_unlockargs) <= 0)
- {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req, vol, stat, nlm4err);
-
- if (nlm_grace_period) {
- gf_log (GF_NLM, GF_LOG_WARNING, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_generic_reply (req, cs->args.nlm4_unlockargs.cookie, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- /* FIXME: check if trans is being used at all for unlock */
- cs->trans = rpcsvc_request_transport_ref(req);
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh,
- NULL, nlm4_unlock_resume);
-
-nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to resolve and resume");
- nlm4_generic_reply (req, cs->args.nlm4_unlockargs.cookie, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
-rpcerr:
- if (ret < 0) {
- nfs3_call_state_wipe (cs);
- }
- return ret;
-}
-
-int
-nlm4_share_reply (nfs3_call_state_t *cs, nlm4_stats stat)
-{
- nlm4_shareres res = {{0}, 0, 0};
-
- if (!cs)
- return -1;
-
- res.cookie = cs->args.nlm4_shareargs.cookie;
- res.stat = stat;
- res.sequence = 0;
-
- nlm4svc_submit_reply (cs->req, (void *)&res,
- (nlm4_serializer)xdr_serialize_nlm4_shareres);
- return 0;
-}
-
-nlm_share_t *
-nlm4_share_new ()
-{
- nlm_share_t *share = NULL;
-
- share = GF_CALLOC (1, sizeof (nlm_share_t),
- gf_nfs_mt_nlm4_share);
- if (!share)
- goto out;
-
- INIT_LIST_HEAD (&share->client_list);
- INIT_LIST_HEAD (&share->inode_list);
- out:
- return share;
-}
-
-int
-nlm4_add_share_to_inode (nlm_share_t *share)
-{
- int ret = -1;
- uint64_t ctx = 0;
- struct list_head *head = NULL;
- xlator_t *this = NULL;
- inode_t *inode = NULL;
-
- this = THIS;
- inode = share->inode;
- ret = inode_ctx_get (inode, this, &ctx);
-
- head = (struct list_head *)ctx;
-
- if (ret || !head) {
- head = GF_CALLOC (1, sizeof (struct list_head),
- gf_common_mt_list_head);
- if (!head ) {
- ret = -1;
- goto out;
- }
-
- INIT_LIST_HEAD (head);
- ret = inode_ctx_put (inode, this, (uint64_t)head);
- if (ret)
- goto out;
- }
-
- list_add (&share->inode_list, head);
-
- out:
- if (ret && head)
- GF_FREE (head);
-
- return ret;
-}
-
-int
-nlm4_approve_share_reservation (nfs3_call_state_t *cs)
-{
- int ret = -1;
- uint64_t ctx = 0;
- fsh_mode req_mode = 0;
- fsh_access req_access = 0;
- inode_t *inode = NULL;
- nlm_share_t *share = NULL;
- struct list_head *head = NULL;
-
- if (!cs)
- goto out;
-
- inode = cs->resolvedloc.inode;
-
- ret = inode_ctx_get (inode, THIS, &ctx);
- if (ret) {
- ret = 0;
- goto out;
- }
-
- head = (struct list_head *)ctx;
- if (!head || list_empty (head))
- goto out;
-
- req_mode = cs->args.nlm4_shareargs.share.mode;
- req_access = cs->args.nlm4_shareargs.share.access;
-
- list_for_each_entry (share, head, inode_list) {
- ret = (((req_mode & share->access) == 0) &&
- ((req_access & share->mode) == 0));
- if (!ret) {
- ret = -1;
- goto out;
- }
- }
- ret = 0;
-
- out:
- return ret;
-}
-
-int
-nlm4_create_share_reservation (nfs3_call_state_t *cs)
-{
- int ret = -1;
- nlm_share_t *share = NULL;
- nlm_client_t *client = NULL;
- inode_t *inode = NULL;
-
- LOCK (&nlm_client_list_lk);
-
- inode = inode_ref (cs->resolvedloc.inode);
- if (!inode) {
- gf_log (GF_NLM, GF_LOG_ERROR, "inode not found");
- goto out;
- }
-
- client = __nlm_get_uniq (cs->args.nlm4_shareargs.share.caller_name);
- if (!client) {
- /* DO NOT add client. the client is supposed
- to be here, since nlm4svc_share adds it */
- gf_log (GF_NLM, GF_LOG_ERROR, "client not found");
- goto out;
- }
-
- ret = nlm4_approve_share_reservation (cs);
- if (ret)
- goto out;
-
- share = nlm4_share_new ();
- if (!share) {
- ret = -1;
- goto out;
- }
-
- share->inode = inode;
- share->mode = cs->args.nlm4_shareargs.share.mode;
- share->access = cs->args.nlm4_shareargs.share.access;
- nlm_copy_lkowner (&share->lkowner,
- &cs->args.nlm4_shareargs.share.oh);
-
- ret = nlm4_add_share_to_inode (share);
- if (ret)
- goto out;
-
- list_add (&share->client_list, &client->shares);
-
- out:
- if (ret && inode) {
- inode_unref (inode);
- GF_FREE (share);
- }
-
- UNLOCK (&nlm_client_list_lk);
- return ret;
-}
-
-/*
- SHARE and UNSHARE calls DO NOT perform STACK_WIND,
- the (non-monitored) share reservations are maintained
- at *nfs xlator level only*, in memory
-*/
-int
-nlm4_share_resume (void *call_state)
-{
- int ret = -1;
- nlm4_stats stat = nlm4_failed;
- nfs3_call_state_t *cs = NULL;
-
- if (!call_state)
- return ret;
-
- cs = (nfs3_call_state_t *)call_state;
- nlm4_check_fh_resolve_status (cs, stat, out);
-
- ret = nlm4_create_share_reservation (cs);
- if (!ret)
- stat = nlm4_granted;
-
- out:
- nlm4_share_reply (cs, stat);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-int
-nlm4svc_share (rpcsvc_request_t *req)
-{
- nlm4_stats stat = nlm4_failed;
- xlator_t *vol = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- struct nfs_state *nfs = NULL;
- struct nfs3_fh fh = {{0}, };
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_shareargs (&cs->args.nlm4_shareargs, &cs->lockfh,
- &cs->lkowner, cs->cookiebytes);
-
- if (xdr_to_nlm4_shareargs (req->msg[0],
- &cs->args.nlm4_shareargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding SHARE args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- fh = cs->lockfh;
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req,
- vol, stat, nlm4err);
-
- if (nlm_grace_period && !cs->args.nlm4_shareargs.reclaim) {
- gf_log (GF_NLM, GF_LOG_DEBUG, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_share_reply (cs, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- cs->trans = rpcsvc_request_transport_ref(req);
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nlm_add_nlmclnt (cs->args.nlm4_shareargs.share.caller_name);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh, NULL, nlm4_share_resume);
-
- nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "SHARE call failed");
- nlm4_share_reply (cs, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- rpcerr:
- if (ret < 0)
- nfs3_call_state_wipe (cs);
-
- return ret;
-}
-
-int
-nlm4_remove_share_reservation (nfs3_call_state_t *cs)
-{
- int ret = -1;
- uint64_t ctx = 0;
- fsh_mode req_mode = 0;
- fsh_access req_access = 0;
- nlm_share_t *share = NULL;
- nlm_share_t *tmp = NULL;
- nlm_client_t *client = NULL;
- char *caller = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
- struct list_head *head = NULL;
- nlm4_shareargs *args = NULL;
-
- LOCK (&nlm_client_list_lk);
-
- args = &cs->args.nlm4_shareargs;
- caller = args->share.caller_name;
-
- client = __nlm_get_uniq (caller);
- if (!client) {
- gf_log (GF_NLM, GF_LOG_ERROR,
- "client not found: %s", caller);
- goto out;
- }
-
- inode = cs->resolvedloc.inode;
- if (!inode) {
- gf_log (GF_NLM, GF_LOG_ERROR,
- "inode not found: client: %s", caller);
- goto out;
- }
-
- this = THIS;
- ret = inode_ctx_get (inode, this, &ctx);
- if (ret) {
- gf_log (GF_NLM, GF_LOG_ERROR,
- "no shares found for inode:"
- "gfid: %s; client: %s",
- inode->gfid, caller);
- goto out;
- }
-
- head = (struct list_head *)ctx;
- if (list_empty (head)) {
- ret = -1;
- goto out;
- }
-
- ret = 0;
- req_mode = args->share.mode;
- req_access = args->share.access;
-
- list_for_each_entry_safe (share, tmp, head, inode_list) {
- ret = ((req_mode == share->mode) &&
- (req_access == share->access) &&
- nlm_is_oh_same_lkowner (&share->lkowner, &args->share.oh));
- if (ret) {
- list_del (&share->client_list);
- list_del (&share->inode_list);
- inode_unref (share->inode);
- GF_FREE (share);
- break;
- }
- }
-
- ret = 0;
- out:
- UNLOCK (&nlm_client_list_lk);
- return ret;
-
-}
-
-int
-nlm4_unshare_resume (void *call_state)
-{
- int ret = -1;
- nlm4_stats stat = nlm4_failed;
- nfs3_call_state_t *cs = NULL;
-
- if (!call_state)
- return ret;
-
- cs = (nfs3_call_state_t *)call_state;
-
- nlm4_check_fh_resolve_status (cs, stat, out);
- ret = nlm4_remove_share_reservation (cs);
- if (!ret)
- stat = nlm4_granted;
-
- out:
- nlm4_share_reply (cs, stat);
- nfs3_call_state_wipe (cs);
- return 0;
-}
-
-int
-nlm4svc_unshare (rpcsvc_request_t *req)
-{
- nlm4_stats stat = nlm4_failed;
- xlator_t *vol = NULL;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- struct nfs_state *nfs = NULL;
- struct nfs3_fh fh = {{0}, };
- int ret = RPCSVC_ACTOR_ERROR;
-
- if (!req)
- return ret;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, rpcerr, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs, req,
- stat, rpcerr);
-
- nlm4_prep_shareargs (&cs->args.nlm4_shareargs, &cs->lockfh,
- &cs->lkowner, cs->cookiebytes);
-
- if (xdr_to_nlm4_shareargs (req->msg[0],
- &cs->args.nlm4_shareargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding UNSHARE args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto rpcerr;
- }
-
- fh = cs->lockfh;
- nlm4_validate_gluster_fh (&fh, stat, nlm4err);
- nlm4_map_fh_to_volume (cs->nfs3state, fh, req,
- vol, stat, nlm4err);
-
- if (nlm_grace_period && !cs->args.nlm4_shareargs.reclaim) {
- gf_log (GF_NLM, GF_LOG_DEBUG, "NLM in grace period");
- stat = nlm4_denied_grace_period;
- nlm4_share_reply (cs, stat);
- nfs3_call_state_wipe (cs);
- return 0;
- }
-
- cs->vol = vol;
- cs->trans = rpcsvc_request_transport_ref(req);
- nlm4_volume_started_check (nfs3, vol, ret, rpcerr);
-
- ret = nfs3_fh_resolve_and_resume (cs, &fh, NULL,
- nlm4_unshare_resume);
-
- nlm4err:
- if (ret < 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "UNSHARE call failed");
- nlm4_share_reply (cs, stat);
- ret = 0;
- return 0;
- }
-
- rpcerr:
- if (ret < 0)
- nfs3_call_state_wipe (cs);
-
- return ret;
-}
-
-int
-nlm4_free_all_shares (char *caller_name)
-{
- nlm_share_t *share = NULL;
- nlm_share_t *tmp = NULL;
- nlm_client_t *client = NULL;
-
- LOCK (&nlm_client_list_lk);
-
- client = __nlm_get_uniq (caller_name);
- if (!client) {
- gf_log (GF_NLM, GF_LOG_DEBUG,
- "client not found: %s", caller_name);
- goto out;
- }
-
- list_for_each_entry_safe (share, tmp, &client->shares, client_list) {
- list_del (&share->inode_list);
- list_del (&share->client_list);
- inode_unref (share->inode);
- GF_FREE (share);
- }
- out:
- UNLOCK (&nlm_client_list_lk);
- return 0;
-}
-
-int
-nlm4svc_free_all (rpcsvc_request_t *req)
-{
- int ret = RPCSVC_ACTOR_ERROR;
- nlm4_stats stat = nlm4_failed;
- nfs3_state_t *nfs3 = NULL;
- nfs3_call_state_t *cs = NULL;
- struct nfs_state *nfs = NULL;
-
- nlm4_validate_nfs3_state (req, nfs3, stat, err, ret);
- nfs = nfs_state (nfs3->nfsx);
- nlm4_handle_call_state_init (nfs->nfs3state, cs,
- req, stat, err);
-
- nlm4_prep_freeallargs (&cs->args.nlm4_freeallargs,
- &cs->lkowner);
-
- if (xdr_to_nlm4_freeallargs (req->msg[0],
- &cs->args.nlm4_freeallargs) <= 0) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Error decoding FREE_ALL args");
- rpcsvc_request_seterr (req, GARBAGE_ARGS);
- goto err;
- }
-
- ret = nlm4_free_all_shares (cs->args.nlm4_freeallargs.name);
- if (ret)
- goto err;
-
- ret = nlm_cleanup_fds (cs->args.nlm4_freeallargs.name);
- if (ret)
- goto err;
-
- err:
- nfs3_call_state_wipe (cs);
- if (ret)
- gf_log (GF_NLM, GF_LOG_DEBUG,
- "error in free all; stat: %d", stat);
- return ret;
-
-}
-
-void
-nlm4svc_sm_notify (struct nlm_sm_status *status)
-{
- gf_log (GF_NLM, GF_LOG_INFO, "sm_notify: %s, state: %d",
- status->mon_name,
- status->state);
- nlm_cleanup_fds (status->mon_name);
-}
-
-rpcsvc_actor_t nlm4svc_actors[NLM4_PROC_COUNT] = {
- /* 0 */
- {"NULL", NLM4_NULL, nlm4svc_null, NULL, NULL},
- {"TEST", NLM4_TEST, nlm4svc_test, NULL, NULL},
- {"LOCK", NLM4_LOCK, nlm4svc_lock, NULL, NULL},
- {"CANCEL", NLM4_CANCEL, nlm4svc_cancel, NULL, NULL},
- {"UNLOCK", NLM4_UNLOCK, nlm4svc_unlock, NULL, NULL},
- /* 5 */
- {"GRANTED", NLM4_GRANTED, NULL, NULL, NULL},
- {"TEST", NLM4_TEST_MSG, NULL, NULL, NULL},
- {"LOCK", NLM4_LOCK_MSG, NULL, NULL, NULL},
- {"CANCEL", NLM4_CANCEL_MSG, NULL, NULL, NULL},
- {"UNLOCK", NLM4_UNLOCK_MSG, NULL, NULL, NULL},
- /* 10 */
- {"GRANTED", NLM4_GRANTED_MSG, NULL, NULL, NULL},
- {"TEST", NLM4_TEST_RES, NULL, NULL, NULL},
- {"LOCK", NLM4_LOCK_RES, NULL, NULL, NULL},
- {"CANCEL", NLM4_CANCEL_RES, NULL, NULL, NULL},
- {"UNLOCK", NLM4_UNLOCK_RES, NULL, NULL, NULL},
- /* 15 ; procedures 17,18,19 are not defined by nlm */
- {"GRANTED", NLM4_GRANTED_RES, NULL, NULL, NULL},
- {"SM_NOTIFY", NLM4_SM_NOTIFY, NULL, NULL, NULL},
- {"SEVENTEEN", NLM4_SEVENTEEN, NULL, NULL, NULL},
- {"EIGHTEEN", NLM4_EIGHTEEN, NULL, NULL, NULL},
- {"NINETEEN", NLM4_NINETEEN, NULL, NULL, NULL},
- /* 20 */
- {"SHARE", NLM4_SHARE, nlm4svc_share, NULL, NULL},
- {"UNSHARE", NLM4_UNSHARE, nlm4svc_unshare, NULL, NULL},
- {"NM_LOCK", NLM4_NM_LOCK, nlm4svc_nm_lock, NULL, NULL},
- {"FREE_ALL", NLM4_FREE_ALL, nlm4svc_free_all, NULL, NULL},
-};
-
-rpcsvc_program_t nlm4prog = {
- .progname = "NLM4",
- .prognum = NLM_PROGRAM,
- .progver = NLM_V4,
- .progport = GF_NLM4_PORT,
- .actors = nlm4svc_actors,
- .numactors = NLM4_PROC_COUNT,
- .min_auth = AUTH_NULL,
-};
-
-
-int
-nlm4_init_state (xlator_t *nfsx)
-{
- return 0;
-}
-
-extern void *nsm_thread (void *argv);
-
-void nlm_grace_period_over(void *arg)
-{
- nlm_grace_period = 0;
-}
-
-rpcsvc_program_t *
-nlm4svc_init(xlator_t *nfsx)
-{
- struct nfs3_state *ns = NULL;
- struct nfs_state *nfs = NULL;
- dict_t *options = NULL;
- int ret = -1;
- char *portstr = NULL;
- pthread_t thr;
- struct timeval timeout = {0,};
- FILE *pidfile = NULL;
- pid_t pid = -1;
-
- nfs = (struct nfs_state*)nfsx->private;
-
- ns = nfs->nfs3state;
- if (!ns) {
- gf_log (GF_NLM, GF_LOG_ERROR, "NLM4 init failed");
- goto err;
- }
- nlm4prog.private = ns;
-
- options = dict_new ();
-
- ret = gf_asprintf (&portstr, "%d", GF_NLM4_PORT);
- if (ret == -1)
- goto err;
-
- ret = dict_set_dynstr (options, "transport.socket.listen-port",
- portstr);
- if (ret == -1)
- goto err;
- ret = dict_set_str (options, "transport-type", "socket");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- if (nfs->allow_insecure) {
- ret = dict_set_str (options, "rpc-auth-allow-insecure", "on");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- ret = dict_set_str (options, "rpc-auth.ports.insecure", "on");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
- }
-
- ret = dict_set_str (options, "transport.address-family", "inet");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "dict_set_str error");
- goto err;
- }
-
- rpcsvc_create_listeners (nfs->rpcsvc, options, "NLM");
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "Unable to create listeners");
- dict_unref (options);
- goto err;
- }
- INIT_LIST_HEAD(&nlm_client_list);
- LOCK_INIT (&nlm_client_list_lk);
-
- /* unlink sm-notify.pid so that when we restart rpc.statd/sm-notify
- * it thinks that the machine has restarted and sends NOTIFY to clients.
- */
- ret = unlink ("/var/run/sm-notify.pid");
- if (ret == -1 && errno != ENOENT) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to unlink sm-notify");
- goto err;
- }
- /* temporary work around to restart statd, not distro/OS independant.
- * Need to figure out a more graceful way
- * killall will cause problems on solaris.
- */
-
- pidfile = fopen ("/var/run/rpc.statd.pid", "r");
- if (pidfile) {
- ret = fscanf (pidfile, "%d", &pid);
- if (ret <= 0) {
- gf_log (GF_NLM, GF_LOG_WARNING, "unable to get pid of "
- "rpc.statd");
- ret = runcmd ("killall", "-9", "rpc.statd", NULL);
- } else
- kill (pid, SIGKILL);
-
- fclose (pidfile);
- } else {
- gf_log (GF_NLM, GF_LOG_WARNING, "opening the pid file of "
- "rpc.statd failed (%s)", strerror (errno));
- /* if ret == -1, do nothing - case either statd was not
- * running or was running in valgrind mode
- */
- ret = runcmd ("killall", "-9", "rpc.statd", NULL);
- }
-
- ret = unlink ("/var/run/rpc.statd.pid");
- if (ret == -1 && errno != ENOENT) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to unlink rpc.statd");
- goto err;
- }
-
- ret = runcmd ("/sbin/rpc.statd", NULL);
- if (ret == -1) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to start rpc.statd");
- goto err;
- }
- pthread_create (&thr, NULL, nsm_thread, (void*)NULL);
-
- timeout.tv_sec = nlm_grace_period;
- gf_timer_call_after (nfsx->ctx, timeout, nlm_grace_period_over, NULL);
- return &nlm4prog;
-err:
- return NULL;
-}
-
-int32_t
-nlm_priv (xlator_t *this)
-{
- int32_t ret = -1;
- uint32_t client_count = 0;
- uint64_t file_count = 0;
- nlm_client_t *client = NULL;
- nlm_fde_t *fde = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0};
- char gfid_str[64] = {0};
-
- gf_proc_dump_add_section("nfs.nlm");
-
- LOCK (&nlm_client_list_lk);
-
- list_for_each_entry (client, &nlm_client_list, nlm_clients) {
-
- gf_proc_dump_build_key (key, "client", "%d.hostname", client_count);
- gf_proc_dump_write (key, "%s\n", client->caller_name);
-
- file_count = 0;
- list_for_each_entry (fde, &client->fdes, fde_list) {
- gf_proc_dump_build_key (key, "file", "%ld.gfid", file_count);
- memset (gfid_str, 0, 64);
- uuid_utoa_r (fde->fd->inode->gfid, gfid_str);
- gf_proc_dump_write (key, "%s", gfid_str);
- file_count++;
- }
-
- gf_proc_dump_build_key (key, "client", "files-locked");
- gf_proc_dump_write (key, "%ld\n", file_count);
- client_count++;
- }
-
- gf_proc_dump_build_key (key, "nlm", "client-count");
- gf_proc_dump_write (key, "%d", client_count);
-
- UNLOCK (&nlm_client_list_lk);
- return ret;
-}
diff --git a/xlators/nfs/server/src/nlm4.h b/xlators/nfs/server/src/nlm4.h
deleted file mode 100644
index 0cc82f162..000000000
--- a/xlators/nfs/server/src/nlm4.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _NLM4_H_
-#define _NLM4_H_
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <signal.h>
-#include "rpcsvc.h"
-#include "dict.h"
-#include "xlator.h"
-#include "iobuf.h"
-#include "nfs.h"
-#include "list.h"
-#include "xdr-nfs3.h"
-#include "locking.h"
-#include "nfs3-fh.h"
-#include "uuid.h"
-#include "nlm4-xdr.h"
-#include "lkowner.h"
-
-/* Registered with portmap */
-#define GF_NLM4_PORT 38468
-#define GF_NLM GF_NFS"-NLM"
-
-extern rpcsvc_program_t *
-nlm4svc_init (xlator_t *nfsx);
-
-extern int
-nlm4_init_state (xlator_t *nfsx);
-
-#define NLM_PROGRAM 100021
-#define NLM_V4 4
-
-typedef struct nlm4_lwowner {
- char temp[1024];
-} nlm4_lkowner_t;
-
-typedef struct nlm_client {
- struct sockaddr_storage sa;
- pid_t uniq;
- struct list_head nlm_clients;
- struct list_head fdes;
- struct list_head shares;
- struct rpc_clnt *rpc_clnt;
- char *caller_name;
- int nsm_monitor;
-} nlm_client_t;
-
-typedef struct nlm_share {
- struct list_head client_list;
- struct list_head inode_list;
- gf_lkowner_t lkowner;
- inode_t *inode;
- fsh_mode mode;
- fsh_access access;
-} nlm_share_t;
-
-typedef struct nlm_fde {
- struct list_head fde_list;
- fd_t *fd;
- int transit_cnt;
-} nlm_fde_t;
-
-typedef struct {
- pthread_cond_t cond;
- pthread_mutex_t mutex;
-} nlm_condmutex_t;
-
-#endif
diff --git a/xlators/nfs/server/src/nlmcbk_svc.c b/xlators/nfs/server/src/nlmcbk_svc.c
deleted file mode 100644
index 5401dc39b..000000000
--- a/xlators/nfs/server/src/nlmcbk_svc.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- Copyright (c) 2012 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include "nlmcbk-xdr.h"
-#include "nlm4.h"
-#include "logging.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <rpc/pmap_clnt.h>
-#include <string.h>
-#include <memory.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#ifndef SIG_PF
-#define SIG_PF void(*)(int)
-#endif
-
-void
-nlm4svc_sm_notify (struct nlm_sm_status *status);
-
-void *nlmcbk_sm_notify_0_svc(struct nlm_sm_status *status, struct svc_req *req)
-{
- nlm4svc_sm_notify (status);
- return NULL;
-}
-
-static void
-nlmcbk_program_0(struct svc_req *rqstp, register SVCXPRT *transp)
-{
- union {
- struct nlm_sm_status nlmcbk_sm_notify_0_arg;
- } argument;
- char *result;
- xdrproc_t _xdr_argument, _xdr_result;
- char *(*local)(char *, struct svc_req *);
-
- switch (rqstp->rq_proc) {
- case NULLPROC:
- (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
- return;
-
- case NLMCBK_SM_NOTIFY:
- _xdr_argument = (xdrproc_t) xdr_nlm_sm_status;
- _xdr_result = (xdrproc_t) xdr_void;
- local = (char *(*)(char *, struct svc_req *)) nlmcbk_sm_notify_0_svc;
- break;
-
- default:
- svcerr_noproc (transp);
- return;
- }
- memset ((char *)&argument, 0, sizeof (argument));
- if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
- svcerr_decode (transp);
- return;
- }
- result = (*local)((char *)&argument, rqstp);
- if (!svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
- svcerr_systemerr (transp);
- }
-
- if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to free arguments");
- return;
- }
- return;
-}
-
-void *
-nsm_thread (void *argv)
-{
- register SVCXPRT *transp;
-
- pmap_unset (NLMCBK_PROGRAM, NLMCBK_V1);
-
- transp = svcudp_create(RPC_ANYSOCK);
- if (transp == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "cannot create udp service.");
- return NULL;
- }
- if (!svc_register(transp, NLMCBK_PROGRAM, NLMCBK_V1, nlmcbk_program_0, IPPROTO_UDP)) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to register (NLMCBK_PROGRAM, NLMCBK_V0, udp).");
- return NULL;
- }
-
- transp = svctcp_create(RPC_ANYSOCK, 0, 0);
- if (transp == NULL) {
- gf_log (GF_NLM, GF_LOG_ERROR, "cannot create tcp service.");
- return NULL;
- }
- if (!svc_register(transp, NLMCBK_PROGRAM, NLMCBK_V1, nlmcbk_program_0, IPPROTO_TCP)) {
- gf_log (GF_NLM, GF_LOG_ERROR, "unable to register (NLMCBK_PROGRAM, NLMCBK_V0, tcp).");
- return NULL;
- }
-
- svc_run ();
- gf_log (GF_NLM, GF_LOG_ERROR, "svc_run returned");
- return NULL;
- /* NOTREACHED */
-}
diff --git a/xlators/performance/Makefile.am b/xlators/performance/Makefile.am
index eb94d8d6a..e91d5f6ef 100644
--- a/xlators/performance/Makefile.am
+++ b/xlators/performance/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = write-behind read-ahead io-threads io-cache symlink-cache quick-read md-cache
+SUBDIRS = write-behind read-ahead io-threads io-cache symlink-cache quick-read stat-prefetch
CLEANFILES =
diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c
index 6062f9a68..a3ebaf47c 100644
--- a/xlators/performance/io-cache/src/io-cache.c
+++ b/xlators/performance/io-cache/src/io-cache.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -28,7 +37,8 @@ int ioc_log2_page_size;
uint32_t
ioc_get_priority (ioc_table_t *table, const char *path);
-struct volume_options options[];
+uint32_t
+ioc_get_priority (ioc_table_t *table, const char *path);
inline uint32_t
@@ -44,55 +54,50 @@ ioc_hashfn (void *data, int len)
inline ioc_inode_t *
ioc_inode_reupdate (ioc_inode_t *ioc_inode)
{
- ioc_table_t *table = NULL;
-
- table = ioc_inode->table;
+ ioc_table_t *table = ioc_inode->table;
- list_add_tail (&ioc_inode->inode_lru,
- &table->inode_lru[ioc_inode->weight]);
+ list_add_tail (&ioc_inode->inode_lru,
+ &table->inode_lru[ioc_inode->weight]);
- return ioc_inode;
+ return ioc_inode;
}
inline ioc_inode_t *
ioc_get_inode (dict_t *dict, char *name)
{
- ioc_inode_t *ioc_inode = NULL;
- data_t *ioc_inode_data = NULL;
- ioc_table_t *table = NULL;
-
- ioc_inode_data = dict_get (dict, name);
- if (ioc_inode_data) {
- ioc_inode = data_to_ptr (ioc_inode_data);
- table = ioc_inode->table;
-
- ioc_table_lock (table);
- {
- if (list_empty (&ioc_inode->inode_lru)) {
- ioc_inode = ioc_inode_reupdate (ioc_inode);
- }
- }
- ioc_table_unlock (table);
- }
-
- return ioc_inode;
+ ioc_inode_t *ioc_inode = NULL;
+ data_t *ioc_inode_data = dict_get (dict, name);
+ ioc_table_t *table = NULL;
+
+ if (ioc_inode_data) {
+ ioc_inode = data_to_ptr (ioc_inode_data);
+ table = ioc_inode->table;
+
+ ioc_table_lock (table);
+ {
+ if (list_empty (&ioc_inode->inode_lru)) {
+ ioc_inode = ioc_inode_reupdate (ioc_inode);
+ }
+ }
+ ioc_table_unlock (table);
+ }
+
+ return ioc_inode;
}
int32_t
ioc_inode_need_revalidate (ioc_inode_t *ioc_inode)
{
- int8_t need_revalidate = 0;
- struct timeval tv = {0,};
- ioc_table_t *table = NULL;
+ int8_t need_revalidate = 0;
+ struct timeval tv = {0,};
+ ioc_table_t *table = ioc_inode->table;
- table = ioc_inode->table;
-
- gettimeofday (&tv, NULL);
+ gettimeofday (&tv, NULL);
- if (time_elapsed (&tv, &ioc_inode->cache.tv) >= table->cache_timeout)
- need_revalidate = 1;
+ if (time_elapsed (&tv, &ioc_inode->cache.tv) >= table->cache_timeout)
+ need_revalidate = 1;
- return need_revalidate;
+ return need_revalidate;
}
/*
@@ -105,87 +110,86 @@ ioc_inode_need_revalidate (ioc_inode_t *ioc_inode)
int64_t
__ioc_inode_flush (ioc_inode_t *ioc_inode)
{
- ioc_page_t *curr = NULL, *next = NULL;
- int64_t destroy_size = 0;
- int64_t ret = 0;
+ ioc_page_t *curr = NULL, *next = NULL;
+ int64_t destroy_size = 0;
+ int64_t ret = 0;
- list_for_each_entry_safe (curr, next, &ioc_inode->cache.page_lru,
+ list_for_each_entry_safe (curr, next, &ioc_inode->cache.page_lru,
page_lru) {
- ret = __ioc_page_destroy (curr);
+ ret = ioc_page_destroy (curr);
- if (ret != -1)
- destroy_size += ret;
- }
+ if (ret != -1)
+ destroy_size += ret;
+ }
- return destroy_size;
+ return destroy_size;
}
void
ioc_inode_flush (ioc_inode_t *ioc_inode)
{
- int64_t destroy_size = 0;
-
- ioc_inode_lock (ioc_inode);
- {
- destroy_size = __ioc_inode_flush (ioc_inode);
- }
- ioc_inode_unlock (ioc_inode);
-
- if (destroy_size) {
- ioc_table_lock (ioc_inode->table);
- {
- ioc_inode->table->cache_used -= destroy_size;
- }
- ioc_table_unlock (ioc_inode->table);
- }
-
- return;
+ int64_t destroy_size = 0;
+
+ ioc_inode_lock (ioc_inode);
+ {
+ destroy_size = __ioc_inode_flush (ioc_inode);
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ if (destroy_size) {
+ ioc_table_lock (ioc_inode->table);
+ {
+ ioc_inode->table->cache_used -= destroy_size;
+ }
+ ioc_table_unlock (ioc_inode->table);
+ }
+
+ return;
}
int32_t
ioc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop,
- xdata);
- return 0;
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop);
+ return 0;
}
int32_t
ioc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
- uint64_t ioc_inode = 0;
+ uint64_t ioc_inode = 0;
- inode_ctx_get (loc->inode, this, &ioc_inode);
+ inode_ctx_get (loc->inode, this, &ioc_inode);
- if (ioc_inode
+ if (ioc_inode
&& ((valid & GF_SET_ATTR_ATIME)
|| (valid & GF_SET_ATTR_MTIME)))
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_WIND (frame, ioc_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid, xdata);
+ STACK_WIND (frame, ioc_setattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid);
- return 0;
+ return 0;
}
int32_t
ioc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *stbuf, dict_t *xdata, struct iatt *postparent)
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, dict_t *dict, struct iatt *postparent)
{
- ioc_inode_t *ioc_inode = NULL;
- ioc_table_t *table = NULL;
- uint8_t cache_still_valid = 0;
- uint64_t tmp_ioc_inode = 0;
- uint32_t weight = 0xffffffff;
- const char *path = NULL;
- ioc_local_t *local = NULL;
-
- if (op_ret != 0)
- goto out;
+ ioc_inode_t *ioc_inode = NULL;
+ ioc_table_t *table = NULL;
+ uint8_t cache_still_valid = 0;
+ uint64_t tmp_ioc_inode = 0;
+ uint32_t weight = 0xffffffff;
+ const char *path = NULL;
+ ioc_local_t *local = NULL;
+
+ if (op_ret != 0)
+ goto out;
local = frame->local;
if (local == NULL) {
@@ -252,19 +256,20 @@ out:
loc_wipe (&local->file_loc);
}
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, stbuf,
- xdata, postparent);
- return 0;
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, stbuf,
+ dict, postparent);
+ return 0;
}
int32_t
ioc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+ dict_t *xattr_req)
{
- ioc_local_t *local = NULL;
+ ioc_local_t *local = NULL;
int32_t op_errno = -1, ret = -1;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_ioc_mt_ioc_local_t);
if (local == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -280,16 +285,16 @@ ioc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
frame->local = local;
- STACK_WIND (frame, ioc_lookup_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lookup, loc, xdata);
+ STACK_WIND (frame, ioc_lookup_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lookup, loc, xattr_req);
return 0;
unwind:
- STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL,
+ STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL,
NULL, NULL);
- return 0;
+ return 0;
}
/*
@@ -303,29 +308,17 @@ unwind:
int32_t
ioc_forget (xlator_t *this, inode_t *inode)
{
- uint64_t ioc_inode = 0;
-
- inode_ctx_get (inode, this, &ioc_inode);
-
- if (ioc_inode)
- ioc_inode_destroy ((ioc_inode_t *)(long)ioc_inode);
-
- return 0;
-}
-
-static int32_t
-ioc_invalidate(xlator_t *this, inode_t *inode)
-{
- ioc_inode_t *ioc_inode = NULL;
+ uint64_t ioc_inode = 0;
- inode_ctx_get(inode, this, (uint64_t *) &ioc_inode);
+ inode_ctx_get (inode, this, &ioc_inode);
if (ioc_inode)
- ioc_inode_flush(ioc_inode);
+ ioc_inode_destroy ((ioc_inode_t *)(long)ioc_inode);
return 0;
}
+
/*
* ioc_cache_validate_cbk -
*
@@ -339,88 +332,86 @@ ioc_invalidate(xlator_t *this, inode_t *inode)
*/
int32_t
ioc_cache_validate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
{
- ioc_local_t *local = NULL;
- ioc_inode_t *ioc_inode = NULL;
- size_t destroy_size = 0;
- struct iatt *local_stbuf = NULL;
+ ioc_local_t *local = NULL;
+ ioc_inode_t *ioc_inode = NULL;
+ size_t destroy_size = 0;
+ struct iatt *local_stbuf = NULL;
local = frame->local;
- ioc_inode = local->inode;
+ ioc_inode = local->inode;
local_stbuf = stbuf;
- if ((op_ret == -1) ||
- ((op_ret >= 0) && !ioc_cache_still_valid(ioc_inode, stbuf))) {
- gf_log (ioc_inode->table->xl->name, GF_LOG_DEBUG,
- "cache for inode(%p) is invalid. flushing all pages",
- ioc_inode);
- /* NOTE: only pages with no waiting frames are flushed by
- * ioc_inode_flush. page_fault will be generated for all
- * the pages which have waiting frames by ioc_inode_wakeup()
- */
- ioc_inode_lock (ioc_inode);
- {
- destroy_size = __ioc_inode_flush (ioc_inode);
- if (op_ret >= 0) {
- ioc_inode->cache.mtime = stbuf->ia_mtime;
- ioc_inode->cache.mtime_nsec
- = stbuf->ia_mtime_nsec;
+ if ((op_ret == -1) ||
+ ((op_ret >= 0) && !ioc_cache_still_valid(ioc_inode, stbuf))) {
+ gf_log (ioc_inode->table->xl->name, GF_LOG_DEBUG,
+ "cache for inode(%p) is invalid. flushing all pages",
+ ioc_inode);
+ /* NOTE: only pages with no waiting frames are flushed by
+ * ioc_inode_flush. page_fault will be generated for all
+ * the pages which have waiting frames by ioc_inode_wakeup()
+ */
+ ioc_inode_lock (ioc_inode);
+ {
+ destroy_size = __ioc_inode_flush (ioc_inode);
+ if (op_ret >= 0) {
+ ioc_inode->cache.mtime = stbuf->ia_mtime;
+ ioc_inode->cache.mtime_nsec = stbuf->ia_mtime_nsec;
}
- }
- ioc_inode_unlock (ioc_inode);
- local_stbuf = NULL;
- }
+ }
+ ioc_inode_unlock (ioc_inode);
+ local_stbuf = NULL;
+ }
- if (destroy_size) {
- ioc_table_lock (ioc_inode->table);
- {
- ioc_inode->table->cache_used -= destroy_size;
- }
- ioc_table_unlock (ioc_inode->table);
- }
+ if (destroy_size) {
+ ioc_table_lock (ioc_inode->table);
+ {
+ ioc_inode->table->cache_used -= destroy_size;
+ }
+ ioc_table_unlock (ioc_inode->table);
+ }
- if (op_ret < 0)
- local_stbuf = NULL;
+ if (op_ret < 0)
+ local_stbuf = NULL;
- ioc_inode_lock (ioc_inode);
- {
- gettimeofday (&ioc_inode->cache.tv, NULL);
- }
- ioc_inode_unlock (ioc_inode);
+ ioc_inode_lock (ioc_inode);
+ {
+ gettimeofday (&ioc_inode->cache.tv, NULL);
+ }
+ ioc_inode_unlock (ioc_inode);
- ioc_inode_wakeup (frame, ioc_inode, local_stbuf);
+ ioc_inode_wakeup (frame, ioc_inode, local_stbuf);
- /* any page-fault initiated by ioc_inode_wakeup() will have its own
- * fd_ref on fd, safe to unref validate frame's private copy
- */
- fd_unref (local->fd);
+ /* any page-fault initiated by ioc_inode_wakeup() will have its own
+ * fd_ref on fd, safe to unref validate frame's private copy
+ */
+ fd_unref (local->fd);
- STACK_DESTROY (frame->root);
+ STACK_DESTROY (frame->root);
- return 0;
+ return 0;
}
int32_t
ioc_wait_on_inode (ioc_inode_t *ioc_inode, ioc_page_t *page)
{
- ioc_waitq_t *waiter = NULL, *trav = NULL;
- uint32_t page_found = 0;
- int32_t ret = 0;
-
- trav = ioc_inode->waitq;
-
- while (trav) {
- if (trav->data == page) {
- page_found = 1;
- break;
- }
- trav = trav->next;
- }
-
- if (!page_found) {
- waiter = GF_CALLOC (1, sizeof (ioc_waitq_t),
+ ioc_waitq_t *waiter = NULL, *trav = NULL;
+ uint32_t page_found = 0;
+ int32_t ret = 0;
+
+ trav = ioc_inode->waitq;
+
+ while (trav) {
+ if (trav->data == page) {
+ page_found = 1;
+ break;
+ }
+ trav = trav->next;
+ }
+
+ if (!page_found) {
+ waiter = GF_CALLOC (1, sizeof (ioc_waitq_t),
gf_ioc_mt_ioc_waitq_t);
if (waiter == NULL) {
gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR,
@@ -429,13 +420,13 @@ ioc_wait_on_inode (ioc_inode_t *ioc_inode, ioc_page_t *page)
goto out;
}
- waiter->data = page;
- waiter->next = ioc_inode->waitq;
- ioc_inode->waitq = waiter;
- }
+ waiter->data = page;
+ waiter->next = ioc_inode->waitq;
+ ioc_inode->waitq = waiter;
+ }
out:
- return ret;
+ return ret;
}
/*
@@ -448,15 +439,16 @@ out:
*/
int32_t
ioc_cache_validate (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd,
- ioc_page_t *page)
+ ioc_page_t *page)
{
- call_frame_t *validate_frame = NULL;
- ioc_local_t *validate_local = NULL;
- ioc_local_t *local = NULL;
- int32_t ret = 0;
+ call_frame_t *validate_frame = NULL;
+ ioc_local_t *validate_local = NULL;
+ ioc_local_t *local = NULL;
+ int32_t ret = 0;
local = frame->local;
- validate_local = mem_get0 (THIS->local_pool);
+ validate_local = GF_CALLOC (1, sizeof (ioc_local_t),
+ gf_ioc_mt_ioc_local_t);
if (validate_local == NULL) {
ret = -1;
local->op_ret = -1;
@@ -466,55 +458,55 @@ ioc_cache_validate (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd,
goto out;
}
- validate_frame = copy_frame (frame);
+ validate_frame = copy_frame (frame);
if (validate_frame == NULL) {
ret = -1;
local->op_ret = -1;
local->op_errno = ENOMEM;
- mem_put (validate_local);
+ GF_FREE (validate_local);
gf_log (ioc_inode->table->xl->name, GF_LOG_ERROR,
"out of memory");
goto out;
}
- validate_local->fd = fd_ref (fd);
- validate_local->inode = ioc_inode;
- validate_frame->local = validate_local;
+ validate_local->fd = fd_ref (fd);
+ validate_local->inode = ioc_inode;
+ validate_frame->local = validate_local;
- STACK_WIND (validate_frame, ioc_cache_validate_cbk,
+ STACK_WIND (validate_frame, ioc_cache_validate_cbk,
FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->fstat, fd, NULL);
+ FIRST_CHILD (frame->this)->fops->fstat, fd);
out:
- return ret;
+ return ret;
}
inline uint32_t
is_match (const char *path, const char *pattern)
{
- int32_t ret = 0;
+ int32_t ret = 0;
- ret = fnmatch (pattern, path, FNM_NOESCAPE);
+ ret = fnmatch (pattern, path, FNM_NOESCAPE);
- return (ret == 0);
+ return (ret == 0);
}
uint32_t
ioc_get_priority (ioc_table_t *table, const char *path)
{
- uint32_t priority = 1;
- struct ioc_priority *curr = NULL;
+ uint32_t priority = 1;
+ struct ioc_priority *curr = NULL;
- if (list_empty(&table->priority_list))
- return priority;
+ if (list_empty(&table->priority_list))
+ return priority;
- priority = 0;
- list_for_each_entry (curr, &table->priority_list, list) {
- if (is_match (path, curr->pattern))
- priority = curr->priority;
- }
+ priority = 0;
+ list_for_each_entry (curr, &table->priority_list, list) {
+ if (is_match (path, curr->pattern))
+ priority = curr->priority;
+ }
- return priority;
+ return priority;
}
/*
@@ -530,13 +522,13 @@ ioc_get_priority (ioc_table_t *table, const char *path)
*/
int32_t
ioc_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_errno, fd_t *fd)
{
- uint64_t tmp_ioc_inode = 0;
- ioc_local_t *local = NULL;
- ioc_table_t *table = NULL;
- ioc_inode_t *ioc_inode = NULL;
- uint32_t weight = 0xffffffff;
+ uint64_t tmp_ioc_inode = 0;
+ ioc_local_t *local = NULL;
+ ioc_table_t *table = NULL;
+ ioc_inode_t *ioc_inode = NULL;
+ uint32_t weight = 0xffffffff;
local = frame->local;
if (!this || !this->private) {
@@ -561,7 +553,7 @@ ioc_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
ioc_inode_lock (ioc_inode);
{
if ((table->min_file_size > ioc_inode->ia_size)
- || ((table->max_file_size > 0)
+ || ((table->max_file_size >= 0)
&& (table->max_file_size < ioc_inode->ia_size))) {
fd_ctx_set (fd, this, 1);
}
@@ -573,24 +565,28 @@ ioc_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
/* O_DIRECT is only for one fd, not the inode
* as a whole
*/
+ fd_ctx_set (fd, this, 1);
+ }
+ if ((local->wbflags & GF_OPEN_NOWB) != 0) {
+ /* disable caching as asked by NFS */
fd_ctx_set (fd, this, 1);
}
/* weight = 0, we disable caching on it */
if (weight == 0) {
/* we allow a pattern-matched cache disable this way
- */
+ */
fd_ctx_set (fd, this, 1);
}
}
out:
- mem_put (local);
+ GF_FREE (local);
frame->local = NULL;
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
- return 0;
+ return 0;
}
/*
@@ -609,15 +605,15 @@ out:
int32_t
ioc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd,
- inode_t *inode, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ inode_t *inode, struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
{
- ioc_local_t *local = NULL;
- ioc_table_t *table = NULL;
- ioc_inode_t *ioc_inode = NULL;
- uint32_t weight = 0xffffffff;
- const char *path = NULL;
- int ret = -1;
+ ioc_local_t *local = NULL;
+ ioc_table_t *table = NULL;
+ ioc_inode_t *ioc_inode = NULL;
+ uint32_t weight = 0xffffffff;
+ const char *path = NULL;
+ int ret = -1;
local = frame->local;
if (!this || !this->private) {
@@ -629,7 +625,7 @@ ioc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
table = this->private;
path = local->file_loc.path;
- if (op_ret != -1) {
+ if (op_ret != -1) {
/* assign weight */
weight = ioc_get_priority (table, path);
@@ -642,13 +638,9 @@ ioc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ioc_inode->ia_size = buf->ia_size;
if ((table->min_file_size > ioc_inode->ia_size)
- || ((table->max_file_size > 0)
+ || ((table->max_file_size >= 0)
&& (table->max_file_size < ioc_inode->ia_size))) {
ret = fd_ctx_set (fd, this, 1);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set fd ctx",
- local->file_loc.path);
}
}
ioc_inode_unlock (ioc_inode);
@@ -656,38 +648,28 @@ ioc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_ctx_put (fd->inode, this,
(uint64_t)(long)ioc_inode);
- /* If O_DIRECT open, we disable caching on it */
- if (local->flags & O_DIRECT) {
- /*
+ /* If O_DIRECT open, we disable caching on it */
+ if (local->flags & O_DIRECT)
+ /*
* O_DIRECT is only for one fd, not the inode
- * as a whole */
- ret = fd_ctx_set (fd, this, 1);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set fd ctx",
- local->file_loc.path);
- }
+ * as a whole */
+ ret = fd_ctx_set (fd, this, 1);
/* if weight == 0, we disable caching on it */
- if (!weight) {
- /* we allow a pattern-matched cache disable this way */
- ret = fd_ctx_set (fd, this, 1);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "%s: failed to set fd ctx",
- local->file_loc.path);
- }
+ if (!weight)
+ /* we allow a pattern-matched cache disable this way */
+ ret = fd_ctx_set (fd, this, 1);
- }
+ }
out:
- frame->local = NULL;
- mem_put (local);
+ frame->local = NULL;
+ GF_FREE (local);
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
- return 0;
+ return 0;
}
@@ -695,13 +677,13 @@ int32_t
ioc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
ioc_local_t *local = NULL;
- ioc_table_t *table = NULL;
- ioc_inode_t *ioc_inode = NULL;
- uint32_t weight = 0xffffffff;
- const char *path = NULL;
+ ioc_table_t *table = NULL;
+ ioc_inode_t *ioc_inode = NULL;
+ uint32_t weight = 0xffffffff;
+ const char *path = NULL;
local = frame->local;
if (!this || !this->private) {
@@ -713,7 +695,7 @@ ioc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
table = this->private;
path = local->file_loc.path;
- if (op_ret != -1) {
+ if (op_ret != -1) {
/* assign weight */
weight = ioc_get_priority (table, path);
@@ -729,28 +711,29 @@ ioc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_ctx_put (inode, this,
(uint64_t)(long)ioc_inode);
- }
+ }
out:
- frame->local = NULL;
+ frame->local = NULL;
loc_wipe (&local->file_loc);
- mem_put (local);
+ GF_FREE (local);
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
+ STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
+ preparent, postparent);
+ return 0;
}
int
ioc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *params)
{
- ioc_local_t *local = NULL;
+ ioc_local_t *local = NULL;
int32_t op_errno = -1, ret = -1;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_ioc_mt_ioc_local_t);
if (local == NULL) {
op_errno = ENOMEM;
gf_log (this->name, GF_LOG_ERROR, "out of memory");
@@ -766,22 +749,22 @@ ioc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
frame->local = local;
- STACK_WIND (frame, ioc_mknod_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
+ STACK_WIND (frame, ioc_mknod_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod,
+ loc, mode, rdev, params);
return 0;
unwind:
if (local != NULL) {
loc_wipe (&local->file_loc);
- mem_put (local);
+ GF_FREE (local);
}
- STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL,
- NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL,
+ NULL, NULL);
- return 0;
+ return 0;
}
@@ -795,29 +778,29 @@ unwind:
*/
int32_t
ioc_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
- ioc_local_t *local = NULL;
+ ioc_local_t *local = NULL;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (ioc_local_t), gf_ioc_mt_ioc_local_t);
if (local == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
- STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, ENOMEM, NULL);
return 0;
}
- local->flags = flags;
- local->file_loc.path = loc->path;
- local->file_loc.inode = loc->inode;
+ local->flags = flags;
+ local->file_loc.path = loc->path;
+ local->file_loc.inode = loc->inode;
+ local->wbflags = wbflags;
- frame->local = local;
+ frame->local = local;
- STACK_WIND (frame, ioc_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd,
- xdata);
+ STACK_WIND (frame, ioc_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
- return 0;
+ return 0;
}
/*
@@ -832,27 +815,27 @@ ioc_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
*/
int32_t
ioc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
- ioc_local_t *local = NULL;
+ ioc_local_t *local = NULL;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (ioc_local_t), gf_ioc_mt_ioc_local_t);
if (local == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
STACK_UNWIND_STRICT (create, frame, -1, ENOMEM, NULL, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL);
return 0;
}
- local->flags = flags;
- local->file_loc.path = loc->path;
- frame->local = local;
+ local->flags = flags;
+ local->file_loc.path = loc->path;
+ frame->local = local;
- STACK_WIND (frame, ioc_create_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->create, loc, flags, mode,
- umask, fd, xdata);
+ STACK_WIND (frame, ioc_create_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create, loc, flags, mode,
+ fd, params);
- return 0;
+ return 0;
}
@@ -869,7 +852,7 @@ ioc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
int32_t
ioc_release (xlator_t *this, fd_t *fd)
{
- return 0;
+ return 0;
}
/*
@@ -886,30 +869,30 @@ ioc_release (xlator_t *this, fd_t *fd)
int32_t
ioc_readv_disabled_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata)
+ int32_t count, struct iatt *stbuf,
+ struct iobref *iobref)
{
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
- return 0;
+ STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
+ stbuf, iobref);
+ return 0;
}
int32_t
ioc_need_prune (ioc_table_t *table)
{
- int64_t cache_difference = 0;
-
- ioc_table_lock (table);
- {
- cache_difference = table->cache_used - table->cache_size;
- }
- ioc_table_unlock (table);
-
- if (cache_difference > 0)
- return 1;
- else
- return 0;
+ int64_t cache_difference = 0;
+
+ ioc_table_lock (table);
+ {
+ cache_difference = table->cache_used - table->cache_size;
+ }
+ ioc_table_unlock (table);
+
+ if (cache_difference > 0)
+ return 1;
+ else
+ return 0;
}
/*
@@ -924,132 +907,122 @@ void
ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd,
off_t offset, size_t size)
{
- ioc_local_t *local = NULL;
- ioc_table_t *table = NULL;
- ioc_page_t *trav = NULL;
- ioc_waitq_t *waitq = NULL;
- off_t rounded_offset = 0;
- off_t rounded_end = 0;
- off_t trav_offset = 0;
- int32_t fault = 0;
- size_t trav_size = 0;
- off_t local_offset = 0;
- int32_t ret = -1;
- int8_t need_validate = 0;
- int8_t might_need_validate = 0; /*
- * if a page exists, do we need
- * to validate it?
- */
+ ioc_local_t *local = NULL;
+ ioc_table_t *table = NULL;
+ ioc_page_t *trav = NULL;
+ ioc_waitq_t *waitq = NULL;
+ off_t rounded_offset = 0;
+ off_t rounded_end = 0;
+ off_t trav_offset = 0;
+ int32_t fault = 0;
+ size_t trav_size = 0;
+ off_t local_offset = 0;
+ int32_t ret = -1;
+ int8_t need_validate = 0;
+ int8_t might_need_validate = 0; /*
+ * if a page exists, do we need
+ * to validate it?
+ */
local = frame->local;
table = ioc_inode->table;
- rounded_offset = floor (offset, table->page_size);
- rounded_end = roof (offset + size, table->page_size);
- trav_offset = rounded_offset;
-
- /* once a frame does read, it should be waiting on something */
- local->wait_count++;
-
- /* Requested region can fall in three different pages,
- * 1. Ready - region is already in cache, we just have to serve it.
- * 2. In-transit - page fault has been generated on this page, we need
- * to wait till the page is ready
- * 3. Fault - page is not in cache, we have to generate a page fault
- */
+ rounded_offset = floor (offset, table->page_size);
+ rounded_end = roof (offset + size, table->page_size);
+ trav_offset = rounded_offset;
+
+ /* once a frame does read, it should be waiting on something */
+ local->wait_count++;
+
+ /* Requested region can fall in three different pages,
+ * 1. Ready - region is already in cache, we just have to serve it.
+ * 2. In-transit - page fault has been generated on this page, we need
+ * to wait till the page is ready
+ * 3. Fault - page is not in cache, we have to generate a page fault
+ */
+
+ might_need_validate = ioc_inode_need_revalidate (ioc_inode);
+
+ while (trav_offset < rounded_end) {
+ ioc_inode_lock (ioc_inode);
+ //{
+
+ /* look for requested region in the cache */
+ trav = ioc_page_get (ioc_inode, trav_offset);
+
+ local_offset = max (trav_offset, offset);
+ trav_size = min (((offset+size) - local_offset),
+ table->page_size);
+
+ if (!trav) {
+ /* page not in cache, we need to generate page fault */
+ trav = ioc_page_create (ioc_inode, trav_offset);
+ fault = 1;
+ if (!trav) {
+ gf_log (frame->this->name, GF_LOG_CRITICAL,
+ "out of memory");
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ ioc_wait_on_page (trav, frame, local_offset, trav_size);
+
+ if (trav->ready) {
+ /* page found in cache */
+ if (!might_need_validate && !ioc_inode->waitq) {
+ /* fresh enough */
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "cache hit for trav_offset=%"PRId64""
+ "/local_offset=%"PRId64"",
+ trav_offset, local_offset);
+ waitq = ioc_page_wakeup (trav);
+ } else {
+ /* if waitq already exists, fstat revalidate is
+ already on the way */
+ if (!ioc_inode->waitq) {
+ need_validate = 1;
+ }
+
+ ret = ioc_wait_on_inode (ioc_inode, trav);
+ if (ret < 0) {
+ local->op_ret = -1;
+ local->op_errno = -ret;
+ need_validate = 0;
- might_need_validate = ioc_inode_need_revalidate (ioc_inode);
+ waitq = ioc_page_wakeup (trav);
+ ioc_inode_unlock (ioc_inode);
- while (trav_offset < rounded_end) {
- ioc_inode_lock (ioc_inode);
- {
- /* look for requested region in the cache */
- trav = __ioc_page_get (ioc_inode, trav_offset);
-
- local_offset = max (trav_offset, offset);
- trav_size = min (((offset+size) - local_offset),
- table->page_size);
-
- if (!trav) {
- /* page not in cache, we need to generate page
- * fault
- */
- trav = __ioc_page_create (ioc_inode,
- trav_offset);
- fault = 1;
- if (!trav) {
- gf_log (frame->this->name,
- GF_LOG_CRITICAL,
- "out of memory");
- local->op_ret = -1;
- local->op_errno = ENOMEM;
+ ioc_waitq_return (waitq);
+ waitq = NULL;
goto out;
}
- }
-
- __ioc_wait_on_page (trav, frame, local_offset,
- trav_size);
-
- if (trav->ready) {
- /* page found in cache */
- if (!might_need_validate && !ioc_inode->waitq) {
- /* fresh enough */
- gf_log (frame->this->name, GF_LOG_TRACE,
- "cache hit for trav_offset=%"
- PRId64"/local_offset=%"PRId64"",
- trav_offset, local_offset);
- waitq = __ioc_page_wakeup (trav,
- trav->op_errno);
- } else {
- /* if waitq already exists, fstat
- * revalidate is
- * already on the way
- */
- if (!ioc_inode->waitq) {
- need_validate = 1;
- }
-
- ret = ioc_wait_on_inode (ioc_inode,
- trav);
- if (ret < 0) {
- local->op_ret = -1;
- local->op_errno = -ret;
- need_validate = 0;
-
- waitq = __ioc_page_wakeup (trav,
- trav->op_errno);
- ioc_inode_unlock (ioc_inode);
-
- ioc_waitq_return (waitq);
- waitq = NULL;
- goto out;
- }
- }
- }
-
- }
- ioc_inode_unlock (ioc_inode);
-
- ioc_waitq_return (waitq);
- waitq = NULL;
-
- if (fault) {
- fault = 0;
- /* new page created, increase the table->cache_used */
- ioc_page_fault (ioc_inode, frame, fd, trav_offset);
- }
-
- if (need_validate) {
- need_validate = 0;
- gf_log (frame->this->name, GF_LOG_TRACE,
- "sending validate request for "
- "inode(%s) at offset=%"PRId64"",
- uuid_utoa (fd->inode->gfid), trav_offset);
- ret = ioc_cache_validate (frame, ioc_inode, fd, trav);
+ }
+ }
+
+ //}
+ ioc_inode_unlock (ioc_inode);
+
+ ioc_waitq_return (waitq);
+ waitq = NULL;
+
+ if (fault) {
+ fault = 0;
+ /* new page created, increase the table->cache_used */
+ ioc_page_fault (ioc_inode, frame, fd, trav_offset);
+ }
+
+ if (need_validate) {
+ need_validate = 0;
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "sending validate request for "
+ "inode(%"PRId64") at offset=%"PRId64"",
+ fd->inode->ino, trav_offset);
+ ret = ioc_cache_validate (frame, ioc_inode, fd, trav);
if (ret == -1) {
ioc_inode_lock (ioc_inode);
{
- waitq = __ioc_page_wakeup (trav,
- trav->op_errno);
+ waitq = ioc_page_wakeup (trav);
}
ioc_inode_unlock (ioc_inode);
@@ -1057,19 +1030,19 @@ ioc_dispatch_requests (call_frame_t *frame, ioc_inode_t *ioc_inode, fd_t *fd,
waitq = NULL;
goto out;
}
- }
+ }
- trav_offset += table->page_size;
- }
+ trav_offset += table->page_size;
+ }
out:
- ioc_frame_return (frame);
+ ioc_frame_return (frame);
- if (ioc_need_prune (ioc_inode->table)) {
- ioc_prune (ioc_inode->table);
- }
+ if (ioc_need_prune (ioc_inode->table)) {
+ ioc_prune (ioc_inode->table);
+ }
- return;
+ return;
}
@@ -1085,29 +1058,30 @@ out:
*/
int32_t
ioc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, uint32_t flags, dict_t *xdata)
+ size_t size, off_t offset)
{
- uint64_t tmp_ioc_inode = 0;
- ioc_inode_t *ioc_inode = NULL;
- ioc_local_t *local = NULL;
- uint32_t weight = 0;
- ioc_table_t *table = NULL;
- int32_t op_errno = -1;
+ uint64_t tmp_ioc_inode = 0;
+ ioc_inode_t *ioc_inode = NULL;
+ ioc_local_t *local = NULL;
+ uint32_t weight = 0;
+ ioc_table_t *table = NULL;
+ uint32_t num_pages = 0;
+ int32_t op_errno = -1;
if (!this) {
goto out;
}
- inode_ctx_get (fd->inode, this, &tmp_ioc_inode);
- ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
- if (!ioc_inode) {
- /* caching disabled, go ahead with normal readv */
- STACK_WIND (frame, ioc_readv_disabled_cbk,
+ inode_ctx_get (fd->inode, this, &tmp_ioc_inode);
+ ioc_inode = (ioc_inode_t *)(long)tmp_ioc_inode;
+ if (!ioc_inode) {
+ /* caching disabled, go ahead with normal readv */
+ STACK_WIND (frame, ioc_readv_disabled_cbk,
FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv, fd, size,
- offset, flags, xdata);
- return 0;
- }
+ FIRST_CHILD (frame->this)->fops->readv, fd, size,
+ offset);
+ return 0;
+ }
table = this->private;
@@ -1118,14 +1092,37 @@ ioc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
+
+ ioc_table_lock (table);
+ {
+ if (!table->mem_pool) {
+
+ num_pages = (table->cache_size / table->page_size)
+ + ((table->cache_size % table->page_size)
+ ? 1 : 0);
+
+ table->mem_pool
+ = mem_pool_new (rbthash_entry_t, num_pages);
+
+ if (!table->mem_pool) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to allocate mem_pool");
+ op_errno = ENOMEM;
+ ioc_table_unlock (table);
+ goto out;
+ }
+ }
+ }
+ ioc_table_unlock (table);
+
ioc_inode_lock (ioc_inode);
{
if (!ioc_inode->cache.page_table) {
ioc_inode->cache.page_table
= rbthash_table_init
- (IOC_PAGE_TABLE_BUCKET_COUNT,
- ioc_hashfn, NULL, 0,
- table->mem_pool);
+ (IOC_PAGE_TABLE_BUCKET_COUNT,
+ ioc_hashfn, NULL, 0,
+ table->mem_pool);
if (ioc_inode->cache.page_table == NULL) {
op_errno = ENOMEM;
@@ -1136,50 +1133,50 @@ ioc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
ioc_inode_unlock (ioc_inode);
- if (!fd_ctx_get (fd, this, NULL)) {
- /* disable caching for this fd, go ahead with normal readv */
- STACK_WIND (frame, ioc_readv_disabled_cbk,
+ if (!fd_ctx_get (fd, this, NULL)) {
+ /* disable caching for this fd, go ahead with normal readv */
+ STACK_WIND (frame, ioc_readv_disabled_cbk,
FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv, fd, size,
- offset, flags, xdata);
- return 0;
- }
+ FIRST_CHILD (frame->this)->fops->readv, fd, size,
+ offset);
+ return 0;
+ }
- local = mem_get0 (this->local_pool);
+ local = (ioc_local_t *) GF_CALLOC (1, sizeof (ioc_local_t),
+ gf_ioc_mt_ioc_local_t);
if (local == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
op_errno = ENOMEM;
goto out;
}
- INIT_LIST_HEAD (&local->fill_list);
+ INIT_LIST_HEAD (&local->fill_list);
- frame->local = local;
- local->pending_offset = offset;
- local->pending_size = size;
- local->offset = offset;
- local->size = size;
- local->inode = ioc_inode;
+ frame->local = local;
+ local->pending_offset = offset;
+ local->pending_size = size;
+ local->offset = offset;
+ local->size = size;
+ local->inode = ioc_inode;
- gf_log (this->name, GF_LOG_TRACE,
- "NEW REQ (%p) offset = %"PRId64" && size = %"GF_PRI_SIZET"",
- frame, offset, size);
+ gf_log (this->name, GF_LOG_TRACE,
+ "NEW REQ (%p) offset = %"PRId64" && size = %"GF_PRI_SIZET"",
+ frame, offset, size);
- weight = ioc_inode->weight;
+ weight = ioc_inode->weight;
- ioc_table_lock (ioc_inode->table);
- {
- list_move_tail (&ioc_inode->inode_lru,
- &ioc_inode->table->inode_lru[weight]);
- }
- ioc_table_unlock (ioc_inode->table);
+ ioc_table_lock (ioc_inode->table);
+ {
+ list_move_tail (&ioc_inode->inode_lru,
+ &ioc_inode->table->inode_lru[weight]);
+ }
+ ioc_table_unlock (ioc_inode->table);
- ioc_dispatch_requests (frame, ioc_inode, fd, offset, size);
- return 0;
+ ioc_dispatch_requests (frame, ioc_inode, fd, offset, size);
+ return 0;
out:
- STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
}
@@ -1195,21 +1192,20 @@ out:
*/
int32_t
ioc_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
- ioc_local_t *local = NULL;
- uint64_t ioc_inode = 0;
+ ioc_local_t *local = NULL;
+ uint64_t ioc_inode = 0;
local = frame->local;
- inode_ctx_get (local->fd->inode, this, &ioc_inode);
+ inode_ctx_get (local->fd->inode, this, &ioc_inode);
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ if (ioc_inode)
+ ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
- return 0;
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
}
/*
@@ -1225,33 +1221,33 @@ ioc_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
int32_t
ioc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref)
{
- ioc_local_t *local = NULL;
- uint64_t ioc_inode = 0;
+ ioc_local_t *local = NULL;
+ uint64_t ioc_inode = 0;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (ioc_local_t), gf_ioc_mt_ioc_local_t);
if (local == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
- STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOMEM, NULL, NULL);
return 0;
}
- /* TODO: why is it not fd_ref'ed */
- local->fd = fd;
- frame->local = local;
+ /* TODO: why is it not fd_ref'ed */
+ local->fd = fd;
+ frame->local = local;
- inode_ctx_get (fd->inode, this, &ioc_inode);
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ inode_ctx_get (fd->inode, this, &ioc_inode);
+ if (ioc_inode)
+ ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_WIND (frame, ioc_writev_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
- flags, iobref, xdata);
+ STACK_WIND (frame, ioc_writev_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev, fd, vector, count, offset,
+ iobref);
- return 0;
+ return 0;
}
/*
@@ -1268,12 +1264,12 @@ ioc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
int32_t
ioc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
+ postbuf);
+ return 0;
}
@@ -1290,13 +1286,13 @@ ioc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*/
int32_t
ioc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
- return 0;
+ STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
+ postbuf);
+ return 0;
}
@@ -1310,19 +1306,17 @@ ioc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
*
*/
int32_t
-ioc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+ioc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
- uint64_t ioc_inode = 0;
-
- inode_ctx_get (loc->inode, this, &ioc_inode);
+ uint64_t ioc_inode = 0;
+ inode_ctx_get (loc->inode, this, &ioc_inode);
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ if (ioc_inode)
+ ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_WIND (frame, ioc_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
- return 0;
+ STACK_WIND (frame, ioc_truncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
+ return 0;
}
/*
@@ -1335,99 +1329,68 @@ ioc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
*
*/
int32_t
-ioc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+ioc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
- uint64_t ioc_inode = 0;
+ uint64_t ioc_inode = 0;
+ inode_ctx_get (fd->inode, this, &ioc_inode);
- inode_ctx_get (fd->inode, this, &ioc_inode);
-
- if (ioc_inode)
- ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
+ if (ioc_inode)
+ ioc_inode_flush ((ioc_inode_t *)(long)ioc_inode);
- STACK_WIND (frame, ioc_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
- return 0;
+ STACK_WIND (frame, ioc_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ return 0;
}
int32_t
ioc_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_errno, struct gf_flock *lock)
{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock, xdata);
- return 0;
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, lock);
+ return 0;
}
int32_t
ioc_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
- ioc_inode_t *ioc_inode = NULL;
- uint64_t tmp_inode = 0;
-
- inode_ctx_get (fd->inode, this, &tmp_inode);
- ioc_inode = (ioc_inode_t *)(long)tmp_inode;
- if (!ioc_inode) {
- gf_log (this->name, GF_LOG_DEBUG,
- "inode context is NULL: returning EBADFD");
- STACK_UNWIND_STRICT (lk, frame, -1, EBADFD, NULL, NULL);
- return 0;
- }
+ ioc_inode_t *ioc_inode = NULL;
+ uint64_t tmp_inode = 0;
+
+ inode_ctx_get (fd->inode, this, &tmp_inode);
+ ioc_inode = (ioc_inode_t *)(long)tmp_inode;
+ if (!ioc_inode) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "inode context is NULL: returning EBADFD");
+ STACK_UNWIND_STRICT (lk, frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ ioc_inode_lock (ioc_inode);
+ {
+ gettimeofday (&ioc_inode->cache.tv, NULL);
+ }
+ ioc_inode_unlock (ioc_inode);
+
+ STACK_WIND (frame, ioc_lk_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->lk, fd, cmd, lock);
- ioc_inode_lock (ioc_inode);
- {
- gettimeofday (&ioc_inode->cache.tv, NULL);
- }
- ioc_inode_unlock (ioc_inode);
-
- STACK_WIND (frame, ioc_lk_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lk, fd, cmd, lock, xdata);
-
- return 0;
-}
-
-int
-ioc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata)
-{
- gf_dirent_t *entry = NULL;
-
- if (op_ret <= 0)
- goto unwind;
-
- list_for_each_entry (entry, &entries->list, list) {
- /* TODO: fill things */
- }
-
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
-
- return 0;
-}
-int
-ioc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *dict)
-{
- STACK_WIND (frame, ioc_readdirp_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
- fd, size, offset, dict);
-
- return 0;
+ return 0;
}
int32_t
ioc_get_priority_list (const char *opt_str, struct list_head *first)
{
- int32_t max_pri = 1;
- char *tmp_str = NULL;
- char *tmp_str1 = NULL;
- char *tmp_str2 = NULL;
- char *dup_str = NULL;
- char *stripe_str = NULL;
- char *pattern = NULL;
- char *priority = NULL;
- char *string = NULL;
- struct ioc_priority *curr = NULL, *tmp = NULL;
+ int32_t max_pri = 1;
+ char *tmp_str = NULL;
+ char *tmp_str1 = NULL;
+ char *tmp_str2 = NULL;
+ char *dup_str = NULL;
+ char *stripe_str = NULL;
+ char *pattern = NULL;
+ char *priority = NULL;
+ char *string = NULL;
+ struct ioc_priority *curr = NULL, *tmp = NULL;
string = gf_strdup (opt_str);
if (string == NULL) {
@@ -1435,69 +1398,73 @@ ioc_get_priority_list (const char *opt_str, struct list_head *first)
goto out;
}
- /* Get the pattern for cache priority.
- * "option priority *.jpg:1,abc*:2" etc
- */
- /* TODO: inode_lru in table is statically hard-coded to 5,
- * should be changed to run-time configuration
- */
- stripe_str = strtok_r (string, ",", &tmp_str);
- while (stripe_str) {
- curr = GF_CALLOC (1, sizeof (struct ioc_priority),
+ /* Get the pattern for cache priority.
+ * "option priority *.jpg:1,abc*:2" etc
+ */
+ /* TODO: inode_lru in table is statically hard-coded to 5,
+ * should be changed to run-time configuration
+ */
+ stripe_str = strtok_r (string, ",", &tmp_str);
+ while (stripe_str) {
+ curr = GF_CALLOC (1, sizeof (struct ioc_priority),
gf_ioc_mt_ioc_priority);
if (curr == NULL) {
max_pri = -1;
goto out;
}
- list_add_tail (&curr->list, first);
+ list_add_tail (&curr->list, first);
- dup_str = gf_strdup (stripe_str);
+ dup_str = gf_strdup (stripe_str);
if (dup_str == NULL) {
max_pri = -1;
goto out;
}
- pattern = strtok_r (dup_str, ":", &tmp_str1);
- if (!pattern) {
+ pattern = strtok_r (dup_str, ":", &tmp_str1);
+ if (!pattern) {
max_pri = -1;
goto out;
}
- priority = strtok_r (NULL, ":", &tmp_str1);
- if (!priority) {
+ priority = strtok_r (NULL, ":", &tmp_str1);
+ if (!priority) {
max_pri = -1;
goto out;
}
- gf_log ("io-cache", GF_LOG_TRACE,
- "ioc priority : pattern %s : priority %s",
- pattern,
- priority);
+ gf_log ("io-cache", GF_LOG_TRACE,
+ "ioc priority : pattern %s : priority %s",
+ pattern,
+ priority);
- curr->pattern = gf_strdup (pattern);
+ curr->pattern = gf_strdup (pattern);
if (curr->pattern == NULL) {
max_pri = -1;
goto out;
}
- curr->priority = strtol (priority, &tmp_str2, 0);
- if (tmp_str2 && (*tmp_str2)) {
+ curr->priority = strtol (priority, &tmp_str2, 0);
+ if (tmp_str2 && (*tmp_str2)) {
max_pri = -1;
goto out;
} else {
- max_pri = max (max_pri, curr->priority);
+ max_pri = max (max_pri, curr->priority);
}
GF_FREE (dup_str);
dup_str = NULL;
- stripe_str = strtok_r (NULL, ",", &tmp_str);
- }
+ stripe_str = strtok_r (NULL, ",", &tmp_str);
+ }
out:
- GF_FREE (string);
+ if (string != NULL) {
+ GF_FREE (string);
+ }
- GF_FREE (dup_str);
+ if (dup_str != NULL) {
+ GF_FREE (dup_str);
+ }
if (max_pri == -1) {
list_for_each_entry_safe (curr, tmp, first, list) {
@@ -1507,7 +1474,7 @@ out:
}
}
- return max_pri;
+ return max_pri;
}
int32_t
@@ -1522,118 +1489,210 @@ mem_acct_init (xlator_t *this)
if (ret != 0) {
gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
- "failed");
+ "failed");
return ret;
}
return ret;
}
-
-static gf_boolean_t
-check_cache_size_ok (xlator_t *this, uint64_t cache_size)
+int
+validate_options (xlator_t *this, char **op_errstr)
{
- gf_boolean_t ret = _gf_true;
- uint64_t total_mem = 0;
- uint64_t max_cache_size = 0;
- volume_option_t *opt = NULL;
-
- GF_ASSERT (this);
- opt = xlator_volume_option_get (this, "cache-size");
- if (!opt) {
- ret = _gf_false;
- gf_log (this->name, GF_LOG_ERROR,
- "could not get cache-size option");
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
goto out;
}
- total_mem = get_mem_size ();
- if (-1 == total_mem)
- max_cache_size = opt->max;
- else
- max_cache_size = total_mem;
-
- gf_log (this->name, GF_LOG_DEBUG, "Max cache size is %"PRIu64,
- max_cache_size);
-
- if (cache_size > max_cache_size) {
- ret = _gf_false;
- gf_log (this->name, GF_LOG_ERROR, "Cache size %"PRIu64
- " is greater than the max size of %"PRIu64,
- cache_size, max_cache_size);
+ if (list_empty (&this->volume_options))
goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
}
+
out:
+
return ret;
}
int
reconfigure (xlator_t *this, dict_t *options)
{
- data_t *data = NULL;
- ioc_table_t *table = NULL;
- int ret = -1;
- uint64_t cache_size_new = 0;
+ ioc_table_t *table = NULL;
+ int32_t cache_timeout;
+ int64_t min_file_size = 0;
+ int64_t max_file_size = 0;
+ char *tmp = NULL;
+ uint64_t cache_size;
+ char *cache_size_string = NULL;
+ int ret = 0;
+
if (!this || !this->private)
goto out;
- table = this->private;
-
- ioc_table_lock (table);
- {
- GF_OPTION_RECONF ("cache-timeout", table->cache_timeout,
- options, int32, unlock);
-
- data = dict_get (options, "priority");
- if (data) {
- char *option_list = data_to_str (data);
-
- gf_log (this->name, GF_LOG_TRACE,
- "option path %s", option_list);
- /* parse the list of pattern:priority */
- table->max_pri = ioc_get_priority_list (option_list,
- &table->priority_list);
-
- if (table->max_pri == -1) {
- goto unlock;
- }
- table->max_pri ++;
- }
-
- GF_OPTION_RECONF ("max-file-size", table->max_file_size,
- options, size, unlock);
-
- GF_OPTION_RECONF ("min-file-size", table->min_file_size,
- options, size, unlock);
-
- if ((table->max_file_size >= 0) &&
- (table->min_file_size > table->max_file_size)) {
- gf_log (this->name, GF_LOG_ERROR, "minimum size (%"
+ table = this->private;
+
+ ioc_table_lock (table);
+ {
+ if (dict_get (options, "cache-timeout")) {
+ cache_timeout =
+ data_to_uint32 (dict_get (options,
+ "cache-timeout"));
+ if (cache_timeout < 0){
+ gf_log (this->name, GF_LOG_WARNING,
+ "cache-timeout %d seconds invalid,"
+ " has to be >=0", cache_timeout);
+ goto out;
+ }
+
+
+ if (cache_timeout > 60){
+ gf_log (this->name, GF_LOG_WARNING,
+ "cache-timeout %d seconds invalid,"
+ " has to be <=60", cache_timeout);
+ goto out;
+ }
+
+ table->cache_timeout = cache_timeout;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring %d seconds to"
+ " revalidate cache", table->cache_timeout);
+ }
+ else
+ table->cache_timeout = 1;
+
+
+
+ if (dict_get (options, "cache-size"))
+ cache_size_string = data_to_str (dict_get (options,
+ "cache-size"));
+ if (cache_size_string) {
+ if (gf_string2bytesize (cache_size_string,
+ &cache_size) != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option cache-size\" Defaulting"
+ "to old value", cache_size_string);
+ goto out;
+ }
+
+ if (cache_size < (4 * GF_UNIT_MB)) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "Reconfiguration"
+ "'option cache-size %s' failed , "
+ "Max value can be 4MiB, Defaulting to "
+ "old value (%"PRIu64")",
+ cache_size_string, table->cache_size);
+ goto out;
+ }
+
+ if (cache_size > (6 * GF_UNIT_GB)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Reconfiguration"
+ "'option cache-size %s' failed , "
+ "Max value can be 6GiB, Defaulting to "
+ "old value (%"PRIu64")",
+ cache_size_string, table->cache_size);
+ goto out;
+ }
+
+
+ gf_log (this->name, GF_LOG_DEBUG, "Reconfiguring "
+ " cache-size %"PRIu64"", cache_size);
+ table->cache_size = cache_size;
+ }
+ else
+ table->cache_size = IOC_CACHE_SIZE;
+
+
+ if (dict_get (options, "priority")) {
+ char *option_list = data_to_str (dict_get (options,
+ "priority"));
+ gf_log (this->name, GF_LOG_TRACE,
+ "option path %s", option_list);
+ /* parse the list of pattern:priority */
+ table->max_pri = ioc_get_priority_list (option_list,
+ &table->priority_list);
+
+ if (table->max_pri == -1) {
+ ret = -1;
+ goto out;
+ }
+ table->max_pri ++;
+ }
+
+
+
+ min_file_size = table->min_file_size;
+ tmp = data_to_str (dict_get (options, "min-file-size"));
+ if (tmp != NULL) {
+ if (gf_string2bytesize (tmp,
+ (uint64_t *)&min_file_size)
+ != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option min-file-size\"", tmp);
+ ret = -1;
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring min-file-size %"PRIu64"",
+ table->min_file_size);
+ }
+
+ max_file_size = table->max_file_size;
+ tmp = data_to_str (dict_get (options, "max-file-size"));
+ if (tmp != NULL) {
+ if (gf_string2bytesize (tmp,
+ (uint64_t *)&max_file_size)
+ != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option max-file-size\"", tmp);
+ ret = -1;
+ goto out;
+ }
+
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring max-file-size %"PRIu64"",
+ table->max_file_size);
+ }
+
+ if ((max_file_size >= 0) & (min_file_size > max_file_size)) {
+ gf_log ("io-cache", GF_LOG_ERROR, "minimum size (%"
PRIu64") of a file that can be cached is "
"greater than maximum size (%"PRIu64"). "
- "Hence Defaulting to old value",
+ "Hence Defaulting to old value",
table->min_file_size, table->max_file_size);
- goto unlock;
- }
-
- GF_OPTION_RECONF ("cache-size", cache_size_new,
- options, size, unlock);
- if (!check_cache_size_ok (this, cache_size_new)) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Not reconfiguring cache-size");
- goto unlock;
- }
- table->cache_size = cache_size_new;
-
- ret = 0;
- }
-unlock:
- ioc_table_unlock (table);
+ goto out;
+ }
+
+ table->min_file_size = min_file_size;
+ table->max_file_size = max_file_size;
+ if (!data_to_str (dict_get (options, "min-file-size")))
+ table->min_file_size = 0;
+ if (data_to_str (dict_get (options, "max-file-size")))
+ table->max_file_size = 0;
+ }
+
+ ioc_table_unlock (table);
out:
- return ret;
-}
+ return ret;
+}
/*
* init -
@@ -1643,110 +1702,141 @@ out:
int32_t
init (xlator_t *this)
{
- ioc_table_t *table = NULL;
- dict_t *xl_options = NULL;
- uint32_t index = 0;
- int32_t ret = -1;
- glusterfs_ctx_t *ctx = NULL;
- data_t *data = 0;
- uint32_t num_pages = 0;
-
- xl_options = this->options;
-
- if (!this->children || this->children->next) {
- gf_log (this->name, GF_LOG_ERROR,
- "FATAL: io-cache not configured with exactly "
- "one child");
+ ioc_table_t *table = NULL;
+ dict_t *options = this->options;
+ uint32_t index = 0;
+ char *cache_size_string = NULL, *tmp = NULL;
+ int32_t ret = -1;
+ glusterfs_ctx_t *ctx = NULL;
+ data_t *data = 0;
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: io-cache not configured with exactly "
+ "one child");
goto out;
- }
+ }
- if (!this->parents) {
- gf_log (this->name, GF_LOG_WARNING,
- "dangling volume. check volfile ");
- }
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
- table = (void *) GF_CALLOC (1, sizeof (*table), gf_ioc_mt_ioc_table_t);
+ table = (void *) GF_CALLOC (1, sizeof (*table), gf_ioc_mt_ioc_table_t);
if (table == NULL) {
gf_log (this->name, GF_LOG_ERROR, "out of memory");
goto out;
}
- table->xl = this;
- table->page_size = this->ctx->page_size;
+ table->xl = this;
+ table->page_size = this->ctx->page_size;
+ table->cache_size = IOC_CACHE_SIZE;
+
+ data = dict_get (options, "cache-size");
+ if (data)
+ cache_size_string = data_to_str (data);
- GF_OPTION_INIT ("cache-size", table->cache_size, size, out);
+ if (cache_size_string) {
+ if (gf_string2bytesize (cache_size_string,
+ &table->cache_size) != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option cache-size\"",
+ cache_size_string);
+ goto out;
+ }
- GF_OPTION_INIT ("cache-timeout", table->cache_timeout, int32, out);
+ gf_log (this->name, GF_LOG_TRACE,
+ "using cache-size %"PRIu64"", table->cache_size);
+ }
- GF_OPTION_INIT ("min-file-size", table->min_file_size, size, out);
+ table->cache_timeout = 1;
- GF_OPTION_INIT ("max-file-size", table->max_file_size, size, out);
+ data = dict_get (options, "cache-timeout");
+ if (data) {
+ table->cache_timeout = data_to_uint32 (data);
+ gf_log (this->name, GF_LOG_TRACE,
+ "Using %d seconds to revalidate cache",
+ table->cache_timeout);
+ }
+
+ INIT_LIST_HEAD (&table->priority_list);
+ table->max_pri = 1;
+ data = dict_get (options, "priority");
+ if (data) {
+ char *option_list = data_to_str (data);
+ gf_log (this->name, GF_LOG_TRACE,
+ "option path %s", option_list);
+ /* parse the list of pattern:priority */
+ table->max_pri = ioc_get_priority_list (option_list,
+ &table->priority_list);
+
+ if (table->max_pri == -1) {
+ goto out;
+ }
+ }
+ table->max_pri ++;
- if (!check_cache_size_ok (this, table->cache_size)) {
- ret = -1;
- goto out;
+ table->min_file_size = 0;
+
+ data = dict_get (options, "min-file-size");
+ if (data)
+ tmp = data_to_str (data);
+
+ if (tmp != NULL) {
+ if (gf_string2bytesize (tmp,
+ (uint64_t *)&table->min_file_size) != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option min-file-size\"", tmp);
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "using min-file-size %"PRIu64"", table->min_file_size);
}
- INIT_LIST_HEAD (&table->priority_list);
- table->max_pri = 1;
- data = dict_get (xl_options, "priority");
- if (data) {
- char *option_list = data_to_str (data);
- gf_log (this->name, GF_LOG_TRACE,
- "option path %s", option_list);
- /* parse the list of pattern:priority */
- table->max_pri = ioc_get_priority_list (option_list,
- &table->priority_list);
+ tmp = NULL;
+ table->max_file_size = -1;
+ data = dict_get (options, "max-file-size");
+ if (data)
+ tmp = data_to_str (data);
- if (table->max_pri == -1) {
+ if (tmp != NULL) {
+ if (gf_string2bytesize (tmp,
+ (uint64_t *)&table->max_file_size) != 0) {
+ gf_log ("io-cache", GF_LOG_ERROR,
+ "invalid number format \"%s\" of "
+ "\"option max-file-size\"", tmp);
goto out;
}
- }
- table->max_pri ++;
- INIT_LIST_HEAD (&table->inodes);
+ gf_log (this->name, GF_LOG_TRACE,
+ "using max-file-size %"PRIu64"", table->max_file_size);
+ }
+ INIT_LIST_HEAD (&table->inodes);
if ((table->max_file_size >= 0)
&& (table->min_file_size > table->max_file_size)) {
- gf_log ("io-cache", GF_LOG_ERROR, "minimum size (%"
- PRIu64") of a file that can be cached is "
- "greater than maximum size (%"PRIu64")",
- table->min_file_size, table->max_file_size);
- goto out;
+ gf_log ("io-cache", GF_LOG_ERROR, "minimum size (%"
+ PRIu64") of a file that can be cached is "
+ "greater than maximum size (%"PRIu64")",
+ table->min_file_size, table->max_file_size);
+ goto out;
}
- table->inode_lru = GF_CALLOC (table->max_pri,
+ table->inode_lru = GF_CALLOC (table->max_pri,
sizeof (struct list_head),
gf_ioc_mt_list_head);
if (table->inode_lru == NULL) {
goto out;
}
- for (index = 0; index < (table->max_pri); index++)
- INIT_LIST_HEAD (&table->inode_lru[index]);
-
- this->local_pool = mem_pool_new (ioc_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
- pthread_mutex_init (&table->table_lock, NULL);
- this->private = table;
-
- num_pages = (table->cache_size / table->page_size)
- + ((table->cache_size % table->page_size)
- ? 1 : 0);
-
- table->mem_pool = mem_pool_new (rbthash_entry_t, num_pages);
- if (!table->mem_pool) {
- gf_log (this->name, GF_LOG_ERROR,
- "Unable to allocate mem_pool");
- goto out;
- }
+ for (index = 0; index < (table->max_pri); index++)
+ INIT_LIST_HEAD (&table->inode_lru[index]);
+ pthread_mutex_init (&table->table_lock, NULL);
+ this->private = table;
ret = 0;
ctx = this->ctx;
@@ -1760,138 +1850,15 @@ out:
}
}
- return ret;
-}
-
-void
-ioc_page_waitq_dump (ioc_page_t *page, char *prefix)
-{
- ioc_waitq_t *trav = NULL;
- call_frame_t *frame = NULL;
- int32_t i = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
-
- trav = page->waitq;
-
- while (trav) {
- frame = trav->data;
- sprintf (key, "waitq.frame[%d]", i++);
- gf_proc_dump_write (key, "%"PRId64, frame->root->unique);
-
- trav = trav->next;
- }
-}
-
-void
-__ioc_inode_waitq_dump (ioc_inode_t *ioc_inode, char *prefix)
-{
- ioc_waitq_t *trav = NULL;
- ioc_page_t *page = NULL;
- int32_t i = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
-
- trav = ioc_inode->waitq;
-
- while (trav) {
- page = trav->data;
-
- sprintf (key, "cache-validation-waitq.page[%d].offset", i++);
- gf_proc_dump_write (key, "%"PRId64, page->offset);
-
- trav = trav->next;
- }
-}
-
-void
-__ioc_page_dump (ioc_page_t *page, char *prefix)
-{
-
- ioc_page_lock (page);
- {
- gf_proc_dump_write ("offset", "%"PRId64, page->offset);
- gf_proc_dump_write ("size", "%"PRId64, page->size);
- gf_proc_dump_write ("dirty", "%s", page->dirty ? "yes" : "no");
- gf_proc_dump_write ("ready", "%s", page->ready ? "yes" : "no");
- ioc_page_waitq_dump (page, prefix);
- }
- ioc_page_unlock (page);
-}
-
-void
-__ioc_cache_dump (ioc_inode_t *ioc_inode, char *prefix)
-{
- off_t offset = 0;
- ioc_table_t *table = NULL;
- ioc_page_t *page = NULL;
- int i = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
- char timestr[256] = {0, };
-
- if ((ioc_inode == NULL) || (prefix == NULL)) {
- goto out;
- }
-
- table = ioc_inode->table;
-
- if (ioc_inode->cache.tv.tv_sec) {
- gf_time_fmt (timestr, sizeof timestr,
- ioc_inode->cache.tv.tv_sec, gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, ioc_inode->cache.tv.tv_usec);
-
- gf_proc_dump_write ("last-cache-validation-time", "%s",
- timestr);
- }
-
- for (offset = 0; offset < ioc_inode->ia_size;
- offset += table->page_size) {
- page = __ioc_page_get (ioc_inode, offset);
- if (page == NULL) {
- continue;
- }
-
- sprintf (key, "inode.cache.page[%d]", i++);
- __ioc_page_dump (page, key);
- }
-out:
- return;
-}
-
-
-void
-ioc_inode_dump (ioc_inode_t *ioc_inode, char *prefix)
-{
-
- char *path = NULL;
-
- if ((ioc_inode == NULL) || (prefix == NULL)) {
- goto out;
- }
-
- ioc_inode_lock (ioc_inode);
- {
- gf_proc_dump_write ("inode.weight", "%d", ioc_inode->weight);
- inode_path (ioc_inode->inode, NULL, &path);
- if (path) {
- gf_proc_dump_write ("path", "%s", path);
- GF_FREE (path);
- }
- gf_proc_dump_write ("uuid", "%s", uuid_utoa
- (ioc_inode->inode->gfid));
- __ioc_cache_dump (ioc_inode, prefix);
- __ioc_inode_waitq_dump (ioc_inode, prefix);
- }
- ioc_inode_unlock (ioc_inode);
-out:
- return;
+ return ret;
}
int
ioc_priv_dump (xlator_t *this)
{
- ioc_table_t *priv = NULL;
- ioc_inode_t *ioc_inode = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
+ ioc_table_t *priv = NULL;
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+ char key[GF_DUMP_MAX_BUF_LEN];
if (!this || !this->private)
goto out;
@@ -1901,21 +1868,15 @@ ioc_priv_dump (xlator_t *this)
"priv");
gf_proc_dump_add_section (key_prefix);
- ioc_table_lock (priv);
- {
- gf_proc_dump_write ("page_size", "%ld", priv->page_size);
- gf_proc_dump_write ("cache_size", "%ld", priv->cache_size);
- gf_proc_dump_write ("cache_used", "%ld", priv->cache_used);
- gf_proc_dump_write ("inode_count", "%u", priv->inode_count);
- gf_proc_dump_write ("cache_timeout", "%u", priv->cache_timeout);
- gf_proc_dump_write ("min-file-size", "%u", priv->min_file_size);
- gf_proc_dump_write ("max-file-size", "%u", priv->max_file_size);
-
- list_for_each_entry (ioc_inode, &priv->inodes, inode_list) {
- ioc_inode_dump (ioc_inode, key_prefix);
- }
- }
- ioc_table_unlock (priv);
+ gf_proc_dump_build_key (key, key_prefix, "page_size");
+ gf_proc_dump_write (key, "%ld", priv->page_size);
+ gf_proc_dump_build_key (key, key_prefix, "cache_size");
+ gf_proc_dump_write (key, "%ld", priv->cache_size);
+ gf_proc_dump_build_key (key, key_prefix, "cache_used");
+ gf_proc_dump_write (key, "%ld", priv->cache_used);
+ gf_proc_dump_build_key (key, key_prefix, "inode_count");
+ gf_proc_dump_write (key, "%u", priv->inode_count);
+
out:
return 0;
}
@@ -1929,53 +1890,36 @@ out:
void
fini (xlator_t *this)
{
- ioc_table_t *table = NULL;
- struct ioc_priority *curr = NULL, *tmp = NULL;
- int i = 0;
+ ioc_table_t *table = NULL;
table = this->private;
if (table == NULL)
return;
- this->private = NULL;
-
if (table->mem_pool != NULL) {
mem_pool_destroy (table->mem_pool);
table->mem_pool = NULL;
}
- list_for_each_entry_safe (curr, tmp, &table->priority_list, list) {
- list_del_init (&curr->list);
- GF_FREE (curr->pattern);
- GF_FREE (curr);
- }
-
- for (i = 0; i < table->max_pri; i++) {
- GF_ASSERT (list_empty (&table->inode_lru[i]));
- }
-
- GF_ASSERT (list_empty (&table->inodes));
- pthread_mutex_destroy (&table->table_lock);
- GF_FREE (table);
+ pthread_mutex_destroy (&table->table_lock);
+ GF_FREE (table);
- this->private = NULL;
- return;
+ this->private = NULL;
+ return;
}
struct xlator_fops fops = {
- .open = ioc_open,
- .create = ioc_create,
- .readv = ioc_readv,
- .writev = ioc_writev,
- .truncate = ioc_truncate,
- .ftruncate = ioc_ftruncate,
- .lookup = ioc_lookup,
- .lk = ioc_lk,
+ .open = ioc_open,
+ .create = ioc_create,
+ .readv = ioc_readv,
+ .writev = ioc_writev,
+ .truncate = ioc_truncate,
+ .ftruncate = ioc_ftruncate,
+ .lookup = ioc_lookup,
+ .lk = ioc_lk,
.setattr = ioc_setattr,
- .mknod = ioc_mknod,
-
- .readdirp = ioc_readdirp,
+ .mknod = ioc_mknod
};
@@ -1984,47 +1928,29 @@ struct xlator_dumpops dumpops = {
};
struct xlator_cbks cbks = {
- .forget = ioc_forget,
- .release = ioc_release,
- .invalidate = ioc_invalidate,
+ .forget = ioc_forget,
+ .release = ioc_release
};
struct volume_options options[] = {
- { .key = {"priority"},
- .type = GF_OPTION_TYPE_PRIORITY_LIST,
- .default_value = "",
- .description = "Assigns priority to filenames with specific "
- "patterns so that when a page needs to be ejected "
- "out of the cache, the page of a file whose "
- "priority is the lowest will be ejected earlier"
- },
- { .key = {"cache-timeout", "force-revalidate-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = 60,
- .default_value = "1",
- .description = "The cached data for a file will be retained till "
- "'cache-refresh-timeout' seconds, after which data "
- "re-validation is performed."
- },
- { .key = {"cache-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = 4 * GF_UNIT_MB,
- .max = 32 * GF_UNIT_GB,
- .default_value = "32MB",
- .description = "Size of the read cache."
- },
+ { .key = {"priority"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"cache-timeout", "force-revalidate-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,
+ .max = 60
+ },
+ { .key = {"cache-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 4 * GF_UNIT_MB,
+ .max = 6 * GF_UNIT_GB
+ },
{ .key = {"min-file-size"},
.type = GF_OPTION_TYPE_SIZET,
- .default_value = "0",
- .description = "Minimum file size which would be cached by the "
- "io-cache translator."
},
{ .key = {"max-file-size"},
.type = GF_OPTION_TYPE_SIZET,
- .default_value = "0",
- .description = "Maximum file size which would be cached by the "
- "io-cache translator."
},
- { .key = {NULL} },
+ { .key = {NULL} },
};
diff --git a/xlators/performance/io-cache/src/io-cache.h b/xlators/performance/io-cache/src/io-cache.h
index 41bbeea8b..5d0526440 100644
--- a/xlators/performance/io-cache/src/io-cache.h
+++ b/xlators/performance/io-cache/src/io-cache.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __IO_CACHE_H
@@ -75,6 +84,7 @@ struct ioc_fill {
struct ioc_local {
mode_t mode;
int32_t flags;
+ int32_t wbflags;
loc_t file_loc;
off_t offset;
size_t size;
@@ -116,8 +126,6 @@ struct ioc_page {
struct ioc_waitq *waitq;
struct iobref *iobref;
pthread_mutex_t page_lock;
- int32_t op_errno;
- char stale;
};
struct ioc_cache {
@@ -149,15 +157,14 @@ struct ioc_inode {
* weight of the inode, increases
* on each read
*/
- inode_t *inode;
};
struct ioc_table {
uint64_t page_size;
uint64_t cache_size;
uint64_t cache_used;
- uint64_t min_file_size;
- uint64_t max_file_size;
+ int64_t min_file_size;
+ int64_t max_file_size;
struct list_head inodes; /* list of inodes cached */
struct list_head active;
struct list_head *inode_lru;
@@ -188,29 +195,32 @@ int32_t
ioc_readv_disabled_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
int32_t count, struct iatt *stbuf,
- struct iobref *iobref, dict_t *xdata);
+ struct iobref *iobref);
ioc_page_t *
-__ioc_page_get (ioc_inode_t *ioc_inode, off_t offset);
+ioc_page_get (ioc_inode_t *ioc_inode, off_t offset);
ioc_page_t *
-__ioc_page_create (ioc_inode_t *ioc_inode, off_t offset);
+ioc_page_create (ioc_inode_t *ioc_inode, off_t offset);
void
ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
off_t offset);
void
-__ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset,
+ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset,
size_t size);
ioc_waitq_t *
-__ioc_page_wakeup (ioc_page_t *page, int32_t op_errno);
+ioc_page_wakeup (ioc_page_t *page);
void
ioc_page_flush (ioc_page_t *page);
ioc_waitq_t *
-__ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno);
+ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno);
+
+void
+ioc_page_purge (ioc_page_t *page);
void
ioc_frame_return (call_frame_t *frame);
@@ -220,7 +230,7 @@ ioc_waitq_return (ioc_waitq_t *waitq);
int32_t
ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
- size_t size, int32_t op_errno);
+ size_t size);
#define ioc_inode_lock(ioc_inode) \
do { \
@@ -308,7 +318,7 @@ ioc_inode_t *
ioc_inode_update (ioc_table_t *table, inode_t *inode, uint32_t weight);
int64_t
-__ioc_page_destroy (ioc_page_t *page);
+ioc_page_destroy (ioc_page_t *page);
int64_t
__ioc_inode_flush (ioc_inode_t *ioc_inode);
diff --git a/xlators/performance/io-cache/src/ioc-inode.c b/xlators/performance/io-cache/src/ioc-inode.c
index 86a54bb14..e268cac26 100644
--- a/xlators/performance/io-cache/src/ioc-inode.c
+++ b/xlators/performance/io-cache/src/ioc-inode.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -27,7 +36,6 @@ void *
str_to_ptr (char *string)
{
void *ptr = NULL;
-
GF_VALIDATE_OR_GOTO ("io-cache", string, out);
ptr = (void *)strtoul (string, NULL, 16);
@@ -114,8 +122,7 @@ ioc_inode_wakeup (call_frame_t *frame, ioc_inode_t *ioc_inode,
ioc_inode_lock (ioc_inode);
{
page_waitq =
- __ioc_page_wakeup (waiter_page,
- waiter_page->op_errno);
+ ioc_page_wakeup (waiter_page);
}
ioc_inode_unlock (ioc_inode);
if (page_waitq)
@@ -125,19 +132,17 @@ ioc_inode_wakeup (call_frame_t *frame, ioc_inode_t *ioc_inode,
* page->ready = 0, to avoid double faults
*/
ioc_inode_lock (ioc_inode);
- {
- if (waiter_page->ready) {
- waiter_page->ready = 0;
- need_fault = 1;
- } else {
- gf_log (frame->this->name,
- GF_LOG_TRACE,
- "validate frame(%p) is "
- "waiting for in-transit"
- " page = %p", frame,
- waiter_page);
- }
+
+ if (waiter_page->ready) {
+ waiter_page->ready = 0;
+ need_fault = 1;
+ } else {
+ gf_log (frame->this->name, GF_LOG_TRACE,
+ "validate frame(%p) is waiting"
+ "for in-transit page = %p",
+ frame, waiter_page);
}
+
ioc_inode_unlock (ioc_inode);
if (need_fault) {
@@ -183,7 +188,6 @@ ioc_inode_update (ioc_table_t *table, inode_t *inode, uint32_t weight)
goto out;
}
- ioc_inode->inode = inode;
ioc_inode->table = table;
INIT_LIST_HEAD (&ioc_inode->cache.page_lru);
pthread_mutex_init (&ioc_inode->inode_lock, NULL);
diff --git a/xlators/performance/io-cache/src/ioc-mem-types.h b/xlators/performance/io-cache/src/ioc-mem-types.h
index 9b68f9fce..08596d5f4 100644
--- a/xlators/performance/io-cache/src/ioc-mem-types.h
+++ b/xlators/performance/io-cache/src/ioc-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __IOC_MT_H__
@@ -17,6 +26,7 @@ enum gf_ioc_mem_types_ {
gf_ioc_mt_iovec = gf_common_mt_end + 1,
gf_ioc_mt_ioc_table_t,
gf_ioc_mt_char,
+ gf_ioc_mt_ioc_local_t,
gf_ioc_mt_ioc_waitq_t,
gf_ioc_mt_ioc_priority,
gf_ioc_mt_list_head,
diff --git a/xlators/performance/io-cache/src/page.c b/xlators/performance/io-cache/src/page.c
index c18c04a0b..0721f5f04 100644
--- a/xlators/performance/io-cache/src/page.c
+++ b/xlators/performance/io-cache/src/page.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -37,7 +46,7 @@ out:
ioc_page_t *
-__ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
+ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
{
ioc_page_t *page = NULL;
ioc_table_t *table = NULL;
@@ -63,34 +72,14 @@ out:
}
-ioc_page_t *
-ioc_page_get (ioc_inode_t *ioc_inode, off_t offset)
-{
- ioc_page_t *page = NULL;
-
- if (ioc_inode == NULL) {
- goto out;
- }
-
- ioc_inode_lock (ioc_inode);
- {
- page = __ioc_page_get (ioc_inode, offset);
- }
- ioc_inode_unlock (ioc_inode);
-
-out:
- return page;
-}
-
-
/*
- * __ioc_page_destroy -
+ * ioc_page_destroy -
*
* @page:
*
*/
int64_t
-__ioc_page_destroy (ioc_page_t *page)
+ioc_page_destroy (ioc_page_t *page)
{
int64_t page_size = 0;
@@ -102,7 +91,6 @@ __ioc_page_destroy (ioc_page_t *page)
if (page->waitq) {
/* frames waiting on this page, do not destroy this page */
page_size = -1;
- page->stale = 1;
} else {
rbthash_remove (page->inode->cache.page_table, &page->offset,
sizeof (page->offset));
@@ -131,63 +119,6 @@ out:
return page_size;
}
-
-int64_t
-ioc_page_destroy (ioc_page_t *page)
-{
- int64_t ret = 0;
-
- if (page == NULL) {
- goto out;
- }
-
- ioc_inode_lock (page->inode);
- {
- ret = __ioc_page_destroy (page);
- }
- ioc_inode_unlock (page->inode);
-
-out:
- return ret;
-}
-
-int32_t
-__ioc_inode_prune (ioc_inode_t *curr, uint64_t *size_pruned,
- uint64_t size_to_prune, uint32_t index)
-{
- ioc_page_t *page = NULL, *next = NULL;
- int32_t ret = 0;
- ioc_table_t *table = NULL;
-
- if (curr == NULL) {
- goto out;
- }
-
- table = curr->table;
-
- list_for_each_entry_safe (page, next, &curr->cache.page_lru, page_lru) {
- *size_pruned += page->size;
- ret = __ioc_page_destroy (page);
-
- if (ret != -1)
- table->cache_used -= ret;
-
- gf_log (table->xl->name, GF_LOG_TRACE,
- "index = %d && table->cache_used = %"PRIu64" && table->"
- "cache_size = %"PRIu64, index, table->cache_used,
- table->cache_size);
-
- if ((*size_pruned) >= size_to_prune)
- break;
- }
-
- if (ioc_empty (&curr->cache)) {
- list_del_init (&curr->inode_lru);
- }
-
-out:
- return 0;
-}
/*
* ioc_prune - prune the cache. we have a limit to the number of pages we
* can have in-memory.
@@ -199,6 +130,8 @@ int32_t
ioc_prune (ioc_table_t *table)
{
ioc_inode_t *curr = NULL, *next_ioc_inode = NULL;
+ ioc_page_t *page = NULL, *next = NULL;
+ int32_t ret = -1;
int32_t index = 0;
uint64_t size_to_prune = 0;
uint64_t size_pruned = 0;
@@ -216,11 +149,37 @@ ioc_prune (ioc_table_t *table)
/* prune page-by-page for this inode, till
* we reach the equilibrium */
ioc_inode_lock (curr);
- {
- __ioc_inode_prune (curr, &size_pruned,
- size_to_prune,
- index);
+ /* { */
+
+ list_for_each_entry_safe (page, next,
+ &curr->cache.page_lru,
+ page_lru) {
+ /* done with all pages, and not
+ * reached equilibrium yet??
+ * continue with next inode in
+ * lru_list */
+ size_pruned += page->size;
+ ret = ioc_page_destroy (page);
+
+ if (ret != -1)
+ table->cache_used -= ret;
+
+ gf_log (table->xl->name, GF_LOG_TRACE,
+ "index = %d && table->cache_"
+ "used = %"PRIu64" && table->"
+ "cache_size = %"PRIu64,
+ index, table->cache_used,
+ table->cache_size);
+
+ if (size_pruned >= size_to_prune)
+ break;
+ } /* list_for_each_entry_safe(page...) */
+
+ if (ioc_empty (&curr->cache)) {
+ list_del_init (&curr->inode_lru);
}
+
+ /* } */
ioc_inode_unlock (curr);
if (size_pruned >= size_to_prune)
@@ -239,14 +198,14 @@ out:
}
/*
- * __ioc_page_create - create a new page.
+ * ioc_page_create - create a new page.
*
* @ioc_inode:
* @offset:
*
*/
ioc_page_t *
-__ioc_page_create (ioc_inode_t *ioc_inode, off_t offset)
+ioc_page_create (ioc_inode_t *ioc_inode, off_t offset)
{
ioc_table_t *table = NULL;
ioc_page_t *page = NULL;
@@ -299,8 +258,8 @@ out:
*
*/
void
-__ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset,
- size_t size)
+ioc_wait_on_page (ioc_page_t *page, call_frame_t *frame, off_t offset,
+ size_t size)
{
ioc_waitq_t *waitq = NULL;
ioc_local_t *local = NULL;
@@ -408,8 +367,7 @@ ioc_waitq_return (ioc_waitq_t *waitq)
int
ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
ioc_local_t *local = NULL;
off_t offset = 0;
@@ -456,14 +414,14 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret < 0) {
/* error, readv returned -1 */
- page = __ioc_page_get (ioc_inode, offset);
+ page = ioc_page_get (ioc_inode, offset);
if (page)
- waitq = __ioc_page_error (page, op_ret,
- op_errno);
+ waitq = ioc_page_error (page, op_ret,
+ op_errno);
} else {
gf_log (ioc_inode->table->xl->name, GF_LOG_TRACE,
"op_ret = %d", op_ret);
- page = __ioc_page_get (ioc_inode, offset);
+ page = ioc_page_get (ioc_inode, offset);
if (!page) {
/* page was flushed */
/* some serious bug ? */
@@ -481,12 +439,11 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* keep a copy of the page for our cache */
page->vector = iov_dup (vector, count);
if (page->vector == NULL) {
- page = __ioc_page_get (ioc_inode,
- offset);
+ page = ioc_page_get (ioc_inode, offset);
if (page != NULL)
- waitq = __ioc_page_error (page,
- -1,
- ENOMEM);
+ waitq = ioc_page_error (page,
+ -1,
+ ENOMEM);
goto unlock;
}
@@ -510,7 +467,6 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
* byte replies */
page_size = iov_length(vector, count);
page->size = page_size;
- page->op_errno = op_errno;
iobref_page_size = iobref_size (page->iobref);
@@ -518,8 +474,7 @@ ioc_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* wake up all the frames waiting on
* this page, including
* the frame which triggered fault */
- waitq = __ioc_page_wakeup (page,
- op_errno);
+ waitq = ioc_page_wakeup (page);
} /* if(page->waitq) */
} /* if(!page)...else */
} /* if(op_ret < 0)...else */
@@ -597,7 +552,8 @@ ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
goto err;
}
- fault_local = mem_get0 (THIS->local_pool);
+ fault_local = GF_CALLOC (1, sizeof (ioc_local_t),
+ gf_ioc_mt_ioc_local_t);
if (fault_local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -624,28 +580,23 @@ ioc_page_fault (ioc_inode_t *ioc_inode, call_frame_t *frame, fd_t *fd,
STACK_WIND (fault_frame, ioc_fault_cbk, FIRST_CHILD(fault_frame->this),
FIRST_CHILD(fault_frame->this)->fops->readv, fd,
- table->page_size, offset, 0, NULL);
+ table->page_size, offset);
return;
err:
- ioc_inode_lock (ioc_inode);
- {
- page = __ioc_page_get (ioc_inode, offset);
- if (page != NULL) {
- waitq = __ioc_page_error (page, op_ret, op_errno);
+ page = ioc_page_get (ioc_inode, offset);
+ if (page != NULL) {
+ waitq = ioc_page_error (page, op_ret, op_errno);
+ if (waitq != NULL) {
+ ioc_waitq_return (waitq);
}
}
- ioc_inode_unlock (ioc_inode);
-
- if (waitq != NULL) {
- ioc_waitq_return (waitq);
- }
}
int32_t
-__ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
- size_t size, int32_t op_errno)
+ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
+ size_t size)
{
ioc_local_t *local = NULL;
ioc_fill_t *fill = NULL;
@@ -680,13 +631,7 @@ __ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
/* immediately move this page to the end of the page_lru list */
list_move_tail (&page->page_lru, &ioc_inode->cache.page_lru);
/* fill local->pending_size bytes from local->pending_offset */
- if (local->op_ret != -1) {
- local->op_errno = op_errno;
-
- if (page->size == 0) {
- goto done;
- }
-
+ if (local->op_ret != -1 && page->size) {
if (offset > page->offset)
/* offset is offset in file, convert it to offset in
* page */
@@ -775,11 +720,9 @@ __ioc_frame_fill (ioc_page_t *page, call_frame_t *frame, off_t offset,
}
}
}
-
local->op_ret += copy_size;
}
-done:
ret = 0;
out:
return ret;
@@ -870,7 +813,7 @@ unwind:
// ioc_local_unlock (local);
STACK_UNWIND_STRICT (readv, frame, op_ret, local->op_errno, vector,
- count, &stbuf, iobref, NULL);
+ count, &stbuf, iobref);
if (iobref != NULL) {
iobref_unref (iobref);
@@ -882,7 +825,7 @@ unwind:
}
pthread_mutex_destroy (&local->local_lock);
- mem_put (local);
+ GF_FREE (local);
return;
}
@@ -924,7 +867,7 @@ ioc_frame_return (call_frame_t *frame)
* to be called only when a frame is waiting on an in-transit page
*/
ioc_waitq_t *
-__ioc_page_wakeup (ioc_page_t *page, int32_t op_errno)
+ioc_page_wakeup (ioc_page_t *page)
{
ioc_waitq_t *waitq = NULL, *trav = NULL;
call_frame_t *frame = NULL;
@@ -942,23 +885,18 @@ __ioc_page_wakeup (ioc_page_t *page, int32_t op_errno)
for (trav = waitq; trav; trav = trav->next) {
frame = trav->data;
- ret = __ioc_frame_fill (page, frame, trav->pending_offset,
- trav->pending_size, op_errno);
+ ret = ioc_frame_fill (page, frame, trav->pending_offset,
+ trav->pending_size);
if (ret == -1) {
break;
}
}
- if (page->stale) {
- __ioc_page_destroy (page);
- }
-
out:
return waitq;
}
-
/*
* ioc_page_error -
* @page:
@@ -967,7 +905,7 @@ out:
*
*/
ioc_waitq_t *
-__ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
+ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
{
ioc_waitq_t *waitq = NULL, *trav = NULL;
call_frame_t *frame = NULL;
@@ -999,7 +937,7 @@ __ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
}
table = page->inode->table;
- ret = __ioc_page_destroy (page);
+ ret = ioc_page_destroy (page);
if (ret != -1) {
table->cache_used -= ret;
@@ -1008,29 +946,3 @@ __ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
out:
return waitq;
}
-
-/*
- * ioc_page_error -
- * @page:
- * @op_ret:
- * @op_errno:
- *
- */
-ioc_waitq_t *
-ioc_page_error (ioc_page_t *page, int32_t op_ret, int32_t op_errno)
-{
- ioc_waitq_t *waitq = NULL;
-
- if (page == NULL) {
- goto out;
- }
-
- ioc_inode_lock (page->inode);
- {
- waitq = __ioc_page_error (page, op_ret, op_errno);
- }
- ioc_inode_unlock (page->inode);
-
-out:
- return waitq;
-}
diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
index 2a5cec7ed..bdc808319 100644
--- a/xlators/performance/io-threads/src/io-threads.c
+++ b/xlators/performance/io-threads/src/io-threads.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -27,22 +36,18 @@
void *iot_worker (void *arg);
int iot_workers_scale (iot_conf_t *conf);
int __iot_workers_scale (iot_conf_t *conf);
-struct volume_options options[];
+
call_stub_t *
-__iot_dequeue (iot_conf_t *conf, int *pri)
+__iot_dequeue (iot_conf_t *conf)
{
call_stub_t *stub = NULL;
int i = 0;
- *pri = -1;
for (i = 0; i < IOT_PRI_MAX; i++) {
- if (list_empty (&conf->reqs[i]) ||
- (conf->ac_iot_count[i] >= conf->ac_iot_limit[i]))
+ if (list_empty (&conf->reqs[i]))
continue;
stub = list_entry (conf->reqs[i].next, call_stub_t, list);
- conf->ac_iot_count[i]++;
- *pri = i;
break;
}
@@ -50,7 +55,6 @@ __iot_dequeue (iot_conf_t *conf, int *pri)
return NULL;
conf->queue_size--;
- conf->queue_sizes[*pri]--;
list_del_init (&stub->list);
return stub;
@@ -66,7 +70,6 @@ __iot_enqueue (iot_conf_t *conf, call_stub_t *stub, int pri)
list_add_tail (&stub->list, &conf->reqs[pri]);
conf->queue_size++;
- conf->queue_sizes[pri]++;
return;
}
@@ -80,7 +83,6 @@ iot_worker (void *data)
call_stub_t *stub = NULL;
struct timespec sleep_till = {0, };
int ret = 0;
- int pri = -1;
char timeout = 0;
char bye = 0;
@@ -93,10 +95,6 @@ iot_worker (void *data)
pthread_mutex_lock (&conf->mutex);
{
- if (pri != -1) {
- conf->ac_iot_count[pri]--;
- pri = -1;
- }
while (conf->queue_size == 0) {
conf->sleep_count++;
@@ -123,7 +121,7 @@ iot_worker (void *data)
}
}
- stub = __iot_dequeue (conf, &pri);
+ stub = __iot_dequeue (conf);
}
pthread_mutex_unlock (&conf->mutex);
@@ -134,13 +132,6 @@ iot_worker (void *data)
break;
}
- if (pri != -1) {
- pthread_mutex_lock (&conf->mutex);
- {
- conf->ac_iot_count[pri]--;
- }
- pthread_mutex_unlock (&conf->mutex);
- }
return NULL;
}
@@ -163,117 +154,49 @@ do_iot_schedule (iot_conf_t *conf, call_stub_t *stub, int pri)
return ret;
}
-char*
-iot_get_pri_meaning (iot_pri_t pri)
+
+int
+iot_schedule_slow (iot_conf_t *conf, call_stub_t *stub)
{
- char *name = NULL;
- switch (pri) {
- case IOT_PRI_HI:
- name = "fast";
- break;
- case IOT_PRI_NORMAL:
- name = "normal";
- break;
- case IOT_PRI_LO:
- name = "slow";
- break;
- case IOT_PRI_LEAST:
- name = "least priority";
- break;
- case IOT_PRI_MAX:
- name = "invalid";
- break;
- }
- return name;
+ return do_iot_schedule (conf, stub, IOT_PRI_LO);
}
+
int
-iot_schedule (call_frame_t *frame, xlator_t *this, call_stub_t *stub)
+iot_schedule_fast (iot_conf_t *conf, call_stub_t *stub)
{
- int ret = -1;
- iot_pri_t pri = IOT_PRI_MAX - 1;
- iot_conf_t *conf = this->private;
+ return do_iot_schedule (conf, stub, IOT_PRI_HI);
+}
- if ((frame->root->pid < GF_CLIENT_PID_MAX) && conf->least_priority) {
- pri = IOT_PRI_LEAST;
- goto out;
- }
+int
+iot_schedule (iot_conf_t *conf, call_stub_t *stub)
+{
+ return do_iot_schedule (conf, stub, IOT_PRI_NORMAL);
+}
- switch (stub->fop) {
- case GF_FOP_OPEN:
- case GF_FOP_STAT:
- case GF_FOP_FSTAT:
- case GF_FOP_LOOKUP:
- case GF_FOP_ACCESS:
- case GF_FOP_READLINK:
- case GF_FOP_OPENDIR:
- case GF_FOP_STATFS:
- case GF_FOP_READDIR:
- case GF_FOP_READDIRP:
- pri = IOT_PRI_HI;
- break;
- case GF_FOP_CREATE:
- case GF_FOP_FLUSH:
- case GF_FOP_LK:
- case GF_FOP_INODELK:
- case GF_FOP_FINODELK:
- case GF_FOP_ENTRYLK:
- case GF_FOP_FENTRYLK:
- case GF_FOP_UNLINK:
- case GF_FOP_SETATTR:
- case GF_FOP_FSETATTR:
- case GF_FOP_MKNOD:
- case GF_FOP_MKDIR:
- case GF_FOP_RMDIR:
- case GF_FOP_SYMLINK:
- case GF_FOP_RENAME:
- case GF_FOP_LINK:
- case GF_FOP_SETXATTR:
- case GF_FOP_GETXATTR:
- case GF_FOP_FGETXATTR:
- case GF_FOP_FSETXATTR:
- case GF_FOP_REMOVEXATTR:
- case GF_FOP_FREMOVEXATTR:
- pri = IOT_PRI_NORMAL;
- break;
+int
+iot_schedule_unordered (iot_conf_t *conf, inode_t *inode, call_stub_t *stub)
+{
+ return do_iot_schedule (conf, stub, 0);
+}
- case GF_FOP_READ:
- case GF_FOP_WRITE:
- case GF_FOP_FSYNC:
- case GF_FOP_TRUNCATE:
- case GF_FOP_FTRUNCATE:
- case GF_FOP_FSYNCDIR:
- case GF_FOP_XATTROP:
- case GF_FOP_FXATTROP:
- case GF_FOP_RCHECKSUM:
- pri = IOT_PRI_LO;
- break;
- case GF_FOP_NULL:
- case GF_FOP_FORGET:
- case GF_FOP_RELEASE:
- case GF_FOP_RELEASEDIR:
- case GF_FOP_GETSPEC:
- case GF_FOP_MAXVALUE:
- //fail compilation on missing fop
- //new fop must choose priority.
- break;
- }
-out:
- ret = do_iot_schedule (this->private, stub, pri);
- gf_log (this->name, GF_LOG_DEBUG, "%s scheduled as %s fop",
- gf_fop_list[stub->fop], iot_get_pri_meaning (pri));
- return ret;
+int
+iot_schedule_ordered (iot_conf_t *conf, inode_t *inode, call_stub_t *stub)
+{
+
+ return do_iot_schedule (conf, stub, 0);
}
+
int
iot_lookup_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xdata,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
struct iatt *postparent)
{
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xdata,
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xattr,
postparent);
return 0;
}
@@ -281,23 +204,23 @@ iot_lookup_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
int
iot_lookup_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+ dict_t *xattr_req)
{
STACK_WIND (frame, iot_lookup_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->lookup,
- loc, xdata);
+ loc, xattr_req);
return 0;
}
int
-iot_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_lookup_stub (frame, iot_lookup_wrapper, loc, xdata);
+ stub = fop_lookup_stub (frame, iot_lookup_wrapper, loc, xattr_req);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create lookup stub (out of memory)");
@@ -305,7 +228,7 @@ iot_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
@@ -323,35 +246,33 @@ out:
int
iot_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop,
- xdata);
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, preop, postop);
return 0;
}
int
iot_setattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
STACK_WIND (frame, iot_setattr_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->setattr,
- loc, stbuf, valid, xdata);
+ loc, stbuf, valid);
return 0;
}
int
iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_setattr_stub (frame, iot_setattr_wrapper, loc, stbuf, valid,
- xdata);
+ stub = fop_setattr_stub (frame, iot_setattr_wrapper, loc, stbuf, valid);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "Cannot create setattr stub"
"(Out of memory)");
@@ -359,7 +280,7 @@ iot_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
@@ -367,7 +288,7 @@ out:
call_stub_destroy (stub);
}
- STACK_UNWIND_STRICT (setattr, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (setattr, frame, -1, -ret, NULL, NULL);
}
return 0;
@@ -377,34 +298,32 @@ out:
int
iot_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
- STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, preop, postop,
- xdata);
+ STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno, preop, postop);
return 0;
}
int
iot_fsetattr_wrapper (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ fd_t *fd, struct iatt *stbuf, int32_t valid)
{
STACK_WIND (frame, iot_fsetattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid,
- xdata);
+ FIRST_CHILD (this)->fops->fsetattr, fd, stbuf, valid);
return 0;
}
int
iot_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_fsetattr_stub (frame, iot_fsetattr_wrapper, fd, stbuf,
- valid, xdata);
+ valid);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create fsetattr stub"
"(out of memory)");
@@ -412,12 +331,11 @@ iot_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fsetattr, frame, -1, -ret, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -428,31 +346,30 @@ out:
int
iot_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (access, frame, op_ret, op_errno);
return 0;
}
int
iot_access_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask, dict_t *xdata)
+ int32_t mask)
{
STACK_WIND (frame, iot_access_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->access, loc, mask, xdata);
+ FIRST_CHILD (this)->fops->access, loc, mask);
return 0;
}
int
-iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
- dict_t *xdata)
+iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_access_stub (frame, iot_access_wrapper, loc, mask, xdata);
+ stub = fop_access_stub (frame, iot_access_wrapper, loc, mask);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create access stub"
"(out of memory)");
@@ -460,10 +377,10 @@ iot_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (access, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (access, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -476,33 +393,32 @@ out:
int
iot_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *path,
- struct iatt *stbuf, dict_t *xdata)
+ struct iatt *stbuf)
{
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, stbuf,
- xdata);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, path, stbuf);
return 0;
}
int
iot_readlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, dict_t *xdata)
+ size_t size)
{
STACK_WIND (frame, iot_readlink_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->readlink,
- loc, size, xdata);
+ loc, size);
return 0;
}
int
-iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict_t *xdata)
+iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_readlink_stub (frame, iot_readlink_wrapper, loc, size, xdata);
+ stub = fop_readlink_stub (frame, iot_readlink_wrapper, loc, size);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create readlink stub"
"(out of memory)");
@@ -510,11 +426,11 @@ iot_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size, dict
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (readlink, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (readlink, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -529,34 +445,33 @@ int
iot_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
iot_mknod_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *params)
{
STACK_WIND (frame, iot_mknod_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->mknod, loc, mode, rdev, umask,
- xdata);
+ FIRST_CHILD (this)->fops->mknod, loc, mode, rdev, params);
return 0;
}
int
iot_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *params)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_mknod_stub (frame, iot_mknod_wrapper, loc, mode, rdev,
- umask, xdata);
+ params);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create mknod stub"
"(out of memory)");
@@ -564,12 +479,12 @@ iot_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (mknod, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -583,33 +498,32 @@ int
iot_mkdir_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
iot_mkdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
STACK_WIND (frame, iot_mkdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->mkdir, loc, mode, umask, xdata);
+ FIRST_CHILD (this)->fops->mkdir, loc, mode, params);
return 0;
}
int
iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- mode_t umask, dict_t *xdata)
+ dict_t *params)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_mkdir_stub (frame, iot_mkdir_wrapper, loc, mode, umask,
- xdata);
+ stub = fop_mkdir_stub (frame, iot_mkdir_wrapper, loc, mode, params);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create mkdir stub"
"(out of memory)");
@@ -617,12 +531,12 @@ iot_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (mkdir, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -635,30 +549,30 @@ out:
int
iot_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
return 0;
}
int
-iot_rmdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
+iot_rmdir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
STACK_WIND (frame, iot_rmdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rmdir, loc, flags, xdata);
+ FIRST_CHILD (this)->fops->rmdir, loc, flags);
return 0;
}
int
-iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *xdata)
+iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_rmdir_stub (frame, iot_rmdir_wrapper, loc, flags, xdata);
+ stub = fop_rmdir_stub (frame, iot_rmdir_wrapper, loc, flags);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create rmdir stub"
"(out of memory)");
@@ -666,10 +580,10 @@ iot_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags, dict_t *x
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (rmdir, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (rmdir, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -683,34 +597,33 @@ int
iot_symlink_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
iot_symlink_wrapper (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
STACK_WIND (frame, iot_symlink_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->symlink, linkname, loc, umask,
- xdata);
+ FIRST_CHILD (this)->fops->symlink, linkname, loc, params);
return 0;
}
int
iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_symlink_stub (frame, iot_symlink_wrapper, linkname, loc,
- umask, xdata);
+ params);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create symlink stub"
"(out of memory)");
@@ -718,12 +631,12 @@ iot_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (symlink, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -737,33 +650,31 @@ int
iot_rename_cbk (call_frame_t *frame, void * cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *buf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, buf, preoldparent,
- postoldparent, prenewparent, postnewparent, xdata);
+ postoldparent, prenewparent, postnewparent);
return 0;
}
int
iot_rename_wrapper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
STACK_WIND (frame, iot_rename_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->rename, oldloc, newloc, xdata);
+ FIRST_CHILD (this)->fops->rename, oldloc, newloc);
return 0;
}
int
-iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_rename_stub (frame, iot_rename_wrapper, oldloc, newloc, xdata);
+ stub = fop_rename_stub (frame, iot_rename_wrapper, oldloc, newloc);
if (!stub) {
gf_log (this->name, GF_LOG_DEBUG, "cannot create rename stub"
"(out of memory)");
@@ -771,12 +682,12 @@ iot_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (rename, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -788,33 +699,31 @@ out:
int
iot_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_errno, fd_t *fd)
{
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
int
iot_open_wrapper (call_frame_t * frame, xlator_t * this, loc_t *loc,
- int32_t flags, fd_t * fd, dict_t *xdata)
+ int32_t flags, fd_t * fd, int32_t wbflags)
{
STACK_WIND (frame, iot_open_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->open, loc, flags, fd,
- xdata);
+ FIRST_CHILD (this)->fops->open, loc, flags, fd, wbflags);
return 0;
}
int
iot_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_open_stub (frame, iot_open_wrapper, loc, flags, fd,
- xdata);
+ stub = fop_open_stub (frame, iot_open_wrapper, loc, flags, fd, wbflags);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create open call stub"
@@ -823,11 +732,11 @@ iot_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (open, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -842,36 +751,35 @@ int
iot_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, stbuf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
iot_create_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, mode_t mode, mode_t umask, fd_t *fd,
- dict_t *xdata)
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
STACK_WIND (frame, iot_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
}
int
iot_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_create_stub (frame, iot_create_wrapper, loc, flags, mode,
- umask, fd, xdata);
+ fd, params);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create \"create\" call stub"
@@ -880,12 +788,12 @@ iot_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (create, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -899,11 +807,10 @@ out:
int
iot_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
return 0;
}
@@ -911,25 +818,24 @@ iot_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
iot_readv_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
STACK_WIND (frame, iot_readv_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
return 0;
}
int
iot_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_readv_stub (frame, iot_readv_wrapper, fd, size, offset,
- flags, xdata);
+ stub = fop_readv_stub (frame, iot_readv_wrapper, fd, size, offset);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create readv call stub"
@@ -938,12 +844,12 @@ iot_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (readv, frame, -1, -ret, NULL, -1, NULL,
- NULL, NULL);
+ NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -954,31 +860,31 @@ out:
int
iot_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
int
-iot_flush_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_flush_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
STACK_WIND (frame, iot_flush_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->flush,
- fd, xdata);
+ fd);
return 0;
}
int
-iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_flush_stub (frame, iot_flush_wrapper, fd, xdata);
+ stub = fop_flush_stub (frame, iot_flush_wrapper, fd);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create flush_cbk call stub"
@@ -987,10 +893,10 @@ iot_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (flush, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1003,34 +909,32 @@ out:
int
iot_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
iot_fsync_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync, dict_t *xdata)
+ int32_t datasync)
{
STACK_WIND (frame, iot_fsync_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsync,
- fd, datasync, xdata);
+ fd, datasync);
return 0;
}
int
-iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
+iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_fsync_stub (frame, iot_fsync_wrapper, fd, datasync, xdata);
+ stub = fop_fsync_stub (frame, iot_fsync_wrapper, fd, datasync);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fsync_cbk call stub"
@@ -1039,11 +943,11 @@ iot_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fsync, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsync, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1056,10 +960,9 @@ out:
int
iot_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -1067,13 +970,12 @@ iot_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
iot_writev_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count,
- off_t offset, uint32_t flags, struct iobref *iobref,
- dict_t *xdata)
+ off_t offset, struct iobref *iobref)
{
STACK_WIND (frame, iot_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
}
@@ -1081,13 +983,13 @@ iot_writev_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
int
iot_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_writev_stub (frame, iot_writev_wrapper, fd, vector,
- count, offset, flags, iobref, xdata);
+ stub = fop_writev_stub (frame, iot_writev_wrapper,
+ fd, vector, count, offset, iobref);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1097,10 +999,10 @@ iot_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (writev, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1113,34 +1015,33 @@ out:
int32_t
iot_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *flock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *flock)
{
- STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock, xdata);
+ STACK_UNWIND_STRICT (lk, frame, op_ret, op_errno, flock);
return 0;
}
int
iot_lk_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t cmd, struct gf_flock *flock, dict_t *xdata)
+ int32_t cmd, struct gf_flock *flock)
{
STACK_WIND (frame, iot_lk_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lk,
- fd, cmd, flock, xdata);
+ fd, cmd, flock);
return 0;
}
int
iot_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *flock, dict_t *xdata)
+ struct gf_flock *flock)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_lk_stub (frame, iot_lk_wrapper, fd, cmd, flock, xdata);
+ stub = fop_lk_stub (frame, iot_lk_wrapper, fd, cmd, flock);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1150,10 +1051,10 @@ iot_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (lk, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (lk, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1165,31 +1066,31 @@ out:
int
iot_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
return 0;
}
int
-iot_stat_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_stat_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
STACK_WIND (frame, iot_stat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->stat,
- loc, xdata);
+ loc);
return 0;
}
int
-iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_stat_stub (frame, iot_stat_wrapper, loc, xdata);
+ stub = fop_stat_stub (frame, iot_stat_wrapper, loc);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fop_stat call stub"
@@ -1198,11 +1099,11 @@ iot_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (stat, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1214,31 +1115,31 @@ out:
int
iot_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int
-iot_fstat_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_fstat_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
STACK_WIND (frame, iot_fstat_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
+ fd);
return 0;
}
int
-iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_fstat_stub (frame, iot_fstat_wrapper, fd, xdata);
+ stub = fop_fstat_stub (frame, iot_fstat_wrapper, fd);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fop_fstat call stub"
@@ -1247,10 +1148,10 @@ iot_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fstat, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (fstat, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1263,35 +1164,34 @@ out:
int
iot_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int
iot_truncate_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
STACK_WIND (frame, iot_truncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
+ loc, offset);
return 0;
}
int
-iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
call_stub_t *stub;
int ret = -1;
- stub = fop_truncate_stub (frame, iot_truncate_wrapper, loc, offset,
- xdata);
+ stub = fop_truncate_stub (frame, iot_truncate_wrapper, loc, offset);
+
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fop_stat call stub"
@@ -1300,12 +1200,11 @@ iot_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (truncate, frame, -1, -ret, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1319,35 +1218,33 @@ out:
int
iot_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int
iot_ftruncate_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
STACK_WIND (frame, iot_ftruncate_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->ftruncate,
- fd, offset, xdata);
+ fd, offset);
return 0;
}
int
-iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_ftruncate_stub (frame, iot_ftruncate_wrapper, fd, offset,
- xdata);
+ stub = fop_ftruncate_stub (frame, iot_ftruncate_wrapper, fd, offset);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fop_ftruncate call stub"
@@ -1356,10 +1253,10 @@ iot_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (ftruncate, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1373,34 +1270,32 @@ out:
int
iot_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
+ postparent);
return 0;
}
int
-iot_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t xflag, dict_t *xdata)
+iot_unlink_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
STACK_WIND (frame, iot_unlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
+ loc);
return 0;
}
int
-iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
- dict_t *xdata)
+iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_unlink_stub (frame, iot_unlink_wrapper, loc, xflag, xdata);
+ stub = fop_unlink_stub (frame, iot_unlink_wrapper, loc);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,
"cannot create fop_unlink call stub"
@@ -1409,11 +1304,11 @@ iot_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (unlink, frame, -1, -ret, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (unlink, frame, -1, -ret, NULL, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1427,34 +1322,31 @@ out:
int
iot_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent, struct iatt *postparent,
- dict_t *xdata)
+ struct iatt *buf, struct iatt *preparent, struct iatt *postparent)
{
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int
-iot_link_wrapper (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new,
- dict_t *xdata)
+iot_link_wrapper (call_frame_t *frame, xlator_t *this, loc_t *old, loc_t *new)
{
STACK_WIND (frame, iot_link_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->link, old, new, xdata);
+ FIRST_CHILD (this)->fops->link, old, new);
return 0;
}
int
-iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
- dict_t *xdata)
+iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_link_stub (frame, iot_link_wrapper, oldloc, newloc, xdata);
+ stub = fop_link_stub (frame, iot_link_wrapper, oldloc, newloc);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create link stub"
"(out of memory)");
@@ -1462,11 +1354,11 @@ iot_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
STACK_UNWIND_STRICT (link, frame, -1, -ret, NULL, NULL, NULL,
- NULL, NULL);
+ NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1478,31 +1370,29 @@ out:
int
iot_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
return 0;
}
int
-iot_opendir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+iot_opendir_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
STACK_WIND (frame, iot_opendir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->opendir, loc, fd, xdata);
+ FIRST_CHILD (this)->fops->opendir, loc, fd);
return 0;
}
int
-iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_opendir_stub (frame, iot_opendir_wrapper, loc, fd, xdata);
+ stub = fop_opendir_stub (frame, iot_opendir_wrapper, loc, fd);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create opendir stub"
"(out of memory)");
@@ -1510,10 +1400,10 @@ iot_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (opendir, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (opendir, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1525,32 +1415,30 @@ out:
int
iot_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsyncdir, frame, op_ret, op_errno);
return 0;
}
int
iot_fsyncdir_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int datasync, dict_t *xdata)
+ int datasync)
{
STACK_WIND (frame, iot_fsyncdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsyncdir, fd, datasync, xdata);
+ FIRST_CHILD (this)->fops->fsyncdir, fd, datasync);
return 0;
}
int
-iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
- dict_t *xdata)
+iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_fsyncdir_stub (frame, iot_fsyncdir_wrapper, fd, datasync,
- xdata);
+ stub = fop_fsyncdir_stub (frame, iot_fsyncdir_wrapper, fd, datasync);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create fsyncdir stub"
"(out of memory)");
@@ -1558,10 +1446,10 @@ iot_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1573,31 +1461,29 @@ out:
int
iot_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
- STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, buf);
return 0;
}
int
-iot_statfs_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+iot_statfs_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
STACK_WIND (frame, iot_statfs_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->statfs, loc, xdata);
+ FIRST_CHILD (this)->fops->statfs, loc);
return 0;
}
int
-iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_statfs_stub (frame, iot_statfs_wrapper, loc, xdata);
+ stub = fop_statfs_stub (frame, iot_statfs_wrapper, loc);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create statfs stub"
"(out of memory)");
@@ -1605,10 +1491,10 @@ iot_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (statfs, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (statfs, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1620,32 +1506,32 @@ out:
int
iot_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
int
iot_setxattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
STACK_WIND (frame, iot_setxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setxattr, loc, dict, flags, xdata);
+ FIRST_CHILD (this)->fops->setxattr, loc, dict, flags);
return 0;
}
int
iot_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_setxattr_stub (frame, iot_setxattr_wrapper, loc, dict,
- flags, xdata);
+ flags);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create setxattr stub"
"(out of memory)");
@@ -1653,11 +1539,11 @@ iot_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (setxattr, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1669,31 +1555,31 @@ out:
int
iot_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
iot_getxattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
STACK_WIND (frame, iot_getxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->getxattr, loc, name, xdata);
+ FIRST_CHILD (this)->fops->getxattr, loc, name);
return 0;
}
int
iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_getxattr_stub (frame, iot_getxattr_wrapper, loc, name, xdata);
+ stub = fop_getxattr_stub (frame, iot_getxattr_wrapper, loc, name);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create getxattr stub"
"(out of memory)");
@@ -1701,11 +1587,11 @@ iot_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (getxattr, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (getxattr, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1717,32 +1603,31 @@ out:
int
iot_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
- STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
return 0;
}
int
iot_fgetxattr_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
STACK_WIND (frame, iot_fgetxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fgetxattr, fd, name, xdata);
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
return 0;
}
int
iot_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_fgetxattr_stub (frame, iot_fgetxattr_wrapper, fd, name, xdata);
+ stub = fop_fgetxattr_stub (frame, iot_fgetxattr_wrapper, fd, name);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create fgetxattr stub"
"(out of memory)");
@@ -1750,10 +1635,10 @@ iot_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1765,33 +1650,32 @@ out:
int
iot_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno);
return 0;
}
int
iot_fsetxattr_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
STACK_WIND (frame, iot_fsetxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags,
- xdata);
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags);
return 0;
}
int
iot_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_fsetxattr_stub (frame, iot_fsetxattr_wrapper, fd, dict,
- flags, xdata);
+ flags);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create fsetxattr stub"
"(out of memory)");
@@ -1799,10 +1683,10 @@ iot_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1814,32 +1698,32 @@ out:
int
iot_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
- STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (removexattr, frame, op_ret, op_errno);
return 0;
}
int
iot_removexattr_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
STACK_WIND (frame, iot_removexattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->removexattr, loc, name, xdata);
+ FIRST_CHILD (this)->fops->removexattr, loc, name);
return 0;
}
int
iot_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_removexattr_stub (frame, iot_removexattr_wrapper, loc,
- name, xdata);
+ name);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR,"cannot get removexattr fop"
"(out of memory)");
@@ -1847,57 +1731,10 @@ iot_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
-out:
- if (ret < 0) {
- STACK_UNWIND_STRICT (removexattr, frame, -1, -ret, NULL);
-
- if (stub != NULL) {
- call_stub_destroy (stub);
- }
- }
- return 0;
-}
-
-int
-iot_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fremovexattr, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-iot_fremovexattr_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- STACK_WIND (frame, iot_fremovexattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fremovexattr, fd, name, xdata);
- return 0;
-}
-
-
-int
-iot_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- int ret = -1;
-
- stub = fop_fremovexattr_stub (frame, iot_fremovexattr_wrapper, fd,
- name, xdata);
- if (!stub) {
- gf_log (this->name, GF_LOG_ERROR,"cannot get fremovexattr fop"
- "(out of memory)");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (removexattr, frame, -1, -ret);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1909,33 +1746,32 @@ out:
int
iot_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries);
return 0;
}
int
iot_readdirp_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
+ size_t size, off_t offset)
{
STACK_WIND (frame, iot_readdirp_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->readdirp, fd, size, offset, xdata);
+ FIRST_CHILD (this)->fops->readdirp, fd, size, offset);
return 0;
}
int
iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_readdirp_stub (frame, iot_readdirp_wrapper, fd, size,
- offset, xdata);
+ offset);
if (!stub) {
gf_log (this->private, GF_LOG_ERROR,"cannot get readdir stub"
"(out of memory)");
@@ -1943,10 +1779,10 @@ iot_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (readdirp, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (readdirp, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -1958,33 +1794,31 @@ out:
int
iot_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
- STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries, xdata);
+ STACK_UNWIND_STRICT (readdir, frame, op_ret, op_errno, entries);
return 0;
}
int
iot_readdir_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
+ size_t size, off_t offset)
{
STACK_WIND (frame, iot_readdir_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->readdir, fd, size, offset, xdata);
+ FIRST_CHILD (this)->fops->readdir, fd, size, offset);
return 0;
}
int
iot_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
call_stub_t *stub = NULL;
int ret = -1;
- stub = fop_readdir_stub (frame, iot_readdir_wrapper, fd, size, offset,
- xdata);
+ stub = fop_readdir_stub (frame, iot_readdir_wrapper, fd, size, offset);
if (!stub) {
gf_log (this->private, GF_LOG_ERROR,"cannot get readdir stub"
"(out of memory)");
@@ -1992,208 +1826,10 @@ iot_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
goto out;
}
- ret = iot_schedule (frame, this, stub);
-out:
- if (ret < 0) {
- STACK_UNWIND_STRICT (readdir, frame, -1, -ret, NULL, NULL);
-
- if (stub != NULL) {
- call_stub_destroy (stub);
- }
- }
- return 0;
-}
-
-int
-iot_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (inodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-iot_inodelk_wrapper (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock,
- dict_t *xdata)
-{
- STACK_WIND (frame, iot_inodelk_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->inodelk, volume, loc, cmd, lock,
- xdata);
- return 0;
-}
-
-
-int
-iot_inodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- int ret = -1;
-
- stub = fop_inodelk_stub (frame, iot_inodelk_wrapper,
- volume, loc, cmd, lock, xdata);
- if (!stub) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_fast (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (inodelk, frame, -1, -ret, NULL);
-
- if (stub != NULL) {
- call_stub_destroy (stub);
- }
- }
- return 0;
-}
-
-int
-iot_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (finodelk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-iot_finodelk_wrapper (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
-{
- STACK_WIND (frame, iot_finodelk_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->finodelk, volume, fd, cmd, lock,
- xdata);
- return 0;
-}
-
-
-int
-iot_finodelk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock,
- dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- int ret = -1;
-
- stub = fop_finodelk_stub (frame, iot_finodelk_wrapper,
- volume, fd, cmd, lock, xdata);
- if (!stub) {
- gf_log (this->private, GF_LOG_ERROR,"cannot get finodelk stub"
- "(out of memory)");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = iot_schedule (frame, this, stub);
-out:
- if (ret < 0) {
- STACK_UNWIND_STRICT (finodelk, frame, -1, -ret, NULL);
-
- if (stub != NULL) {
- call_stub_destroy (stub);
- }
- }
- return 0;
-}
-
-int
-iot_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-iot_entrylk_wrapper (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
-{
- STACK_WIND (frame, iot_entrylk_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->entrylk,
- volume, loc, basename, cmd, type, xdata);
- return 0;
-}
-
-
-int
-iot_entrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, loc_t *loc, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- int ret = -1;
-
- stub = fop_entrylk_stub (frame, iot_entrylk_wrapper,
- volume, loc, basename, cmd, type, xdata);
- if (!stub) {
- gf_log (this->private, GF_LOG_ERROR,"cannot get entrylk stub"
- "(out of memory)");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = iot_schedule (frame, this, stub);
-out:
- if (ret < 0) {
- STACK_UNWIND_STRICT (entrylk, frame, -1, -ret, NULL);
-
- if (stub != NULL) {
- call_stub_destroy (stub);
- }
- }
- return 0;
-}
-
-int
-iot_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- STACK_UNWIND_STRICT (fentrylk, frame, op_ret, op_errno, xdata);
- return 0;
-}
-
-
-int
-iot_fentrylk_wrapper (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
-{
- STACK_WIND (frame, iot_fentrylk_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fentrylk,
- volume, fd, basename, cmd, type, xdata);
- return 0;
-}
-
-
-int
-iot_fentrylk (call_frame_t *frame, xlator_t *this,
- const char *volume, fd_t *fd, const char *basename,
- entrylk_cmd cmd, entrylk_type type, dict_t *xdata)
-{
- call_stub_t *stub = NULL;
- int ret = -1;
-
- stub = fop_fentrylk_stub (frame, iot_fentrylk_wrapper,
- volume, fd, basename, cmd, type, xdata);
- if (!stub) {
- gf_log (this->private, GF_LOG_ERROR,"cannot get fentrylk stub"
- "(out of memory)");
- ret = -ENOMEM;
- goto out;
- }
-
- ret = iot_schedule (frame, this, stub);
-out:
- if (ret < 0) {
- STACK_UNWIND_STRICT (fentrylk, frame, -1, -ret, NULL);
+ STACK_UNWIND_STRICT (readdir, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -2205,32 +1841,32 @@ out:
int
iot_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
- STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr, xdata);
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr);
return 0;
}
int
iot_xattrop_wrapper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
STACK_WIND (frame, iot_xattrop_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->xattrop, loc, optype, xattr, xdata);
+ FIRST_CHILD (this)->fops->xattrop, loc, optype, xattr);
return 0;
}
int
iot_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_xattrop_stub (frame, iot_xattrop_wrapper, loc, optype,
- xattr, xdata);
+ xattr);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create xattrop stub"
"(out of memory)");
@@ -2238,10 +1874,10 @@ iot_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (xattrop, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (xattrop, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
@@ -2253,31 +1889,31 @@ out:
int
iot_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *xattr)
{
- STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, xattr, xdata);
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret, op_errno, xattr);
return 0;
}
int
iot_fxattrop_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
STACK_WIND (frame, iot_fxattrop_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fxattrop, fd, optype, xattr, xdata);
+ FIRST_CHILD (this)->fops->fxattrop, fd, optype, xattr);
return 0;
}
int
iot_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata)
+ gf_xattrop_flags_t optype, dict_t *xattr)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_fxattrop_stub (frame, iot_fxattrop_wrapper, fd, optype,
- xattr, xdata);
+ xattr);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create fxattrop stub"
"(out of memory)");
@@ -2285,10 +1921,10 @@ iot_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (fxattrop, frame, -1, -ret, NULL, NULL);
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, -ret, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -2300,33 +1936,33 @@ out:
int32_t
iot_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, uint32_t weak_checksum,
- uint8_t *strong_checksum, dict_t *xdata)
+ uint8_t *strong_checksum)
{
STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, weak_checksum,
- strong_checksum, xdata);
+ strong_checksum);
return 0;
}
int32_t
iot_rchecksum_wrapper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, int32_t len, dict_t *xdata)
+ off_t offset, int32_t len)
{
STACK_WIND (frame, iot_rchecksum_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->rchecksum, fd, offset, len, xdata);
+ FIRST_CHILD(this)->fops->rchecksum, fd, offset, len);
return 0;
}
int32_t
iot_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
+ int32_t len)
{
call_stub_t *stub = NULL;
int ret = -1;
stub = fop_rchecksum_stub (frame, iot_rchecksum_wrapper, fd, offset,
- len, xdata);
+ len);
if (!stub) {
gf_log (this->name, GF_LOG_ERROR, "cannot create rchecksum stub"
"(out of memory)");
@@ -2334,10 +1970,10 @@ iot_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
goto out;
}
- ret = iot_schedule (frame, this, stub);
+ ret = iot_schedule_slow (this->private, stub);
out:
if (ret < 0) {
- STACK_UNWIND_STRICT (rchecksum, frame, -1, -ret, -1, NULL, NULL);
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, -ret, -1, NULL);
if (stub != NULL) {
call_stub_destroy (stub);
}
@@ -2350,19 +1986,20 @@ out:
int
__iot_workers_scale (iot_conf_t *conf)
{
+ int log2 = 0;
int scale = 0;
int diff = 0;
pthread_t thread;
int ret = 0;
- int i = 0;
- for (i = 0; i < IOT_PRI_MAX; i++)
- scale += min (conf->queue_sizes[i], conf->ac_iot_limit[i]);
+ log2 = log_base2 (conf->queue_size);
- if (scale < IOT_MIN_THREADS)
+ scale = log2;
+
+ if (log2 < IOT_MIN_THREADS)
scale = IOT_MIN_THREADS;
- if (scale > conf->max_count)
+ if (log2 > conf->max_count)
scale = conf->max_count;
if (conf->curr_count < scale) {
@@ -2413,24 +2050,13 @@ set_stack_size (iot_conf_t *conf)
{
int err = 0;
size_t stacksize = IOT_THREAD_STACK_SIZE;
- xlator_t *this = NULL;
-
- this = THIS;
pthread_attr_init (&conf->w_attr);
err = pthread_attr_setstacksize (&conf->w_attr, stacksize);
if (err == EINVAL) {
- err = pthread_attr_getstacksize (&conf->w_attr, &stacksize);
- if (!err)
- gf_log (this->name, GF_LOG_WARNING,
- "Using default thread stack size %zd",
- stacksize);
- else
- gf_log (this->name, GF_LOG_WARNING,
- "Using default thread stack size");
+ gf_log (conf->this->name, GF_LOG_WARNING,
+ "Using default thread stack size");
}
-
- conf->stack_size = stacksize;
}
@@ -2453,70 +2079,75 @@ mem_acct_init (xlator_t *this)
return ret;
}
+
int
-iot_priv_dump (xlator_t *this)
+validate_options ( xlator_t *this, char **op_errstr)
{
- iot_conf_t *conf = NULL;
- char key_prefix[GF_DUMP_MAX_BUF_LEN];
-
- if (!this)
- return 0;
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- conf = this->private;
- if (!conf)
- return 0;
-
- snprintf (key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type,
- this->name);
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
- gf_proc_dump_add_section(key_prefix);
+ if (list_empty (&this->volume_options))
+ goto out;
- gf_proc_dump_write("maximum_threads_count", "%d", conf->max_count);
- gf_proc_dump_write("current_threads_count", "%d", conf->curr_count);
- gf_proc_dump_write("sleep_count", "%d", conf->sleep_count);
- gf_proc_dump_write("idle_time", "%d", conf->idle_time);
- gf_proc_dump_write("stack_size", "%zd", conf->stack_size);
- gf_proc_dump_write("high_priority_threads", "%d",
- conf->ac_iot_limit[IOT_PRI_HI]);
- gf_proc_dump_write("normal_priority_threads", "%d",
- conf->ac_iot_limit[IOT_PRI_NORMAL]);
- gf_proc_dump_write("low_priority_threads", "%d",
- conf->ac_iot_limit[IOT_PRI_LO]);
- gf_proc_dump_write("least_priority_threads", "%d",
- conf->ac_iot_limit[IOT_PRI_LEAST]);
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
- return 0;
+out:
+ return ret;
}
+
int
-reconfigure (xlator_t *this, dict_t *options)
+reconfigure ( xlator_t *this, dict_t *options)
{
iot_conf_t *conf = NULL;
- int ret = -1;
+ int ret = 0;
+ int thread_count;
conf = this->private;
if (!conf)
goto out;
- GF_OPTION_RECONF ("thread-count", conf->max_count, options, int32, out);
+ thread_count = conf->max_count;
- GF_OPTION_RECONF ("high-prio-threads",
- conf->ac_iot_limit[IOT_PRI_HI], options, int32, out);
+ if (dict_get (options, "thread-count")) {
+ thread_count = data_to_int32 (dict_get (options,
+ "thread-count"));
- GF_OPTION_RECONF ("normal-prio-threads",
- conf->ac_iot_limit[IOT_PRI_NORMAL], options, int32,
- out);
+ if (thread_count < IOT_MIN_THREADS) {
+ gf_log ("io-threads", GF_LOG_WARNING,
+ "Number of threads opted (%d) is less then "
+ "min (%d). Restoring it to previous value (%d)",
+ thread_count, IOT_MIN_THREADS, conf->max_count);
+ goto out;
+ }
- GF_OPTION_RECONF ("low-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LO], options, int32, out);
+ if (thread_count > IOT_MAX_THREADS) {
+ gf_log ("io-threads", GF_LOG_WARNING,
+ "Number of threads opted (%d) is greater than "
+ "max (%d). Restoring it to previous value (%d)",
+ thread_count, IOT_MAX_THREADS, conf->max_count);
+ goto out;
+ }
- GF_OPTION_RECONF ("least-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LEAST], options, int32,
- out);
- GF_OPTION_RECONF ("enable-least-priority", conf->least_priority,
- options, bool, out);
+ conf->max_count = thread_count;
+ } else
+ conf->max_count = thread_count;
ret = 0;
+
out:
return ret;
}
@@ -2525,9 +2156,12 @@ out:
int
init (xlator_t *this)
{
- iot_conf_t *conf = NULL;
- int ret = -1;
- int i = 0;
+ iot_conf_t *conf = NULL;
+ dict_t *options = this->options;
+ int thread_count = IOT_DEFAULT_THREADS;
+ int idle_time = IOT_DEFAULT_IDLE;
+ int ret = -1;
+ int i = 0;
if (!this->children || this->children->next) {
gf_log ("io-threads", GF_LOG_ERROR,
@@ -2548,37 +2182,35 @@ init (xlator_t *this)
goto out;
}
- if ((ret = pthread_cond_init(&conf->cond, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_cond_init failed (%d)", ret);
- goto out;
- }
-
- if ((ret = pthread_mutex_init(&conf->mutex, NULL)) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "pthread_mutex_init failed (%d)", ret);
- goto out;
- }
-
set_stack_size (conf);
- GF_OPTION_INIT ("thread-count", conf->max_count, int32, out);
-
- GF_OPTION_INIT ("high-prio-threads",
- conf->ac_iot_limit[IOT_PRI_HI], int32, out);
-
- GF_OPTION_INIT ("normal-prio-threads",
- conf->ac_iot_limit[IOT_PRI_NORMAL], int32, out);
-
- GF_OPTION_INIT ("low-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LO], int32, out);
+ thread_count = IOT_DEFAULT_THREADS;
- GF_OPTION_INIT ("least-prio-threads",
- conf->ac_iot_limit[IOT_PRI_LEAST], int32, out);
+ if (dict_get (options, "thread-count")) {
+ thread_count = data_to_int32 (dict_get (options,
+ "thread-count"));
+ if (thread_count < IOT_MIN_THREADS) {
+ gf_log ("io-threads", GF_LOG_WARNING,
+ "Number of threads opted is less then min"
+ "threads allowed scaling it up to min");
+ thread_count = IOT_MIN_THREADS;
+ }
+ if (thread_count > IOT_MAX_THREADS) {
+ gf_log ("io-threads", GF_LOG_WARNING,
+ "Number of threads opted is more then max"
+ " threads allowed scaling it down to max");
+ thread_count = IOT_MAX_THREADS;
+ }
+ }
+ conf->max_count = thread_count;
- GF_OPTION_INIT ("idle-time", conf->idle_time, int32, out);
- GF_OPTION_INIT ("enable-least-priority", conf->least_priority,
- bool, out);
+ if (dict_get (options, "idle-time")) {
+ idle_time = data_to_int32 (dict_get (options,
+ "idle-time"));
+ if (idle_time < 0)
+ idle_time = 1;
+ }
+ conf->idle_time = idle_time;
conf->this = this;
@@ -2591,15 +2223,13 @@ init (xlator_t *this)
if (ret == -1) {
gf_log (this->name, GF_LOG_ERROR,
"cannot initialize worker threads, exiting init");
+ GF_FREE (conf);
goto out;
}
this->private = conf;
ret = 0;
out:
- if (ret)
- GF_FREE (conf);
-
return ret;
}
@@ -2615,9 +2245,6 @@ fini (xlator_t *this)
return;
}
-struct xlator_dumpops dumpops = {
- .priv = iot_priv_dump,
-};
struct xlator_fops fops = {
.open = iot_open,
@@ -2651,13 +2278,8 @@ struct xlator_fops fops = {
.fgetxattr = iot_fgetxattr,
.fsetxattr = iot_fsetxattr,
.removexattr = iot_removexattr,
- .fremovexattr = iot_fremovexattr,
.readdir = iot_readdir,
.readdirp = iot_readdirp,
- .inodelk = iot_inodelk,
- .finodelk = iot_finodelk,
- .entrylk = iot_entrylk,
- .fentrylk = iot_fentrylk,
.xattrop = iot_xattrop,
.fxattrop = iot_fxattrop,
.rchecksum = iot_rchecksum,
@@ -2670,57 +2292,12 @@ struct volume_options options[] = {
{ .key = {"thread-count"},
.type = GF_OPTION_TYPE_INT,
.min = IOT_MIN_THREADS,
- .max = IOT_MAX_THREADS,
- .default_value = "16",
- .description = "Number of threads in IO threads translator which "
- "perform concurrent IO operations"
-
- },
- { .key = {"high-prio-threads"},
- .type = GF_OPTION_TYPE_INT,
- .min = IOT_MIN_THREADS,
- .max = IOT_MAX_THREADS,
- .default_value = "16",
- .description = "Max number of threads in IO threads translator which "
- "perform high priority IO operations at a given time"
-
- },
- { .key = {"normal-prio-threads"},
- .type = GF_OPTION_TYPE_INT,
- .min = IOT_MIN_THREADS,
- .max = IOT_MAX_THREADS,
- .default_value = "16",
- .description = "Max number of threads in IO threads translator which "
- "perform normal priority IO operations at a given time"
-
+ .max = IOT_MAX_THREADS
},
- { .key = {"low-prio-threads"},
- .type = GF_OPTION_TYPE_INT,
- .min = IOT_MIN_THREADS,
- .max = IOT_MAX_THREADS,
- .default_value = "16",
- .description = "Max number of threads in IO threads translator which "
- "perform low priority IO operations at a given time"
-
- },
- { .key = {"least-prio-threads"},
- .type = GF_OPTION_TYPE_INT,
- .min = IOT_MIN_THREADS,
- .max = IOT_MAX_THREADS,
- .default_value = "1",
- .description = "Max number of threads in IO threads translator which "
- "perform least priority IO operations at a given time"
- },
- { .key = {"enable-least-priority"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "Enable/Disable least priority"
- },
{.key = {"idle-time"},
.type = GF_OPTION_TYPE_INT,
.min = 1,
.max = 0x7fffffff,
- .default_value = "120",
},
{ .key = {NULL},
},
diff --git a/xlators/performance/io-threads/src/io-threads.h b/xlators/performance/io-threads/src/io-threads.h
index a6b640884..250231962 100644
--- a/xlators/performance/io-threads/src/io-threads.h
+++ b/xlators/performance/io-threads/src/io-threads.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __IOT_H
@@ -28,7 +37,6 @@
#include "locking.h"
#include "iot-mem-types.h"
#include <semaphore.h>
-#include "statedump.h"
struct iot_conf;
@@ -49,7 +57,6 @@ typedef enum {
IOT_PRI_HI = 0, /* low latency */
IOT_PRI_NORMAL, /* normal */
IOT_PRI_LO, /* bulk */
- IOT_PRI_LEAST, /* least */
IOT_PRI_MAX,
} iot_pri_t;
@@ -66,15 +73,10 @@ struct iot_conf {
struct list_head reqs[IOT_PRI_MAX];
- int32_t ac_iot_limit[IOT_PRI_MAX];
- int32_t ac_iot_count[IOT_PRI_MAX];
- int queue_sizes[IOT_PRI_MAX];
int queue_size;
pthread_attr_t w_attr;
- gf_boolean_t least_priority; /*Enable/Disable least-priority */
xlator_t *this;
- size_t stack_size;
};
typedef struct iot_conf iot_conf_t;
diff --git a/xlators/performance/io-threads/src/iot-mem-types.h b/xlators/performance/io-threads/src/iot-mem-types.h
index 4fa8302d1..cca4fbef4 100644
--- a/xlators/performance/io-threads/src/iot-mem-types.h
+++ b/xlators/performance/io-threads/src/iot-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/performance/md-cache/src/Makefile.am b/xlators/performance/md-cache/src/Makefile.am
deleted file mode 100644
index 150e7243e..000000000
--- a/xlators/performance/md-cache/src/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-xlator_LTLIBRARIES = md-cache.la
-xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
-
-md_cache_la_LDFLAGS = -module -avoidversion
-
-md_cache_la_SOURCES = md-cache.c
-md_cache_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-
-noinst_HEADERS = md-cache-mem-types.h
-
-AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
- -I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/rbtree -shared -nostartfiles $(GF_CFLAGS)
-
-CLEANFILES =
-
-
-stat-prefetch-compat:
- mkdir -p $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
- rm -rf $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance/stat-prefetch.so
- ln -s ./md-cache.so $(DESTDIR)$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance/stat-prefetch.so
-
-
-install-exec-local: stat-prefetch-compat
diff --git a/xlators/performance/md-cache/src/md-cache-mem-types.h b/xlators/performance/md-cache/src/md-cache-mem-types.h
deleted file mode 100644
index 6634cf962..000000000
--- a/xlators/performance/md-cache/src/md-cache-mem-types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-
-#ifndef __MDC_MEM_TYPES_H__
-#define __MDC_MEM_TYPES_H__
-
-#include "mem-types.h"
-
-enum gf_mdc_mem_types_ {
- gf_mdc_mt_mdc_local_t = gf_common_mt_end + 1,
- gf_mdc_mt_md_cache_t,
- gf_mdc_mt_mdc_conf_t,
- gf_mdc_mt_end
-};
-#endif
-
diff --git a/xlators/performance/md-cache/src/md-cache.c b/xlators/performance/md-cache/src/md-cache.c
deleted file mode 100644
index 55923990d..000000000
--- a/xlators/performance/md-cache/src/md-cache.c
+++ /dev/null
@@ -1,1956 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "glusterfs.h"
-#include "logging.h"
-#include "dict.h"
-#include "xlator.h"
-#include "md-cache-mem-types.h"
-#include <assert.h>
-#include <sys/time.h>
-
-
-/* TODO:
- - cache symlink() link names and nuke symlink-cache
- - send proper postbuf in setattr_cbk even when op_ret = -1
-*/
-
-
-struct mdc_conf {
- int timeout;
- gf_boolean_t cache_posix_acl;
- gf_boolean_t cache_selinux;
-};
-
-
-static struct mdc_key {
- const char *name;
- int load;
- int check;
-} mdc_keys[] = {
- {
- .name = "system.posix_acl_access",
- .load = 0,
- .check = 1,
- },
- {
- .name = "system.posix_acl_default",
- .load = 0,
- .check = 1,
- },
- {
- .name = "security.selinux",
- .load = 0,
- .check = 1,
- },
- {
- .name = "security.capability",
- .load = 0,
- .check = 1,
- },
- {
- .name = "gfid-req",
- .load = 0,
- .check = 1,
- },
- {},
-};
-
-
-static uint64_t
-gfid_to_ino (uuid_t gfid)
-{
- uint64_t ino = 0;
- int i = 0, j = 0;
-
- for (i = 15; i > (15 - 8); i--) {
- ino += (uint64_t)(gfid[i]) << j;
- j += 8;
- }
-
- return ino;
-}
-
-
-struct mdc_local;
-typedef struct mdc_local mdc_local_t;
-
-#define MDC_STACK_UNWIND(fop, frame, params ...) do { \
- mdc_local_t *__local = NULL; \
- xlator_t *__xl = NULL; \
- if (frame) { \
- __xl = frame->this; \
- __local = frame->local; \
- frame->local = NULL; \
- } \
- STACK_UNWIND_STRICT (fop, frame, params); \
- mdc_local_wipe (__xl, __local); \
- } while (0)
-
-
-struct md_cache {
- ia_prot_t md_prot;
- uint32_t md_nlink;
- uint32_t md_uid;
- uint32_t md_gid;
- uint32_t md_atime;
- uint32_t md_atime_nsec;
- uint32_t md_mtime;
- uint32_t md_mtime_nsec;
- uint32_t md_ctime;
- uint32_t md_ctime_nsec;
- uint64_t md_rdev;
- uint64_t md_size;
- uint64_t md_blocks;
- dict_t *xattr;
- char *linkname;
- time_t ia_time;
- time_t xa_time;
- gf_lock_t lock;
-};
-
-
-struct mdc_local {
- loc_t loc;
- loc_t loc2;
- fd_t *fd;
- char *linkname;
- dict_t *xattr;
-};
-
-
-int
-__mdc_inode_ctx_get (xlator_t *this, inode_t *inode, struct md_cache **mdc_p)
-{
- int ret = 0;
- struct md_cache *mdc = NULL;
- uint64_t mdc_int = 0;
-
- ret = __inode_ctx_get (inode, this, &mdc_int);
- mdc = (void *) (long) (mdc_int);
- if (ret == 0 && mdc_p)
- *mdc_p = mdc;
-
- return ret;
-}
-
-
-int
-mdc_inode_ctx_get (xlator_t *this, inode_t *inode, struct md_cache **mdc_p)
-{
- int ret;
-
- LOCK(&inode->lock);
- {
- ret = __mdc_inode_ctx_get (this, inode, mdc_p);
- }
- UNLOCK(&inode->lock);
-
- return ret;
-}
-
-
-int
-__mdc_inode_ctx_set (xlator_t *this, inode_t *inode, struct md_cache *mdc)
-{
- int ret = 0;
- uint64_t mdc_int = 0;
-
- mdc_int = (long) mdc;
- ret = __inode_ctx_set2 (inode, this, &mdc_int, 0);
-
- return ret;
-}
-
-
-int
-mdc_inode_ctx_set (xlator_t *this, inode_t *inode, struct md_cache *mdc)
-{
- int ret;
-
- LOCK(&inode->lock);
- {
- ret = __mdc_inode_ctx_set (this, inode, mdc);
- }
- UNLOCK(&inode->lock);
-
- return ret;
-}
-
-
-mdc_local_t *
-mdc_local_get (call_frame_t *frame)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
- if (local)
- goto out;
-
- local = GF_CALLOC (sizeof (*local), 1, gf_mdc_mt_mdc_local_t);
- if (!local)
- goto out;
-
- frame->local = local;
-out:
- return local;
-}
-
-
-void
-mdc_local_wipe (xlator_t *this, mdc_local_t *local)
-{
- if (!local)
- return;
-
- loc_wipe (&local->loc);
-
- loc_wipe (&local->loc2);
-
- if (local->fd)
- fd_unref (local->fd);
-
- GF_FREE (local->linkname);
-
- if (local->xattr)
- dict_unref (local->xattr);
-
- GF_FREE (local);
- return;
-}
-
-
-int
-mdc_inode_wipe (xlator_t *this, inode_t *inode)
-{
- int ret = 0;
- uint64_t mdc_int = 0;
- struct md_cache *mdc = NULL;
-
- ret = inode_ctx_del (inode, this, &mdc_int);
- if (ret != 0)
- goto out;
-
- mdc = (void *) (long) mdc_int;
-
- if (mdc->xattr)
- dict_unref (mdc->xattr);
-
- GF_FREE (mdc->linkname);
-
- GF_FREE (mdc);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-struct md_cache *
-mdc_inode_prep (xlator_t *this, inode_t *inode)
-{
- int ret = 0;
- struct md_cache *mdc = NULL;
-
- LOCK (&inode->lock);
- {
- ret = __mdc_inode_ctx_get (this, inode, &mdc);
- if (ret == 0)
- goto unlock;
-
- mdc = GF_CALLOC (sizeof (*mdc), 1, gf_mdc_mt_md_cache_t);
- if (!mdc) {
- gf_log (this->name, GF_LOG_ERROR,
- "out of memory :(");
- goto unlock;
- }
-
- LOCK_INIT (&mdc->lock);
-
- ret = __mdc_inode_ctx_set (this, inode, mdc);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "out of memory :(");
- GF_FREE (mdc);
- mdc = NULL;
- }
- }
-unlock:
- UNLOCK (&inode->lock);
-
- return mdc;
-}
-
-
-static gf_boolean_t
-is_md_cache_iatt_valid (xlator_t *this, struct md_cache *mdc)
-{
- struct mdc_conf *conf = NULL;
- time_t now = 0;
- gf_boolean_t ret = _gf_true;
- conf = this->private;
-
- time (&now);
-
- LOCK (&mdc->lock);
- {
- if (now >= (mdc->ia_time + conf->timeout))
- ret = _gf_false;
- }
- UNLOCK (&mdc->lock);
-
- return ret;
-}
-
-
-static gf_boolean_t
-is_md_cache_xatt_valid (xlator_t *this, struct md_cache *mdc)
-{
- struct mdc_conf *conf = NULL;
- time_t now = 0;
- gf_boolean_t ret = _gf_true;
-
- conf = this->private;
-
- time (&now);
-
- LOCK (&mdc->lock);
- {
- if (now >= (mdc->xa_time + conf->timeout))
- ret = _gf_false;
- }
- UNLOCK (&mdc->lock);
-
- return ret;
-}
-
-
-void
-mdc_from_iatt (struct md_cache *mdc, struct iatt *iatt)
-{
- mdc->md_prot = iatt->ia_prot;
- mdc->md_nlink = iatt->ia_nlink;
- mdc->md_uid = iatt->ia_uid;
- mdc->md_gid = iatt->ia_gid;
- mdc->md_atime = iatt->ia_atime;
- mdc->md_atime_nsec = iatt->ia_atime_nsec;
- mdc->md_mtime = iatt->ia_mtime;
- mdc->md_mtime_nsec = iatt->ia_mtime_nsec;
- mdc->md_ctime = iatt->ia_ctime;
- mdc->md_ctime_nsec = iatt->ia_ctime_nsec;
- mdc->md_rdev = iatt->ia_rdev;
- mdc->md_size = iatt->ia_size;
- mdc->md_blocks = iatt->ia_blocks;
-}
-
-
-void
-mdc_to_iatt (struct md_cache *mdc, struct iatt *iatt)
-{
- iatt->ia_prot = mdc->md_prot;
- iatt->ia_nlink = mdc->md_nlink;
- iatt->ia_uid = mdc->md_uid;
- iatt->ia_gid = mdc->md_gid;
- iatt->ia_atime = mdc->md_atime;
- iatt->ia_atime_nsec = mdc->md_atime_nsec;
- iatt->ia_mtime = mdc->md_mtime;
- iatt->ia_mtime_nsec = mdc->md_mtime_nsec;
- iatt->ia_ctime = mdc->md_ctime;
- iatt->ia_ctime_nsec = mdc->md_ctime_nsec;
- iatt->ia_rdev = mdc->md_rdev;
- iatt->ia_size = mdc->md_size;
- iatt->ia_blocks = mdc->md_blocks;
-}
-
-
-int
-mdc_inode_iatt_set_validate(xlator_t *this, inode_t *inode, struct iatt *prebuf,
- struct iatt *iatt)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- mdc = mdc_inode_prep (this, inode);
- if (!mdc)
- goto out;
-
- LOCK (&mdc->lock);
- {
- if (!iatt || !iatt->ia_ctime) {
- mdc->ia_time = 0;
- goto unlock;
- }
-
- /*
- * Invalidate the inode if the mtime or ctime has changed
- * and the prebuf doesn't match the value we have cached.
- * TODO: writev returns with a NULL iatt due to
- * performance/write-behind, causing invalidation on writes.
- */
- if (IA_ISREG(inode->ia_type) &&
- ((iatt->ia_mtime != mdc->md_mtime) ||
- (iatt->ia_ctime != mdc->md_ctime)))
- if (!prebuf || (prebuf->ia_ctime != mdc->md_ctime) ||
- (prebuf->ia_mtime != mdc->md_mtime))
- inode_invalidate(inode);
-
- mdc_from_iatt (mdc, iatt);
-
- time (&mdc->ia_time);
- }
-unlock:
- UNLOCK (&mdc->lock);
- ret = 0;
-out:
- return ret;
-}
-
-int mdc_inode_iatt_set(xlator_t *this, inode_t *inode, struct iatt *iatt)
-{
- return mdc_inode_iatt_set_validate(this, inode, NULL, iatt);
-}
-
-int
-mdc_inode_iatt_get (xlator_t *this, inode_t *inode, struct iatt *iatt)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- if (mdc_inode_ctx_get (this, inode, &mdc) != 0)
- goto out;
-
- if (!is_md_cache_iatt_valid (this, mdc))
- goto out;
-
- LOCK (&mdc->lock);
- {
- mdc_to_iatt (mdc, iatt);
- }
- UNLOCK (&mdc->lock);
-
- uuid_copy (iatt->ia_gfid, inode->gfid);
- iatt->ia_ino = gfid_to_ino (inode->gfid);
- iatt->ia_dev = 42;
- iatt->ia_type = inode->ia_type;
-
- ret = 0;
-out:
- return ret;
-}
-
-struct updatedict {
- dict_t *dict;
- int ret;
-};
-
-static void
-updatefn(dict_t *dict, char *key, data_t *value, void *data)
-{
- struct updatedict *u = data;
- const char *mdc_key;
- int i = 0;
-
- for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) {
- if (!mdc_keys[i].check)
- continue;
- if (strcmp(mdc_key, key))
- continue;
-
- if (!u->dict) {
- u->dict = dict_new();
- if (!u->dict) {
- u->ret = -1;
- return;
- }
- }
-
- if (dict_set(u->dict, key, value) < 0) {
- u->ret = -1;
- return;
- }
-
- break;
- }
-}
-
-static int
-mdc_dict_update(dict_t **tgt, dict_t *src)
-{
- struct updatedict u = {
- .dict = *tgt,
- .ret = 0,
- };
-
- dict_foreach(src, updatefn, &u);
-
- if (*tgt)
- return u.ret;
-
- if ((u.ret < 0) && u.dict) {
- dict_unref(u.dict);
- return u.ret;
- }
-
- *tgt = u.dict;
-
- return u.ret;
-}
-
-int
-mdc_inode_xatt_set (xlator_t *this, inode_t *inode, dict_t *dict)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
- dict_t *newdict = NULL;
-
- mdc = mdc_inode_prep (this, inode);
- if (!mdc)
- goto out;
-
- if (!dict)
- goto out;
-
- LOCK (&mdc->lock);
- {
- if (mdc->xattr) {
- dict_unref (mdc->xattr);
- mdc->xattr = NULL;
- }
-
- ret = mdc_dict_update(&newdict, dict);
- if (ret < 0) {
- UNLOCK(&mdc->lock);
- goto out;
- }
-
- if (newdict)
- mdc->xattr = newdict;
-
- time (&mdc->xa_time);
- }
- UNLOCK (&mdc->lock);
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-mdc_inode_xatt_update (xlator_t *this, inode_t *inode, dict_t *dict)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- mdc = mdc_inode_prep (this, inode);
- if (!mdc)
- goto out;
-
- if (!dict)
- goto out;
-
- LOCK (&mdc->lock);
- {
- ret = mdc_dict_update(&mdc->xattr, dict);
- if (ret < 0) {
- UNLOCK(&mdc->lock);
- goto out;
- }
-
- time (&mdc->xa_time);
- }
- UNLOCK (&mdc->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-
-int
-mdc_inode_xatt_get (xlator_t *this, inode_t *inode, dict_t **dict)
-{
- int ret = -1;
- struct md_cache *mdc = NULL;
-
- if (mdc_inode_ctx_get (this, inode, &mdc) != 0)
- goto out;
-
- if (!is_md_cache_xatt_valid (this, mdc))
- goto out;
-
- LOCK (&mdc->lock);
- {
- if (!mdc->xattr)
- goto unlock;
-
- if (dict)
- *dict = dict_ref (mdc->xattr);
-
- ret = 0;
- }
-unlock:
- UNLOCK (&mdc->lock);
-
-out:
- return ret;
-}
-
-
-void
-mdc_load_reqs (xlator_t *this, dict_t *dict)
-{
- const char *mdc_key = NULL;
- int i = 0;
- int ret = 0;
-
- for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) {
- if (!mdc_keys[i].load)
- continue;
- ret = dict_set_int8 (dict, (char *)mdc_key, 0);
- if (ret)
- return;
- }
-}
-
-
-struct checkpair {
- int ret;
- dict_t *rsp;
-};
-
-
-static int
-is_mdc_key_satisfied (const char *key)
-{
- const char *mdc_key = NULL;
- int i = 0;
-
- if (!key)
- return 0;
-
- for (mdc_key = mdc_keys[i].name; (mdc_key = mdc_keys[i].name); i++) {
- if (!mdc_keys[i].check)
- continue;
- if (strcmp (mdc_key, key) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static void
-checkfn (dict_t *this, char *key, data_t *value, void *data)
-{
- struct checkpair *pair = data;
-
- if (!is_mdc_key_satisfied (key))
- pair->ret = 0;
-}
-
-
-int
-mdc_xattr_satisfied (xlator_t *this, dict_t *req, dict_t *rsp)
-{
- struct checkpair pair = {
- .ret = 1,
- .rsp = rsp,
- };
-
- dict_foreach (req, checkfn, &pair);
-
- return pair.ret;
-}
-
-
-int
-mdc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *stbuf, dict_t *dict, struct iatt *postparent)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, stbuf);
- mdc_inode_xatt_set (this, local->loc.inode, dict);
- }
-out:
- MDC_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, stbuf,
- dict, postparent);
- return 0;
-}
-
-
-int
-mdc_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
-{
- int ret = 0;
- struct iatt stbuf = {0, };
- struct iatt postparent = {0, };
- dict_t *xattr_rsp = NULL;
- mdc_local_t *local = NULL;
-
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- loc_copy (&local->loc, loc);
-
- ret = mdc_inode_iatt_get (this, loc->inode, &stbuf);
- if (ret != 0)
- goto uncached;
-
- if (xdata) {
- ret = mdc_inode_xatt_get (this, loc->inode, &xattr_rsp);
- if (ret != 0)
- goto uncached;
-
- if (!mdc_xattr_satisfied (this, xdata, xattr_rsp))
- goto uncached;
- }
-
- MDC_STACK_UNWIND (lookup, frame, 0, 0, loc->inode, &stbuf,
- xattr_rsp, &postparent);
-
- if (xattr_rsp)
- dict_unref (xattr_rsp);
-
- return 0;
-
-uncached:
- if (xdata)
- mdc_load_reqs (this, xdata);
-
- STACK_WIND (frame, mdc_lookup_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->lookup, loc, xdata);
-
- if (xattr_rsp)
- dict_unref (xattr_rsp);
-
- return 0;
-}
-
-
-int
-mdc_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- if (op_ret != 0)
- goto out;
-
- local = frame->local;
- if (!local)
- goto out;
-
- mdc_inode_iatt_set (this, local->loc.inode, buf);
-
-out:
- MDC_STACK_UNWIND (stat, frame, op_ret, op_errno, buf, xdata);
-
- return 0;
-}
-
-
-int
-mdc_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
-{
- int ret;
- struct iatt stbuf;
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- loc_copy (&local->loc, loc);
-
- ret = mdc_inode_iatt_get (this, loc->inode, &stbuf);
- if (ret != 0)
- goto uncached;
-
- MDC_STACK_UNWIND (stat, frame, 0, 0, &stbuf, xdata);
-
- return 0;
-
-uncached:
- STACK_WIND (frame, mdc_stat_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->stat,
- loc, xdata);
- return 0;
-}
-
-
-int
-mdc_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- if (op_ret != 0)
- goto out;
-
- local = frame->local;
- if (!local)
- goto out;
-
- mdc_inode_iatt_set (this, local->fd->inode, buf);
-
-out:
- MDC_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
-
- return 0;
-}
-
-
-int
-mdc_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- int ret;
- struct iatt stbuf;
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- local->fd = fd_ref (fd);
-
- ret = mdc_inode_iatt_get (this, fd->inode, &stbuf);
- if (ret != 0)
- goto uncached;
-
- MDC_STACK_UNWIND (fstat, frame, 0, 0, &stbuf, xdata);
-
- return 0;
-
-uncached:
- STACK_WIND (frame, mdc_fstat_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat,
- fd, xdata);
- return 0;
-}
-
-
-int
-mdc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->loc.inode = inode_ref (loc->inode);
-
- STACK_WIND (frame, mdc_truncate_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->truncate,
- loc, offset, xdata);
- return 0;
-}
-
-
-int
-mdc_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame, mdc_ftruncate_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->ftruncate,
- fd, offset, xdata);
- return 0;
-}
-
-
-int
-mdc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, buf);
- mdc_inode_xatt_set (this, local->loc.inode, local->xattr);
- }
-out:
- MDC_STACK_UNWIND (mknod, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, dev_t rdev, mode_t umask, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
- local->xattr = dict_ref (xdata);
-
- STACK_WIND (frame, mdc_mknod_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mknod,
- loc, mode, rdev, umask, xdata);
- return 0;
-}
-
-
-int
-mdc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, buf);
- mdc_inode_xatt_set (this, local->loc.inode, local->xattr);
- }
-out:
- MDC_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, mode_t umask, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
- local->xattr = dict_ref (xdata);
-
- STACK_WIND (frame, mdc_mkdir_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->mkdir,
- loc, mode, umask, xdata);
- return 0;
-}
-
-
-int
-mdc_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, NULL);
- }
-
-out:
- MDC_STACK_UNWIND (unlink, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
-
- STACK_WIND (frame, mdc_unlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
- return 0;
-}
-
-
-int
-mdc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
-out:
- MDC_STACK_UNWIND (rmdir, frame, op_ret, op_errno,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
-
- STACK_WIND (frame, mdc_rmdir_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir,
- loc, flag, xdata);
- return 0;
-}
-
-
-int
-mdc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, buf);
- }
-out:
- MDC_STACK_UNWIND (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
- loc_t *loc, mode_t umask, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
-
- local->linkname = gf_strdup (linkname);
-
- STACK_WIND (frame, mdc_symlink_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->symlink,
- linkname, loc, umask, xdata);
- return 0;
-}
-
-
-int
-mdc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postoldparent);
- }
-
- if (local->loc.inode) {
- /* TODO: fix dht_rename() not to return linkfile
- attributes before setting attributes here
- */
-
- mdc_inode_iatt_set (this, local->loc.inode, NULL);
- }
-
- if (local->loc2.parent) {
- mdc_inode_iatt_set (this, local->loc2.parent, postnewparent);
- }
-out:
- MDC_STACK_UNWIND (rename, frame, op_ret, op_errno, buf,
- preoldparent, postoldparent, prenewparent,
- postnewparent, xdata);
- return 0;
-}
-
-
-int
-mdc_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, oldloc);
- loc_copy (&local->loc2, newloc);
-
- STACK_WIND (frame, mdc_rename_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
- return 0;
-}
-
-
-int
-mdc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf,
- struct iatt *preparent, struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, local->loc.inode, buf);
- }
-
- if (local->loc2.parent) {
- mdc_inode_iatt_set (this, local->loc2.parent, postparent);
- }
-out:
- MDC_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, oldloc);
- loc_copy (&local->loc2, newloc);
-
- STACK_WIND (frame, mdc_link_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
- return 0;
-}
-
-
-int
-mdc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
- struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- if (local->loc.parent) {
- mdc_inode_iatt_set (this, local->loc.parent, postparent);
- }
-
- if (local->loc.inode) {
- mdc_inode_iatt_set (this, inode, buf);
- mdc_inode_xatt_set (this, local->loc.inode, local->xattr);
- }
-out:
- MDC_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
- return 0;
-}
-
-
-int
-mdc_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
- local->xattr = dict_ref (xdata);
-
- STACK_WIND (frame, mdc_create_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
- return 0;
-}
-
-
-int
-mdc_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set (this, local->fd->inode, stbuf);
-
-out:
- MDC_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
-
- return 0;
-}
-
-
-int
-mdc_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame, mdc_readv_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
- return 0;
-}
-
-
-int
-mdc_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret == -1)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int count, off_t offset, uint32_t flags, struct iobref *iobref,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame, mdc_writev_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
- return 0;
-}
-
-
-int
-mdc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0) {
- mdc_inode_iatt_set (this, local->loc.inode, NULL);
- goto out;
- }
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->loc.inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (setattr, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int valid, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
-
- STACK_WIND (frame, mdc_setattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->setattr,
- loc, stbuf, valid, xdata);
- return 0;
-}
-
-
-int
-mdc_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int valid, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame, mdc_fsetattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetattr,
- fd, stbuf, valid, xdata);
- return 0;
-}
-
-
-int
-mdc_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno,
- struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_iatt_set_validate(this, local->fd->inode, prebuf, postbuf);
-
-out:
- MDC_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
-
- return 0;
-}
-
-
-int
-mdc_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int datasync,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
-
- STACK_WIND (frame, mdc_fsync_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsync,
- fd, datasync, xdata);
- return 0;
-}
-
-
-int
-mdc_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_xatt_update (this, local->loc.inode, local->xattr);
-
-out:
- MDC_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-
-int
-mdc_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xattr, int flags, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- loc_copy (&local->loc, loc);
- local->xattr = dict_ref (xattr);
-
- STACK_WIND (frame, mdc_setxattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->setxattr,
- loc, xattr, flags, xdata);
- return 0;
-}
-
-
-int
-mdc_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = frame->local;
-
- if (op_ret != 0)
- goto out;
-
- if (!local)
- goto out;
-
- mdc_inode_xatt_update (this, local->fd->inode, local->xattr);
-
-out:
- MDC_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
-
- return 0;
-}
-
-
-int
-mdc_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *xattr, int flags, dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- local = mdc_local_get (frame);
-
- local->fd = fd_ref (fd);
- local->xattr = dict_ref (xattr);
-
- STACK_WIND (frame, mdc_fsetxattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr,
- fd, xattr, flags, xdata);
- return 0;
-}
-
-int
-mdc_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- if (op_ret != 0)
- goto out;
-
- local = frame->local;
- if (!local)
- goto out;
-
- mdc_inode_xatt_update (this, local->loc.inode, xattr);
-
-out:
- MDC_STACK_UNWIND (getxattr, frame, op_ret, op_errno, xattr, xdata);
-
- return 0;
-}
-
-
-int
-mdc_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *key,
- dict_t *xdata)
-{
- int ret;
- mdc_local_t *local = NULL;
- dict_t *xattr = NULL;
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- loc_copy (&local->loc, loc);
-
- if (!is_mdc_key_satisfied (key))
- goto uncached;
-
- ret = mdc_inode_xatt_get (this, loc->inode, &xattr);
- if (ret != 0)
- goto uncached;
-
- if (!dict_get (xattr, (char *)key))
- goto uncached;
-
- MDC_STACK_UNWIND (getxattr, frame, 0, 0, xattr, xdata);
-
- return 0;
-
-uncached:
- STACK_WIND (frame, mdc_getxattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr,
- loc, key, xdata);
- return 0;
-}
-
-
-int
-mdc_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xattr,
- dict_t *xdata)
-{
- mdc_local_t *local = NULL;
-
- if (op_ret != 0)
- goto out;
-
- local = frame->local;
- if (!local)
- goto out;
-
- mdc_inode_xatt_update (this, local->fd->inode, xattr);
-
-out:
- MDC_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, xattr, xdata);
-
- return 0;
-}
-
-
-int
-mdc_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *key,
- dict_t *xdata)
-{
- int ret;
- mdc_local_t *local = NULL;
- dict_t *xattr = NULL;
-
- local = mdc_local_get (frame);
- if (!local)
- goto uncached;
-
- local->fd = fd_ref (fd);
-
- if (!is_mdc_key_satisfied (key))
- goto uncached;
-
- ret = mdc_inode_xatt_get (this, fd->inode, &xattr);
- if (ret != 0)
- goto uncached;
-
- if (!dict_get (xattr, (char *)key))
- goto uncached;
-
- MDC_STACK_UNWIND (fgetxattr, frame, 0, 0, xattr, xdata);
-
- return 0;
-
-uncached:
- STACK_WIND (frame, mdc_fgetxattr_cbk,
- FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr,
- fd, key, xdata);
- return 0;
-}
-
-
-int
-mdc_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, gf_dirent_t *entries, dict_t *xdata)
-{
- gf_dirent_t *entry = NULL;
-
- if (op_ret <= 0)
- goto unwind;
-
- list_for_each_entry (entry, &entries->list, list) {
- if (!entry->inode)
- continue;
- mdc_inode_iatt_set (this, entry->inode, &entry->d_stat);
- mdc_inode_xatt_set (this, entry->inode, entry->dict);
- }
-
-unwind:
- STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata);
- return 0;
-}
-
-
-int
-mdc_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
-{
- STACK_WIND (frame, mdc_readdirp_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp,
- fd, size, offset, xdata);
- return 0;
-}
-
-
-int
-mdc_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, dict_t *xdata)
-{
- int need_unref = 0;
-
- if (!xdata) {
- xdata = dict_new ();
- need_unref = 1;
- }
-
- if (xdata)
- mdc_load_reqs (this, xdata);
-
- STACK_WIND (frame, mdc_readdirp_cbk,
- FIRST_CHILD (this), FIRST_CHILD (this)->fops->readdirp,
- fd, size, offset, xdata);
-
- if (need_unref && xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-mdc_forget (xlator_t *this, inode_t *inode)
-{
- mdc_inode_wipe (this, inode);
-
- return 0;
-}
-
-
-int
-is_strpfx (const char *str1, const char *str2)
-{
- /* is one of the string a prefix of the other? */
- int i;
-
- for (i = 0; str1[i] == str2[i]; i++) {
- if (!str1[i] || !str2[i])
- break;
- }
-
- return !(str1[i] && str2[i]);
-}
-
-
-int
-mdc_key_load_set (struct mdc_key *keys, char *pattern, gf_boolean_t val)
-{
- struct mdc_key *key = NULL;
-
- for (key = keys; key->name; key++) {
- if (is_strpfx (key->name, pattern))
- key->load = val;
- }
-
- return 0;
-}
-
-
-int
-reconfigure (xlator_t *this, dict_t *options)
-{
- struct mdc_conf *conf = NULL;
-
- conf = this->private;
-
- GF_OPTION_RECONF ("md-cache-timeout", conf->timeout, options, int32, out);
-
- GF_OPTION_RECONF ("cache-selinux", conf->cache_selinux, options, bool, out);
- mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux);
-
- GF_OPTION_RECONF ("cache-posix-acl", conf->cache_posix_acl, options, bool, out);
- mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl);
-
-out:
- return 0;
-}
-
-int32_t
-mem_acct_init (xlator_t *this)
-{
- int ret = -1;
-
- ret = xlator_mem_acct_init (this, gf_mdc_mt_end + 1);
- return ret;
-}
-
-int
-init (xlator_t *this)
-{
- struct mdc_conf *conf = NULL;
-
- conf = GF_CALLOC (sizeof (*conf), 1, gf_mdc_mt_mdc_conf_t);
- if (!conf) {
- gf_log (this->name, GF_LOG_ERROR,
- "out of memory");
- return -1;
- }
-
- GF_OPTION_INIT ("md-cache-timeout", conf->timeout, int32, out);
-
- GF_OPTION_INIT ("cache-selinux", conf->cache_selinux, bool, out);
- mdc_key_load_set (mdc_keys, "security.", conf->cache_selinux);
-
- GF_OPTION_INIT ("cache-posix-acl", conf->cache_posix_acl, bool, out);
- mdc_key_load_set (mdc_keys, "system.posix_acl_", conf->cache_posix_acl);
-out:
- this->private = conf;
-
- return 0;
-}
-
-
-void
-fini (xlator_t *this)
-{
- return;
-}
-
-
-struct xlator_fops fops = {
- .lookup = mdc_lookup,
- .stat = mdc_stat,
- .fstat = mdc_fstat,
- .truncate = mdc_truncate,
- .ftruncate = mdc_ftruncate,
- .mknod = mdc_mknod,
- .mkdir = mdc_mkdir,
- .unlink = mdc_unlink,
- .rmdir = mdc_rmdir,
- .symlink = mdc_symlink,
- .rename = mdc_rename,
- .link = mdc_link,
- .create = mdc_create,
- .readv = mdc_readv,
- .writev = mdc_writev,
- .setattr = mdc_setattr,
- .fsetattr = mdc_fsetattr,
- .fsync = mdc_fsync,
- .setxattr = mdc_setxattr,
- .fsetxattr = mdc_fsetxattr,
- .getxattr = mdc_getxattr,
- .fgetxattr = mdc_fgetxattr,
- .readdirp = mdc_readdirp,
- .readdir = mdc_readdir
-};
-
-
-struct xlator_cbks cbks = {
- .forget = mdc_forget,
-};
-
-struct volume_options options[] = {
- { .key = {"cache-selinux"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false",
- },
- { .key = {"cache-posix-acl"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false",
- },
- { .key = {"md-cache-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .min = 0,
- .max = 60,
- .default_value = "1",
- .description = "Time period after which cache has to be refreshed",
- },
-};
diff --git a/xlators/performance/quick-read/src/quick-read-mem-types.h b/xlators/performance/quick-read/src/quick-read-mem-types.h
index 73c87c819..972fdb0d8 100644
--- a/xlators/performance/quick-read/src/quick-read-mem-types.h
+++ b/xlators/performance/quick-read/src/quick-read-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __QR_MEM_TYPES_H__
@@ -16,11 +25,11 @@
enum gf_qr_mem_types_ {
gf_qr_mt_qr_inode_t = gf_common_mt_end + 1,
gf_qr_mt_qr_fd_ctx_t,
+ gf_qr_mt_qr_local_t,
gf_qr_mt_iovec,
gf_qr_mt_qr_conf_t,
gf_qr_mt_qr_priority_t,
gf_qr_mt_qr_private_t,
- gf_qr_mt_qr_unlink_ctx_t,
gf_qr_mt_end
};
#endif
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
index 349ea7789..465881080 100644
--- a/xlators/performance/quick-read/src/quick-read.c
+++ b/xlators/performance/quick-read/src/quick-read.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include "quick-read.h"
@@ -13,11 +22,6 @@
#define QR_DEFAULT_CACHE_SIZE 134217728
-struct volume_options options[];
-
-void
-_fd_unref (fd_t *fd);
-
void
qr_local_free (qr_local_t *local)
{
@@ -29,35 +33,20 @@ qr_local_free (qr_local_t *local)
call_stub_destroy (local->stub);
}
- GF_FREE (local->path);
+ if (local->path != NULL) {
+ GF_FREE (local->path);
+ }
- mem_put (local);
+ GF_FREE (local);
out:
return;
}
-qr_local_t *
-qr_local_new (xlator_t *this)
-{
- qr_local_t *local = NULL;
-
- local = mem_get0 (this->local_pool);
- if (local == NULL) {
- goto out;
- }
-
- LOCK_INIT (&local->lock);
- INIT_LIST_HEAD (&local->list);
-out:
- return local;
-}
-
-
int32_t
qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata);
+ off_t offset);
static void
@@ -91,25 +80,47 @@ static int32_t
qr_loc_fill (loc_t *loc, inode_t *inode, char *path)
{
int32_t ret = -1;
+ char *parent = NULL;
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", loc, out, errno, EINVAL);
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", inode, out, errno,
EINVAL);
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", path, out, errno, EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", inode->table, out, errno,
+ EINVAL);
loc->inode = inode_ref (inode);
- uuid_copy (loc->gfid, inode->gfid);
-
loc->path = gf_strdup (path);
- if (!loc->path)
+ loc->ino = inode->ino;
+
+ parent = gf_strdup (path);
+ if (parent == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ parent = dirname (parent);
+
+ loc->parent = inode_from_path (inode->table, parent);
+ if (loc->parent == NULL) {
+ ret = -1;
+ errno = EINVAL;
+ gf_log ("quick-read", GF_LOG_WARNING,
+ "cannot search parent inode for path (%s)", path);
goto out;
+ }
+ loc->name = strrchr (loc->path, '/');
ret = 0;
out:
if (ret == -1) {
qr_loc_wipe (loc);
}
+ if (parent) {
+ GF_FREE (parent);
+ }
+
return ret;
}
@@ -126,7 +137,6 @@ qr_resume_pending_ops (qr_fd_ctx_t *qr_fd_ctx, int32_t op_ret, int32_t op_errno)
LOCK (&qr_fd_ctx->lock);
{
- qr_fd_ctx->open_in_transit = 0;
list_splice_init (&qr_fd_ctx->waiting_ops,
&waiting_ops);
}
@@ -159,12 +169,6 @@ qr_fd_ctx_free (qr_fd_ctx_t *qr_fd_ctx)
GF_ASSERT (list_empty (&qr_fd_ctx->waiting_ops));
- LOCK (&qr_fd_ctx->fd->inode->lock);
- {
- list_del_init (&qr_fd_ctx->inode_list);
- }
- UNLOCK (&qr_fd_ctx->fd->inode->lock);
-
GF_FREE (qr_fd_ctx->path);
GF_FREE (qr_fd_ctx);
@@ -230,7 +234,6 @@ __qr_inode_alloc (xlator_t *this, char *path, inode_t *inode)
}
INIT_LIST_HEAD (&qr_inode->lru);
- INIT_LIST_HEAD (&qr_inode->fd_list);
priority = qr_get_priority (&priv->conf, path);
@@ -247,8 +250,6 @@ out:
void
__qr_inode_free (qr_inode_t *qr_inode)
{
- qr_fd_ctx_t *fdctx = NULL, *tmp_fdctx = NULL;
-
GF_VALIDATE_OR_GOTO ("quick-read", qr_inode, out);
if (qr_inode->xattr) {
@@ -257,15 +258,6 @@ __qr_inode_free (qr_inode_t *qr_inode)
list_del (&qr_inode->lru);
- LOCK (&qr_inode->inode->lock);
- {
- list_for_each_entry_safe (fdctx, tmp_fdctx, &qr_inode->fd_list,
- inode_list) {
- list_del_init (&fdctx->inode_list);
- }
- }
- UNLOCK (&qr_inode->inode->lock);
-
GF_FREE (qr_inode);
out:
return;
@@ -328,7 +320,7 @@ out:
int32_t
qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata, struct iatt *postparent)
+ struct iatt *buf, dict_t *dict, struct iatt *postparent)
{
data_t *content = NULL;
qr_inode_t *qr_inode = NULL;
@@ -341,7 +333,7 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_ASSERT (frame);
- if ((op_ret == -1) || (xdata == NULL)) {
+ if ((op_ret == -1) || (dict == NULL)) {
goto out;
}
@@ -376,7 +368,7 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- content = dict_get (xdata, GF_CONTENT_KEY);
+ content = dict_get (dict, GF_CONTENT_KEY);
if (content == NULL) {
goto out;
}
@@ -401,8 +393,8 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
op_errno = EINVAL;
gf_log (this->name, GF_LOG_WARNING,
"cannot set quick-read context in "
- "inode (gfid:%s)",
- uuid_utoa (inode->gfid));
+ "inode (ino:%"PRId64" gfid:%s)",
+ inode->ino, inode->gfid);
goto unlock;
}
} else {
@@ -412,38 +404,19 @@ qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
op_errno = EINVAL;
gf_log (this->name, GF_LOG_WARNING,
"cannot find quick-read context in "
- "inode (gfid:%s)",
- uuid_utoa (inode->gfid));
+ "inode (ino:%"PRId64" gfid:%s)",
+ inode->ino, uuid_utoa (inode->gfid));
goto unlock;
}
}
- /*
- * Create our own internal dict and migrate the file content
- * over to it so it isn't floating around in other translator
- * caches.
- */
if (qr_inode->xattr) {
dict_unref (qr_inode->xattr);
qr_inode->xattr = NULL;
table->cache_used -= qr_inode->stbuf.ia_size;
}
- qr_inode->xattr = dict_new();
- if (!qr_inode->xattr) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unlock;
- }
-
- if (dict_set(qr_inode->xattr, GF_CONTENT_KEY, content) < 0) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto unlock;
- }
-
- dict_del(xdata, GF_CONTENT_KEY);
-
+ qr_inode->xattr = dict_ref (dict);
qr_inode->stbuf = *buf;
table->cache_used += buf->ia_size;
@@ -460,7 +433,7 @@ out:
* FIXME: content size in dict can be greater than the size application
* requested for. Applications need to be careful till this is fixed.
*/
- QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf, xdata,
+ QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf, dict,
postparent);
return 0;
@@ -468,8 +441,7 @@ out:
int32_t
-qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
{
qr_conf_t *conf = NULL;
dict_t *new_req_dict = NULL;
@@ -497,8 +469,7 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
table = &priv->table;
-
- local = qr_local_new (this);
+ local = GF_CALLOC (1, sizeof (*local), gf_qr_mt_qr_local_t);
GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, unwind, op_errno,
ENOMEM);
@@ -521,9 +492,9 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
UNLOCK (&table->lock);
- if ((xdata == NULL) && (conf->max_file_size > 0)) {
- new_req_dict = xdata = dict_new ();
- if (xdata == NULL) {
+ if ((xattr_req == NULL) && (conf->max_file_size > 0)) {
+ new_req_dict = xattr_req = dict_new ();
+ if (xattr_req == NULL) {
op_ret = -1;
op_errno = ENOMEM;
goto unwind;
@@ -531,8 +502,8 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
if (!cached) {
- if (xdata) {
- content = dict_get (xdata, GF_CONTENT_KEY);
+ if (xattr_req) {
+ content = dict_get (xattr_req, GF_CONTENT_KEY);
if (content) {
requested_size = data_to_uint64 (content);
}
@@ -543,7 +514,7 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
size = (conf->max_file_size > requested_size) ?
conf->max_file_size : requested_size;
- op_ret = dict_set (xdata, GF_CONTENT_KEY,
+ op_ret = dict_set (xattr_req, GF_CONTENT_KEY,
data_from_uint64 (size));
if (op_ret < 0) {
op_ret = -1;
@@ -558,7 +529,7 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
}
STACK_WIND (frame, qr_lookup_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lookup, loc, xdata);
+ FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
if (new_req_dict) {
dict_unref (new_req_dict);
@@ -567,8 +538,8 @@ qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
return 0;
unwind:
- QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, NULL, NULL,
- NULL, NULL);
+ QR_STACK_UNWIND (lookup, frame, op_ret, op_errno, NULL, NULL, NULL,
+ NULL);
if (new_req_dict) {
dict_unref (new_req_dict);
@@ -580,7 +551,7 @@ unwind:
int32_t
qr_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_errno, fd_t *fd)
{
uint64_t value = 0;
int32_t ret = -1;
@@ -600,6 +571,8 @@ qr_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
local = frame->local;
if (local != NULL) {
+ local->op_ret = op_ret;
+ local->op_errno = op_errno;
is_open = local->is_open;
}
@@ -611,7 +584,8 @@ qr_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
op_errno = EINVAL;
gf_log (this->name, GF_LOG_WARNING,
"cannot find quick-read context in fd (%p) opened on "
- "inode (gfid: %s)", fd, uuid_utoa (fd->inode->gfid));
+ "inode (ino:%"PRId64" gfid: %s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
goto out;
}
@@ -666,9 +640,7 @@ qr_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
out:
if (is_open) {
- QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd, xdata);
- } else {
- STACK_DESTROY (frame->root);
+ QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
}
return 0;
@@ -677,7 +649,7 @@ out:
int32_t
qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
qr_inode_t *qr_inode = NULL;
int32_t ret = -1;
@@ -707,8 +679,6 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
LOCK_INIT (&qr_fd_ctx->lock);
INIT_LIST_HEAD (&qr_fd_ctx->waiting_ops);
- INIT_LIST_HEAD (&qr_fd_ctx->inode_list);
- qr_fd_ctx->fd = fd;
qr_fd_ctx->path = gf_strdup (loc->path);
if (qr_fd_ctx->path == NULL) {
@@ -718,6 +688,7 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
}
qr_fd_ctx->flags = flags;
+ qr_fd_ctx->wbflags = wbflags;
ret = fd_ctx_set (fd, this, (uint64_t)(long)qr_fd_ctx);
if (ret == -1) {
@@ -725,14 +696,14 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
op_errno = EINVAL;
gf_log (this->name, GF_LOG_WARNING,
"cannot set quick-read context in "
- "fd (%p) opened on inode (gfid:%s)", fd,
- uuid_utoa (fd->inode->gfid));
+ "fd (%p) opened on inode (ino:%"PRId64" gfid:%s)", fd,
+ fd->inode->ino, uuid_utoa (fd->inode->gfid));
goto unwind;
}
tmp_fd_ctx = NULL;
- local = qr_local_new (this);
+ local = GF_CALLOC (1, sizeof (*local), gf_qr_mt_qr_local_t);
if (local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -756,7 +727,7 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
}
UNLOCK (&table->lock);
- if (content_cached && (flags & O_DIRECTORY)) {
+ if (content_cached && ((flags & O_DIRECTORY) == O_DIRECTORY)) {
op_ret = -1;
op_errno = ENOTDIR;
gf_log (this->name, GF_LOG_WARNING,
@@ -766,16 +737,18 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
if (!content_cached || ((flags & O_ACCMODE) == O_WRONLY)
|| ((flags & O_TRUNC) == O_TRUNC)
- || ((flags & O_DIRECT) == O_DIRECT)) {
+ || ((flags & O_DIRECT) == O_DIRECT)
+ || ((wbflags & GF_OPEN_NOWB) != 0)) {
LOCK (&qr_fd_ctx->lock);
{
/*
* we really need not set this flag, since open is
- * not yet unwound.
+ * not yet unwounded.
*/
qr_fd_ctx->open_in_transit = 1;
- if ((flags & O_DIRECT) == O_DIRECT) {
+ if (((flags & O_DIRECT) == O_DIRECT)
+ || ((wbflags & GF_OPEN_NOWB)) != 0) {
qr_fd_ctx->disabled = 1;
}
}
@@ -784,13 +757,7 @@ qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
} else {
op_ret = 0;
op_errno = 0;
-
- LOCK (&fd->inode->lock);
- {
- list_add_tail (&qr_fd_ctx->inode_list,
- &qr_inode->fd_list);
- }
- UNLOCK (&fd->inode->lock);
+ goto unwind;
}
unwind:
@@ -798,13 +765,12 @@ unwind:
qr_fd_ctx_free (tmp_fd_ctx);
}
- QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd, NULL);
+ QR_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
return 0;
wind:
STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd,
- xdata);
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
return 0;
}
@@ -845,8 +811,7 @@ out:
static int32_t
qr_validate_cache_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
qr_inode_t *qr_inode = NULL;
qr_local_t *local = NULL;
@@ -913,15 +878,13 @@ qr_validate_cache_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
/* this is actually unwind of readv */
- QR_STACK_UNWIND (readv, frame, op_ret, op_errno, NULL, -1, NULL, NULL,
- NULL);
+ QR_STACK_UNWIND (readv, frame, op_ret, op_errno, NULL, -1, NULL, NULL);
return 0;
}
int32_t
-qr_validate_cache_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *xdata)
+qr_validate_cache_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
qr_local_t *local = NULL;
int32_t op_ret = -1, op_errno = -1;
@@ -941,10 +904,10 @@ qr_validate_cache_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
out:
if (op_ret == -1) {
qr_validate_cache_cbk (frame, NULL, this, op_ret, op_errno,
- NULL, NULL);
+ NULL);
} else {
STACK_WIND (frame, qr_validate_cache_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, xdata);
+ FIRST_CHILD (this)->fops->fstat, fd);
}
return 0;
@@ -955,16 +918,15 @@ int
qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
call_stub_t *stub)
{
- int ret = -1;
- int flags = 0;
- uint64_t value = 0;
- loc_t loc = {0, };
- char *path = NULL;
- qr_local_t *local = NULL;
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- call_stub_t *validate_stub = NULL;
- char need_open = 0, can_wind = 0, validate_cbk_called = 0;
- call_frame_t *open_frame = NULL;
+ int ret = -1;
+ int flags = 0;
+ uint64_t value = 0;
+ loc_t loc = {0, };
+ char *path = NULL;
+ qr_local_t *local = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *validate_stub = NULL;
+ char need_open = 0, can_wind = 0;
GF_ASSERT (frame);
GF_VALIDATE_OR_GOTO (frame->this->name, this, out);
@@ -972,7 +934,7 @@ qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
GF_VALIDATE_OR_GOTO (frame->this->name, stub, out);
if (frame->local == NULL) {
- local = qr_local_new (this);
+ local = GF_CALLOC (1, sizeof (*local), gf_qr_mt_qr_local_t);
if (local == NULL) {
goto out;
}
@@ -1006,12 +968,10 @@ qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
} else {
validate_stub = fop_fstat_stub (frame,
qr_validate_cache_helper,
- fd, NULL);
+ fd);
if (validate_stub == NULL) {
ret = -1;
- if (need_open) {
- qr_fd_ctx->open_in_transit = 0;
- }
+ qr_fd_ctx->open_in_transit = 0;
goto unlock;
}
@@ -1030,40 +990,24 @@ qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
if (need_open) {
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- validate_cbk_called = 1;
- goto out;
- }
-
ret = qr_loc_fill (&loc, fd->inode, path);
if (ret == -1) {
qr_resume_pending_ops (qr_fd_ctx, -1, errno);
- validate_cbk_called = 1;
- STACK_DESTROY (open_frame->root);
goto out;
}
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- &loc, flags, fd, NULL);
+ &loc, flags, fd, qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
} else if (can_wind) {
STACK_WIND (frame, qr_validate_cache_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, NULL);
+ FIRST_CHILD (this)->fops->fstat, fd);
}
ret = 0;
out:
- if ((ret < 0) && !validate_cbk_called) {
- if (frame->local == NULL) {
- call_stub_destroy (stub);
- }
-
- qr_validate_cache_cbk (frame, NULL, this, -1, errno, NULL, NULL);
- }
return ret;
}
@@ -1071,19 +1015,19 @@ out:
int32_t
qr_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int32_t op_errno, struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *stbuf, struct iobref *iobref)
{
GF_ASSERT (frame);
QR_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
return 0;
}
int32_t
qr_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
qr_local_t *local = NULL;
int32_t op_errno = EINVAL, ret = 0;
@@ -1112,19 +1056,18 @@ qr_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
}
STACK_WIND (frame, qr_readv_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->readv, fd, size, offset, flags,
- xdata);
+ FIRST_CHILD (this)->fops->readv, fd, size, offset);
return 0;
unwind:
- QR_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
+ QR_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
}
int32_t
qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t read_flags, dict_t *xdata)
+ off_t offset)
{
qr_inode_t *qr_inode = NULL;
int32_t ret = -1, op_ret = -1, op_errno = -1;
@@ -1149,7 +1092,6 @@ qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
char just_validated = 0;
qr_private_t *priv = NULL;
qr_inode_table_t *table = NULL;
- call_frame_t *open_frame = NULL;
op_ret = 0;
@@ -1178,94 +1120,106 @@ qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
LOCK (&table->lock);
{
ret = inode_ctx_get (fd->inode, this, &value);
- if (ret)
- goto unlock;
-
- qr_inode = (qr_inode_t *)(long)value;
- if (!qr_inode || !qr_inode->xattr)
- goto unlock;
-
- if (!just_validated
- && qr_need_validation (conf, qr_inode)) {
- need_validation = 1;
- goto unlock;
- }
-
- content = dict_get (qr_inode->xattr, GF_CONTENT_KEY);
+ if (ret == 0) {
+ qr_inode = (qr_inode_t *)(long)value;
+ if (qr_inode) {
+ if (qr_inode->xattr){
+ if (!just_validated
+ && qr_need_validation (conf,
+ qr_inode)) {
+ need_validation = 1;
+ goto unlock;
+ }
- stbuf = qr_inode->stbuf;
- content_cached = 1;
- list_move_tail (&qr_inode->lru,
- &table->lru[qr_inode->priority]);
+ content = dict_get (qr_inode->xattr,
+ GF_CONTENT_KEY);
- if (offset > content->len) {
- op_ret = 0;
- end = content->len;
- } else {
- if ((offset + size) > content->len) {
- op_ret = content->len - offset;
- end = content->len;
- } else {
- op_ret = size;
- end = offset + size;
- }
- }
+ stbuf = qr_inode->stbuf;
+ content_cached = 1;
+ list_move_tail (&qr_inode->lru,
+ &table->lru[qr_inode->priority]);
+
+ if (offset > content->len) {
+ op_ret = 0;
+ end = content->len;
+ } else {
+ if ((offset + size)
+ > content->len) {
+ op_ret = content->len
+ - offset;
+ end = content->len;
+ } else {
+ op_ret = size;
+ end = offset + size;
+ }
+ }
- count = (op_ret / iobuf_pool->default_page_size);
- if ((op_ret % iobuf_pool->default_page_size) != 0) {
- count++;
- }
+ count = (op_ret
+ / iobuf_pool->page_size);
+ if ((op_ret % iobuf_pool->page_size)
+ != 0) {
+ count++;
+ }
- if (count == 0) {
- op_ret = 0;
- goto unlock;
- }
+ if (count == 0) {
+ op_ret = 0;
+ goto unlock;
+ }
- vector = GF_CALLOC (count, sizeof (*vector), gf_qr_mt_iovec);
- if (vector == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- need_unwind = 1;
- goto unlock;
- }
+ vector = GF_CALLOC (count,
+ sizeof (*vector),
+ gf_qr_mt_iovec);
+ if (vector == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
- iobref = iobref_new ();
- if (iobref == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- need_unwind = 1;
- goto unlock;
- }
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
- for (i = 0; i < count; i++) {
- /* TODO: Now that we have support for variable
- io-buf-sizes, i guess we need to get rid of
- default size here */
- iobuf = iobuf_get (iobuf_pool);
- if (iobuf == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- need_unwind = 1;
- goto unlock;
- }
+ for (i = 0; i < count; i++) {
+ iobuf = iobuf_get (iobuf_pool);
+ if (iobuf == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
- start = offset + (iobuf_pool->default_page_size * i);
+ start = offset
+ +
+ (iobuf_pool->page_size
+ * i);
+
+ if (start > end) {
+ len = 0;
+ } else {
+ len = (iobuf_pool->page_size
+ > (end - start))
+ ? (end - start)
+ : iobuf_pool->page_size;
+
+ memcpy (iobuf->ptr,
+ content->data
+ + start,
+ len);
+ }
- if (start > end) {
- len = 0;
- } else {
- len = (iobuf_pool->default_page_size >
- ((end - start)) ? (end - start) :
- iobuf_pool->default_page_size);
+ iobref_add (iobref, iobuf);
+ iobuf_unref (iobuf);
- memcpy (iobuf->ptr, content->data + start, len);
+ vector[i].iov_base = iobuf->ptr;
+ vector[i].iov_len = len;
+ }
+ }
}
-
- iobref_add (iobref, iobuf);
- iobuf_unref (iobuf);
-
- vector[i].iov_base = iobuf->ptr;
- vector[i].iov_len = len;
}
}
unlock:
@@ -1274,18 +1228,23 @@ unlock:
out:
if (content_cached || need_unwind) {
QR_STACK_UNWIND (readv, frame, op_ret, op_errno, vector,
- count, &stbuf, iobref, NULL);
+ count, &stbuf, iobref);
} else if (need_validation) {
- stub = fop_readv_stub (frame, qr_readv, fd, size, offset,
- read_flags, xdata);
+ stub = fop_readv_stub (frame, qr_readv, fd, size, offset);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
goto out;
}
- qr_validate_cache (frame, this, fd, stub);
+ op_ret = qr_validate_cache (frame, this, fd, stub);
+ if (op_ret == -1) {
+ need_unwind = 1;
+ op_errno = errno;
+ call_stub_destroy (stub);
+ goto out;
+ }
} else {
if (qr_fd_ctx) {
LOCK (&qr_fd_ctx->lock);
@@ -1303,22 +1262,22 @@ out:
can_wind = 1;
} else {
if (frame->local == NULL) {
- frame->local
- = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
need_unwind = 1;
qr_fd_ctx->open_in_transit = 0;
- goto fdctx_unlock;
}
+ goto fdctx_unlock;
}
stub = fop_readv_stub (frame,
qr_readv_helper,
fd, size,
- offset,
- read_flags, xdata);
+ offset);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1349,27 +1308,23 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open,
- &loc, flags, fd, NULL);
+ &loc, flags, fd, qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
} else if (can_wind) {
STACK_WIND (frame, qr_readv_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->readv, fd, size,
- offset, read_flags, xdata);
+ offset);
}
+
}
ret:
- GF_FREE (vector);
+ if (vector) {
+ GF_FREE (vector);
+ }
if (iobref) {
iobref_unref (iobref);
@@ -1382,11 +1337,10 @@ ret:
int32_t
qr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ QR_STACK_UNWIND (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -1394,7 +1348,7 @@ qr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
qr_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t off,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -1425,32 +1379,30 @@ qr_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->writev, fd, vector, count, off,
- flags, iobref, xdata);
+ iobref);
return 0;
unwind:
- QR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t off, uint32_t wr_flags, struct iobref *iobref,
- dict_t *xdata)
-{
- uint64_t value = 0;
- int flags = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_inode_t *qr_inode = NULL;
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t op_ret = -1, op_errno = -1, ret = -1;
- char can_wind = 0, need_unwind = 0, need_open = 0;
- qr_private_t *priv = NULL;
- qr_inode_table_t *table = NULL;
- call_frame_t *open_frame = NULL;
+ int32_t count, off_t off, struct iobref *iobref)
+{
+ uint64_t value = 0;
+ int flags = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_inode_t *qr_inode = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t op_ret = -1, op_errno = -1, ret = -1;
+ char can_wind = 0, need_unwind = 0, need_open = 0;
+ qr_private_t *priv = NULL;
+ qr_inode_table_t *table = NULL;
priv = this->private;
table = &priv->table;
@@ -1489,7 +1441,9 @@ qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1500,7 +1454,7 @@ qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
stub = fop_writev_stub (frame, qr_writev_helper,
fd, vector, count, off,
- wr_flags, iobref, xdata);
+ iobref);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1520,11 +1474,11 @@ qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
}
if (need_unwind) {
- QR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (writev, frame, op_ret, op_errno, NULL, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->writev, fd, vector, count,
- off, wr_flags, iobref, xdata);
+ off, iobref);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -1532,16 +1486,9 @@ qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -1553,15 +1500,15 @@ ret:
int32_t
qr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_errno, struct iatt *buf)
{
- QR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf, xdata);
+ QR_STACK_UNWIND (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int32_t
-qr_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+qr_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -1591,27 +1538,26 @@ qr_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
STACK_WIND (frame, qr_fstat_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, xdata);
+ FIRST_CHILD (this)->fops->fstat, fd);
return 0;
unwind:
- QR_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
+ QR_STACK_UNWIND (fstat, frame, -1, op_errno, NULL);
return 0;
}
int32_t
-qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
-{
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- uint64_t value = 0;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- call_stub_t *stub = NULL;
- loc_t loc = {0, };
- char *path = NULL;
- int flags = 0;
- call_frame_t *open_frame = NULL;
+qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+ uint64_t value = 0;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ loc_t loc = {0, };
+ char *path = NULL;
+ int flags = 0;
GF_ASSERT (frame);
if ((this == NULL) || (fd == NULL)) {
@@ -1642,7 +1588,9 @@ qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1652,7 +1600,7 @@ qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
stub = fop_fstat_stub (frame, qr_fstat_helper,
- fd, xdata);
+ fd);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1673,10 +1621,10 @@ qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
unwind:
if (need_unwind) {
- QR_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL, NULL);
+ QR_STACK_UNWIND (fstat, frame, op_ret, op_errno, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_fstat_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, xdata);
+ FIRST_CHILD (this)->fops->fstat, fd);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -1684,16 +1632,9 @@ unwind:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -1706,18 +1647,17 @@ ret:
int32_t
qr_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *preop, struct iatt *postop, dict_t *xdata)
+ struct iatt *preop, struct iatt *postop)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, preop, postop,
- xdata);
+ QR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, preop, postop);
return 0;
}
int32_t
qr_fsetattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -1749,28 +1689,27 @@ qr_fsetattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
STACK_WIND (frame, qr_fsetattr_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fsetattr, fd, stbuf,
- valid, xdata);
+ valid);
return 0;
unwind:
- QR_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
qr_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
-{
- uint64_t value = 0;
- int flags = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+ struct iatt *stbuf, int32_t valid)
+{
+ uint64_t value = 0;
+ int flags = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
GF_ASSERT (frame);
if ((this == NULL) || (fd == NULL)) {
@@ -1800,7 +1739,9 @@ qr_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1811,7 +1752,7 @@ qr_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
stub = fop_fsetattr_stub (frame,
qr_fsetattr_helper,
- fd, stbuf, valid, xdata);
+ fd, stbuf, valid);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1832,12 +1773,11 @@ qr_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
out:
if (need_unwind) {
- QR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, NULL, NULL,
- NULL);
+ QR_STACK_UNWIND (fsetattr, frame, op_ret, op_errno, NULL, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_fsetattr_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsetattr, fd, stbuf,
- valid, xdata);
+ valid);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -1845,16 +1785,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -1866,17 +1799,17 @@ ret:
int32_t
qr_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata);
+ QR_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno);
return 0;
}
int32_t
qr_fsetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -1907,29 +1840,27 @@ qr_fsetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
STACK_WIND (frame, qr_fsetxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags,
- xdata);
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags);
return 0;
unwind:
- QR_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
+ QR_STACK_UNWIND (fsetxattr, frame, -1, op_errno);
return 0;
}
int32_t
qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
- int32_t flags, dict_t *xdata)
-{
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- int open_flags = 0;
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+ int32_t flags)
+{
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ int open_flags = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
GF_ASSERT (frame);
if ((this == NULL) || (fd == NULL)) {
@@ -1960,7 +1891,9 @@ qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1971,7 +1904,7 @@ qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
stub = fop_fsetxattr_stub (frame,
qr_fsetxattr_helper,
- fd, dict, flags, xdata);
+ fd, dict, flags);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1992,11 +1925,11 @@ qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
out:
if (need_unwind) {
- QR_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, NULL);
+ QR_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno);
} else if (can_wind) {
STACK_WIND (frame, qr_fsetxattr_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsetxattr, fd, dict,
- flags, xdata);
+ flags);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2004,16 +1937,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, open_flags,
- fd, NULL);
+ fd, qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -2025,17 +1951,17 @@ ret:
int32_t
qr_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict, xdata);
+ QR_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, dict);
return 0;
}
int32_t
qr_fgetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2066,28 +1992,26 @@ qr_fgetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
STACK_WIND (frame, qr_fgetxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fgetxattr, fd, name, xdata);
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
return 0;
unwind:
- QR_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
+ QR_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL);
return 0;
}
int32_t
-qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
- dict_t *xdata)
-{
- int flags = 0;
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
/*
* FIXME: Can quick-read use the extended attributes stored in the
@@ -2123,7 +2047,9 @@ qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2134,7 +2060,7 @@ qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
stub = fop_fgetxattr_stub (frame,
qr_fgetxattr_helper,
- fd, name, xdata);
+ fd, name);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2155,10 +2081,10 @@ qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
out:
if (need_unwind) {
- QR_STACK_UNWIND (open, frame, op_ret, op_errno, NULL, NULL);
+ QR_STACK_UNWIND (open, frame, op_ret, op_errno, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_fgetxattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fgetxattr, fd, name, xdata);
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2166,16 +2092,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -2187,16 +2106,16 @@ ret:
int32_t
qr_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (flush, frame, op_ret, op_errno, xdata);
+ QR_STACK_UNWIND (flush, frame, op_ret, op_errno);
return 0;
}
int32_t
-qr_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+qr_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2226,17 +2145,17 @@ qr_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
STACK_WIND (frame, qr_flush_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->flush, fd, xdata);
+ FIRST_CHILD (this)->fops->flush, fd);
return 0;
unwind:
- QR_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
+ QR_STACK_UNWIND (flush, frame, -1, op_errno);
return 0;
}
int32_t
-qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
uint64_t value = 0;
call_stub_t *stub = NULL;
@@ -2264,7 +2183,9 @@ qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
if (qr_fd_ctx->opened) {
can_wind = 1;
} else if (qr_fd_ctx->open_in_transit) {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2274,7 +2195,7 @@ qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
stub = fop_flush_stub (frame, qr_flush_helper,
- fd, xdata);
+ fd);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2298,10 +2219,10 @@ qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
out:
if (need_unwind) {
- QR_STACK_UNWIND (flush, frame, op_ret, op_errno, NULL);
+ QR_STACK_UNWIND (flush, frame, op_ret, op_errno);
} else if (can_wind) {
STACK_WIND (frame, qr_flush_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->flush, fd, xdata);
+ FIRST_CHILD (this)->fops->flush, fd);
}
return 0;
@@ -2310,10 +2231,10 @@ out:
int32_t
qr_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, xdata);
+ QR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
return 0;
}
@@ -2321,7 +2242,7 @@ qr_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
qr_fentrylk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
fd_t *fd, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
+ entrylk_type type)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2353,29 +2274,27 @@ qr_fentrylk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
STACK_WIND(frame, qr_fentrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename,
- cmd, type, xdata);
+ cmd, type);
return 0;
unwind:
- QR_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
+ QR_STACK_UNWIND (fentrylk, frame, -1, op_errno);
return 0;
}
int32_t
qr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
- const char *basename, entrylk_cmd cmd, entrylk_type type,
- dict_t *xdata)
-{
- int flags = 0;
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+ const char *basename, entrylk_cmd cmd, entrylk_type type)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
if ((this == NULL) || (fd == NULL)) {
gf_log (frame->this->name, GF_LOG_WARNING,
@@ -2405,7 +2324,9 @@ qr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2417,7 +2338,7 @@ qr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
stub = fop_fentrylk_stub (frame,
qr_fentrylk_helper,
volume, fd, basename,
- cmd, type, xdata);
+ cmd, type);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2438,11 +2359,11 @@ qr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
out:
if (need_unwind) {
- QR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno, NULL);
+ QR_STACK_UNWIND (fentrylk, frame, op_ret, op_errno);
} else if (can_wind) {
STACK_WIND (frame, qr_fentrylk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fentrylk, volume, fd,
- basename, cmd, type, xdata);
+ basename, cmd, type);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2450,16 +2371,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -2471,17 +2385,18 @@ ret:
int32_t
qr_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
+
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (finodelk, frame, op_ret, op_errno, xdata);
+ QR_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
return 0;
}
int32_t
qr_finodelk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *lock)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2512,29 +2427,27 @@ qr_finodelk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
}
STACK_WIND (frame, qr_finodelk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock,
- xdata);
+ FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock);
return 0;
unwind:
- QR_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
+ QR_STACK_UNWIND (finodelk, frame, -1, op_errno);
return 0;
}
int32_t
qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
- int32_t cmd, struct gf_flock *lock, dict_t *xdata)
-{
- int flags = 0;
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+ int32_t cmd, struct gf_flock *lock)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
if ((this == NULL) || (fd == NULL)) {
gf_log (frame->this->name, GF_LOG_WARNING,
@@ -2564,7 +2477,9 @@ qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2576,7 +2491,7 @@ qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
stub = fop_finodelk_stub (frame,
qr_finodelk_helper,
volume, fd, cmd,
- lock, xdata);
+ lock);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2597,11 +2512,11 @@ qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
out:
if (need_unwind) {
- QR_STACK_UNWIND (finodelk, frame, op_ret, op_errno, NULL);
+ QR_STACK_UNWIND (finodelk, frame, op_ret, op_errno);
} else if (can_wind) {
STACK_WIND (frame, qr_finodelk_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->finodelk, volume, fd,
- cmd, lock, xdata);
+ cmd, lock);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2609,16 +2524,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -2630,18 +2538,16 @@ ret:
int32_t
qr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
- dict_t *xdata)
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf, xdata);
+ QR_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int32_t
-qr_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
+qr_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2671,28 +2577,26 @@ qr_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
}
STACK_WIND (frame, qr_fsync_cbk, FIRST_CHILD (this),
- FIRST_CHILD(this)->fops->fsync, fd, flags, xdata);
+ FIRST_CHILD(this)->fops->fsync, fd, flags);
return 0;
unwind:
- QR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
-qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
- dict_t *xdata)
-{
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- int open_flags = 0;
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ int open_flags = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
if ((this == NULL) || (fd == NULL)) {
gf_log (frame->this->name, GF_LOG_WARNING,
@@ -2722,7 +2626,9 @@ qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2732,7 +2638,7 @@ qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
}
stub = fop_fsync_stub (frame, qr_fsync_helper,
- fd, flags, xdata);
+ fd, flags);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2753,10 +2659,10 @@ qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags,
out:
if (need_unwind) {
- QR_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (fsync, frame, op_ret, op_errno, NULL, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_fsync_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsync, fd, flags, xdata);
+ FIRST_CHILD (this)->fops->fsync, fd, flags);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2764,16 +2670,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, open_flags,
- fd, NULL);
+ fd, qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -2786,7 +2685,7 @@ ret:
int32_t
qr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
int32_t ret = 0;
uint64_t value = 0;
@@ -2843,14 +2742,14 @@ qr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
out:
QR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int32_t
qr_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -2881,29 +2780,27 @@ qr_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
return 0;
unwind:
- QR_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ QR_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
int32_t
-qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
-{
- int flags = 0;
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_local_t *local = NULL;
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_local_t *local = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
GF_ASSERT (frame);
if ((this == NULL) || (fd == NULL)) {
@@ -2919,7 +2816,7 @@ qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
}
- local = qr_local_new (this);
+ local = GF_CALLOC (1, sizeof (*local), gf_qr_mt_qr_local_t);
if (local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2947,7 +2844,7 @@ qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
} else {
stub = fop_ftruncate_stub (frame,
qr_ftruncate_helper,
- fd, offset, xdata);
+ fd, offset);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2969,10 +2866,10 @@ qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
out:
if (need_unwind) {
QR_STACK_UNWIND (ftruncate, frame, op_ret, op_errno, NULL,
- NULL, NULL);
+ NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -2980,16 +2877,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -3001,17 +2891,17 @@ ret:
int32_t
qr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct gf_flock *lock, dict_t *xdata)
+ int32_t op_errno, struct gf_flock *lock)
{
GF_ASSERT (frame);
- QR_STACK_UNWIND (lk, frame, op_ret, op_errno, lock, xdata);
+ QR_STACK_UNWIND (lk, frame, op_ret, op_errno, lock);
return 0;
}
int32_t
qr_lk_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
qr_local_t *local = NULL;
qr_fd_ctx_t *fdctx = NULL;
@@ -3041,29 +2931,28 @@ qr_lk_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
}
STACK_WIND (frame, qr_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
return 0;
unwind:
- QR_STACK_UNWIND (lk, frame, -1, op_errno, lock, xdata);
+ QR_STACK_UNWIND (lk, frame, -1, op_errno, NULL);
return 0;
}
int32_t
qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
-{
- int flags = 0;
- uint64_t value = 0;
- call_stub_t *stub = NULL;
- char *path = NULL;
- loc_t loc = {0, };
- qr_fd_ctx_t *qr_fd_ctx = NULL;
- int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
- char need_open = 0, can_wind = 0, need_unwind = 0;
- call_frame_t *open_frame = NULL;
+ struct gf_flock *lock)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
GF_ASSERT (frame);
if ((this == NULL) || (fd == NULL)) {
@@ -3094,7 +2983,9 @@ qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
if (qr_fd_ctx->opened) {
can_wind = 1;
} else {
- frame->local = qr_local_new (this);
+ frame->local = GF_CALLOC (1,
+ sizeof (qr_local_t),
+ gf_qr_mt_qr_local_t);
if (frame->local == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -3104,7 +2995,7 @@ qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
}
stub = fop_lk_stub (frame, qr_lk_helper, fd,
- cmd, lock, xdata);
+ cmd, lock);
if (stub == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -3125,10 +3016,10 @@ qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
out:
if (need_unwind) {
- QR_STACK_UNWIND (lk, frame, op_ret, op_errno, NULL, NULL);
+ QR_STACK_UNWIND (lk, frame, op_ret, op_errno, NULL);
} else if (can_wind) {
STACK_WIND (frame, qr_lk_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->lk, fd, cmd, lock, xdata);
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
} else if (need_open) {
op_ret = qr_loc_fill (&loc, fd->inode, path);
if (op_ret == -1) {
@@ -3136,16 +3027,9 @@ out:
goto ret;
}
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (qr_fd_ctx, -1, ENOMEM);
- qr_loc_wipe (&loc);
- goto ret;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->open, &loc, flags, fd,
- NULL);
+ qr_fd_ctx->wbflags);
qr_loc_wipe (&loc);
}
@@ -3156,222 +3040,6 @@ ret:
int32_t
-qr_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
-{
- QR_STACK_UNWIND (unlink, frame, op_ret, op_errno, preparent,
- postparent, xdata);
- return 0;
-}
-
-
-int32_t
-qr_unlink_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- qr_local_t *local = NULL;
- uint32_t open_count = 0;
- qr_unlink_ctx_t *unlink_ctx = NULL, *tmp = NULL;
-
- local = frame->local;
-
- LOCK (&local->lock);
- {
- open_count = --local->open_count;
- }
- UNLOCK (&local->lock);
-
- if (open_count > 0) {
- goto out;
- }
-
- list_for_each_entry_safe (unlink_ctx, tmp, &local->list, list) {
- fd_unref (unlink_ctx->fdctx->fd);
- list_del_init (&unlink_ctx->list);
- GF_FREE (unlink_ctx);
- }
-
- if (local->op_ret < 0) {
- /* unwind even if we couldn't open one fd */
- QR_STACK_UNWIND (unlink, frame, -1, local->op_errno, NULL, NULL,
- NULL);
- } else {
- STACK_WIND (frame, qr_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- }
-
-out:
- return 0;
-}
-
-
-qr_unlink_ctx_t *
-qr_unlink_ctx_new ()
-{
- qr_unlink_ctx_t *ctx = NULL;
-
- ctx = GF_CALLOC (1, sizeof (*ctx), gf_qr_mt_qr_unlink_ctx_t);
- if (ctx == NULL) {
- goto out;
- }
-
- INIT_LIST_HEAD (&ctx->list);
-out:
- return ctx;
-}
-
-
-int32_t
-qr_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
- dict_t *xdata)
-{
- int32_t op_errno = -1, ret = -1, op_ret = -1;
- uint64_t value = 0;
- char need_open = 0;
- qr_local_t *local = NULL;
- qr_fd_ctx_t *fdctx = NULL;
- call_frame_t *open_frame = NULL;
- call_stub_t *stub = NULL;
- qr_inode_t *qr_inode = NULL;
- uint32_t open_count = 0;
- qr_unlink_ctx_t *unlink_ctx = NULL;
-
- ret = inode_ctx_get (loc->inode, this, &value);
- if (ret == 0) {
- qr_inode = (qr_inode_t *)(unsigned long)value;
- }
-
- if (qr_inode == NULL) {
- goto wind;
- }
-
- local = qr_local_new (this);
- GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, unwind, op_errno,
- ENOMEM);
-
- frame->local = local;
-
- op_ret = 0;
-
- LOCK (&loc->inode->lock);
- {
- list_for_each_entry (fdctx, &qr_inode->fd_list, inode_list) {
- need_open = 0;
-
- LOCK (&fdctx->lock);
- {
- if (qr_inode->stbuf.ia_nlink == 1) {
- fdctx->disabled = 1;
- }
-
- if ((fdctx->opened)
- || (strcmp (loc->path, fdctx->path) != 0)) {
- goto unlock;
- }
-
- if (!(fdctx->opened
- || fdctx->open_in_transit)) {
- need_open = 1;
- fdctx->open_in_transit = 1;
- }
-
- if (!fdctx->opened) {
- unlink_ctx = qr_unlink_ctx_new ();
- if (unlink_ctx == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- fdctx->open_in_transit = 0;
- goto unlock;
- }
-
- stub = fop_unlink_stub (frame,
- qr_unlink_helper,
- loc, xflag,
- xdata);
- if (stub == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- fdctx->open_in_transit = 0;
- GF_FREE (unlink_ctx);
- goto unlock;
- }
-
- list_add_tail (&stub->list,
- &fdctx->waiting_ops);
-
- local->open_count++;
-
- unlink_ctx->need_open = need_open;
- __fd_ref (fdctx->fd);
- unlink_ctx->fdctx = fdctx;
- list_add_tail (&unlink_ctx->list,
- &local->list);
- }
- }
- unlock:
- UNLOCK (&fdctx->lock);
-
- if (op_ret == -1) {
- break;
- }
- }
-
- open_count = local->open_count;
- }
- UNLOCK (&loc->inode->lock);
-
- if (op_ret == -1) {
- goto unwind;
- }
-
- if (open_count == 0) {
- goto wind;
- }
-
- /* no need to hold local->lock, since we are gaurded by condition
- * local->open_count cannot be zero till we send open on
- * all the required fds. qr_unlink_helper will not modify
- * local->list till local->open_count becomes 0.
- */
- list_for_each_entry (unlink_ctx, &local->list, list) {
- if (!unlink_ctx->need_open) {
- continue;
- }
-
- fdctx = unlink_ctx->fdctx;
- open_frame = create_frame (this, this->ctx->pool);
- if (open_frame == NULL) {
- qr_resume_pending_ops (fdctx, -1, ENOMEM);
- continue;
- }
-
- STACK_WIND (open_frame, qr_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open,
- loc, fdctx->flags, fdctx->fd, fdctx->xdata);
- }
-
- return 0;
-
-unwind:
- if (local && !list_empty (&local->list)) {
- list_for_each_entry (unlink_ctx, &local->list, list) {
- qr_resume_pending_ops (unlink_ctx->fdctx, -1, op_errno);
- }
- } else {
- QR_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
- }
-
- return 0;
-
-wind:
- STACK_WIND (frame, qr_unlink_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->unlink, loc, xflag, xdata);
- return 0;
-}
-
-
-int32_t
qr_release (xlator_t *this, fd_t *fd)
{
qr_fd_ctx_t *qr_fd_ctx = NULL;
@@ -3423,104 +3091,6 @@ out:
}
-int32_t
-qr_inodectx_dump (xlator_t *this, inode_t *inode)
-{
- qr_inode_t *qr_inode = NULL;
- uint64_t value = 0;
- int32_t ret = -1;
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- char buf[256] = {0, };
- ret = inode_ctx_get (inode, this, &value);
- if (ret != 0) {
- goto out;
- }
-
- qr_inode = (qr_inode_t *)(long)value;
- if (qr_inode == NULL) {
- goto out;
- }
-
- gf_proc_dump_build_key (key_prefix, "xlator.performance.quick-read",
- "inodectx");
- gf_proc_dump_add_section (key_prefix);
-
- gf_proc_dump_write ("entire-file-cached", "%s", qr_inode->xattr ? "yes" : "no");
-
- if (qr_inode->tv.tv_sec) {
- gf_time_fmt (buf, sizeof buf, qr_inode->tv.tv_sec,
- gf_timefmt_FT);
- snprintf (buf + strlen (buf), sizeof buf - strlen (buf),
- ".%"GF_PRI_SUSECONDS, qr_inode->tv.tv_usec);
-
- gf_proc_dump_write ("last-cache-validation-time", "%s", buf);
- }
-
- ret = 0;
-out:
- return ret;
-}
-
-int32_t
-qr_fdctx_dump (xlator_t *this, fd_t *fd)
-{
- qr_fd_ctx_t *fdctx = NULL;
- uint64_t value = 0;
- int32_t ret = 0, i = 0;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
- call_stub_t *stub = NULL;
-
- ret = fd_ctx_get (fd, this, &value);
- if (ret != 0) {
- goto out;
- }
-
- fdctx = (qr_fd_ctx_t *)(long)value;
- if (fdctx == NULL) {
- goto out;
- }
-
- gf_proc_dump_build_key (key_prefix, "xlator.performance.quick-read",
- "fdctx");
- gf_proc_dump_add_section (key_prefix);
-
- gf_proc_dump_write ("fd", "%p", fd);
-
- gf_proc_dump_write ("path", "%s", fdctx->path);
-
- LOCK (&fdctx->lock);
- {
- gf_proc_dump_write ("opened", "%s", fdctx->opened ? "yes" : "no");
-
- gf_proc_dump_write ("open-in-progress", "%s", fdctx->open_in_transit ?
- "yes" : "no");
-
- gf_proc_dump_write ("caching disabled (for this fd)", "%s",
- fdctx->disabled ? "yes" : "no");
-
- gf_proc_dump_write ("flags", "%d", fdctx->flags);
-
- list_for_each_entry (stub, &fdctx->waiting_ops, list) {
- gf_proc_dump_build_key (key, "",
- "waiting-ops[%d].frame", i);
- gf_proc_dump_write (key, "%"PRId64,
- stub->frame->root->unique);
-
- gf_proc_dump_build_key (key, "",
- "waiting-ops[%d].fop", i);
- gf_proc_dump_write (key, "%s", gf_fop_list[stub->fop]);
-
- i++;
- }
- }
- UNLOCK (&fdctx->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
int
qr_priv_dump (xlator_t *this)
{
@@ -3531,6 +3101,7 @@ qr_priv_dump (xlator_t *this)
uint32_t i = 0;
qr_inode_t *curr = NULL;
uint64_t total_size = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
char key_prefix[GF_DUMP_MAX_BUF_LEN];
if (!this) {
@@ -3553,8 +3124,10 @@ qr_priv_dump (xlator_t *this)
gf_proc_dump_add_section (key_prefix);
- gf_proc_dump_write ("max_file_size", "%d", conf->max_file_size);
- gf_proc_dump_write ("cache_timeout", "%d", conf->cache_timeout);
+ gf_proc_dump_build_key (key, key_prefix, "max_file_size");
+ gf_proc_dump_write (key, "%d", conf->max_file_size);
+ gf_proc_dump_build_key (key, key_prefix, "cache_timeout");
+ gf_proc_dump_write (key, "%d", conf->cache_timeout);
if (!table) {
gf_log (this->name, GF_LOG_WARNING, "table is NULL");
@@ -3568,8 +3141,10 @@ qr_priv_dump (xlator_t *this)
}
}
- gf_proc_dump_write ("total_files_cached", "%d", file_count);
- gf_proc_dump_write ("total_cache_used", "%d", total_size);
+ gf_proc_dump_build_key (key, key_prefix, "total_files_cached");
+ gf_proc_dump_write (key, "%d", file_count);
+ gf_proc_dump_build_key (key, key_prefix, "total_cache_used");
+ gf_proc_dump_write (key, "%d", total_size);
out:
return 0;
@@ -3596,49 +3171,45 @@ mem_acct_init (xlator_t *this)
}
-static gf_boolean_t
-check_cache_size_ok (xlator_t *this, int64_t cache_size)
+int
+validate_options (xlator_t *this, char **op_errstr)
{
- int ret = _gf_true;
- uint64_t total_mem = 0;
- uint64_t max_cache_size = 0;
- volume_option_t *opt = NULL;
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- GF_ASSERT (this);
- opt = xlator_volume_option_get (this, "cache-size");
- if (!opt) {
- ret = _gf_false;
- gf_log (this->name, GF_LOG_ERROR,
- "could not get cache-size option");
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
goto out;
}
- total_mem = get_mem_size ();
- if (-1 == total_mem)
- max_cache_size = opt->max;
- else
- max_cache_size = total_mem;
-
- gf_log (this->name, GF_LOG_DEBUG, "Max cache size is %"PRIu64,
- max_cache_size);
- if (cache_size > max_cache_size) {
- ret = _gf_false;
- gf_log (this->name, GF_LOG_ERROR, "Cache size %"PRIu64
- " is greater than the max size of %"PRIu64,
- cache_size, max_cache_size);
+ if (list_empty (&this->volume_options))
goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
}
+
out:
return ret;
}
+
int
reconfigure (xlator_t *this, dict_t *options)
{
- int32_t ret = -1;
- qr_private_t *priv = NULL;
- qr_conf_t *conf = NULL;
- uint64_t cache_size_new = 0;
+ char *str = NULL;
+ int32_t ret = -1;
+ qr_private_t *priv = NULL;
+ qr_conf_t *conf = NULL;
+ int32_t cache_timeout = 0;
+ uint64_t cache_size = 0;
+
GF_VALIDATE_OR_GOTO ("quick-read", this, out);
GF_VALIDATE_OR_GOTO (this->name, this->private, out);
GF_VALIDATE_OR_GOTO (this->name, options, out);
@@ -3650,17 +3221,40 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
}
- GF_OPTION_RECONF ("cache-timeout", conf->cache_timeout, options, int32,
- out);
+ cache_timeout = conf->cache_timeout;
+ ret = dict_get_str (options, "cache-timeout", &str);
+ if (ret == 0) {
+ ret = gf_string2uint_base10 (str,
+ (unsigned int *)&conf->cache_timeout);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cache-timeout value %s", str);
+ ret = -1;
+ goto out;
+ }
+ conf->cache_timeout = cache_timeout;
+ } else {
+ conf->cache_timeout = 1;
+ }
- GF_OPTION_RECONF ("cache-size", cache_size_new, options, size, out);
- if (!check_cache_size_ok (this, cache_size_new)) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "Not reconfiguring cache-size");
- goto out;
+ cache_size = conf->cache_size;
+ ret = dict_get_str (options, "cache-size", &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &cache_size);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cache-size %s(old value used)", str);
+ conf->cache_size = cache_size;
+ ret = -1;
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "Reconfiguring cache-siz to %"PRIu64, cache_size);
+ conf->cache_size = cache_size;
+ } else {
+ conf->cache_size = QR_DEFAULT_CACHE_SIZE;
}
- conf->cache_size = cache_size_new;
ret = 0;
out:
@@ -3750,9 +3344,13 @@ qr_get_priority_list (const char *opt_str, struct list_head *first)
priority_str = strtok_r (NULL, ",", &tmp_str);
}
out:
- GF_FREE (string);
+ if (string != NULL) {
+ GF_FREE (string);
+ }
- GF_FREE (dup_str);
+ if (dup_str != NULL) {
+ GF_FREE (dup_str);
+ }
if (max_pri == -1) {
list_for_each_entry_safe (curr, tmp, first, list) {
@@ -3769,6 +3367,7 @@ out:
int32_t
init (xlator_t *this)
{
+ char *str = NULL;
int32_t ret = -1, i = 0;
qr_private_t *priv = NULL;
qr_conf_t *conf = NULL;
@@ -3793,15 +3392,44 @@ init (xlator_t *this)
LOCK_INIT (&priv->table.lock);
conf = &priv->conf;
+ conf->max_file_size = 65536;
+ ret = dict_get_str (this->options, "max-file-size",
+ &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &conf->max_file_size);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\" of \"option "
+ "max-file-size\"",
+ str);
+ ret = -1;
+ goto out;
+ }
+ }
- GF_OPTION_INIT ("max-file-size", conf->max_file_size, size, out);
-
- GF_OPTION_INIT ("cache-timeout", conf->cache_timeout, int32, out);
+ conf->cache_timeout = 1;
+ ret = dict_get_str (this->options, "cache-timeout", &str);
+ if (ret == 0) {
+ ret = gf_string2uint_base10 (str,
+ (unsigned int *)&conf->cache_timeout);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cache-timeout value %s", str);
+ ret = -1;
+ goto out;
+ }
+ }
- GF_OPTION_INIT ("cache-size", conf->cache_size, size, out);
- if (!check_cache_size_ok (this, conf->cache_size)) {
- ret = -1;
- goto out;
+ conf->cache_size = QR_DEFAULT_CACHE_SIZE;
+ ret = dict_get_str (this->options, "cache-size", &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &conf->cache_size);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cache-size value %s", str);
+ ret = -1;
+ goto out;
+ }
}
INIT_LIST_HEAD (&conf->priority_list);
@@ -3832,14 +3460,6 @@ init (xlator_t *this)
INIT_LIST_HEAD (&priv->table.lru[i]);
}
- this->local_pool = mem_pool_new (qr_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
-
ret = 0;
this->private = priv;
@@ -3853,59 +3473,8 @@ out:
void
-qr_inode_table_destroy (qr_private_t *priv)
-{
- int i = 0;
- qr_conf_t *conf = NULL;
-
- conf = &priv->conf;
-
- for (i = 0; i < conf->max_pri; i++) {
- GF_ASSERT (list_empty (&priv->table.lru[i]));
- }
-
- LOCK_DESTROY (&priv->table.lock);
-
- return;
-}
-
-
-void
-qr_conf_destroy (qr_conf_t *conf)
-{
- struct qr_priority *curr = NULL, *tmp = NULL;
-
- list_for_each_entry_safe (curr, tmp, &conf->priority_list, list) {
- list_del (&curr->list);
- GF_FREE (curr->pattern);
- GF_FREE (curr);
- }
-
- return;
-}
-
-
-void
fini (xlator_t *this)
{
- qr_private_t *priv = NULL;
-
- if (this == NULL) {
- goto out;
- }
-
- priv = this->private;
- if (priv == NULL) {
- goto out;
- }
-
- qr_inode_table_destroy (priv);
- qr_conf_destroy (&priv->conf);
-
- this->private = NULL;
-
- GF_FREE (priv);
-out:
return;
}
@@ -3924,7 +3493,6 @@ struct xlator_fops fops = {
.ftruncate = qr_ftruncate,
.lk = qr_lk,
.fsetattr = qr_fsetattr,
- .unlink = qr_unlink,
};
struct xlator_cbks cbks = {
@@ -3934,8 +3502,6 @@ struct xlator_cbks cbks = {
struct xlator_dumpops dumpops = {
.priv = qr_priv_dump,
- .inodectx = qr_inodectx_dump,
- .fdctx = qr_fdctx_dump
};
struct volume_options options[] = {
@@ -3945,20 +3511,16 @@ struct volume_options options[] = {
{ .key = {"cache-size"},
.type = GF_OPTION_TYPE_SIZET,
.min = 0,
- .max = 32 * GF_UNIT_GB,
- .default_value = "128MB",
- .description = "Size of the read cache."
+ .max = 6 * GF_UNIT_GB,
},
{ .key = {"cache-timeout"},
.type = GF_OPTION_TYPE_INT,
.min = 1,
- .max = 60,
- .default_value = "1",
+ .max = 60
},
{ .key = {"max-file-size"},
.type = GF_OPTION_TYPE_SIZET,
.min = 0,
.max = 1 * GF_UNIT_KB * 1000,
- .default_value = "64KB",
},
};
diff --git a/xlators/performance/quick-read/src/quick-read.h b/xlators/performance/quick-read/src/quick-read.h
index 10a04e79c..3b5c90094 100644
--- a/xlators/performance/quick-read/src/quick-read.h
+++ b/xlators/performance/quick-read/src/quick-read.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __QUICK_READ_H
@@ -43,24 +52,18 @@ struct qr_fd_ctx {
int wbflags;
struct list_head waiting_ops;
gf_lock_t lock;
- struct list_head inode_list;
- fd_t *fd;
- dict_t *xdata;
};
typedef struct qr_fd_ctx qr_fd_ctx_t;
struct qr_local {
- char is_open;
- char *path;
- char just_validated;
- fd_t *fd;
- int open_flags;
- int32_t op_ret;
- int32_t op_errno;
- uint32_t open_count;
- call_stub_t *stub;
- struct list_head list;
- gf_lock_t lock;
+ char is_open;
+ char *path;
+ char just_validated;
+ fd_t *fd;
+ int open_flags;
+ int32_t op_ret;
+ int32_t op_errno;
+ call_stub_t *stub;
};
typedef struct qr_local qr_local_t;
@@ -71,8 +74,6 @@ struct qr_inode {
struct iatt stbuf;
struct timeval tv;
struct list_head lru;
- struct list_head fd_list;
- struct list_head unlinked_dentries;
};
typedef struct qr_inode qr_inode_t;
@@ -105,13 +106,6 @@ struct qr_private {
};
typedef struct qr_private qr_private_t;
-struct qr_unlink_ctx {
- struct list_head list;
- qr_fd_ctx_t *fdctx;
- char need_open;
-};
-typedef struct qr_unlink_ctx qr_unlink_ctx_t;
-
void qr_local_free (qr_local_t *local);
#define QR_STACK_UNWIND(op, frame, params ...) do { \
diff --git a/xlators/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c
index e79e7ae78..dfa9dc22b 100644
--- a/xlators/performance/read-ahead/src/page.c
+++ b/xlators/performance/read-ahead/src/page.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -133,8 +142,7 @@ ra_waitq_return (ra_waitq_t *waitq)
int
ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
ra_local_t *local = NULL;
off_t pending_offset = 0;
@@ -167,8 +175,14 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0)
file->stbuf = *stbuf;
- page = ra_page_get (file, pending_offset);
+ if (op_ret < 0) {
+ page = ra_page_get (file, pending_offset);
+ if (page)
+ waitq = ra_page_error (page, op_ret, op_errno);
+ goto unlock;
+ }
+ page = ra_page_get (file, pending_offset);
if (!page) {
gf_log (this->name, GF_LOG_TRACE,
"wasted copy: %"PRId64"[+%"PRId64"] file=%p",
@@ -176,29 +190,6 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
- /*
- * "Dirty" means that the request was a pure read-ahead; it's
- * set for requests we issue ourselves, and cleared when user
- * requests are issued or put on the waitq. "Poisoned" means
- * that we got a write while a read was still in flight, and we
- * couldn't stop it so we marked it instead. If it's both
- * dirty and poisoned by the time we get here, we cancel its
- * effect so that a subsequent user read doesn't get data that
- * we know is stale (because we made it stale ourselves). We
- * can't use ESTALE because that has special significance.
- * ECANCELED has no such special meaning, and is close to what
- * we're trying to indicate.
- */
- if (page->dirty && page->poisoned) {
- op_ret = -1;
- op_errno = ECANCELED;
- }
-
- if (op_ret < 0) {
- waitq = ra_page_error (page, op_ret, op_errno);
- goto unlock;
- }
-
if (page->vector) {
iobref_unref (page->iobref);
GF_FREE (page->vector);
@@ -225,7 +216,7 @@ unlock:
fd_unref (local->fd);
- mem_put (frame->local);
+ GF_FREE (frame->local);
frame->local = NULL;
out:
@@ -253,7 +244,7 @@ ra_page_fault (ra_file_t *file, call_frame_t *frame, off_t offset)
goto err;
}
- fault_local = mem_get0 (THIS->local_pool);
+ fault_local = GF_CALLOC (1, sizeof (ra_local_t), gf_ra_mt_ra_local_t);
if (fault_local == NULL) {
STACK_DESTROY (fault_frame->root);
op_ret = -1;
@@ -270,7 +261,7 @@ ra_page_fault (ra_file_t *file, call_frame_t *frame, off_t offset)
STACK_WIND (fault_frame, ra_fault_cbk,
FIRST_CHILD (fault_frame->this),
FIRST_CHILD (fault_frame->this)->fops->readv,
- file->fd, file->page_size, offset, 0, NULL);
+ file->fd, file->page_size, offset);
return;
@@ -439,11 +430,11 @@ ra_frame_unwind (call_frame_t *frame)
file = (ra_file_t *)(long)tmp_file;
STACK_UNWIND_STRICT (readv, frame, local->op_ret, local->op_errno,
- vector, count, &file->stbuf, iobref, NULL);
+ vector, count, &file->stbuf, iobref);
iobref_unref (iobref);
pthread_mutex_destroy (&local->local_lock);
- mem_put (local);
+ GF_FREE (local);
GF_FREE (vector);
out:
@@ -500,9 +491,6 @@ ra_page_wakeup (ra_page_t *page)
ra_frame_fill (page, frame);
}
- if (page->stale) {
- ra_page_purge (page);
- }
out:
return waitq;
}
diff --git a/xlators/performance/read-ahead/src/read-ahead-mem-types.h b/xlators/performance/read-ahead/src/read-ahead-mem-types.h
index 219e29289..1c703a059 100644
--- a/xlators/performance/read-ahead/src/read-ahead-mem-types.h
+++ b/xlators/performance/read-ahead/src/read-ahead-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -16,6 +25,7 @@
enum gf_ra_mem_types_ {
gf_ra_mt_ra_file_t = gf_common_mt_end + 1,
+ gf_ra_mt_ra_local_t,
gf_ra_mt_ra_conf_t,
gf_ra_mt_ra_page_t,
gf_ra_mt_ra_waitq_t,
diff --git a/xlators/performance/read-ahead/src/read-ahead.c b/xlators/performance/read-ahead/src/read-ahead.c
index 7b23049d3..d41931eec 100644
--- a/xlators/performance/read-ahead/src/read-ahead.c
+++ b/xlators/performance/read-ahead/src/read-ahead.c
@@ -1,18 +1,27 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
/*
TODO:
- handle O_DIRECT
- maintain offset, flush on lseek
- - ensure efficient memory management in case of random seek
+ - ensure efficient memory managment in case of random seek
*/
#ifndef _CONFIG_H
@@ -35,11 +44,12 @@ read_ahead (call_frame_t *frame, ra_file_t *file);
int
ra_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
ra_conf_t *conf = NULL;
ra_file_t *file = NULL;
int ret = 0;
+ long wbflags = 0;
GF_ASSERT (frame);
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
@@ -50,6 +60,8 @@ ra_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unwind;
}
+ wbflags = (long)frame->local;
+
file = GF_CALLOC (1, sizeof (*file), gf_ra_mt_ra_file_t);
if (!file) {
op_ret = -1;
@@ -62,6 +74,10 @@ ra_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((fd->flags & O_DIRECT) || ((fd->flags & O_ACCMODE) == O_WRONLY))
file->disabled = 1;
+ if (wbflags & GF_OPEN_NOWB) {
+ file->disabled = 1;
+ }
+
file->offset = (unsigned long long) 0;
file->conf = conf;
file->pages.next = &file->pages;
@@ -100,7 +116,7 @@ ra_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
frame->local = NULL;
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
@@ -110,7 +126,7 @@ int
ra_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
ra_conf_t *conf = NULL;
ra_file_t *file = NULL;
@@ -171,7 +187,7 @@ ra_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unwind:
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
@@ -179,15 +195,17 @@ unwind:
int
ra_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
GF_ASSERT (frame);
GF_ASSERT (this);
+ frame->local = (void *)(long)wbflags;
+
STACK_WIND (frame, ra_open_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->open,
- loc, flags, fd, xdata);
+ loc, flags, fd, wbflags);
return 0;
}
@@ -195,7 +213,7 @@ ra_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
int
ra_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
GF_ASSERT (frame);
GF_ASSERT (this);
@@ -203,7 +221,7 @@ ra_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
STACK_WIND (frame, ra_create_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
}
@@ -213,8 +231,7 @@ ra_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
*/
static void
-flush_region (call_frame_t *frame, ra_file_t *file, off_t offset, off_t size,
- int for_write)
+flush_region (call_frame_t *frame, ra_file_t *file, off_t offset, off_t size)
{
ra_page_t *trav = NULL;
ra_page_t *next = NULL;
@@ -226,17 +243,8 @@ flush_region (call_frame_t *frame, ra_file_t *file, off_t offset, off_t size,
&& trav->offset < (offset + size)) {
next = trav->next;
- if (trav->offset >= offset) {
- if (!trav->waitq) {
- ra_page_purge (trav);
- }
- else {
- trav->stale = 1;
-
- if (for_write) {
- trav->poisoned = 1;
- }
- }
+ if (trav->offset >= offset && !trav->waitq) {
+ ra_page_purge (trav);
}
trav = next;
}
@@ -344,8 +352,7 @@ out:
int
ra_need_atime_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
GF_ASSERT (frame);
STACK_DESTROY (frame->root);
@@ -385,15 +392,15 @@ dispatch_requests (call_frame_t *frame, ra_file_t *file)
trav = ra_page_get (file, trav_offset);
if (!trav) {
trav = ra_page_create (file, trav_offset);
- if (!trav) {
- local->op_ret = -1;
- local->op_errno = ENOMEM;
- goto unlock;
- }
fault = 1;
need_atime_update = 0;
}
- trav->dirty = 0;
+
+ if (!trav) {
+ local->op_ret = -1;
+ local->op_errno = ENOMEM;
+ goto unlock;
+ }
if (trav->ready) {
gf_log (frame->this->name, GF_LOG_TRACE,
@@ -436,7 +443,7 @@ dispatch_requests (call_frame_t *frame, ra_file_t *file)
STACK_WIND (ra_frame, ra_need_atime_cbk,
FIRST_CHILD (frame->this),
FIRST_CHILD (frame->this)->fops->readv,
- file->fd, 1, 1, 0, NULL);
+ file->fd, 1, 1);
}
out:
@@ -447,13 +454,12 @@ out:
int
ra_readv_disabled_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iovec *vector,
- int32_t count, struct iatt *stbuf, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, struct iatt *stbuf, struct iobref *iobref)
{
GF_ASSERT (frame);
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
return 0;
}
@@ -461,7 +467,7 @@ ra_readv_disabled_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
ra_file_t *file = NULL;
ra_local_t *local = NULL;
@@ -483,8 +489,12 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (!file || file->disabled) {
- goto disabled;
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_WARNING,
+ "readv received on fd (%p) with no"
+ " file set in its context", fd);
+ goto unwind;
}
if (file->offset != offset) {
@@ -507,10 +517,18 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
}
if (!expected_offset) {
- flush_region (frame, file, 0, file->pages.prev->offset + 1, 0);
+ flush_region (frame, file, 0, file->pages.prev->offset + 1);
+ }
+
+ if (file->disabled) {
+ STACK_WIND (frame, ra_readv_disabled_cbk,
+ FIRST_CHILD (frame->this),
+ FIRST_CHILD (frame->this)->fops->readv,
+ file->fd, size, offset);
+ return 0;
}
- local = mem_get0 (this->local_pool);
+ local = (void *) GF_CALLOC (1, sizeof (*local), gf_ra_mt_ra_local_t);
if (!local) {
op_errno = ENOMEM;
goto unwind;
@@ -530,7 +548,7 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
dispatch_requests (frame, file);
- flush_region (frame, file, 0, floor (offset, file->page_size), 0);
+ flush_region (frame, file, 0, floor (offset, file->page_size));
read_ahead (frame, file);
@@ -541,26 +559,18 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
return 0;
unwind:
- STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL,
- NULL);
-
- return 0;
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
-disabled:
- STACK_WIND (frame, ra_readv_disabled_cbk,
- FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv,
- fd, size, offset, flags, xdata);
return 0;
}
int
ra_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
GF_ASSERT (frame);
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
@@ -568,18 +578,16 @@ ra_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int
ra_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
- dict_t *xdata)
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf)
{
GF_ASSERT (frame);
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
-ra_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+ra_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
ra_file_t *file = NULL;
uint64_t tmp_file = 0;
@@ -592,23 +600,28 @@ ra_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file) {
- flush_region (frame, file, 0, file->pages.prev->offset+1, 0);
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_WARNING,
+ "flush received on fd (%p) with no"
+ " file set in its context", fd);
+ goto unwind;
}
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
+
STACK_WIND (frame, ra_flush_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->flush, fd, xdata);
+ FIRST_CHILD (this)->fops->flush, fd);
return 0;
unwind:
- STACK_UNWIND_STRICT (flush, frame, -1, op_errno, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
return 0;
}
int
-ra_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
+ra_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
{
ra_file_t *file = NULL;
uint64_t tmp_file = 0;
@@ -621,16 +634,22 @@ ra_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file) {
- flush_region (frame, file, 0, file->pages.prev->offset+1, 0);
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_WARNING,
+ "fsync received on fd (%p) with no"
+ " file set in its context", fd);
+ goto unwind;
}
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
+
STACK_WIND (frame, ra_fsync_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fsync, fd, datasync, xdata);
+ FIRST_CHILD (this)->fops->fsync, fd, datasync);
return 0;
unwind:
- STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -638,29 +657,39 @@ unwind:
int
ra_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
+ fd_t *fd = NULL;
ra_file_t *file = NULL;
+ uint64_t tmp_file = 0;
GF_ASSERT (frame);
- file = frame->local;
+ fd = frame->local;
+
+ fd_ctx_get (fd, this, &tmp_file);
+ file = (ra_file_t *)(long)tmp_file;
- if (file) {
- flush_region (frame, file, 0, file->pages.prev->offset+1, 1);
+ if (file == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "no read-ahead context set in fd (%p)", fd);
+ op_errno = EBADF;
+ op_ret = -1;
+ goto out;
}
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
+
+out:
frame->local = NULL;
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int
ra_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t offset, uint32_t flags, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, off_t offset, struct iobref *iobref)
{
ra_file_t *file = NULL;
uint64_t tmp_file = 0;
@@ -672,22 +701,29 @@ ra_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file) {
- flush_region (frame, file, 0, file->pages.prev->offset+1, 1);
- frame->local = file;
- /* reset the read-ahead counters too */
- file->expected = file->page_count = 0;
+ if (file == NULL) {
+ op_errno = EBADF;
+ gf_log (this->name, GF_LOG_WARNING, "writev received on fd with"
+ "no file set in its context");
+ goto unwind;
}
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
+
+ /* reset the read-ahead counters too */
+ file->expected = file->page_count = 0;
+
+ frame->local = fd;
+
STACK_WIND (frame, ra_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
unwind:
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -695,30 +731,29 @@ unwind:
int
ra_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
GF_ASSERT (frame);
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
int
ra_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *buf)
{
GF_ASSERT (frame);
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
return 0;
}
int
-ra_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+ra_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
ra_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -740,16 +775,8 @@ ra_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
if (!file)
continue;
- /*
- * Truncation invalidates reads just like writing does.
- * TBD: this seems to flush more than it should. The
- * only time we should flush at all is when we're
- * shortening (not lengthening) the file, and then only
- * from new EOF to old EOF. The same problem exists in
- * ra_ftruncate.
- */
flush_region (frame, file, 0,
- file->pages.prev->offset + 1, 1);
+ file->pages.prev->offset + 1);
}
}
UNLOCK (&inode->lock);
@@ -757,108 +784,17 @@ ra_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
STACK_WIND (frame, ra_truncate_cbk,
FIRST_CHILD (this),
FIRST_CHILD (this)->fops->truncate,
- loc, offset, xdata);
+ loc, offset);
return 0;
unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
-void
-ra_page_dump (struct ra_page *page)
-{
- int i = 0;
- call_frame_t *frame = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
- ra_waitq_t *trav = NULL;
-
- if (page == NULL) {
- goto out;
- }
-
- gf_proc_dump_write ("offset", "%"PRId64, page->offset);
-
- gf_proc_dump_write ("size", "%"PRId64, page->size);
-
- gf_proc_dump_write ("dirty", "%s", page->dirty ? "yes" : "no");
-
- gf_proc_dump_write ("poisoned", "%s", page->poisoned ? "yes" : "no");
-
- gf_proc_dump_write ("ready", "%s", page->ready ? "yes" : "no");
-
- for (trav = page->waitq; trav; trav = trav->next) {
- frame = trav->data;
- sprintf (key, "waiting-frame[%d]", i++);
- gf_proc_dump_write (key, "%"PRId64, frame->root->unique);
- }
-
-out:
- return;
-}
-
-int32_t
-ra_fdctx_dump (xlator_t *this, fd_t *fd)
-{
- ra_file_t *file = NULL;
- ra_page_t *page = NULL;
- int32_t ret = 0, i = 0;
- uint64_t tmp_file = 0;
- char *path = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0, };
- char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
-
- fd_ctx_get (fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
-
- if (file == NULL) {
- ret = 0;
- goto out;
- }
-
- gf_proc_dump_build_key (key_prefix,
- "xlator.performance.read-ahead",
- "file");
-
- gf_proc_dump_add_section (key_prefix);
-
- ret = __inode_path (fd->inode, NULL, &path);
- if (path != NULL) {
- gf_proc_dump_write ("path", "%s", path);
- GF_FREE (path);
- }
-
- gf_proc_dump_write ("fd", "%p", fd);
-
- gf_proc_dump_write ("disabled", "%s", file->disabled ? "yes" : "no");
-
- if (file->disabled) {
- ret = 0;
- goto out;
- }
-
- gf_proc_dump_write ("page-size", "%"PRId64, file->page_size);
-
- gf_proc_dump_write ("page-count", "%u", file->page_count);
-
- gf_proc_dump_write ("next-expected-offset-for-sequential-reads",
- "%"PRId64, file->offset);
-
- for (page = file->pages.next; page != &file->pages;
- page = page->next) {
- sprintf (key, "page[%d]", i);
- gf_proc_dump_write (key, "%p", page[i++]);
- ra_page_dump (page);
- }
-
- ret = 0;
-out:
- return ret;
-}
-
int
-ra_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+ra_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
ra_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -881,24 +817,23 @@ ra_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
if (!file)
continue;
flush_region (frame, file, 0,
- file->pages.prev->offset + 1, 0);
+ file->pages.prev->offset + 1);
}
}
UNLOCK (&inode->lock);
STACK_WIND (frame, ra_attr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->fstat, fd, xdata);
+ FIRST_CHILD (this)->fops->fstat, fd);
return 0;
unwind:
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
return 0;
}
int
-ra_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+ra_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
ra_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -919,26 +854,18 @@ ra_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
file = (ra_file_t *)(long)tmp_file;
if (!file)
continue;
- /*
- * Truncation invalidates reads just like writing does.
- * TBD: this seems to flush more than it should. The
- * only time we should flush at all is when we're
- * shortening (not lengthening) the file, and then only
- * from new EOF to old EOF. The same problem exists in
- * ra_truncate.
- */
flush_region (frame, file, 0,
- file->pages.prev->offset + 1, 1);
+ file->pages.prev->offset + 1);
}
}
UNLOCK (&inode->lock);
STACK_WIND (frame, ra_truncate_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD (this)->fops->ftruncate, fd, offset);
return 0;
unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -948,6 +875,7 @@ ra_priv_dump (xlator_t *this)
{
ra_conf_t *conf = NULL;
int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0, };
char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
if (!this) {
@@ -972,9 +900,12 @@ ra_priv_dump (xlator_t *this)
"priv");
gf_proc_dump_add_section (key_prefix);
- gf_proc_dump_write ("page_size", "%d", conf->page_size);
- gf_proc_dump_write ("page_count", "%d", conf->page_count);
- gf_proc_dump_write ("force_atime_update", "%d", conf->force_atime_update);
+ gf_proc_dump_build_key (key, key_prefix, "page_size");
+ gf_proc_dump_write (key, "%d", conf->page_size);
+ gf_proc_dump_build_key (key, key_prefix, "page_count");
+ gf_proc_dump_write (key, "%d", conf->page_count);
+ gf_proc_dump_build_key (key, key_prefix, "force_atime_update");
+ gf_proc_dump_write (key, "%d", conf->force_atime_update);
pthread_mutex_unlock (&conf->conf_lock);
@@ -1005,31 +936,16 @@ out:
}
int
-reconfigure (xlator_t *this, dict_t *options)
-{
- ra_conf_t *conf = NULL;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("read-ahead", this, out);
- GF_VALIDATE_OR_GOTO ("read-ahead", this->private, out);
-
- conf = this->private;
-
- GF_OPTION_RECONF ("page-count", conf->page_count, options, uint32, out);
-
- ret = 0;
- out:
- return ret;
-}
-
-int
init (xlator_t *this)
{
ra_conf_t *conf = NULL;
+ dict_t *options = NULL;
+ char *page_count_string = NULL;
int32_t ret = -1;
GF_VALIDATE_OR_GOTO ("read-ahead", this, out);
+ options = this->options;
if (!this->children || this->children->next) {
gf_log (this->name, GF_LOG_ERROR,
"FATAL: read-ahead not configured with exactly one"
@@ -1048,30 +964,60 @@ init (xlator_t *this)
}
conf->page_size = this->ctx->page_size;
+ conf->page_count = 4;
- GF_OPTION_INIT ("page-count", conf->page_count, uint32, out);
+ if (dict_get (options, "page-count")) {
+ page_count_string = data_to_str (dict_get (options,
+ "page-count"));
+ }
- GF_OPTION_INIT ("force-atime-update", conf->force_atime_update, bool, out);
+ if (page_count_string) {
+ if (gf_string2uint_base10 (page_count_string, &conf->page_count)
+ != 0) {
+ gf_log ("read-ahead", GF_LOG_ERROR,
+ "invalid number format \"%s\" of \"option "
+ "page-count\"",
+ page_count_string);
+ goto out;
+ }
- conf->files.next = &conf->files;
- conf->files.prev = &conf->files;
+ gf_log (this->name, GF_LOG_WARNING,
+ "Using conf->page_count = %u", conf->page_count);
+ }
- pthread_mutex_init (&conf->conf_lock, NULL);
+ if (dict_get (options, "force-atime-update")) {
+ char *force_atime_update_str = NULL;
- this->local_pool = mem_pool_new (ra_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
+ force_atime_update_str
+ = data_to_str (dict_get (options,
+ "force-atime-update"));
+
+ if (gf_string2boolean (force_atime_update_str,
+ &conf->force_atime_update) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'force-atime-update' takes only boolean "
+ "options");
+ goto out;
+ }
+
+ if (conf->force_atime_update) {
+ gf_log (this->name, GF_LOG_WARNING, "Forcing atime "
+ "updates on cache hit");
+ }
}
+ conf->files.next = &conf->files;
+ conf->files.prev = &conf->files;
+
+ pthread_mutex_init (&conf->conf_lock, NULL);
this->private = conf;
ret = 0;
out:
if (ret == -1) {
- GF_FREE (conf);
+ if (conf != NULL) {
+ GF_FREE (conf);
+ }
}
return ret;
@@ -1090,14 +1036,11 @@ fini (xlator_t *this)
goto out;
}
- this->private = NULL;
-
- GF_ASSERT ((conf->files.next == &conf->files)
- && (conf->files.prev == &conf->files));
-
pthread_mutex_destroy (&conf->conf_lock);
GF_FREE (conf);
+ this->private = NULL;
+
out:
return;
}
@@ -1120,20 +1063,16 @@ struct xlator_cbks cbks = {
struct xlator_dumpops dumpops = {
.priv = ra_priv_dump,
- .fdctx = ra_fdctx_dump,
};
struct volume_options options[] = {
{ .key = {"force-atime-update"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "false"
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"page-count"},
.type = GF_OPTION_TYPE_INT,
.min = 1,
- .max = 16,
- .default_value = "4",
- .description = "Number of pages that will be pre-fetched"
+ .max = 16
},
{ .key = {NULL} },
};
diff --git a/xlators/performance/read-ahead/src/read-ahead.h b/xlators/performance/read-ahead/src/read-ahead.h
index d1d768c34..ed918094f 100644
--- a/xlators/performance/read-ahead/src/read-ahead.h
+++ b/xlators/performance/read-ahead/src/read-ahead.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef __READ_AHEAD_H
@@ -67,8 +76,7 @@ struct ra_page {
struct ra_page *next;
struct ra_page *prev;
struct ra_file *file;
- char dirty; /* Internal request, not from user. */
- char poisoned; /* Pending read invalidated by write. */
+ char dirty;
char ready;
struct iovec *vector;
int32_t count;
@@ -76,7 +84,6 @@ struct ra_page {
size_t size;
struct ra_waitq *waitq;
struct iobref *iobref;
- char stale;
};
diff --git a/xlators/performance/md-cache/Makefile.am b/xlators/performance/stat-prefetch/Makefile.am
index af437a64d..af437a64d 100644
--- a/xlators/performance/md-cache/Makefile.am
+++ b/xlators/performance/stat-prefetch/Makefile.am
diff --git a/xlators/performance/stat-prefetch/src/Makefile.am b/xlators/performance/stat-prefetch/src/Makefile.am
new file mode 100644
index 000000000..cfb130714
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/Makefile.am
@@ -0,0 +1,14 @@
+xlator_LTLIBRARIES = stat-prefetch.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
+
+stat_prefetch_la_LDFLAGS = -module -avoidversion
+stat_prefetch_la_SOURCES = stat-prefetch.c
+noinst_HEADERS = stat-prefetch.h stat-prefetch-mem-types.h
+
+stat_prefetch_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
+ -I$(top_srcdir)/libglusterfs/src -I$(CONTRIBDIR)/rbtree -shared -nostartfiles $(GF_CFLAGS)
+
+CLEANFILES =
+
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch-mem-types.h b/xlators/performance/stat-prefetch/src/stat-prefetch-mem-types.h
new file mode 100644
index 000000000..007ed799d
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch-mem-types.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __SP_MEM_TYPES_H__
+#define __SP_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_sp_mem_types_ {
+ gf_sp_mt_sp_cache_t = gf_common_mt_end + 1,
+ gf_sp_mt_sp_fd_ctx_t,
+ gf_sp_mt_stat,
+ gf_sp_mt_sp_local_t,
+ gf_sp_mt_sp_inode_ctx_t,
+ gf_sp_mt_sp_private_t,
+ gf_sp_mt_fd_wrapper_t,
+ gf_sp_mt_end
+};
+#endif
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c
new file mode 100644
index 000000000..b99c91bce
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c
@@ -0,0 +1,4115 @@
+/*
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "stat-prefetch.h"
+#include "statedump.h"
+
+#define GF_SP_CACHE_BUCKETS 1
+#define GF_SP_CACHE_ENTRIES_EXPECTED (128 * 1024) //1048576
+
+typedef enum {
+ SP_EXPECT,
+ SP_DONT_EXPECT,
+ SP_DONT_CARE
+} sp_expect_t;
+
+
+void
+sp_inode_ctx_free (xlator_t *this, sp_inode_ctx_t *ctx)
+{
+ call_stub_t *stub = NULL, *tmp = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, ctx, out);
+
+ LOCK (&ctx->lock);
+ {
+ if (!list_empty (&ctx->waiting_ops)) {
+ gf_log (this->name, GF_LOG_WARNING, "inode ctx is "
+ "being freed even when there are file "
+ "operations waiting for lookup-behind to "
+ "complete. The operations in the waiting list "
+ "are:");
+ list_for_each_entry_safe (stub, tmp, &ctx->waiting_ops,
+ list) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "OP (%s)", gf_fop_list[stub->fop]);
+
+ list_del_init (&stub->list);
+ call_stub_destroy (stub);
+ }
+ }
+ }
+ UNLOCK (&ctx->lock);
+
+ LOCK_DESTROY (&ctx->lock);
+ GF_FREE (ctx);
+
+out:
+ return;
+}
+
+
+sp_inode_ctx_t *
+sp_inode_ctx_init ()
+{
+ sp_inode_ctx_t *inode_ctx = NULL;
+
+ inode_ctx = GF_CALLOC (1, sizeof (*inode_ctx), gf_sp_mt_sp_inode_ctx_t);
+ if (inode_ctx == NULL) {
+ goto out;
+ }
+
+ LOCK_INIT (&inode_ctx->lock);
+ INIT_LIST_HEAD (&inode_ctx->waiting_ops);
+
+out:
+ return inode_ctx;
+}
+
+
+int
+sp_update_inode_ctx (xlator_t *this, inode_t *inode, int32_t *op_ret,
+ int32_t *op_errno, char *lookup_in_progress,
+ char *looked_up, struct iatt *stbuf,
+ struct list_head *waiting_ops, int32_t *error)
+{
+ int32_t ret = -1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ uint64_t value = 0;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ ret = inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ }
+
+ if (inode_ctx == NULL) {
+ ret = -1;
+ if (error != NULL) {
+ *error = EINVAL;
+ }
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", inode->ino,
+ uuid_utoa (inode->gfid));
+ goto out;
+ }
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (op_ret != NULL) {
+ inode_ctx->op_ret = *op_ret;
+ }
+
+ if (op_errno != NULL) {
+ inode_ctx->op_errno = *op_errno;
+ }
+
+ if (looked_up != NULL) {
+ inode_ctx->looked_up = *looked_up;
+ }
+
+ if (lookup_in_progress != NULL) {
+ inode_ctx->lookup_in_progress = *lookup_in_progress;
+ }
+
+ if ((op_ret != NULL ) && (*op_ret == 0) && (stbuf != NULL)
+ && IA_ISDIR (stbuf->ia_type)) {
+ memcpy (&inode_ctx->stbuf, stbuf, sizeof (*stbuf));
+ }
+
+ if (waiting_ops != NULL) {
+ list_splice_init (&inode_ctx->waiting_ops, waiting_ops);
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+sp_inode_ctx_t *
+sp_check_and_create_inode_ctx (xlator_t *this, inode_t *inode,
+ sp_expect_t expect)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+
+ if ((expect == SP_DONT_EXPECT) && (inode_ctx != NULL)) {
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "stat-prefetch context is "
+ "present in inode "
+ "(ino:%"PRId64" gfid:%s) "
+ "when it is supposed to be "
+ "not present", inode->ino,
+ uuid_utoa (inode->gfid));
+ }
+ } else {
+ if (expect == SP_EXPECT) {
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "stat-prefetch context is "
+ "not present in inode "
+ "(ino:%"PRId64" gfid:%s)"
+ " when it is supposed to be "
+ "present", inode->ino,
+ uuid_utoa (inode->gfid));
+ }
+
+ inode_ctx = sp_inode_ctx_init ();
+ if (inode_ctx != NULL) {
+ ret = __inode_ctx_put (inode, this,
+ (long)inode_ctx);
+ if (ret == -1) {
+ sp_inode_ctx_free (this, inode_ctx);
+ inode_ctx = NULL;
+ }
+ }
+ }
+ }
+ UNLOCK (&inode->lock);
+
+out:
+ return inode_ctx;
+}
+
+
+sp_cache_t *
+sp_cache_ref (sp_cache_t *cache)
+{
+ if (cache == NULL) {
+ goto out;
+ }
+
+ LOCK (&cache->lock);
+ {
+ cache->ref++;
+ }
+ UNLOCK (&cache->lock);
+
+out:
+ return cache;;
+}
+
+
+void
+sp_cache_unref (sp_cache_t *cache)
+{
+ int refcount = 0;
+
+ if (cache == NULL) {
+ goto out;
+ }
+
+ LOCK (&cache->lock);
+ {
+ refcount = --cache->ref;
+ }
+ UNLOCK (&cache->lock);
+
+ if (refcount == 0) {
+ rbthash_table_destroy (cache->table);
+ GF_FREE (cache);
+ }
+
+out:
+ return;
+}
+
+
+int32_t
+sp_process_inode_ctx (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ call_stub_t *stub, char *need_unwind, char *need_lookup,
+ char *can_wind, int32_t *error)
+{
+ int32_t ret = -1, op_errno = EINVAL;
+ sp_local_t *local = NULL;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ uint64_t value = 0;
+
+ if (need_unwind != NULL) {
+ *need_unwind = 1;
+ }
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", frame, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, loc->inode, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, need_unwind, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, need_lookup, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, can_wind, out);
+
+ inode_ctx_get (loc->inode, this, &value);
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ if (inode_ctx == NULL) {
+ gf_log_callingfn (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ *can_wind = 1;
+ *need_unwind = 0;
+ op_errno = 0;
+ ret = 0;
+ goto out;
+ }
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (!(inode_ctx->looked_up || inode_ctx->lookup_in_progress)) {
+ if (frame->local == NULL) {
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_sp_mt_sp_local_t);
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unlock;
+ }
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING,
+ "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto unlock;
+ }
+ }
+
+ *need_lookup = 1;
+ inode_ctx->lookup_in_progress = 1;
+ }
+
+ if (inode_ctx->looked_up) {
+ *can_wind = 1;
+ } else {
+ list_add_tail (&stub->list, &inode_ctx->waiting_ops);
+ stub = NULL;
+ }
+
+ *need_unwind = 0;
+ ret = 0;
+ }
+unlock:
+ UNLOCK (&inode_ctx->lock);
+
+out:
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+
+ if (error != NULL) {
+ *error = op_errno;
+ }
+
+ return ret;
+}
+
+
+inline uint32_t
+sp_hashfn (void *data, int len)
+{
+ return gf_dm_hashfn ((const char *)data, len);
+}
+
+
+sp_cache_t *
+sp_cache_init (xlator_t *this)
+{
+ sp_cache_t *cache = NULL;
+ sp_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+
+ priv = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, priv, out);
+ GF_VALIDATE_OR_GOTO (this->name, priv->mem_pool, out);
+
+ cache = GF_CALLOC (1, sizeof (*cache), gf_sp_mt_sp_cache_t);
+ if (cache) {
+ cache->table =
+ rbthash_table_init (GF_SP_CACHE_BUCKETS,
+ sp_hashfn, __gf_free,
+ 0, priv->mem_pool);
+ if (cache->table == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot init a new rbthash table to hold "
+ "cache");
+ GF_FREE (cache);
+ cache = NULL;
+ goto out;
+ }
+
+ LOCK_INIT (&cache->lock);
+ cache->this = this;
+ }
+
+out:
+ return cache;
+}
+
+
+void
+sp_local_free (sp_local_t *local)
+{
+ if (local) {
+ loc_wipe (&local->loc);
+ GF_FREE (local);
+ }
+}
+
+
+int32_t
+sp_cache_remove_entry (sp_cache_t *cache, char *name, char remove_all)
+{
+ int32_t ret = -1;
+ rbthash_table_t *table = NULL;
+ xlator_t *this = NULL;
+ sp_private_t *priv = NULL;
+ void *data = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", cache, out);
+ if ((name == NULL) && !remove_all) {
+ gf_log ((cache->this ? cache->this->name : "stat-prefetch"),
+ GF_LOG_WARNING,
+ "request to remove a single entry from cache and is no "
+ "name passed to identify it");
+ goto out;
+ }
+
+ this = cache->this;
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
+
+ priv = this->private;
+
+ LOCK (&cache->lock);
+ {
+ if (remove_all) {
+ table = cache->table;
+ cache->table = rbthash_table_init (GF_SP_CACHE_BUCKETS,
+ sp_hashfn, __gf_free,
+ 0, priv->mem_pool);
+ if (cache->table == NULL) {
+ cache->table = table;
+ } else {
+ rbthash_table_destroy (table);
+ ret = 0;
+ if (priv) {
+ LOCK (&priv->lock);
+ {
+ priv->entries = 0;
+ }
+ UNLOCK (&priv->lock);
+ }
+ }
+ } else {
+ data = rbthash_remove (cache->table, name,
+ strlen (name));
+ GF_FREE (data);
+ ret = 0;
+ if (priv) {
+ LOCK (&priv->lock);
+ {
+ priv->entries--;
+ }
+ UNLOCK (&priv->lock);
+ }
+ }
+ }
+ UNLOCK (&cache->lock);
+
+out:
+ return ret;
+}
+
+
+int32_t
+sp_cache_get_entry (sp_cache_t *cache, char *name, gf_dirent_t **entry)
+{
+ int32_t ret = -1;
+ gf_dirent_t *tmp = NULL, *new = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", cache, out);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", cache->this, out);
+ GF_VALIDATE_OR_GOTO (cache->this->name, name, out);
+ GF_VALIDATE_OR_GOTO (cache->this->name, entry, out);
+
+ LOCK (&cache->lock);
+ {
+ tmp = rbthash_get (cache->table, name, strlen (name));
+ if (tmp != NULL) {
+ new = gf_dirent_for_name (tmp->d_name);
+ if (new == NULL) {
+ gf_log (cache->this->name, GF_LOG_WARNING,
+ "cannot create a new dentry to copy "
+ "from cache");
+ goto unlock;
+ }
+
+ new->d_ino = tmp->d_ino;
+ new->d_off = tmp->d_off;
+ new->d_len = tmp->d_len;
+ new->d_type = tmp->d_type;
+ new->d_stat = tmp->d_stat;
+
+ *entry = new;
+ ret = 0;
+ }
+ }
+unlock:
+ UNLOCK (&cache->lock);
+
+out:
+ return ret;
+}
+
+
+void
+sp_cache_free (sp_cache_t *cache)
+{
+ sp_cache_remove_entry (cache, NULL, 1);
+ sp_cache_unref (cache);
+}
+
+
+sp_cache_t *
+__sp_get_cache_fd (xlator_t *this, fd_t *fd)
+{
+ int32_t ret = -1;
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ ret = __fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ goto out;
+ }
+
+ fd_ctx = (void *)(long) value;
+
+ cache = fd_ctx->cache;
+
+out:
+ return cache;
+}
+
+
+sp_cache_t *
+sp_get_cache_fd (xlator_t *this, fd_t *fd)
+{
+ sp_cache_t *cache = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ LOCK (&fd->lock);
+ {
+ cache = __sp_get_cache_fd (this, fd);
+ if (cache != NULL) {
+ sp_cache_ref (cache);
+ }
+ }
+ UNLOCK (&fd->lock);
+
+out:
+ return cache;
+}
+
+
+void
+sp_fd_ctx_free (sp_fd_ctx_t *fd_ctx)
+{
+ if (fd_ctx == NULL) {
+ goto out;
+ }
+
+ if (fd_ctx->parent_inode) {
+ inode_unref (fd_ctx->parent_inode);
+ fd_ctx->parent_inode = NULL;
+ }
+
+ if (fd_ctx->name) {
+ GF_FREE (fd_ctx->name);
+ fd_ctx->name = NULL;
+ }
+
+ if (fd_ctx->cache) {
+ sp_cache_free (fd_ctx->cache);
+ }
+
+ GF_FREE (fd_ctx);
+out:
+ return;
+}
+
+
+inline sp_fd_ctx_t *
+sp_fd_ctx_init (void)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ fd_ctx = GF_CALLOC (1, sizeof (*fd_ctx), gf_sp_mt_sp_fd_ctx_t);
+
+ return fd_ctx;
+}
+
+
+sp_fd_ctx_t *
+sp_fd_ctx_new (xlator_t *this, inode_t *parent, char *name, sp_cache_t *cache)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ fd_ctx = sp_fd_ctx_init ();
+ if (fd_ctx == NULL) {
+ goto out;
+ }
+
+ if (parent) {
+ fd_ctx->parent_inode = inode_ref (parent);
+ }
+
+ if (name) {
+ fd_ctx->name = gf_strdup (name);
+ if (fd_ctx->name == NULL) {
+ sp_fd_ctx_free (fd_ctx);
+ fd_ctx = NULL;
+ goto out;
+ }
+ }
+
+ fd_ctx->cache = cache;
+
+out:
+ return fd_ctx;
+}
+
+
+sp_cache_t *
+sp_del_cache_fd (xlator_t *this, fd_t *fd)
+{
+ sp_cache_t *cache = NULL;
+ uint64_t value = 0;
+ int32_t ret = -1;
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ if (fd == NULL) {
+ goto out;
+ }
+
+ LOCK (&fd->lock);
+ {
+ ret = __fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ fd_ctx = (void *)(long) value;
+ cache = fd_ctx->cache;
+ fd_ctx->cache = NULL;
+ }
+ }
+ UNLOCK (&fd->lock);
+
+out:
+ return cache;
+}
+
+
+sp_cache_t *
+sp_get_cache_inode (xlator_t *this, inode_t *inode, int32_t pid)
+{
+ fd_t *fd = NULL;
+ sp_cache_t *cache = NULL;
+
+ if (inode == NULL) {
+ goto out;
+ }
+
+ fd = fd_lookup (inode, pid);
+ if (fd == NULL) {
+ goto out;
+ }
+
+ cache = sp_get_cache_fd (this, fd);
+
+ fd_unref (fd);
+out:
+ return cache;
+}
+
+
+fd_t *
+_fd_ref (fd_t *fd);
+
+void
+sp_remove_caches_from_all_fds_opened (xlator_t *this, inode_t *inode,
+ char *name)
+{
+ fd_t *fd = NULL;
+ sp_cache_t *cache = NULL;
+ struct fd_wrapper {
+ fd_t *fd;
+ struct list_head list;
+ };
+
+ struct fd_wrapper *wrapper = NULL, *tmp = NULL;
+ struct list_head head = {0, };
+ char remove_all = 0;
+
+ wrapper = NULL;
+
+ INIT_LIST_HEAD (&head);
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ remove_all = (name == NULL);
+
+ LOCK (&inode->lock);
+ {
+ list_for_each_entry (fd, &inode->fd_list, inode_list) {
+ wrapper = GF_CALLOC (1, sizeof (*wrapper),
+ gf_sp_mt_fd_wrapper_t);
+ if (wrapper == NULL) {
+ goto unlock;
+ }
+
+ INIT_LIST_HEAD (&wrapper->list);
+
+ wrapper->fd = _fd_ref (fd);
+ list_add_tail (&wrapper->list, &head);
+ }
+ }
+unlock:
+ UNLOCK (&inode->lock);
+
+ list_for_each_entry_safe (wrapper, tmp, &head, list) {
+ cache = sp_get_cache_fd (this, wrapper->fd);
+ if (cache) {
+ sp_cache_remove_entry (cache, name, remove_all);
+ sp_cache_unref (cache);
+ }
+
+ list_del (&wrapper->list);
+ fd_unref (wrapper->fd);
+ GF_FREE (wrapper);
+ }
+
+out:
+ return;
+}
+
+
+inline int32_t
+__sp_put_cache (xlator_t *this, fd_t *fd, sp_cache_t *cache)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ int32_t ret = -1;
+ uint64_t value = 0;
+
+ ret = __fd_ctx_get (fd, this, &value);
+ if (!ret) {
+ fd_ctx = (void *)(long)value;
+ } else {
+ fd_ctx = sp_fd_ctx_init ();
+ if (fd_ctx == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = __fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot set stat-prefetch context in fd (%p) "
+ "opened on inode (ino:%"PRId64" gfid:%s)",
+ fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ sp_fd_ctx_free (fd_ctx);
+ goto out;
+ }
+ }
+
+ if (fd_ctx->cache) {
+ sp_cache_free (fd_ctx->cache);
+ }
+
+ fd_ctx->cache = cache;
+
+out:
+ return ret;
+}
+
+
+inline int32_t
+sp_put_cache (xlator_t *this, fd_t *fd, sp_cache_t *cache)
+{
+ int32_t ret = -1;
+
+ if (fd != NULL) {
+ LOCK (&fd->lock);
+ {
+ ret = __sp_put_cache (this, fd, cache);
+ }
+ UNLOCK (&fd->lock);
+ }
+
+ return ret;
+}
+
+
+int32_t
+sp_cache_add_entries (sp_cache_t *cache, gf_dirent_t *entries)
+{
+ gf_dirent_t *entry = NULL, *new = NULL;
+ int32_t ret = -1;
+ uint64_t expected_offset = 0;
+ xlator_t *this = NULL;
+ sp_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", cache, out);
+
+ this = cache->this;
+ if (this && this->private) {
+ priv = this->private;
+ }
+
+ LOCK (&cache->lock);
+ {
+ list_for_each_entry (entry, &entries->list, list) {
+ if (IA_ISDIR (entry->d_stat.ia_type)) {
+ continue;
+ }
+
+ if (uuid_is_null (entry->d_stat.ia_gfid))
+ continue;
+
+ new = gf_dirent_for_name (entry->d_name);
+ if (new == NULL) {
+ gf_log (cache->this->name, GF_LOG_WARNING,
+ "cannot create a new dentry to store "
+ "in cache");
+ goto unlock;
+ }
+
+ new->d_ino = entry->d_ino;
+ new->d_off = entry->d_off;
+ new->d_len = entry->d_len;
+ new->d_type = entry->d_type;
+ new->d_stat = entry->d_stat;
+
+ ret = rbthash_insert (cache->table, new, new->d_name,
+ strlen (new->d_name));
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "cannot "
+ "insert dentry (name:%s) into cache",
+ new->d_name);
+
+ GF_FREE (new);
+ continue;
+ }
+
+ expected_offset = new->d_off;
+ if (priv) {
+ LOCK (&priv->lock);
+ {
+ priv->entries++;
+ }
+ UNLOCK (&priv->lock);
+ }
+ }
+
+ cache->expected_offset = expected_offset;
+
+ ret = 0;
+ }
+unlock:
+ UNLOCK (&cache->lock);
+
+out:
+ return ret;
+}
+
+
+int32_t
+sp_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *dict, struct iatt *postparent)
+{
+ struct list_head waiting_ops = {0, };
+ call_stub_t *stub = NULL, *tmp = NULL;
+ sp_local_t *local = NULL;
+ int need_unwind = 0;
+ char looked_up = 0, lookup_in_progress = 0;
+
+ GF_ASSERT (frame);
+
+ INIT_LIST_HEAD (&waiting_ops);
+
+ local = frame->local;
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING, "local is NULL, but it is "
+ "needed to find and resume operations waiting on "
+ "lookup");
+ goto out;
+ }
+
+ if (this == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ gf_log (frame->this ? frame->this->name : "stat-prefetch",
+ GF_LOG_WARNING, "xlator object (this) is NULL");
+ goto out;
+ }
+
+ /* For '/' Entry is never cached, don't try to remove it */
+ if ((op_ret == -1) && local->loc.parent) {
+ sp_remove_caches_from_all_fds_opened (this, local->loc.parent,
+ (char *)local->loc.name);
+ }
+
+ if (local->is_lookup)
+ need_unwind = 1;
+
+ lookup_in_progress = 0;
+ looked_up = 1;
+ sp_update_inode_ctx (this, local->loc.inode, &op_ret, &op_errno,
+ &lookup_in_progress, &looked_up, buf,
+ &waiting_ops, &op_errno);
+
+ list_for_each_entry_safe (stub, tmp, &waiting_ops, list) {
+ list_del_init (&stub->list);
+ call_resume (stub);
+ }
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (lookup, frame, op_ret, op_errno, inode, buf,
+ dict, postparent);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_get_ancestors (char *path, char **parent, char **grand_parent)
+{
+ int32_t ret = -1, i = 0;
+ char *cpy = NULL;
+
+ if (!path || !parent || !grand_parent) {
+ ret = 0;
+ goto out;
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (!strcmp (path, "/")) {
+ break;
+ }
+
+ cpy = gf_strdup (path);
+ if (cpy == NULL) {
+ ret = -errno;
+ goto out;
+ }
+
+ path = dirname (cpy);
+ switch (i)
+ {
+ case 0:
+ *parent = path;
+ break;
+ case 1:
+ *grand_parent = path;
+ break;
+ }
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int32_t
+sp_cache_remove_parent_entry (call_frame_t *frame, xlator_t *this,
+ inode_table_t *itable, char *path)
+{
+ char *parent = NULL, *grand_parent = NULL, *cpy = NULL;
+ inode_t *inode_gp = NULL;
+ int32_t ret = -1;
+
+ ret = sp_get_ancestors (path, &parent, &grand_parent);
+ if (ret < 0) {
+ goto out;
+ }
+
+ if (grand_parent && strcmp (grand_parent, "/")) {
+ inode_gp = inode_from_path (itable, grand_parent);
+ if (inode_gp) {
+ cpy = gf_strdup (parent);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name,
+ cpy, out, ret,
+ -ENOMEM);
+ path = basename (cpy);
+ sp_remove_caches_from_all_fds_opened (this, inode_gp,
+ path);
+ GF_FREE (cpy);
+
+ inode_unref (inode_gp);
+ }
+ }
+
+ ret = 0;
+out:
+ if (parent) {
+ GF_FREE (parent);
+ }
+
+ if (grand_parent) {
+ GF_FREE (grand_parent);
+ }
+
+ return ret;
+}
+
+
+void
+sp_is_empty (dict_t *this, char *key, data_t *value, void *data)
+{
+ char *ptr = data;
+
+ if (strcmp (key, "gfid-req") == 0)
+ return;
+
+ if (ptr && *ptr) {
+ *ptr = 0;
+ }
+}
+
+
+int32_t
+sp_lookup_helper (call_frame_t *frame,xlator_t *this, loc_t *loc,
+ dict_t *xattr_req)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0;
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
+ EINVAL);
+
+ stub = fop_lookup_stub (frame, sp_lookup_helper, loc, xattr_req);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, stub, unwind,
+ op_errno, ENOMEM);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ if (op_ret == 0) {
+ if (!inode_ctx->lookup_in_progress) {
+ inode_ctx->lookup_in_progress = 1;
+ can_wind = 1;
+ } else {
+ list_add_tail (&stub->list,
+ &inode_ctx->waiting_ops);
+ stub = NULL;
+ }
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ goto unwind;
+ }
+
+ if (can_wind) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc,
+ xattr_req);
+ }
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+}
+
+
+/*
+ * TODO: implement sending lookups for every fop done on this path. As of now
+ * lookup on the path is sent only for the first fop on this path.
+ */
+int32_t
+sp_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
+{
+ gf_dirent_t *dirent = NULL;
+ char entry_cached = 0;
+ uint64_t value = 0;
+ char xattr_req_empty = 1, can_wind = 0;
+ sp_cache_t *cache = NULL;
+ struct iatt postparent = {0, }, buf = {0, };
+ int32_t ret = -1, op_ret = -1, op_errno = EINVAL;
+ sp_inode_ctx_t *inode_ctx = NULL, *parent_inode_ctx = NULL;
+ sp_local_t *local = NULL;
+ call_stub_t *stub = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
+ GF_VALIDATE_OR_GOTO (frame->this->name, loc, unwind);
+ GF_VALIDATE_OR_GOTO (frame->this->name, loc->inode, unwind);
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_CARE);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot create stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s)(%s)", loc->inode->ino,
+ loc->inode->gfid, strerror (op_errno));
+ goto unwind;
+ }
+
+ if ((loc->parent == NULL) || (loc->name == NULL)) {
+ goto wind;
+ }
+
+ if (xattr_req != NULL) {
+ dict_foreach (xattr_req, sp_is_empty, &xattr_req_empty);
+ }
+
+ if (!xattr_req_empty) {
+ goto wind;
+ }
+
+ cache = sp_get_cache_inode (this, loc->parent, frame->root->pid);
+ if (cache) {
+ ret = sp_cache_get_entry (cache, (char *)loc->name, &dirent);
+ if (ret == 0) {
+ ret = inode_ctx_get (loc->parent, this, &value);
+ if ((ret == 0) && (value != 0)) {
+ parent_inode_ctx = (void *)(long)value;
+ postparent = parent_inode_ctx->stbuf;
+ buf = dirent->d_stat;
+ op_ret = 0;
+ op_errno = 0;
+ entry_cached = 1;
+ }
+
+ GF_FREE (dirent);
+ }
+ } else if (IA_ISDIR (loc->inode->ia_type)) {
+ cache = sp_get_cache_inode (this, loc->inode, frame->root->pid);
+ if (cache) {
+ ret = sp_cache_get_entry (cache, ".", &dirent);
+ if (ret == 0) {
+ ret = inode_ctx_get (loc->parent, this, &value);
+ if ((ret == 0) && (value != 0)) {
+ parent_inode_ctx = (void *)(long)value;
+ postparent = parent_inode_ctx->stbuf;
+ buf = dirent->d_stat;
+ op_ret = 0;
+ op_errno = 0;
+ entry_cached = 1;
+ }
+
+ GF_FREE (dirent);
+ }
+ }
+ }
+
+wind:
+ if (entry_cached) {
+ if (cache) {
+ cache->hits++;
+ sp_cache_unref (cache);
+ }
+ } else {
+ if (cache) {
+ cache->miss++;
+ sp_cache_unref (cache);
+ }
+
+ stub = fop_lookup_stub (frame, sp_lookup_helper, loc,
+ xattr_req);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, stub, unwind,
+ op_errno, ENOMEM);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, unwind,
+ op_errno, ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING,
+ "loc_copy failed (%s)", strerror (op_errno));
+ goto unwind;
+ }
+
+ local->is_lookup = 1;
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (inode_ctx->lookup_in_progress) {
+ list_add_tail (&stub->list,
+ &inode_ctx->waiting_ops);
+ stub = NULL;
+ } else {
+ can_wind = 1;
+ inode_ctx->lookup_in_progress = 1;
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (can_wind) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc,
+ xattr_req);
+ }
+
+ if (stub != NULL) {
+ call_stub_destroy (stub);
+ }
+
+ return 0;
+ }
+
+unwind:
+ SP_STACK_UNWIND (lookup, frame, op_ret, op_errno, (loc)?loc->inode:NULL,
+ &buf, NULL, &postparent);
+
+ return 0;
+}
+
+
+int32_t
+sp_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+{
+ sp_local_t *local = NULL;
+ sp_cache_t *cache = NULL;
+ fd_t *fd = NULL;
+ int32_t ret = 0;
+ char was_present = 1;
+ sp_private_t *priv = NULL;
+
+ GF_ASSERT (frame);
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ if ((this == NULL) || (this->private == NULL)) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ (this == NULL) ? "xlator object (this) is NULL"
+ : "stat-prefetch configuration (this->private) is "
+ "NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ gf_log (frame->this->name, GF_LOG_WARNING, "local is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ fd = local->fd;
+
+ priv = this->private;
+
+ LOCK (&priv->lock);
+ {
+ if (!priv->mem_pool)
+ priv->mem_pool = mem_pool_new (rbthash_entry_t,
+ GF_SP_CACHE_ENTRIES_EXPECTED);
+ }
+ UNLOCK (&priv->lock);
+
+ if (!priv->mem_pool)
+ goto out;
+
+ LOCK (&fd->lock);
+ {
+ cache = __sp_get_cache_fd (this, fd);
+ if (cache == NULL) {
+ was_present = 0;
+ cache = sp_cache_init (this);
+ if (cache == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "creation of stat-prefetch cache "
+ "for fd (%p) opened on inode "
+ "(ino:%"PRId64", gfid:%s) failed", fd,
+ fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unlock;
+ }
+
+ ret = __sp_put_cache (this, fd, cache);
+ if (ret == -1) {
+ sp_cache_free (cache);
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot store cache in fd (%p) opened "
+ "on inode (ino:%"PRId64", gfid:%s)", fd,
+ fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unlock;
+ }
+ }
+
+ sp_cache_ref (cache);
+ }
+unlock:
+ UNLOCK (&fd->lock);
+
+ if (cache != NULL) {
+ sp_cache_add_entries (cache, entries);
+ if (was_present) {
+ sp_cache_unref (cache);
+ }
+ }
+
+out:
+ SP_STACK_UNWIND (readdir, frame, op_ret, op_errno, entries);
+ return 0;
+}
+
+
+int32_t
+sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t off)
+{
+ sp_cache_t *cache = NULL;
+ sp_local_t *local = NULL;
+ char *path = NULL;
+ int32_t ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ cache = sp_get_cache_fd (this, fd);
+ if (cache) {
+ if (off != cache->expected_offset) {
+ sp_cache_remove_entry (cache, NULL, 1);
+ }
+
+ sp_cache_unref (cache);
+ }
+
+ ret = inode_path (fd->inode, NULL, &path);
+ if (ret < 0) {
+ op_errno = -ret;
+ gf_log (this->name, GF_LOG_WARNING, "cannot construct path on "
+ "which fd (%p) is opened (fd.inode.ino = %"PRId64", "
+ "fd.inode.gfid = %s) (%s)", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid), strerror (op_errno));
+ goto unwind;
+ }
+
+ ret = sp_cache_remove_parent_entry (frame, this, fd->inode->table,
+ path);
+
+ if (ret < 0) {
+ op_errno = -ret;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache"
+ " for path %s", path);
+ goto unwind;
+ }
+
+ GF_FREE (path);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ if (local) {
+ local->fd = fd;
+ frame->local = local;
+ }
+
+ STACK_WIND (frame, sp_readdir_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readdirp, fd, size, off);
+
+ return 0;
+
+unwind:
+ if (path != NULL) {
+ GF_FREE (path);
+ }
+
+ SP_STACK_UNWIND (readdir, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ GF_ASSERT (frame);
+
+ SP_STACK_UNWIND (truncate, frame, op_ret, op_errno, prebuf, postbuf);
+ return 0;
+}
+
+
+
+int32_t
+sp_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *buf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (rename, frame, op_ret, op_errno, buf, preoldparent,
+ postoldparent, prenewparent, postnewparent);
+ return 0;
+}
+
+
+int32_t
+sp_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, fd_t *fd)
+{
+ sp_local_t *local = NULL;
+ sp_fd_ctx_t *fd_ctx = NULL;
+
+ GF_ASSERT (frame);
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ if (this == NULL) {
+ gf_log (frame->this ? frame->this->name : "stat-prefetch",
+ GF_LOG_WARNING, "xlator object (this) is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ gf_log (this->name, GF_LOG_WARNING, "local is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ if (fd == NULL) {
+ gf_log (this->name, GF_LOG_WARNING, "fd is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ fd_ctx = sp_fd_ctx_new (this, local->loc.parent,
+ (char *)local->loc.name, NULL);
+ if (fd_ctx == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ op_ret = fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot set stat-prefetch context in fd (%p) opened on "
+ "inode (ino:%"PRId64", gfid:%s)", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ sp_fd_ctx_free (fd_ctx);
+ op_errno = ENOMEM;
+ }
+
+out:
+ SP_STACK_UNWIND (open, frame, op_ret, op_errno, fd);
+ return 0;
+}
+
+
+int32_t
+sp_open_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
+ GF_VALIDATE_OR_GOTO (frame->this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
+ EINVAL);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if ((op_ret == -1) && ((op_errno != ENOENT)
+ || !((op_errno == ENOENT)
+ && (flags & O_CREAT)))) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding open call waiting on "
+ "it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_fd_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (open, frame, -1, op_errno, fd);
+ return 0;
+}
+
+
+int32_t
+sp_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int wbflags)
+{
+ call_stub_t *stub = NULL;
+ sp_local_t *local = NULL;
+ int32_t op_errno = EINVAL, ret = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING, "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ stub = fop_open_stub (frame, sp_open_helper, loc, flags, fd, wbflags);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (open, frame, -1, op_errno, fd);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_fd_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd,
+ wbflags);
+ }
+
+ return 0;
+
+}
+
+static int32_t
+sp_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ sp_local_t *local = NULL;
+ sp_fd_ctx_t *fd_ctx = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
+
+ GF_ASSERT (frame);
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ if (this == NULL) {
+ gf_log (frame->this ? frame->this->name : "stat-prefetch",
+ GF_LOG_WARNING, "xlator object (this) is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ gf_log (this->name, GF_LOG_WARNING, "local is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ looked_up = 1;
+ op_ret = sp_update_inode_ctx (this, local->loc.inode, &op_ret,
+ &op_errno, &lookup_in_progress,
+ &looked_up, buf, NULL, &op_errno);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "updating stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s) (path: %s) failed (%s)",
+ local->loc.inode->ino,
+ uuid_utoa (local->loc.inode->gfid), local->loc.path,
+ strerror (op_errno));
+ goto out;
+ }
+
+ op_ret = sp_update_inode_ctx (this, local->loc.parent, NULL, NULL, NULL,
+ NULL, postparent, NULL, &op_errno);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "updating stat-prefetch context in parent inode failed "
+ "for path (%s)(%s)", local->loc.path,
+ strerror (op_errno));
+ goto out;
+ }
+
+ fd_ctx = sp_fd_ctx_new (this, local->loc.parent,
+ (char *)local->loc.name, NULL);
+ if (fd_ctx == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ op_ret = fd_ctx_set (fd, this, (long)(void *)fd_ctx);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot set stat-prefetch context in fd (%p) opened on "
+ "inode (ino:%"PRId64", gfid:%s)", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ sp_fd_ctx_free (fd_ctx);
+ op_errno = ENOMEM;
+ }
+
+out:
+ SP_STACK_UNWIND (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent);
+ return 0;
+}
+
+
+int32_t
+sp_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd, dict_t *params)
+{
+ sp_local_t *local = NULL;
+ int32_t op_errno = -1, ret = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->path, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->name, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, loc->inode, out,
+ op_errno, EINVAL);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->inode->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING,
+ "loc_copy failed (%s)", strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot create stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s)(%s)", loc->inode->ino,
+ loc->inode->gfid, strerror (op_errno));
+ goto out;
+ }
+
+ need_unwind = 0;
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+ } else {
+ STACK_WIND (frame, sp_create_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->create, loc, flags,
+ mode, fd, params);
+ }
+ return 0;
+}
+
+
+int32_t
+sp_opendir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding opendir call waiting "
+ "on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_fd_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir, loc, fd);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
+{
+ sp_local_t *local = NULL;
+ call_stub_t *stub = NULL;
+ int32_t op_errno = EINVAL, ret = -1;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING, "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ stub = fop_opendir_stub (frame, sp_opendir_helper, loc, fd);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (opendir, frame, -1, op_errno, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_fd_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->opendir, loc, fd);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_new_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ sp_local_t *local = NULL;
+ char lookup_in_progress = 0, looked_up = 0;
+
+ GF_ASSERT (frame);
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ if (local == NULL) {
+ gf_log (frame->this->name, GF_LOG_WARNING, "local is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ if (this == NULL) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "xlator object (this) is NULL");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ looked_up = 1;
+ op_ret = sp_update_inode_ctx (this, local->loc.inode, &op_ret,
+ &op_errno, &lookup_in_progress,
+ &looked_up, buf, NULL, &op_errno);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "updating stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s) (path: %s) failed (%s)",
+ local->loc.inode->ino,
+ uuid_utoa (local->loc.inode->gfid), local->loc.path,
+ strerror (op_errno));
+ goto out;
+ }
+
+ op_ret = sp_update_inode_ctx (this, local->loc.parent, NULL, NULL, NULL,
+ NULL, postparent, NULL, &op_errno);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "updating stat-prefetch context in parent inode failed "
+ "for path (%s)(%s)", local->loc.path,
+ strerror (op_errno));
+ }
+
+out:
+ SP_STACK_UNWIND (mkdir, frame, op_ret, op_errno, inode, buf, preparent,
+ postparent);
+ return 0;
+}
+
+
+int
+sp_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *params)
+{
+ int32_t ret = -1, op_errno = EINVAL;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->inode->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", loc->path);
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING, "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot create stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s)(%s)", loc->inode->ino,
+ loc->inode->gfid, strerror (op_errno));
+ goto out;
+ }
+
+ need_unwind = 0;
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+ } else {
+ STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mkdir, loc, mode, params);
+ }
+
+ return 0;
+}
+
+
+int
+sp_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t rdev, dict_t *params)
+{
+ int32_t op_errno = EINVAL, ret = -1;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->inode->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", loc->path);
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING, "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot create stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s)(%s)", loc->inode->ino,
+ loc->inode->gfid, strerror (op_errno));
+ goto out;
+ }
+
+ need_unwind = 0;
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+ } else {
+ STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->mknod, loc, mode,
+ rdev, params);
+ }
+
+ return 0;
+}
+
+
+int
+sp_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
+ loc_t *loc, dict_t *params)
+{
+ int32_t ret = -1, op_errno = EINVAL;
+ char need_unwind = 1;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ sp_local_t *local = NULL;
+
+ GF_ASSERT (frame);
+
+ GF_VALIDATE_OR_GOTO ((frame->this ? frame->this->name
+ : "stat-prefetch"),
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->inode->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", loc->path);
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_sp_mt_sp_local_t);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, local, out, op_errno,
+ ENOMEM);
+
+ frame->local = local;
+
+ ret = loc_copy (&local->loc, loc);
+ if (ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_WARNING, "loc_copy failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ inode_ctx = sp_check_and_create_inode_ctx (this, loc->inode,
+ SP_DONT_EXPECT);
+ if (inode_ctx == NULL) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot create stat-prefetch context in inode (ino:%"
+ PRId64", gfid:%s)(%s)", loc->inode->ino,
+ loc->inode->gfid, strerror (op_errno));
+ goto out;
+ }
+
+ need_unwind = 0;
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+ } else {
+ STACK_WIND (frame, sp_new_entry_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->symlink, linkpath, loc,
+ params);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (link, frame, op_ret, op_errno, inode, buf, preparent,
+ postparent);
+ return 0;
+}
+
+
+int32_t
+sp_link_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, newloc, unwind);
+
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", oldloc->inode->ino,
+ uuid_utoa (oldloc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
+ EINVAL);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding link call waiting on "
+ "it", oldloc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_link_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link, oldloc, newloc);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ call_stub_t *stub = NULL;
+ int32_t ret = 0, op_errno = EINVAL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc->inode, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc->name, out);
+
+ ret = sp_cache_remove_parent_entry (frame, this, newloc->parent->table,
+ (char *)newloc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", newloc->path);
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_remove_caches_from_all_fds_opened (this, oldloc->parent,
+ (char *)oldloc->name);
+
+ stub = fop_link_stub (frame, sp_link_helper, oldloc, newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, oldloc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_link_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->link, oldloc, newloc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_truncate_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ off_t offset)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, inode_ctx, unwind, op_errno,
+ EINVAL);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding truncate call "
+ "waiting on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_truncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_truncate_stub (frame, sp_truncate_helper, loc, offset);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_truncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "stat-prefetch context not "
+ "set in fd (%p) opened on inode (ino:%"PRId64", "
+ "gfid:%s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ sp_remove_caches_from_all_fds_opened (this, parent, (char *)name);
+
+ STACK_WIND (frame, sp_truncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prestat, struct iatt *poststat)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (setattr, frame, op_ret, op_errno, prestat, poststat);
+ return 0;
+}
+
+
+int
+sp_setattr_helper (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, struct iatt *buf, int32_t valid)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding setattr call "
+ "waiting on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_setattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setattr, loc, buf, valid);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+sp_setattr (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, struct iatt *buf, int32_t valid)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_setattr_stub (frame, sp_setattr_helper, loc, buf, valid);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_setattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setattr, loc, buf, valid);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *path,
+ struct iatt *buf)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (readlink, frame, op_ret, op_errno, path, buf);
+ return 0;
+}
+
+
+int32_t
+sp_readlink_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ size_t size)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding readlink call "
+ "waiting on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_readlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink, loc, size);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_readlink_stub (frame, sp_readlink_helper, loc, size);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_readlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readlink, loc, size);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (unlink, frame, op_ret, op_errno, preparent,
+ postparent);
+ return 0;
+}
+
+
+
+int32_t
+sp_err_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (setxattr, frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_unlink_helper (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding unlink call "
+ "waiting on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink, loc);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int32_t ret = -1, op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->parent->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", loc->path);
+ goto out;
+ }
+
+ stub = fop_unlink_stub (frame, sp_unlink_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->unlink, loc);
+ }
+
+ return 0;
+}
+
+
+int
+sp_rmdir_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "lookup-behind has failed "
+ "for path (%s)(%s), unwinding rmdir call "
+ "waiting on it", loc->path, strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir, loc, flags);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int
+sp_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
+{
+ int32_t ret = -1, op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->inode, NULL);
+
+ ret = sp_cache_remove_parent_entry (frame, this, loc->inode->table,
+ (char *)loc->path);
+ if (ret == -1) {
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", loc->path);
+ goto out;
+ }
+
+ stub = fop_rmdir_stub (frame, sp_rmdir_helper, loc, flags);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rmdir, loc, flags);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (readv, frame, op_ret, op_errno, vector, count, stbuf,
+ iobref);
+ return 0;
+}
+
+
+int32_t
+sp_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "stat-prefetch context not "
+ "set in fd (%p) opened on inode (ino:%"PRId64", "
+ "gfid:%s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ sp_remove_caches_from_all_fds_opened (this, parent, (char *)name);
+
+ STACK_WIND (frame, sp_readv_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->readv, fd, size, offset);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (readv, frame, -1, op_errno, NULL, -1, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, struct iobref *iobref)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "stat-prefetch context not "
+ "set in fd (%p) opened on inode (ino:%"PRId64", "
+ "gfid:%s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ sp_remove_caches_from_all_fds_opened (this, parent, (char *)name);
+
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->writev, fd, vector, count, off,
+ iobref);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "stat-prefetch context not "
+ "set in fd (%p) opened on inode (ino:%"PRId64", "
+ "gfid:%s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ sp_remove_caches_from_all_fds_opened (this, parent, (char *)name);
+
+ STACK_WIND (frame, sp_unlink_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fsync, fd, flags);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_rename_helper (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ uint64_t value = 0;
+ char need_unwind = 0;
+ char can_wind = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ int32_t old_op_ret = -1, old_op_errno = -1;
+ int32_t new_op_ret = -1, new_op_errno = -1;
+ char old_inode_looked_up = 0, new_inode_looked_up = 0;
+ sp_inode_ctx_t *old_inode_ctx = NULL, *new_inode_ctx = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, newloc, unwind);
+
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", oldloc->inode->ino,
+ uuid_utoa (oldloc->inode->gfid));
+ goto unwind;
+ }
+
+ old_inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, old_inode_ctx, unwind);
+
+ LOCK (&old_inode_ctx->lock);
+ {
+ old_inode_looked_up = old_inode_ctx->looked_up;
+ old_op_ret = old_inode_ctx->op_ret;
+ old_op_errno = old_inode_ctx->op_errno;
+ need_unwind = old_inode_ctx->need_unwind;
+ }
+ UNLOCK (&old_inode_ctx->lock);
+
+ if (need_unwind) {
+ /* there was an error while queuing up lookup stub for newloc */
+ gf_log (this->name, GF_LOG_WARNING,
+ "could not queue lookup stub for path (%s)",
+ newloc->path);
+ goto unwind;
+ }
+
+ if (newloc->inode != NULL) {
+ ret = inode_ctx_get (newloc->inode, this, &value);
+ if (ret == 0) {
+ new_inode_ctx = (sp_inode_ctx_t *)(long)value;
+ if (new_inode_ctx != NULL) {
+ LOCK (&new_inode_ctx->lock);
+ {
+ new_inode_looked_up
+ = new_inode_ctx->looked_up;
+ new_op_ret = new_inode_ctx->op_ret;
+ new_op_errno = new_inode_ctx->op_errno;
+ }
+ UNLOCK (&new_inode_ctx->lock);
+ }
+ }
+ }
+
+ if (new_inode_ctx == NULL) {
+ if (old_op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed "
+ "for path (%s)(%s), unwinding rename call "
+ "waiting on it", oldloc->path,
+ strerror (old_op_errno));
+
+ op_errno = old_op_errno;
+ goto unwind;
+ } else {
+ can_wind = 1;
+ }
+ } else {
+ if (new_inode_looked_up && old_inode_looked_up) {
+ if ((old_op_ret == -1)
+ || ((new_op_ret == -1)
+ && (new_op_errno != ENOENT))) {
+ if (old_op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed "
+ "for path (%s)(%s), unwinding "
+ "rename call waiting on it",
+ oldloc->path,
+ strerror (old_op_errno));
+ op_errno = old_op_errno;
+ } else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed "
+ "for path (%s)(%s), unwinding "
+ "rename call waiting on it",
+ newloc->path,
+ strerror (new_op_errno));
+ op_errno = new_op_errno;
+ }
+
+ goto unwind;
+ } else {
+ can_wind = 1;
+ }
+ }
+ }
+
+ if (can_wind) {
+ STACK_WIND (frame, sp_rename_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ }
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL,
+ NULL);
+ return 0;
+}
+
+
+int32_t
+sp_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,loc_t *newloc)
+{
+ char need_unwind = 1;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = -1, op_errno = EINVAL;
+ char old_inode_can_wind = 0, new_inode_can_wind = 0;
+ char old_inode_need_lookup = 0, new_inode_need_lookup = 0;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (frame->this ? frame->this->name : "stat-prefetch",
+ this, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc->path, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc->name, out);
+ GF_VALIDATE_OR_GOTO (this->name, oldloc->inode, out);
+
+ GF_VALIDATE_OR_GOTO (this->name, newloc, out);
+ GF_VALIDATE_OR_GOTO (this->name, newloc->path, out);
+
+ sp_remove_caches_from_all_fds_opened (this, oldloc->parent,
+ (char *)oldloc->name);
+
+ sp_remove_caches_from_all_fds_opened (this, newloc->parent,
+ (char *)newloc->name);
+
+ ret = sp_cache_remove_parent_entry (frame, this, oldloc->parent->table,
+ (char *)oldloc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", oldloc->path);
+ goto out;
+ }
+
+ ret = sp_cache_remove_parent_entry (frame, this, newloc->parent->table,
+ (char *)newloc->path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot remove parent entry from grand-parent's cache "
+ "for path (%s)", newloc->path);
+ goto out;
+ }
+
+ if (IA_ISDIR (oldloc->inode->ia_type)) {
+ sp_remove_caches_from_all_fds_opened (this, oldloc->inode,
+ NULL);
+ }
+
+ stub = fop_rename_stub (frame, sp_rename_helper, oldloc, newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ ret = sp_process_inode_ctx (frame, this, oldloc, stub, &need_unwind,
+ &old_inode_need_lookup, &old_inode_can_wind,
+ &op_errno);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "processing stat-prefetch "
+ "context in inode (ino:%"PRId64", gfid:%s) (path:%s) "
+ "failed (%s)", oldloc->inode->ino,
+ uuid_utoa (oldloc->inode->gfid), oldloc->path,
+ strerror (op_errno));
+ goto out;
+ }
+
+ if (newloc->inode != NULL) {
+ stub = fop_rename_stub (frame, sp_rename_helper, oldloc,
+ newloc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ ret = sp_process_inode_ctx (frame, this, newloc, stub,
+ &need_unwind,
+ &new_inode_need_lookup,
+ &new_inode_can_wind, &op_errno);
+ if (ret == -1) {
+ ret = inode_ctx_get (oldloc->inode, this, &value);
+
+ inode_ctx = (sp_inode_ctx_t *)(long)value;
+ if (inode_ctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode"
+ " (ino:%"PRId64", gfid:%s) (path:%s)",
+ oldloc->inode->ino,
+ uuid_utoa (oldloc->inode->gfid),
+ oldloc->path);
+ goto out;
+ }
+
+ LOCK (&inode_ctx->lock);
+ {
+ if (!inode_ctx->looked_up) {
+ /* unwind in sp_rename_helper */
+ need_unwind = 0;
+ inode_ctx->need_unwind = 1;
+ }
+ }
+ UNLOCK (&inode_ctx->lock);
+ }
+
+ } else {
+ new_inode_can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+ } else if (old_inode_need_lookup || new_inode_need_lookup) {
+ if (old_inode_need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, oldloc,
+ NULL);
+ }
+
+ if (new_inode_need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, newloc,
+ NULL);
+ }
+ } else if (old_inode_can_wind && new_inode_can_wind) {
+ STACK_WIND (frame, sp_rename_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->rename, oldloc, newloc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_setxattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding setxattr call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr, loc, dict,
+ flags);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (setxattr, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
+ int32_t flags)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_setxattr_stub (frame, sp_setxattr_helper, loc, dict, flags);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (setxattr, frame, -1, op_errno);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->setxattr, loc, dict,
+ flags);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_removexattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding setxattr call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr, loc, name);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (removexattr, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_removexattr_stub (frame, sp_removexattr_helper, loc, name);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (removexattr, frame, -1, op_errno);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->removexattr, loc, name);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+
+int32_t
+sp_getxattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding getxattr call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_getxattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr, loc, name);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ stub = fop_getxattr_stub (frame, sp_getxattr_helper, loc, name);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (getxattr, frame, -1, op_errno, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_getxattr_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->getxattr, loc, name);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (xattrop, frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+
+int32_t
+sp_xattrop_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding xattrop call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, out);
+
+ sp_remove_caches_from_all_fds_opened (this, loc->parent,
+ (char *)loc->name);
+
+ stub = fop_xattrop_stub (frame, sp_xattrop_helper, loc, flags, dict);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->xattrop, loc, flags, dict);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0, op_errno = EINVAL;
+ inode_t *parent = NULL;
+ char *name = NULL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, fd, unwind);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "stat-prefetch context not "
+ "set in fd (%p) opened on inode (ino:%"PRId64", "
+ "gfid:%s", fd, fd->inode->ino,
+ uuid_utoa (fd->inode->gfid));
+ goto unwind;
+ }
+
+ fd_ctx = (void *)(long)value;
+ name = fd_ctx->name;
+ parent = fd_ctx->parent_inode;
+
+ sp_remove_caches_from_all_fds_opened (this, parent, name);
+
+ STACK_WIND (frame, sp_xattrop_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fxattrop, fd, flags, dict);
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+int32_t
+sp_stbuf_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *buf)
+{
+ GF_ASSERT (frame);
+ SP_STACK_UNWIND (stat, frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+
+int32_t
+sp_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding stat call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_stbuf_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat, loc);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+sp_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ stub = fop_stat_stub (frame, sp_stat_helper, loc);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (stat, frame, -1, op_errno, NULL);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_stbuf_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->stat, loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_access_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding access call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access, loc, mask);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (access, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ int32_t op_errno = -1;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ stub = fop_access_stub (frame, sp_access_helper, loc, mask);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (access, frame, -1, op_errno);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->access, loc, mask);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_inodelk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *lock)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding inodelk call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd, lock);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (inodelk, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_inodelk (call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc,
+ int32_t cmd, struct gf_flock *lock)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ stub = fop_inodelk_stub (frame, sp_inodelk_helper, volume, loc, cmd,
+ lock);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (inodelk, frame, -1, op_errno);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->inodelk, volume, loc, cmd,
+ lock);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_entrylk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, const char *basename, entrylk_cmd cmd,
+ entrylk_type type)
+{
+ uint64_t value = 0;
+ sp_inode_ctx_t *inode_ctx = NULL;
+ int32_t ret = 0, op_ret = -1, op_errno = EINVAL;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ ret = inode_ctx_get (loc->inode, this, &value);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat-prefetch context not set in inode "
+ "(ino:%"PRId64" gfid:%s)", loc->inode->ino,
+ uuid_utoa (loc->inode->gfid));
+ goto unwind;
+ }
+
+ inode_ctx = (sp_inode_ctx_t *)(long) value;
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, unwind);
+
+ LOCK (&inode_ctx->lock);
+ {
+ op_ret = inode_ctx->op_ret;
+ op_errno = inode_ctx->op_errno;
+ }
+ UNLOCK (&inode_ctx->lock);
+
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lookup-behind has failed for path (%s)(%s), "
+ "unwinding entrylk call waiting on it", loc->path,
+ strerror (op_errno));
+ goto unwind;
+ }
+
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->entrylk, volume, loc, basename,
+ cmd, type);
+
+ return 0;
+
+unwind:
+ SP_STACK_UNWIND (entrylk, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+sp_entrylk (call_frame_t *frame, xlator_t *this, const char *volume, loc_t *loc,
+ const char *basename, entrylk_cmd cmd, entrylk_type type)
+{
+ int32_t op_errno = EINVAL;
+ call_stub_t *stub = NULL;
+ char can_wind = 0, need_lookup = 0, need_unwind = 1;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc->inode, out);
+
+ stub = fop_entrylk_stub (frame, sp_entrylk_helper, volume, loc,
+ basename, cmd, type);
+ if (stub == NULL) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ sp_process_inode_ctx (frame, this, loc, stub, &need_unwind,
+ &need_lookup, &can_wind, &op_errno);
+
+out:
+ if (need_unwind) {
+ SP_STACK_UNWIND (entrylk, frame, -1, op_errno);
+ } else if (need_lookup) {
+ STACK_WIND (frame, sp_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, sp_err_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->entrylk, volume, loc,
+ basename, cmd, type);
+ }
+
+ return 0;
+}
+
+
+int32_t
+sp_forget (xlator_t *this, inode_t *inode)
+{
+ struct iatt *buf = NULL;
+ uint64_t value = 0;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ inode_ctx_del (inode, this, &value);
+
+ if (value) {
+ buf = (void *)(long)value;
+ GF_FREE (buf);
+ }
+
+out:
+ return 0;
+}
+
+
+int32_t
+sp_release (xlator_t *this, fd_t *fd)
+{
+ sp_fd_ctx_t *fd_ctx = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+ sp_cache_t *cache = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ ret = fd_ctx_del (fd, this, &value);
+ if (!ret) {
+ fd_ctx = (void *)(long) value;
+ cache = fd_ctx->cache;
+ if (cache) {
+ gf_log (this->name, GF_LOG_TRACE, "cache hits: %lu, "
+ "cache miss: %lu", cache->hits, cache->miss);
+ }
+
+ sp_fd_ctx_free (fd_ctx);
+ }
+
+out:
+ return 0;
+}
+
+
+int
+sp_priv_dump (xlator_t *this)
+{
+ sp_private_t *priv = NULL;
+ uint32_t total_entries = 0;
+ uint32_t ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
+
+ priv = this->private;
+
+ total_entries = priv->entries;
+
+ gf_proc_dump_build_key (key_prefix, "xlator.performance.stat-prefetch",
+ "priv");
+ gf_proc_dump_add_section (key_prefix);
+
+ gf_proc_dump_build_key (key, key_prefix, "max_allowed_entries");
+ gf_proc_dump_write (key, "%lu", GF_SP_CACHE_ENTRIES_EXPECTED);
+ gf_proc_dump_build_key (key, key_prefix, "num_entries_cached");
+ gf_proc_dump_write (key, "%lu",(unsigned long)total_entries);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+
+ ret = xlator_mem_acct_init (this, gf_sp_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+
+int32_t
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ sp_private_t *priv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("stat-prefetch", this, out);
+
+ if (!this->children || this->children->next) {
+ gf_log ("stat-prefetch",
+ GF_LOG_ERROR,
+ "FATAL: translator %s does not have exactly one child "
+ "node", this->name);
+ goto out;
+ }
+
+ priv = GF_CALLOC (1, sizeof(sp_private_t), gf_sp_mt_sp_private_t);
+ LOCK_INIT (&priv->lock);
+
+ this->private = priv;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+void
+fini (xlator_t *this)
+{
+ sp_private_t *priv = NULL;
+
+ if (!this)
+ goto out;
+ else {
+ priv = this->private;
+ if (priv) {
+ if (priv->mem_pool)
+ mem_pool_destroy (priv->mem_pool);
+ LOCK_DESTROY (&priv->lock);
+ GF_FREE (priv);
+ this->private = NULL;
+ }
+ }
+out:
+ return;
+}
+
+
+struct xlator_fops fops = {
+ .lookup = sp_lookup,
+ .readdir = sp_readdir,
+ .readdirp = sp_readdir,
+ .open = sp_open,
+ .create = sp_create,
+ .opendir = sp_opendir,
+ .mkdir = sp_mkdir,
+ .mknod = sp_mknod,
+ .symlink = sp_symlink,
+ .link = sp_link,
+ .truncate = sp_truncate,
+ .ftruncate = sp_ftruncate,
+ .readlink = sp_readlink,
+ .unlink = sp_unlink,
+ .rmdir = sp_rmdir,
+ .readv = sp_readv,
+ .writev = sp_writev,
+ .fsync = sp_fsync,
+ .rename = sp_rename,
+ .setxattr = sp_setxattr,
+ .removexattr = sp_removexattr,
+ .xattrop = sp_xattrop,
+ .fxattrop = sp_fxattrop,
+ .setattr = sp_setattr,
+ .stat = sp_stat,
+ .access = sp_access,
+ .getxattr = sp_getxattr,
+ .inodelk = sp_inodelk,
+ .entrylk = sp_entrylk,
+};
+
+struct xlator_cbks cbks = {
+ .forget = sp_forget,
+ .release = sp_release,
+ .releasedir = sp_release
+};
+
+struct xlator_dumpops dumpops = {
+ .priv = sp_priv_dump,
+};
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.h b/xlators/performance/stat-prefetch/src/stat-prefetch.h
new file mode 100644
index 000000000..2a3740f65
--- /dev/null
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2009-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _STAT_PREFETCH_H
+#define _STAT_PREFETCH_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "locking.h"
+#include "inode.h"
+#include "glusterfs.h"
+#include "dict.h"
+#include "xlator.h"
+#include "rbthash.h"
+#include "hashfn.h"
+#include "call-stub.h"
+#include "stat-prefetch-mem-types.h"
+#include <libgen.h>
+
+struct sp_cache {
+ rbthash_table_t *table;
+ xlator_t *this;
+ uint64_t expected_offset; /* Offset where the next read will
+ * happen.
+ */
+ gf_lock_t lock;
+ unsigned long miss;
+ unsigned long hits;
+ uint32_t ref;
+};
+typedef struct sp_cache sp_cache_t;
+
+struct sp_fd_ctx {
+ sp_cache_t *cache;
+ inode_t *parent_inode; /*
+ * inode corresponding to dirname (path)
+ */
+ char *name; /*
+ * basename of path on which this fd is
+ * opened
+ */
+};
+typedef struct sp_fd_ctx sp_fd_ctx_t;
+
+struct sp_local {
+ loc_t loc;
+ fd_t *fd;
+ char is_lookup;
+};
+typedef struct sp_local sp_local_t;
+
+struct sp_inode_ctx {
+ char looked_up;
+ char lookup_in_progress;
+ char need_unwind;
+ int32_t op_ret;
+ int32_t op_errno;
+ struct iatt stbuf;
+ gf_lock_t lock;
+ struct list_head waiting_ops;
+};
+typedef struct sp_inode_ctx sp_inode_ctx_t;
+
+struct sp_private {
+ struct mem_pool *mem_pool;
+ uint32_t entries;
+ gf_lock_t lock;
+};
+typedef struct sp_private sp_private_t;
+
+void sp_local_free (sp_local_t *local);
+
+#define SP_STACK_UNWIND(op, frame, params ...) do { \
+ sp_local_t *__local = frame->local; \
+ frame->local = NULL; \
+ STACK_UNWIND_STRICT (op, frame, params); \
+ sp_local_free (__local); \
+ } while (0)
+
+#define SP_STACK_DESTROY(frame) do { \
+ sp_local_t *__local = frame->local; \
+ frame->local = NULL; \
+ STACK_DESTROY (frame->root); \
+ sp_local_free (__local); \
+ } while (0)
+
+#endif /* #ifndef _STAT_PREFETCH_H */
diff --git a/xlators/performance/symlink-cache/src/symlink-cache.c b/xlators/performance/symlink-cache/src/symlink-cache.c
index 3b5fbc252..0fe7be5ff 100644
--- a/xlators/performance/symlink-cache/src/symlink-cache.c
+++ b/xlators/performance/symlink-cache/src/symlink-cache.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -137,7 +146,8 @@ sc_cache_set (xlator_t *this, inode_t *inode, struct iatt *buf,
err:
if (sc) {
- FREE (sc->readlink);
+ if (sc->readlink)
+ FREE (sc->readlink);
sc->readlink = NULL;
FREE (sc);
}
@@ -232,7 +242,7 @@ sc_cache_get (xlator_t *this, inode_t *inode, char **link)
int
sc_readlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
- const char *link, struct iatt *sbuf, dict_t *xdata)
+ const char *link, struct iatt *sbuf)
{
if (op_ret > 0)
sc_cache_update (this, frame->local, link);
@@ -240,15 +250,14 @@ sc_readlink_cbk (call_frame_t *frame, void *cookie,
inode_unref (frame->local);
frame->local = NULL;
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, link, sbuf,
- xdata);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, link, sbuf);
return 0;
}
int
sc_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
+ loc_t *loc, size_t size)
{
char *link = NULL;
struct iatt buf = {0, };
@@ -266,8 +275,7 @@ sc_readlink (call_frame_t *frame, xlator_t *this,
using buf in readlink_cbk should be aware that @buf
is 0 filled
*/
- STACK_UNWIND_STRICT (readlink, frame, strlen (link), 0, link,
- &buf, NULL);
+ STACK_UNWIND_STRICT (readlink, frame, strlen (link), 0, link, &buf);
FREE (link);
return 0;
}
@@ -277,7 +285,7 @@ sc_readlink (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, sc_readlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readlink,
- loc, size, xdata);
+ loc, size);
return 0;
}
@@ -287,7 +295,7 @@ int
sc_symlink_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
inode_t *inode, struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
if (op_ret == 0) {
if (frame->local) {
@@ -295,22 +303,22 @@ sc_symlink_cbk (call_frame_t *frame, void *cookie,
}
}
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf,
- preparent, postparent, xdata);
+ STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, preparent,
+ postparent);
return 0;
}
int
sc_symlink (call_frame_t *frame, xlator_t *this,
- const char *dst, loc_t *src, mode_t umask, dict_t *xdata)
+ const char *dst, loc_t *src, dict_t *params)
{
frame->local = strdup (dst);
STACK_WIND (frame, sc_symlink_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->symlink,
- dst, src, umask, xdata);
+ dst, src, params);
return 0;
}
@@ -319,7 +327,7 @@ sc_symlink (call_frame_t *frame, xlator_t *this,
int
sc_lookup_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int op_ret, int op_errno,
- inode_t *inode, struct iatt *buf, dict_t *xdata,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
struct iatt *postparent)
{
if (op_ret == 0)
@@ -327,20 +335,19 @@ sc_lookup_cbk (call_frame_t *frame, void *cookie,
else
sc_cache_flush (this, inode);
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf,
- xdata, postparent);
+ STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno, inode, buf, xattr, postparent);
return 0;
}
int
sc_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc, dict_t *xattr_req)
{
STACK_WIND (frame, sc_lookup_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->lookup,
- loc, xdata);
+ loc, xattr_req);
return 0;
}
@@ -356,9 +363,10 @@ sc_forget (xlator_t *this,
}
-int32_t
+int32_t
init (xlator_t *this)
{
+
if (!this->children || this->children->next)
{
gf_log (this->name, GF_LOG_ERROR,
diff --git a/xlators/performance/write-behind/src/write-behind-mem-types.h b/xlators/performance/write-behind/src/write-behind-mem-types.h
index 33b8d93c6..75248fbbf 100644
--- a/xlators/performance/write-behind/src/write-behind-mem-types.h
+++ b/xlators/performance/write-behind/src/write-behind-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -16,6 +25,7 @@
enum gf_wb_mem_types_ {
gf_wb_mt_wb_file_t = gf_common_mt_end + 1,
+ gf_wb_mt_wb_local_t,
gf_wb_mt_wb_request_t,
gf_wb_mt_iovec,
gf_wb_mt_wb_conf_t,
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index ddd8a6ba2..cdc889699 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
/*TODO: check for non null wb_file_data before getting wb_file */
@@ -28,9 +37,9 @@
#include "statedump.h"
#include "write-behind-mem-types.h"
-#define MAX_VECTOR_COUNT 8
-#define WB_AGGREGATE_SIZE 131072 /* 128 KB */
-#define WB_WINDOW_SIZE 1048576 /* 1MB */
+#define MAX_VECTOR_COUNT 8
+#define WB_AGGREGATE_SIZE 131072 /* 128 KB */
+#define WB_WINDOW_SIZE 1048576 /* 1MB */
typedef struct list_head list_head_t;
struct wb_conf;
@@ -55,23 +64,22 @@ typedef struct wb_file {
}wb_file_t;
typedef struct wb_request {
- list_head_t list;
- list_head_t winds;
- list_head_t unwinds;
- list_head_t other_requests;
- call_stub_t *stub;
- size_t write_size;
- int32_t refcount;
- wb_file_t *file;
- glusterfs_fop_t fop;
- gf_lkowner_t lk_owner;
+ list_head_t list;
+ list_head_t winds;
+ list_head_t unwinds;
+ list_head_t other_requests;
+ call_stub_t *stub;
+ size_t write_size;
+ int32_t refcount;
+ wb_file_t *file;
+ glusterfs_fop_t fop;
union {
struct {
- char write_behind;
- char stack_wound;
- char got_reply;
- char virgin;
- char flush_all; /* while trying to sync to back-end,
+ char write_behind;
+ char stack_wound;
+ char got_reply;
+ char virgin;
+ char flush_all; /* while trying to sync to back-end,
* don't wait till a data of size
* equal to configured aggregate-size
* is accumulated, instead sync
@@ -88,17 +96,18 @@ typedef struct wb_request {
} wb_request_t;
struct wb_conf {
- uint64_t aggregate_size;
- uint64_t window_size;
- uint64_t disable_till;
- gf_boolean_t enable_O_SYNC;
- gf_boolean_t flush_behind;
- gf_boolean_t enable_trickling_writes;
+ uint64_t aggregate_size;
+ uint64_t window_size;
+ uint64_t disable_till;
+ gf_boolean_t enable_O_SYNC;
+ gf_boolean_t flush_behind;
+ gf_boolean_t enable_trickling_writes;
};
typedef struct wb_local {
list_head_t winds;
int32_t flags;
+ int32_t wbflags;
struct wb_file *file;
wb_request_t *request;
int op_ret;
@@ -120,71 +129,6 @@ ssize_t
__wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_size,
char enable_trickling_writes);
-/*
- Below is a succinct explanation of the code deciding whether two regions
- overlap, from Pavan <tcp@gluster.com>.
-
- For any two ranges to be non-overlapping, either the end of the first
- range is lesser than the start of the second, or vice versa. Example -
-
- <---------> <-------------->
- p q x y
-
- ( q < x ) or (y < p) = > No overlap.
-
- To check for *overlap*, we can negate this (using de morgan's laws), and
- it becomes -
-
- (q >= x ) and (y >= p)
-
- Either that, or you write the negation using -
-
- if (! ((q < x) or (y < p)) ) {
- "Overlap"
- }
-*/
-
-static inline char
-wb_requests_overlap (wb_request_t *request1, wb_request_t *request2)
-{
- off_t r1_start = 0, r1_end = 0, r2_start = 0, r2_end = 0;
-
- r1_start = request1->stub->args.writev.off;
- r1_end = r1_start + iov_length (request1->stub->args.writev.vector,
- request1->stub->args.writev.count);
-
- r2_start = request2->stub->args.writev.off;
- r2_end = r2_start + iov_length (request2->stub->args.writev.vector,
- request2->stub->args.writev.count);
-
- return ((r1_end >= r2_start) && (r2_end >= r1_start));
-}
-
-
-static inline char
-wb_overlap (list_head_t *list, wb_request_t *request)
-{
- char overlap = 0;
- wb_request_t *tmp = NULL;
-
- GF_VALIDATE_OR_GOTO ("write-behind", list, out);
- GF_VALIDATE_OR_GOTO ("write-behind", request, out);
-
- list_for_each_entry (tmp, list, list) {
- if (tmp == request) {
- break;
- }
-
- overlap = wb_requests_overlap (tmp, request);
- if (overlap) {
- break;
- }
- }
-
-out:
- return overlap;
-}
-
static int
__wb_request_unref (wb_request_t *this)
@@ -318,8 +262,6 @@ wb_enqueue (wb_file_t *file, call_stub_t *stub)
request->flags.write_request.virgin = 1;
}
- request->lk_owner = frame->root->lk_owner;
-
LOCK (&file->lock);
{
list_add_tail (&request->list, &file->request);
@@ -370,7 +312,7 @@ wb_file_create (xlator_t *this, fd_t *fd, int32_t flags)
INIT_LIST_HEAD (&file->passive_requests);
/*
- fd_ref() not required, file should never decide the existence of
+ fd_ref() not required, file should never decide the existance of
an fd
*/
file->fd= fd;
@@ -380,8 +322,6 @@ wb_file_create (xlator_t *this, fd_t *fd, int32_t flags)
file->window_conf = conf->window_size;
file->flags = flags;
- LOCK_INIT (&file->lock);
-
fd_ctx_set (fd, this, (uint64_t)(long)file);
out:
@@ -414,8 +354,7 @@ out:
int32_t
wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
- dict_t *xdata)
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf)
{
wb_local_t *local = NULL;
list_head_t *winds = NULL;
@@ -423,7 +362,6 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
wb_request_t *request = NULL, *dummy = NULL;
wb_local_t *per_request_local = NULL;
int32_t ret = -1;
- int32_t total_write_size = 0;
fd_t *fd = NULL;
GF_ASSERT (frame);
@@ -449,7 +387,6 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (request->flags.write_request.write_behind) {
file->window_current -= request->write_size;
- total_write_size += request->write_size;
}
__wb_request_unref (request);
@@ -458,19 +395,7 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (op_ret == -1) {
file->op_ret = op_ret;
file->op_errno = op_errno;
- } else if (op_ret < total_write_size) {
- /*
- * We've encountered a short write, for whatever reason.
- * Set an EIO error for the next fop. This should be
- * valid for writev or flush (close).
- *
- * TODO: Retry the write so we can potentially capture
- * a real error condition (i.e., ENOSPC).
- */
- file->op_ret = -1;
- file->op_errno = EIO;
- }
-
+ }
fd = file->fd;
}
UNLOCK (&file->lock);
@@ -503,21 +428,19 @@ out:
ssize_t
wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
{
- wb_request_t *dummy = NULL, *request = NULL;
- wb_request_t *first_request = NULL, *next = NULL;
- size_t total_count = 0, count = 0;
- size_t copied = 0;
- call_frame_t *sync_frame = NULL;
- struct iobref *iobref = NULL;
- wb_local_t *local = NULL;
- struct iovec *vector = NULL;
- ssize_t current_size = 0, bytes = 0;
- size_t bytecount = 0;
- wb_conf_t *conf = NULL;
- fd_t *fd = NULL;
- int32_t op_errno = -1;
- off_t next_offset_expected = 0;
- gf_lkowner_t lk_owner = {0, };
+ wb_request_t *dummy = NULL, *request = NULL;
+ wb_request_t *first_request = NULL, *next = NULL;
+ size_t total_count = 0, count = 0;
+ size_t copied = 0;
+ call_frame_t *sync_frame = NULL;
+ struct iobref *iobref = NULL;
+ wb_local_t *local = NULL;
+ struct iovec *vector = NULL;
+ ssize_t current_size = 0, bytes = 0;
+ size_t bytecount = 0;
+ wb_conf_t *conf = NULL;
+ fd_t *fd = NULL;
+ int32_t op_errno = -1;
GF_VALIDATE_OR_GOTO_WITH_ERROR ((file ? file->this->name
: "write-behind"), frame,
@@ -558,7 +481,8 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
goto out;
}
- local = mem_get0 (THIS->local_pool);
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_wb_mt_wb_local_t);
if (local == NULL) {
bytes = -1;
op_errno = ENOMEM;
@@ -569,10 +493,6 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
first_request = request;
current_size = 0;
-
- next_offset_expected = request->stub->args.writev.off
- + request->write_size;
- lk_owner = request->lk_owner;
}
count += request->stub->args.writev.count;
@@ -602,9 +522,8 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
|| ((count + next->stub->args.writev.count)
> MAX_VECTOR_COUNT)
|| ((current_size + next->write_size)
- > conf->aggregate_size)
- || (next_offset_expected != next->stub->args.writev.off)
- || (!is_same_lkowner (&lk_owner, &next->lk_owner))) {
+ > conf->aggregate_size)) {
+
sync_frame = copy_frame (frame);
if (sync_frame == NULL) {
bytes = -1;
@@ -612,8 +531,6 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
goto out;
}
- frame->root->lk_owner = lk_owner;
-
sync_frame->local = local;
local->file = file;
@@ -631,8 +548,7 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
FIRST_CHILD(sync_frame->this)->fops->writev,
fd, vector, count,
first_request->stub->args.writev.off,
- first_request->stub->args.writev.flags,
- iobref, NULL);
+ iobref);
iobref_unref (iobref);
GF_FREE (vector);
@@ -660,7 +576,7 @@ out:
wb_request_unref (request);
}
- mem_put (local);
+ GF_FREE (local);
local = NULL;
}
@@ -668,7 +584,9 @@ out:
iobref_unref (iobref);
}
- GF_FREE (vector);
+ if (vector != NULL) {
+ GF_FREE (vector);
+ }
if (bytes == -1) {
/*
@@ -698,7 +616,7 @@ out:
int32_t
wb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_errno, struct iatt *buf)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -722,7 +640,7 @@ wb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
}
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, buf);
if (request != NULL) {
wb_request_unref (request);
@@ -762,19 +680,19 @@ wb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
static int32_t
-wb_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+wb_stat_helper (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
GF_ASSERT (frame);
GF_ASSERT (this);
STACK_WIND (frame, wb_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
+ FIRST_CHILD(this)->fops->stat, loc);
return 0;
}
int32_t
-wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
wb_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -801,7 +719,7 @@ wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
}
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -812,7 +730,7 @@ wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
frame->local = local;
if (file) {
- stub = fop_stat_stub (frame, wb_stat_helper, loc, xdata);
+ stub = fop_stat_stub (frame, wb_stat_helper, loc);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -831,12 +749,12 @@ wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
}
} else {
STACK_WIND (frame, wb_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
+ FIRST_CHILD(this)->fops->stat, loc);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
if (stub) {
call_stub_destroy (stub);
@@ -852,7 +770,7 @@ unwind:
int32_t
wb_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *buf, dict_t *xdata)
+ int32_t op_errno, struct iatt *buf)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -879,26 +797,26 @@ wb_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
}
- STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf, xdata);
+ STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, buf);
return 0;
}
int32_t
-wb_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+wb_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
GF_ASSERT (frame);
GF_ASSERT (this);
STACK_WIND (frame, wb_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ FIRST_CHILD(this)->fops->fstat, fd);
return 0;
}
int32_t
-wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
wb_file_t *file = NULL;
wb_local_t *local = NULL;
@@ -912,21 +830,19 @@ wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+ op_errno = EBADFD;
+ goto unwind;
}
- local = mem_get0 (this->local_pool);
+ file = (wb_file_t *)(long)tmp_file;
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -937,7 +853,7 @@ wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
frame->local = local;
if (file) {
- stub = fop_fstat_stub (frame, wb_fstat_helper, fd, xdata);
+ stub = fop_fstat_stub (frame, wb_fstat_helper, fd);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -959,13 +875,13 @@ wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
} else {
STACK_WIND (frame, wb_fstat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fstat, fd, xdata);
+ FIRST_CHILD(this)->fops->fstat, fd);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL);
if (stub) {
call_stub_destroy (stub);
@@ -978,7 +894,7 @@ unwind:
int32_t
wb_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -1002,7 +918,7 @@ wb_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (truncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
if (request) {
wb_request_unref (request);
@@ -1043,21 +959,20 @@ wb_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int32_t
wb_truncate_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
GF_ASSERT (frame);
GF_ASSERT (this);
STACK_WIND (frame, wb_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset, xdata);
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
return 0;
}
int32_t
-wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
- dict_t *xdata)
+wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
wb_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -1086,7 +1001,8 @@ wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
}
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1097,7 +1013,7 @@ wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
frame->local = local;
if (file) {
stub = fop_truncate_stub (frame, wb_truncate_helper, loc,
- offset, xdata);
+ offset);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1116,14 +1032,13 @@ wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
}
} else {
STACK_WIND (frame, wb_truncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->truncate, loc, offset,
- xdata);
+ FIRST_CHILD(this)->fops->truncate, loc, offset);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
if (stub) {
call_stub_destroy (stub);
@@ -1136,7 +1051,7 @@ unwind:
int32_t
wb_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -1164,7 +1079,7 @@ wb_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (ftruncate, frame, op_ret, op_errno, prebuf,
- postbuf, xdata);
+ postbuf);
return 0;
}
@@ -1172,20 +1087,19 @@ wb_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int32_t
wb_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
+ off_t offset)
{
GF_ASSERT (frame);
GF_ASSERT (this);
STACK_WIND (frame, wb_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
return 0;
}
int32_t
-wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- dict_t *xdata)
+wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
wb_file_t *file = NULL;
wb_local_t *local = NULL;
@@ -1199,21 +1113,19 @@ wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
-
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+ op_errno = EBADFD;
+ goto unwind;
}
- local = mem_get0 (this->local_pool);
+ file = (wb_file_t *)(long)tmp_file;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1225,7 +1137,7 @@ wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
if (file) {
stub = fop_ftruncate_stub (frame, wb_ftruncate_helper, fd,
- offset, xdata);
+ offset);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1244,13 +1156,13 @@ wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
}
} else {
STACK_WIND (frame, wb_ftruncate_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->ftruncate, fd, offset, xdata);
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL);
if (stub) {
call_stub_destroy (stub);
@@ -1263,7 +1175,7 @@ unwind:
int32_t
wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
- struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpost)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -1287,7 +1199,7 @@ wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
- statpost, xdata);
+ statpost);
if (request) {
wb_request_unref (request);
@@ -1328,20 +1240,20 @@ wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
static int32_t
wb_setattr_helper (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
GF_ASSERT (frame);
GF_ASSERT (this);
STACK_WIND (frame, wb_setattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid, xdata);
+ FIRST_CHILD(this)->fops->setattr, loc, stbuf, valid);
return 0;
}
int32_t
wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
wb_file_t *file = NULL;
fd_t *iter_fd = NULL;
@@ -1355,7 +1267,7 @@ wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
GF_VALIDATE_OR_GOTO (frame->this->name, loc, unwind);
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1363,6 +1275,13 @@ wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
frame->local = local;
+ if (!(valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME))) {
+ STACK_WIND (frame, wb_setattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->setattr, loc, stbuf,
+ valid);
+ goto out;
+ }
+
if (loc->inode) {
/*
FIXME: fd_lookup extends life of fd till the execution
@@ -1383,7 +1302,7 @@ wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
if (file) {
stub = fop_setattr_stub (frame, wb_setattr_helper, loc, stbuf,
- valid, xdata);
+ valid);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -1403,49 +1322,26 @@ wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
} else {
STACK_WIND (frame, wb_setattr_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->setattr, loc, stbuf,
- valid, xdata);
+ valid);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL);
if (stub) {
call_stub_destroy (stub);
}
-
+out:
return 0;
}
-void
-wb_disable_all (xlator_t *this, fd_t *origfd)
-{
- inode_t *inode = NULL;
- fd_t *otherfd = NULL;
- uint64_t tmp_file = 0;
-
- inode = origfd->inode;
- LOCK(&inode->lock);
- list_for_each_entry (otherfd, &inode->fd_list, inode_list) {
- if (otherfd == origfd) {
- continue;
- }
- if (fd_ctx_get(otherfd,this,&tmp_file)) {
- continue;
- }
- gf_log(this->name,GF_LOG_DEBUG,
- "disabling wb on %p because %p is O_SYNC",
- otherfd, origfd);
- ((wb_file_t *)(long)tmp_file)->disabled = 1;
- }
- UNLOCK(&inode->lock);
-}
int32_t
wb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_errno, fd_t *fd)
{
- int32_t flags = 0;
+ int32_t wbflags = 0, flags = 0;
wb_file_t *file = NULL;
wb_conf_t *conf = NULL;
wb_local_t *local = NULL;
@@ -1461,6 +1357,7 @@ wb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
EINVAL);
flags = local->flags;
+ wbflags = local->wbflags;
if (op_ret != -1) {
file = wb_file_create (this, fd, flags);
@@ -1470,57 +1367,51 @@ wb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
goto out;
}
- LOCK (&file->lock);
- {
- /* If O_DIRECT then, we disable caching */
- if (((flags & O_DIRECT) == O_DIRECT)
- || ((flags & O_ACCMODE) == O_RDONLY)
- || (((flags & O_SYNC) == O_SYNC)
- && conf->enable_O_SYNC == _gf_true)) {
- gf_log(this->name,GF_LOG_DEBUG,
- "disabling wb on %p", fd);
- file->disabled = 1;
- wb_disable_all(this,fd);
- }
- /* TODO: decide about wbflags's fate */
- /*
- else if (wbflags & GF_OPEN_NOWB) {
- file->disabled = 1;
- }
- */
+ /* If O_DIRECT then, we disable chaching */
+ if (((flags & O_DIRECT) == O_DIRECT)
+ || ((flags & O_ACCMODE) == O_RDONLY)
+ || (((flags & O_SYNC) == O_SYNC)
+ && conf->enable_O_SYNC == _gf_true)) {
+ file->window_conf = 0;
}
- UNLOCK (&file->lock);
+
+ if (wbflags & GF_OPEN_NOWB) {
+ file->disabled = 1;
+ }
+
+ LOCK_INIT (&file->lock);
}
out:
- STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, xdata);
+ STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd);
return 0;
}
int32_t
wb_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- fd_t *fd, dict_t *xdata)
+ fd_t *fd, int32_t wbflags)
{
wb_local_t *local = NULL;
int32_t op_errno = EINVAL;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
}
local->flags = flags;
+ local->wbflags = wbflags;
frame->local = local;
STACK_WIND (frame, wb_open_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->open, loc, flags, fd, xdata);
+ FIRST_CHILD(this)->fops->open, loc, flags, fd, wbflags);
return 0;
unwind:
- STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
return 0;
}
@@ -1529,7 +1420,7 @@ int32_t
wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
struct iatt *buf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
long flags = 0;
wb_file_t *file = NULL;
@@ -1552,33 +1443,31 @@ wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- LOCK (&file->lock);
- {
- /* If O_DIRECT then, we disable caching */
- if (frame->local) {
- if (((flags & O_DIRECT) == O_DIRECT)
- || ((flags & O_ACCMODE) == O_RDONLY)
- || (((flags & O_SYNC) == O_SYNC)
- && (conf->enable_O_SYNC == _gf_true))) {
- file->window_conf = 0;
- }
+ /* If O_DIRECT then, we disable chaching */
+ if (frame->local) {
+ if (((flags & O_DIRECT) == O_DIRECT)
+ || ((flags & O_ACCMODE) == O_RDONLY)
+ || (((flags & O_SYNC) == O_SYNC)
+ && (conf->enable_O_SYNC == _gf_true))) {
+ file->window_conf = 0;
}
}
- UNLOCK (&file->lock);
+
+ LOCK_INIT (&file->lock);
}
frame->local = NULL;
out:
STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
- preparent, postparent, xdata);
+ preparent, postparent);
return 0;
}
int32_t
wb_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+ mode_t mode, fd_t *fd, dict_t *params)
{
int32_t op_errno = EINVAL;
@@ -1591,12 +1480,12 @@ wb_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
STACK_WIND (frame, wb_create_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->create,
- loc, flags, mode, umask, fd, xdata);
+ loc, flags, mode, fd, params);
return 0;
unwind:
STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
@@ -1609,11 +1498,12 @@ unwind:
size_t
__wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
{
- wb_request_t *request = NULL;
- size_t size = 0;
- char first_request = 1, overlap = 0;
- wb_conf_t *conf = NULL;
- int count = 0;
+ wb_request_t *request = NULL;
+ size_t size = 0;
+ char first_request = 1;
+ off_t offset_expected = 0;
+ wb_conf_t *conf = NULL;
+ int count = 0;
GF_VALIDATE_OR_GOTO ("write-behind", file, out);
GF_VALIDATE_OR_GOTO (file->this->name, list, out);
@@ -1631,11 +1521,12 @@ __wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
if (!request->flags.write_request.stack_wound) {
if (first_request) {
first_request = 0;
- } else {
- overlap = wb_overlap (list, request);
- if (overlap) {
- goto out;
- }
+ offset_expected
+ = request->stub->args.writev.off;
+ }
+
+ if (request->stub->args.writev.off != offset_expected) {
+ break;
}
if ((file->flags & O_APPEND)
@@ -1643,10 +1534,12 @@ __wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
> conf->aggregate_size)
|| ((count + request->stub->args.writev.count)
> MAX_VECTOR_COUNT))) {
- goto out;
+ break;
}
size += request->write_size;
+ offset_expected += request->write_size;
+ file->aggregate_current -= request->write_size;
count += request->stub->args.writev.count;
request->flags.write_request.stack_wound = 1;
@@ -1655,23 +1548,19 @@ __wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
}
out:
- if (file != NULL) {
- file->aggregate_current -= size;
- }
-
return size;
}
int32_t
__wb_can_wind (list_head_t *list, char *other_fop_in_queue,
- char *overlapping_writes, char *incomplete_writes,
+ char *non_contiguous_writes, char *incomplete_writes,
char *wind_all)
{
wb_request_t *request = NULL;
char first_request = 1;
+ off_t offset_expected = 0;
int32_t ret = -1;
- char overlap = 0;
GF_VALIDATE_OR_GOTO ("write-behind", list, out);
@@ -1696,6 +1585,8 @@ __wb_can_wind (list_head_t *list, char *other_fop_in_queue,
if (first_request) {
char flush = 0;
first_request = 0;
+ offset_expected
+ = request->stub->args.writev.off;
flush = request->flags.write_request.flush_all;
if (wind_all != NULL) {
@@ -1703,14 +1594,14 @@ __wb_can_wind (list_head_t *list, char *other_fop_in_queue,
}
}
- overlap = wb_overlap (list, request);
- if (overlap) {
- if (overlapping_writes != NULL) {
- *overlapping_writes = 1;
+ if (offset_expected != request->stub->args.writev.off) {
+ if (non_contiguous_writes) {
+ *non_contiguous_writes = 1;
}
-
break;
}
+
+ offset_expected += request->write_size;
}
}
@@ -1727,7 +1618,7 @@ __wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
size_t size = 0;
char other_fop_in_queue = 0;
char incomplete_writes = 0;
- char overlapping_writes = 0;
+ char non_contiguous_writes = 0;
wb_request_t *request = NULL;
wb_file_t *file = NULL;
char wind_all = 0;
@@ -1744,7 +1635,7 @@ __wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
file = request->file;
ret = __wb_can_wind (list, &other_fop_in_queue,
- &overlapping_writes, &incomplete_writes,
+ &non_contiguous_writes, &incomplete_writes,
&wind_all);
if (ret == -1) {
gf_log (file->this->name, GF_LOG_WARNING,
@@ -1753,7 +1644,7 @@ __wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
}
if (!incomplete_writes && ((enable_trickling_writes)
- || (wind_all) || (overlapping_writes)
+ || (wind_all) || (non_contiguous_writes)
|| (other_fop_in_queue)
|| (file->aggregate_current
>= aggregate_conf))) {
@@ -1877,8 +1768,8 @@ wb_stack_unwind (list_head_t *unwinds)
frame = request->stub->frame;
local = frame->local;
- STACK_UNWIND (frame, local->op_ret, local->op_errno,
- &buf, &buf, NULL, NULL);
+ STACK_UNWIND (frame, local->op_ret, local->op_errno, &buf,
+ &buf);
ret = wb_request_unref (request);
if (ret == 0) {
@@ -1998,7 +1889,6 @@ __wb_copy_into_holder (wb_request_t *holder, wb_request_t *request)
int ret = -1;
if (holder->flags.write_request.virgin) {
- /* TODO: check the required size */
iobuf = iobuf_get (request->file->this->ctx->iobuf_pool);
if (iobuf == NULL) {
goto out;
@@ -2077,9 +1967,7 @@ __wb_collapse_write_bufs (list_head_t *requests, size_t page_size)
offset_expected = holder->stub->args.writev.off
+ holder->write_size;
- if ((request->stub->args.writev.off != offset_expected)
- || (!is_same_lkowner (&request->lk_owner,
- &holder->lk_owner))) {
+ if (request->stub->args.writev.off != offset_expected) {
holder = request;
continue;
}
@@ -2131,7 +2019,7 @@ wb_process_queue (call_frame_t *frame, wb_file_t *file)
{
/*
* make sure requests are marked for unwinding and adjacent
- * contiguous write buffers (each of size less than that of
+ * continguous write buffers (each of size less than that of
* an iobuf) are packed properly so that iobufs are filled to
* their maximum capacity, before calling __wb_mark_winds.
*/
@@ -2161,20 +2049,18 @@ out:
int32_t
wb_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
GF_ASSERT (frame);
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
int32_t
wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
- int32_t count, off_t offset, uint32_t flags, struct iobref *iobref,
- dict_t *xdata)
+ int32_t count, off_t offset, struct iobref *iobref)
{
wb_file_t *file = NULL;
char wb_disabled = 0;
@@ -2199,15 +2085,21 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
}
if (file != NULL) {
@@ -2235,14 +2127,14 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
if (op_ret == -1) {
STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, NULL,
- NULL, NULL);
+ NULL);
return 0;
}
if (wb_disabled) {
STACK_WIND (frame, wb_writev_cbk, FIRST_CHILD (frame->this),
FIRST_CHILD (frame->this)->fops->writev,
- fd, vector, count, offset, flags, iobref, xdata);
+ fd, vector, count, offset, iobref);
return 0;
}
@@ -2252,7 +2144,8 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
goto unwind;
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2261,8 +2154,7 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
frame->local = local;
local->file = file;
- stub = fop_writev_stub (frame, NULL, fd, vector, count, offset, flags,
- iobref, xdata);
+ stub = fop_writev_stub (frame, NULL, fd, vector, count, offset, iobref);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2285,7 +2177,7 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
return 0;
unwind:
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
if (process_frame) {
STACK_DESTROY (process_frame->root);
@@ -2302,7 +2194,7 @@ unwind:
int32_t
wb_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int32_t op_errno, struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *stbuf, struct iobref *iobref)
{
wb_local_t *local = NULL;
wb_file_t *file = NULL;
@@ -2331,7 +2223,7 @@ wb_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, vector, count,
- stbuf, iobref, xdata);
+ stbuf, iobref);
return 0;
}
@@ -2339,11 +2231,10 @@ wb_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
static int32_t
wb_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
STACK_WIND (frame, wb_readv_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->readv, fd, size, offset, flags,
- xdata);
+ FIRST_CHILD(this)->fops->readv, fd, size, offset);
return 0;
}
@@ -2351,7 +2242,7 @@ wb_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
int32_t
wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
wb_file_t *file = NULL;
wb_local_t *local = NULL;
@@ -2368,18 +2259,17 @@ wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+ op_errno = EBADFD;
+ goto unwind;
}
- local = mem_get0 (this->local_pool);
+ file = (wb_file_t *)(long)tmp_file;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2390,7 +2280,7 @@ wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
frame->local = local;
if (file) {
stub = fop_readv_stub (frame, wb_readv_helper, fd, size,
- offset, flags, xdata);
+ offset);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2411,21 +2301,20 @@ wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
} else {
STACK_WIND (frame, wb_readv_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->readv,
- fd, size, offset, flags, xdata);
+ fd, size, offset);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL,
- NULL);
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
}
int32_t
wb_ffr_bg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
STACK_DESTROY (frame->root);
return 0;
@@ -2434,7 +2323,7 @@ wb_ffr_bg_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t
wb_ffr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
wb_local_t *local = NULL;
wb_file_t *file = NULL;
@@ -2457,14 +2346,14 @@ wb_ffr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
UNLOCK (&file->lock);
}
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, xdata);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
return 0;
}
int32_t
-wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
wb_conf_t *conf = NULL;
wb_local_t *local = NULL;
@@ -2506,10 +2395,10 @@ wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
STACK_WIND (flush_frame, wb_ffr_bg_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
+ FIRST_CHILD(this)->fops->flush, fd);
} else {
STACK_WIND (frame, wb_ffr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
+ FIRST_CHILD(this)->fops->flush, fd);
}
if (process_frame != NULL) {
@@ -2523,19 +2412,19 @@ wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
}
if (conf->flush_behind) {
- STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, NULL);
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (flush, frame, -1, op_errno, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
return 0;
}
int32_t
-wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
wb_conf_t *conf = NULL;
wb_file_t *file = NULL;
@@ -2554,22 +2443,21 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
conf = this->private;
-
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+
+ op_errno = EBADFD;
+ goto unwind;
}
+ file = (wb_file_t *)(long)tmp_file;
+
if (file != NULL) {
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2579,7 +2467,7 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
frame->local = local;
- stub = fop_flush_stub (frame, wb_flush_helper, fd, xdata);
+ stub = fop_flush_stub (frame, wb_flush_helper, fd);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2605,29 +2493,28 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto unwind;
}
- STACK_UNWIND_STRICT (flush, frame, 0, 0, NULL);
+ STACK_UNWIND_STRICT (flush, frame, 0, 0);
STACK_WIND (flush_frame, wb_ffr_bg_cbk,
FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
+ FIRST_CHILD(this)->fops->flush, fd);
} else {
STACK_WIND (frame, wb_ffr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush, fd, xdata);
+ FIRST_CHILD(this)->fops->flush, fd);
}
}
return 0;
unwind:
- STACK_UNWIND_STRICT (flush, frame, -1, op_errno, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
return 0;
}
static int32_t
wb_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
- int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf,
- dict_t *xdata)
+ int32_t op_errno, struct iatt *prebuf, struct iatt *postbuf)
{
wb_local_t *local = NULL;
wb_file_t *file = NULL;
@@ -2668,8 +2555,7 @@ wb_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
- STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf,
- xdata);
+ STACK_UNWIND_STRICT (fsync, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
}
@@ -2677,17 +2563,16 @@ wb_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
static int32_t
wb_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t datasync, dict_t *xdata)
+ int32_t datasync)
{
STACK_WIND (frame, wb_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata);
+ FIRST_CHILD(this)->fops->fsync, fd, datasync);
return 0;
}
int32_t
-wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
- dict_t *xdata)
+wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
{
wb_file_t *file = NULL;
wb_local_t *local = NULL;
@@ -2702,21 +2587,19 @@ wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
GF_VALIDATE_OR_GOTO_WITH_ERROR (frame->this->name, fd, unwind,
op_errno, EINVAL);
-
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- file = wb_file_create (this, fd, 0);
- } else {
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
- }
+ gf_log (this->name, GF_LOG_WARNING,
+ "write behind file pointer is"
+ " not stored in context of fd(%p), returning EBADFD",
+ fd);
+ op_errno = EBADFD;
+ goto unwind;
}
- local = mem_get0 (this->local_pool);
+ file = (wb_file_t *)(long)tmp_file;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2727,8 +2610,7 @@ wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
frame->local = local;
if (file) {
- stub = fop_fsync_stub (frame, wb_fsync_helper, fd, datasync,
- xdata);
+ stub = fop_fsync_stub (frame, wb_fsync_helper, fd, datasync);
if (stub == NULL) {
op_errno = ENOMEM;
goto unwind;
@@ -2748,13 +2630,13 @@ wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync,
}
} else {
STACK_WIND (frame, wb_fsync_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->fsync, fd, datasync, xdata);
+ FIRST_CHILD(this)->fops->fsync, fd, datasync);
}
return 0;
unwind:
- STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL);
return 0;
}
@@ -2790,6 +2672,7 @@ int
wb_priv_dump (xlator_t *this)
{
wb_conf_t *conf = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0, };
char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
int ret = -1;
@@ -2803,13 +2686,18 @@ wb_priv_dump (xlator_t *this)
gf_proc_dump_add_section (key_prefix);
- gf_proc_dump_write ("aggregate_size", "%d", conf->aggregate_size);
- gf_proc_dump_write ("window_size", "%d", conf->window_size);
- gf_proc_dump_write ("disable_till", "%d", conf->disable_till);
- gf_proc_dump_write ("enable_O_SYNC", "%d", conf->enable_O_SYNC);
- gf_proc_dump_write ("flush_behind", "%d", conf->flush_behind);
- gf_proc_dump_write ("enable_trickling_writes", "%d",
- conf->enable_trickling_writes);
+ gf_proc_dump_build_key (key, key_prefix, "aggregate_size");
+ gf_proc_dump_write (key, "%d", conf->aggregate_size);
+ gf_proc_dump_build_key (key, key_prefix, "window_size");
+ gf_proc_dump_write (key, "%d", conf->window_size);
+ gf_proc_dump_build_key (key, key_prefix, "disable_till");
+ gf_proc_dump_write (key, "%d", conf->disable_till);
+ gf_proc_dump_build_key (key, key_prefix, "enable_O_SYNC");
+ gf_proc_dump_write (key, "%d", conf->enable_O_SYNC);
+ gf_proc_dump_build_key (key, key_prefix, "flush_behind");
+ gf_proc_dump_write (key, "%d", conf->flush_behind);
+ gf_proc_dump_build_key (key, key_prefix, "enable_trickling_writes");
+ gf_proc_dump_write (key, "%d", conf->enable_trickling_writes);
ret = 0;
out:
@@ -2832,34 +2720,46 @@ __wb_dump_requests (struct list_head *head, char *prefix, char passive)
gf_proc_dump_add_section(key_prefix);
- gf_proc_dump_write ("request-ptr", "%p", request);
+ gf_proc_dump_build_key (key, key_prefix, "request-ptr");
+ gf_proc_dump_write (key, "%p", request);
- gf_proc_dump_write ("refcount", "%d", request->refcount);
+ gf_proc_dump_build_key (key, key_prefix, "refcount");
+ gf_proc_dump_write (key, "%d", request->refcount);
if (request->fop == GF_FOP_WRITE) {
flag = request->flags.write_request.stack_wound;
- gf_proc_dump_write ("stack_wound", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix, "stack_wound");
+ gf_proc_dump_write (key, "%d", flag);
- gf_proc_dump_write ("size", "%"GF_PRI_SIZET,
+ gf_proc_dump_build_key (key, key_prefix, "size");
+ gf_proc_dump_write (key, "%"GF_PRI_SIZET,
request->write_size);
- gf_proc_dump_write ("offset", "%"PRId64,
+ gf_proc_dump_build_key (key, key_prefix, "offset");
+ gf_proc_dump_write (key, "%"PRId64,
request->stub->args.writev.off);
flag = request->flags.write_request.write_behind;
- gf_proc_dump_write ("write_behind", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix,
+ "write_behind");
+ gf_proc_dump_write (key, "%d", flag);
flag = request->flags.write_request.got_reply;
- gf_proc_dump_write ("got_reply", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix, "got_reply");
+ gf_proc_dump_write (key, "%d", flag);
flag = request->flags.write_request.virgin;
- gf_proc_dump_write ("virgin", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix, "virgin");
+ gf_proc_dump_write (key, "%d", flag);
flag = request->flags.write_request.flush_all;
- gf_proc_dump_write ("flush_all", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix, "flush_all");
+ gf_proc_dump_write (key, "%d", flag);
} else {
flag = request->flags.other_requests.marked_for_resume;
- gf_proc_dump_write ("marked_for_resume", "%d", flag);
+ gf_proc_dump_build_key (key, key_prefix,
+ "marked_for_resume");
+ gf_proc_dump_write (key, "%d", flag);
}
}
}
@@ -2871,7 +2771,7 @@ wb_file_dump (xlator_t *this, fd_t *fd)
wb_file_t *file = NULL;
uint64_t tmp_file = 0;
int32_t ret = -1;
- char *path = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN] = {0, };
char key_prefix[GF_DUMP_MAX_BUF_LEN] = {0, };
if ((fd == NULL) || (this == NULL)) {
@@ -2896,32 +2796,36 @@ wb_file_dump (xlator_t *this, fd_t *fd)
gf_proc_dump_add_section (key_prefix);
- __inode_path (fd->inode, NULL, &path);
- if (path != NULL) {
- gf_proc_dump_write ("path", "%s", path);
- GF_FREE (path);
- }
-
- gf_proc_dump_write ("fd", "%p", fd);
+ gf_proc_dump_build_key (key, key_prefix, "fd");
+ gf_proc_dump_write (key, "%p", fd);
- gf_proc_dump_write ("disabled", "%d", file->disabled);
+ gf_proc_dump_build_key (key, key_prefix, "disabled");
+ gf_proc_dump_write (key, "%d", file->disabled);
- gf_proc_dump_write ("disable_till", "%lu", file->disable_till);
+ gf_proc_dump_build_key (key, key_prefix, "disable_till");
+ gf_proc_dump_write (key, "%lu", file->disable_till);
- gf_proc_dump_write ("window_conf", "%"GF_PRI_SIZET, file->window_conf);
+ gf_proc_dump_build_key (key, key_prefix, "window_conf");
+ gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_conf);
- gf_proc_dump_write ("window_current", "%"GF_PRI_SIZET, file->window_current);
+ gf_proc_dump_build_key (key, key_prefix, "window_current");
+ gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->window_current);
- gf_proc_dump_write ("flags", "%s", (file->flags & O_APPEND) ? "O_APPEND"
+ gf_proc_dump_build_key (key, key_prefix, "flags");
+ gf_proc_dump_write (key, "%s", (file->flags & O_APPEND) ? "O_APPEND"
: "!O_APPEND");
- gf_proc_dump_write ("aggregate_current", "%"GF_PRI_SIZET, file->aggregate_current);
+ gf_proc_dump_build_key (key, key_prefix, "aggregate_current");
+ gf_proc_dump_write (key, "%"GF_PRI_SIZET, file->aggregate_current);
- gf_proc_dump_write ("refcount", "%d", file->refcount);
+ gf_proc_dump_build_key (key, key_prefix, "refcount");
+ gf_proc_dump_write (key, "%d", file->refcount);
- gf_proc_dump_write ("op_ret", "%d", file->op_ret);
+ gf_proc_dump_build_key (key, key_prefix, "op_ret");
+ gf_proc_dump_write (key, "%d", file->op_ret);
- gf_proc_dump_write ("op_errno", "%d", file->op_errno);
+ gf_proc_dump_build_key (key, key_prefix, "op_errno");
+ gf_proc_dump_write (key, "%d", file->op_errno);
LOCK (&file->lock);
{
@@ -2936,7 +2840,6 @@ wb_file_dump (xlator_t *this, fd_t *fd)
}
UNLOCK (&file->lock);
- ret = 0;
out:
return ret;
}
@@ -2964,28 +2867,109 @@ out:
int
+validate_options (xlator_t *this, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
+
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
+
+out:
+
+ return ret;
+}
+
+int
reconfigure (xlator_t *this, dict_t *options)
{
- wb_conf_t *conf = NULL;
- int ret = -1;
+ char *str = NULL;
+ uint64_t window_size = 0;
+ wb_conf_t *conf = NULL;
+ int ret = 0;
conf = this->private;
- GF_OPTION_RECONF ("cache-size", conf->window_size, options, size, out);
+ ret = dict_get_str (options, "cache-size", &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &window_size);
+ if (ret != 0) {
+ gf_log(this->name, GF_LOG_ERROR, "Reconfiguration"
+ "'option cache-size %s failed , Invalid"
+ " number format, Defaulting to old value "
+ "(%"PRIu64")", str, conf->window_size);
+ goto out;
+ }
- GF_OPTION_RECONF ("flush-behind", conf->flush_behind, options, bool,
- out);
+ if (window_size < (512 * GF_UNIT_KB)) {
+ gf_log(this->name, GF_LOG_ERROR, "Reconfiguration"
+ "'option cache-size %s' failed , Max value"
+ "can be 512KiB, Defaulting to old value "
+ "(%"PRIu64")", str, conf->window_size);
+ goto out;
+ }
+
+ if (window_size > (2 * GF_UNIT_GB)) {
+ gf_log(this->name, GF_LOG_ERROR, "Reconfiguration"
+ "'option cache-size %s' failed , Max value"
+ "can be 1 GiB, Defaulting to old value "
+ "(%"PRIu64")", str, conf->window_size);
+ goto out;
+ }
+
+ conf->window_size = window_size;
+ gf_log(this->name, GF_LOG_WARNING, "Reconfiguring "
+ "'option cache-size %s ' to %"PRIu64, str,
+ conf->window_size);
+ } else {
+ conf->window_size = WB_WINDOW_SIZE;
+ }
+
+ ret = dict_get_str (options, "flush-behind", &str);
+ if (ret == 0) {
+ ret = gf_string2boolean (str, &conf->flush_behind);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'flush-behind' takes only boolean arguments");
+ conf->flush_behind = 1;
+ goto out;
+ }
+
+ if (conf->flush_behind) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "enabling flush-behind");
+ } else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "disabling flush-behind");
+ }
+ }
- ret = 0;
out:
- return ret;
+ return 0;
}
int32_t
init (xlator_t *this)
{
+ dict_t *options = NULL;
wb_conf_t *conf = NULL;
+ char *str = NULL;
int32_t ret = -1;
if ((this->children == NULL)
@@ -3001,21 +2985,56 @@ init (xlator_t *this)
"dangling volume. check volfile");
}
+ options = this->options;
+
conf = GF_CALLOC (1, sizeof (*conf), gf_wb_mt_wb_conf_t);
if (conf == NULL) {
goto out;
}
- GF_OPTION_INIT("enable-O_SYNC", conf->enable_O_SYNC, bool, out);
+ conf->enable_O_SYNC = _gf_false;
+ ret = dict_get_str (options, "enable-O_SYNC", &str);
+ if (ret == 0) {
+ ret = gf_string2boolean (str, &conf->enable_O_SYNC);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'enable-O_SYNC' takes only boolean arguments");
+ goto out;
+ }
+ }
/* configure 'options aggregate-size <size>' */
conf->aggregate_size = WB_AGGREGATE_SIZE;
+ conf->disable_till = 0;
+ ret = dict_get_str (options, "disable-for-first-nbytes", &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &conf->disable_till);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\" of \"option "
+ "disable-for-first-nbytes\"",
+ str);
+ goto out;
+ }
+ }
- GF_OPTION_INIT("disable-for-first-nbytes", conf->disable_till, size,
- out);
+ gf_log (this->name, GF_LOG_WARNING,
+ "disabling write-behind for first %"PRIu64" bytes",
+ conf->disable_till);
/* configure 'option window-size <size>' */
- GF_OPTION_INIT ("cache-size", conf->window_size, size, out);
+ conf->window_size = WB_WINDOW_SIZE;
+ ret = dict_get_str (options, "cache-size", &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &conf->window_size);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\" of \"option "
+ "window-size\"", str);
+ GF_FREE (conf);
+ goto out;
+ }
+ }
if (!conf->window_size && conf->aggregate_size) {
gf_log (this->name, GF_LOG_WARNING,
@@ -3030,30 +3049,43 @@ init (xlator_t *this)
"aggregate-size(%"PRIu64") cannot be more than "
"window-size(%"PRIu64")", conf->aggregate_size,
conf->window_size);
+ GF_FREE (conf);
goto out;
}
/* configure 'option flush-behind <on/off>' */
- GF_OPTION_INIT ("flush-behind", conf->flush_behind, bool, out);
+ conf->flush_behind = 1;
+ ret = dict_get_str (options, "flush-behind", &str);
+ if (ret == 0) {
+ ret = gf_string2boolean (str, &conf->flush_behind);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'flush-behind' takes only boolean arguments");
+ goto out;
+ }
- GF_OPTION_INIT ("enable-trickling-writes", conf->enable_trickling_writes,
- bool, out);
+ if (conf->flush_behind) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "enabling flush-behind");
+ }
+ }
- this->local_pool = mem_pool_new (wb_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
+ conf->enable_trickling_writes = _gf_true;
+ ret = dict_get_str (options, "enable-trickling-writes", &str);
+ if (ret == 0) {
+ ret = gf_string2boolean (str, &conf->enable_trickling_writes);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'enable-trickling_writes' takes only boolean"
+ " arguments");
+ goto out;
+ }
}
this->private = conf;
ret = 0;
out:
- if (ret) {
- GF_FREE (conf);
- }
return ret;
}
@@ -3103,35 +3135,23 @@ struct xlator_dumpops dumpops = {
struct volume_options options[] = {
{ .key = {"flush-behind"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
- .description = "If this option is set ON, instructs write-behind "
- "translator to perform flush in background, by "
- "returning success (or any errors, if any of "
- "previous writes were failed) to application even "
- "before flush is sent to backend filesystem. "
+ .type = GF_OPTION_TYPE_BOOL
},
{ .key = {"cache-size", "window-size"},
.type = GF_OPTION_TYPE_SIZET,
.min = 512 * GF_UNIT_KB,
- .max = 1 * GF_UNIT_GB,
- .default_value = "1MB",
- .description = "Size of the per-file write-behind buffer. "
-
+ .max = 1 * GF_UNIT_GB
},
{ .key = {"disable-for-first-nbytes"},
.type = GF_OPTION_TYPE_SIZET,
- .min = 0,
+ .min = 1,
.max = 1 * GF_UNIT_MB,
- .default_value = "0",
},
{ .key = {"enable-O_SYNC"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
},
{ .key = {"enable-trickling-writes"},
.type = GF_OPTION_TYPE_BOOL,
- .default_value = "on",
},
{ .key = {NULL} },
};
diff --git a/xlators/protocol/auth/addr/src/Makefile.am b/xlators/protocol/auth/addr/src/Makefile.am
index f09d1c502..7f1dd7445 100644
--- a/xlators/protocol/auth/addr/src/Makefile.am
+++ b/xlators/protocol/auth/addr/src/Makefile.am
@@ -8,5 +8,4 @@ addr_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
- -I$(top_srcdir)/xlators/protocol/server/src \
- -I$(top_srcdir)/rpc/rpc-lib/src/
+ -I$(top_srcdir)/xlators/protocol/server/src
diff --git a/xlators/protocol/auth/addr/src/addr.c b/xlators/protocol/auth/addr/src/addr.c
index 199fc6db0..21dfa5e58 100644
--- a/xlators/protocol/auth/addr/src/addr.c
+++ b/xlators/protocol/auth/addr/src/addr.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -28,7 +28,6 @@
#include <netdb.h>
#include "authenticate.h"
#include "dict.h"
-#include "rpc-transport.h"
#define ADDR_DELIMITER " ,"
#define PRIVILEGED_PORT_CEILING 1024
@@ -37,6 +36,13 @@
#define AF_INET_SDP 27
#endif
+/* TODO: duplicate declaration */
+typedef struct peer_info {
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ char identifier[UNIX_PATH_MAX];
+}peer_info_t;
+
auth_result_t
gf_auth (dict_t *input_params, dict_t *config_params)
{
@@ -57,8 +63,6 @@ gf_auth (dict_t *input_params, dict_t *config_params)
char negate = 0;
char match = 0;
char peer_addr[UNIX_PATH_MAX];
- char *type = NULL;
- gf_boolean_t allow_insecure = _gf_false;
name = data_to_str (dict_get (input_params, "remote-subvolume"));
if (!name) {
@@ -133,20 +137,8 @@ gf_auth (dict_t *input_params, dict_t *config_params)
((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET_SDP;
}
- ret = dict_get_str (config_params, "rpc-auth-allow-insecure",
- &type);
- if (ret == 0) {
- ret = gf_string2boolean (type, &allow_insecure);
- if (ret < 0) {
- gf_log ("auth/addr", GF_LOG_WARNING,
- "rpc-auth-allow-insecure option %s "
- "is not a valid bool option", type);
- goto out;
- }
- }
-
peer_port = atoi (service);
- if (peer_port >= PRIVILEGED_PORT_CEILING && !allow_insecure) {
+ if (peer_port >= PRIVILEGED_PORT_CEILING) {
gf_log ("auth/addr", GF_LOG_ERROR,
"client is bound to port %d which is not privileged",
peer_port);
@@ -218,21 +210,22 @@ gf_auth (dict_t *input_params, dict_t *config_params)
}
out:
- GF_FREE (addr_cpy);
+ if (addr_cpy)
+ GF_FREE (addr_cpy);
return result;
}
struct volume_options options[] = {
{ .key = {"auth.addr.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
+ .type = GF_OPTION_TYPE_ANY
},
{ .key = {"auth.addr.*.reject"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
+ .type = GF_OPTION_TYPE_ANY
},
/* Backword compatibility */
{ .key = {"auth.ip.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST
+ .type = GF_OPTION_TYPE_ANY
},
{ .key = {NULL} }
};
diff --git a/xlators/protocol/auth/login/src/login.c b/xlators/protocol/auth/login/src/login.c
index 702a876ac..81b8efa05 100644
--- a/xlators/protocol/auth/login/src/login.c
+++ b/xlators/protocol/auth/login/src/login.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -121,7 +121,8 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
}
out:
- GF_FREE (username_cpy);
+ if (username_cpy)
+ GF_FREE (username_cpy);
return result;
}
diff --git a/xlators/protocol/client/src/Makefile.am b/xlators/protocol/client/src/Makefile.am
index a62a68a5f..29c6e9dde 100644
--- a/xlators/protocol/client/src/Makefile.am
+++ b/xlators/protocol/client/src/Makefile.am
@@ -8,11 +8,10 @@ client_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/rpc-lib/src/libgfrpc.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la
-client_la_SOURCES = client.c client-helpers.c client-rpc-fops.c \
+client_la_SOURCES = client.c client-helpers.c client3_1-fops.c \
client-handshake.c client-callback.c client-lk.c
-
noinst_HEADERS = client.h client-mem-types.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
- -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/
+ -I$(top_srcdir)/rpc/xdr/src -I$(top_srcdir)/rpc/rpc-lib/src/ \ No newline at end of file
diff --git a/xlators/protocol/client/src/client-callback.c b/xlators/protocol/client/src/client-callback.c
index d886862f7..bfc864112 100644
--- a/xlators/protocol/client/src/client-callback.c
+++ b/xlators/protocol/client/src/client-callback.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -17,7 +26,7 @@
#include "rpc-clnt.h"
int
-client_cbk_null (struct rpc_clnt *rpc, void *mydata, void *data)
+client_cbk_null (void *data)
{
gf_log (THIS->name, GF_LOG_WARNING,
"this function should not be called");
@@ -25,7 +34,7 @@ client_cbk_null (struct rpc_clnt *rpc, void *mydata, void *data)
}
int
-client_cbk_fetchspec (struct rpc_clnt *rpc, void *mydata, void *data)
+client_cbk_fetchspec (void *data)
{
gf_log (THIS->name, GF_LOG_WARNING,
"this function should not be called");
@@ -33,7 +42,7 @@ client_cbk_fetchspec (struct rpc_clnt *rpc, void *mydata, void *data)
}
int
-client_cbk_ino_flush (struct rpc_clnt *rpc, void *mydata, void *data)
+client_cbk_ino_flush (void *data)
{
gf_log (THIS->name, GF_LOG_WARNING,
"this function should not be called");
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
index 3242cf0ae..5af149d56 100644
--- a/xlators/protocol/client/src/client-handshake.c
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -13,7 +22,6 @@
#include "config.h"
#endif
-#include "fd-lk.h"
#include "client.h"
#include "xlator.h"
#include "defaults.h"
@@ -22,27 +30,14 @@
#include "compat-errno.h"
#include "glusterfs3.h"
-#include "portmap-xdr.h"
-#include "rpc-common-xdr.h"
+#include "portmap.h"
-extern rpc_clnt_prog_t clnt3_3_fop_prog;
+extern rpc_clnt_prog_t clnt3_1_fop_prog;
extern rpc_clnt_prog_t clnt_pmap_prog;
int client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe);
-int client_set_lk_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe);
-
-int client_set_lk_version (xlator_t *this);
-
-typedef struct client_fd_lk_local {
- int ref;
- gf_boolean_t error;
- gf_lock_t lock;
- clnt_fd_ctx_t *fdctx;
-}clnt_fd_lk_local_t;
-
/* Handshake */
void
@@ -61,7 +56,7 @@ rpc_client_ping_timer_expired (void *data)
this = data;
if (!this || !this->private) {
- gf_log (THIS->name, GF_LOG_WARNING, "xlator initialization not done");
+ gf_log ("", GF_LOG_WARNING, "xlator initialization not done");
goto out;
}
@@ -145,7 +140,7 @@ client_start_ping (void *data)
this = data;
if (!this || !this->private) {
- gf_log (THIS->name, GF_LOG_WARNING, "xlator not initialized");
+ gf_log ("", GF_LOG_WARNING, "xlator not initialized");
goto fail;
}
@@ -216,16 +211,15 @@ client_start_ping (void *data)
goto fail;
ret = client_submit_request (this, NULL, frame, conf->handshake,
- GF_HNDSK_PING, client_ping_cbk, NULL,
- NULL, 0, NULL, 0, NULL, (xdrproc_t)NULL);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to start ping timer");
- }
+ GF_HNDSK_PING, client_ping_cbk, NULL, NULL,
+ NULL, 0, NULL, 0, NULL);
+ if (ret)
+ goto fail;
return;
-
fail:
+ gf_log ("", GF_LOG_ERROR, "failed to start ping timer");
+
if (frame) {
STACK_DESTROY (frame->root);
}
@@ -245,40 +239,35 @@ client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count,
clnt_conf_t *conf = NULL;
if (!myframe) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "frame with the request is NULL");
+ gf_log ("", GF_LOG_WARNING, "frame with the request is NULL");
goto out;
}
frame = myframe;
this = frame->this;
if (!this || !this->private) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "xlator private is not set");
+ gf_log ("", GF_LOG_WARNING, "xlator private is not set");
goto out;
}
conf = this->private;
conn = &conf->rpc->conn;
- pthread_mutex_lock (&conn->lock);
- {
- if (req->rpc_status == -1) {
- if (conn->ping_timer != NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "socket or ib related error");
- gf_timer_call_cancel (this->ctx,
- conn->ping_timer);
- conn->ping_timer = NULL;
- } else {
- /* timer expired and transport bailed out */
- gf_log (this->name, GF_LOG_WARNING,
- "timer must have expired");
- }
-
- goto unlock;
+ if (req->rpc_status == -1) {
+ if (conn->ping_timer != NULL) {
+ gf_log (this->name, GF_LOG_WARNING, "socket or ib"
+ " related error");
+ gf_timer_call_cancel (this->ctx, conn->ping_timer);
+ conn->ping_timer = NULL;
+ } else {
+ /* timer expired and transport bailed out */
+ gf_log (this->name, GF_LOG_WARNING, "timer must have "
+ "expired");
}
+ goto out;
+ }
-
+ pthread_mutex_lock (&conn->lock);
+ {
timeout.tv_sec = conf->opt.ping_timeout;
timeout.tv_usec = 0;
@@ -293,7 +282,6 @@ client_ping_cbk (struct rpc_req *req, struct iovec *iov, int count,
gf_log (this->name, GF_LOG_WARNING,
"failed to set the ping timer");
}
-unlock:
pthread_mutex_unlock (&conn->lock);
out:
if (frame)
@@ -313,7 +301,7 @@ client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
frame = myframe;
if (!frame || !frame->this) {
- gf_log (THIS->name, GF_LOG_ERROR, "frame not found with the request, "
+ gf_log ("", GF_LOG_ERROR, "frame not found with the request, "
"returning EINVAL");
rsp.op_ret = -1;
rsp.op_errno = EINVAL;
@@ -327,7 +315,7 @@ client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_getspec_rsp);
+ ret = xdr_to_getspec_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (frame->this->name, GF_LOG_ERROR,
"XDR decoding failed, returning EINVAL");
@@ -343,11 +331,11 @@ client3_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count,
}
out:
- CLIENT_STACK_UNWIND (getspec, frame, rsp.op_ret, rsp.op_errno,
- rsp.spec);
+ STACK_UNWIND_STRICT (getspec, frame, rsp.op_ret, rsp.op_errno, rsp.spec);
/* Don't use 'GF_FREE', this is allocated by libc */
- free (rsp.spec);
+ if (rsp.spec)
+ free (rsp.spec);
return 0;
}
@@ -370,17 +358,16 @@ int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data)
ret = client_submit_request (this, &req, frame, conf->handshake,
GF_HNDSK_GETSPEC, client3_getspec_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_getspec_req);
+ NULL, xdr_from_getspec_req, NULL, 0,
+ NULL, 0, NULL);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to send the request");
- }
+ if (ret)
+ goto unwind;
return 0;
unwind:
- CLIENT_STACK_UNWIND (getspec, frame, -1, op_errno, NULL);
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the request");
+ STACK_UNWIND_STRICT (getspec, frame, -1, op_errno, NULL);
return 0;
}
@@ -402,491 +389,7 @@ client_notify_parents_child_up (xlator_t *this)
}
int
-clnt_fd_lk_reacquire_failed (xlator_t *this, clnt_fd_ctx_t *fdctx,
- clnt_conf_t *conf)
-{
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
- GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->remote_fd = -1;
- fdctx->lk_heal_state = GF_LK_HEAL_DONE;
-
- list_add_tail (&fdctx->sfd_pos,
- &conf->saved_fds);
- }
- pthread_mutex_unlock (&conf->lock);
-
- ret = 0;
-out:
- return ret;
-}
-
-int
-client_set_lk_version_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- call_frame_t *fr = NULL;
- gf_set_lk_ver_rsp rsp = {0,};
-
- fr = (call_frame_t *) myframe;
- GF_VALIDATE_OR_GOTO ("client", fr, out);
-
- if (req->rpc_status == -1) {
- gf_log (fr->this->name, GF_LOG_WARNING,
- "received RPC status error");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_set_lk_ver_rsp);
- if (ret < 0)
- gf_log (fr->this->name, GF_LOG_WARNING,
- "xdr decoding failed");
- else
- gf_log (fr->this->name, GF_LOG_INFO,
- "Server lk version = %d", rsp.lk_ver);
-
- ret = 0;
-out:
- if (fr)
- STACK_DESTROY (fr->root);
-
- return ret;
-}
-
-//TODO: Check for all released fdctx and destroy them
-int
-client_set_lk_version (xlator_t *this)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
- call_frame_t *frame = NULL;
- gf_set_lk_ver_req req = {0, };
-
- GF_VALIDATE_OR_GOTO ("client", this, err);
-
- conf = (clnt_conf_t *) this->private;
-
- req.lk_ver = client_get_lk_ver (conf);
- ret = gf_asprintf (&req.uid, "%s-%s-%d",
- this->ctx->process_uuid, this->name,
- this->graph->id);
- if (ret == -1)
- goto err;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Sending SET_LK_VERSION");
-
- ret = client_submit_request (this, &req, frame,
- conf->handshake,
- GF_HNDSK_SET_LK_VER,
- client_set_lk_version_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_set_lk_ver_req);
-out:
- GF_FREE (req.uid);
- return ret;
-err:
- gf_log (this->name, GF_LOG_WARNING,
- "Failed to send SET_LK_VERSION to server");
-
- return ret;
-}
-
-int
-client_fd_lk_count (fd_lk_ctx_t *lk_ctx)
-{
- int count = 0;
- fd_lk_ctx_node_t *fd_lk = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", lk_ctx, err);
-
- LOCK (&lk_ctx->lock);
- {
- list_for_each_entry (fd_lk, &lk_ctx->lk_list, next)
- count++;
- }
- UNLOCK (&lk_ctx->lock);
-
- return count;
-err:
- return -1;
-}
-
-clnt_fd_lk_local_t *
-clnt_fd_lk_local_ref (xlator_t *this, clnt_fd_lk_local_t *local)
-{
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- LOCK (&local->lock);
- {
- local->ref++;
- }
- UNLOCK (&local->lock);
-out:
- return local;
-}
-
-int
-clnt_fd_lk_local_unref (xlator_t *this, clnt_fd_lk_local_t *local)
-{
- int ref = -1;
-
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- LOCK (&local->lock);
- {
- ref = --local->ref;
- }
- UNLOCK (&local->lock);
-
- if (ref == 0) {
- LOCK_DESTROY (&local->lock);
- GF_FREE (local);
- }
-out:
- return ref;
-}
-
-clnt_fd_lk_local_t *
-clnt_fd_lk_local_create (clnt_fd_ctx_t *fdctx)
-{
- clnt_fd_lk_local_t *local = NULL;
-
- local = GF_CALLOC (1, sizeof (clnt_fd_lk_local_t),
- gf_client_mt_clnt_fd_lk_local_t);
- if (!local)
- goto out;
-
- local->ref = 1;
- local->error = _gf_false;
- local->fdctx = fdctx;
-
- LOCK_INIT (&local->lock);
-out:
- return local;
-}
-
-void
-clnt_mark_fd_bad (clnt_conf_t *conf, clnt_fd_ctx_t *fdctx)
-{
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->remote_fd = -1;
- }
- pthread_mutex_unlock (&conf->lock);
-}
-
-int
-clnt_release_reopen_fd_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
-
- frame = myframe;
- this = frame->this;
- fdctx = (clnt_fd_ctx_t *) frame->local;
- conf = (clnt_conf_t *) this->private;
-
- clnt_fd_lk_reacquire_failed (this, fdctx, conf);
-
- decrement_reopen_fd_count (this, conf);
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- return 0;
-}
-
-int
-clnt_release_reopen_fd (xlator_t *this, clnt_fd_ctx_t *fdctx)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
- call_frame_t *frame = NULL;
- gfs3_release_req req = {{0,},};
-
- conf = (clnt_conf_t *) this->private;
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame)
- goto out;
-
- frame->local = (void *) fdctx;
- req.fd = fdctx->remote_fd;
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_RELEASE,
- clnt_release_reopen_fd_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_releasedir_req);
- out:
- if (ret) {
- decrement_reopen_fd_count (this, conf);
- clnt_fd_lk_reacquire_failed (this, fdctx, conf);
- if (frame) {
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
- }
- return 0;
-}
-
-int
-clnt_reacquire_lock_error (xlator_t *this, clnt_fd_ctx_t *fdctx,
- clnt_conf_t *conf)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
-
- clnt_release_reopen_fd (this, fdctx);
-
- ret = 0;
-out:
- return ret;
-}
-
-gf_boolean_t
-clnt_fd_lk_local_error_status (xlator_t *this,
- clnt_fd_lk_local_t *local)
-{
- gf_boolean_t error = _gf_false;
-
- LOCK (&local->lock);
- {
- error = local->error;
- }
- UNLOCK (&local->lock);
-
- return error;
-}
-
-int
-clnt_fd_lk_local_mark_error (xlator_t *this,
- clnt_fd_lk_local_t *local)
-{
- int32_t ret = -1;
- clnt_conf_t *conf = NULL;
- gf_boolean_t error = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, local, out);
-
- conf = (clnt_conf_t *) this->private;
-
- LOCK (&local->lock);
- {
- error = local->error;
- local->error = _gf_true;
- }
- UNLOCK (&local->lock);
-
- if (!error)
- clnt_reacquire_lock_error (this, local->fdctx, conf);
- ret = 0;
-out:
- return ret;
-}
-
-int
-client_reacquire_lock_cbk (struct rpc_req *req, struct iovec *iov,
- int count, void *myframe)
-{
- int32_t ret = -1;
- xlator_t *this = NULL;
- gfs3_lk_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- clnt_fd_lk_local_t *local = NULL;
- struct gf_flock lock = {0,};
-
- frame = (call_frame_t *) myframe;
- this = frame->this;
- local = (clnt_fd_lk_local_t *) frame->local;
- conf = (clnt_conf_t *) this->private;
-
- if (req->rpc_status == -1) {
- gf_log ("client", GF_LOG_WARNING,
- "request failed at rpc");
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lk_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- goto out;
- }
-
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_ERROR, "lock request failed");
- ret = -1;
- goto out;
- }
-
- fdctx = local->fdctx;
-
- gf_proto_flock_to_flock (&rsp.flock, &lock);
-
- gf_log (this->name, GF_LOG_DEBUG, "%s type lock reacquired on file "
- "with gfid %s from %"PRIu64 " to %"PRIu64,
- get_lk_type (lock.l_type), uuid_utoa (fdctx->gfid),
- lock.l_start, lock.l_start + lock.l_len);
-
- if (!clnt_fd_lk_local_error_status (this, local) &&
- clnt_fd_lk_local_unref (this, local) == 0) {
- pthread_mutex_lock (&conf->lock);
- {
- fdctx->lk_heal_state = GF_LK_HEAL_DONE;
-
- list_add_tail (&fdctx->sfd_pos,
- &conf->saved_fds);
- }
- pthread_mutex_unlock (&conf->lock);
-
- decrement_reopen_fd_count (this, conf);
- }
-
- ret = 0;
-out:
- if (ret < 0) {
- clnt_fd_lk_local_mark_error (this, local);
-
- clnt_fd_lk_local_unref (this, local);
- }
-
- frame->local = NULL;
- STACK_DESTROY (frame->root);
-
- return ret;
-}
-
-int
-_client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx)
-{
- int32_t ret = -1;
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- gfs3_lk_req req = {{0,},};
- struct gf_flock flock = {0,};
- fd_lk_ctx_t *lk_ctx = NULL;
- clnt_fd_lk_local_t *local = NULL;
- fd_lk_ctx_node_t *fd_lk = NULL;
- call_frame_t *frame = NULL;
- clnt_conf_t *conf = NULL;
-
- conf = (clnt_conf_t *) this->private;
- lk_ctx = fdctx->lk_ctx;
-
- local = clnt_fd_lk_local_create (fdctx);
- if (!local) {
- gf_log (this->name, GF_LOG_WARNING, "clnt_fd_lk_local_create "
- "failed, aborting reacquring of locks on %s.",
- uuid_utoa (fdctx->gfid));
- clnt_reacquire_lock_error (this, fdctx, conf);
- goto out;
- }
-
- list_for_each_entry (fd_lk, &lk_ctx->lk_list, next) {
- memcpy (&flock, &fd_lk->user_flock,
- sizeof (struct gf_flock));
-
- /* Always send F_SETLK even if the cmd was F_SETLKW */
- /* to avoid frame being blocked if lock cannot be granted. */
- ret = client_cmd_to_gf_cmd (F_SETLK, &gf_cmd);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "client_cmd_to_gf_cmd failed, "
- "aborting reacquiring of locks");
- break;
- }
-
- gf_type = client_type_to_gf_type (flock.l_type);
- req.fd = fdctx->remote_fd;
- req.cmd = gf_cmd;
- req.type = gf_type;
- (void) gf_proto_flock_from_flock (&req.flock,
- &flock);
-
- memcpy (req.gfid, fdctx->gfid, 16);
-
- frame = create_frame (this, this->ctx->pool);
- if (!frame) {
- ret = -1;
- break;
- }
-
- frame->local = clnt_fd_lk_local_ref (this, local);
- frame->root->lk_owner = fd_lk->user_flock.l_owner;
-
- ret = client_submit_request (this, &req, frame,
- conf->fops, GFS3_OP_LK,
- client_reacquire_lock_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "reacquiring locks failed on file with gfid %s",
- uuid_utoa (fdctx->gfid));
- break;
- }
-
- ret = 0;
- frame = NULL;
- }
-
- if (local)
- (void) clnt_fd_lk_local_unref (this, local);
-out:
- return ret;
-}
-
-int
-client_reacquire_lock (xlator_t *this, clnt_fd_ctx_t *fdctx)
-{
- int32_t ret = -1;
- fd_lk_ctx_t *lk_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
-
- if (client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) {
- gf_log (this->name, GF_LOG_DEBUG,
- "fd lock list is empty");
- decrement_reopen_fd_count (this,
- (clnt_conf_t *)this->private);
- } else {
- lk_ctx = fdctx->lk_ctx;
-
- LOCK (&lk_ctx->lock);
- {
- (void) _client_reacquire_lock (this, fdctx);
- }
- UNLOCK (&lk_ctx->lock);
- }
- ret = 0;
-out:
- return ret;
-}
-
-int
-client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
+client3_1_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
{
int32_t ret = -1;
@@ -897,13 +400,11 @@ client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
clnt_conf_t *conf = NULL;
clnt_fd_ctx_t *fdctx = NULL;
call_frame_t *frame = NULL;
- xlator_t *this = NULL;
frame = myframe;
if (!frame || !frame->this)
goto out;
- this = frame->this;
local = frame->local;
conf = frame->this->private;
@@ -915,7 +416,7 @@ client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_open_rsp);
+ ret = xdr_to_open_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
rsp.op_ret = -1;
@@ -939,6 +440,7 @@ client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
}
fdctx = local->fdctx;
+
if (!fdctx) {
gf_log (frame->this->name, GF_LOG_WARNING, "fdctx not found");
ret = -1;
@@ -949,13 +451,9 @@ client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
{
fdctx->remote_fd = rsp.fd;
if (!fdctx->released) {
- if (!client_fd_lk_list_empty (fdctx->lk_ctx, _gf_false)) {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ if (!list_empty (&fdctx->lock_list))
attempt_lock_recovery = _gf_true;
- fdctx->lk_heal_state = GF_LK_HEAL_IN_PROGRESS;
- } else {
- list_add_tail (&fdctx->sfd_pos,
- &conf->saved_fds);
- }
fdctx = NULL;
}
}
@@ -963,33 +461,31 @@ client3_3_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
ret = 0;
- if (conf->lk_heal && attempt_lock_recovery) {
- /* Delay decrementing the reopen fd count untill all the
- locks corresponding to this fd are acquired.*/
- gf_log (this->name, GF_LOG_DEBUG, "acquiring locks "
- "on %s", local->loc.path);
- ret = client_reacquire_lock (frame->this, local->fdctx);
- if (ret) {
- clnt_reacquire_lock_error (this, local->fdctx, conf);
- gf_log (this->name, GF_LOG_WARNING, "acquiring locks "
- "failed on %s", local->loc.path);
- ret = 0;
+ attempt_lock_recovery = _gf_false; /* temporarily */
+
+ if (attempt_lock_recovery) {
+ ret = client_attempt_lock_recovery (frame->this, local->fdctx);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "lock recovery not attempted on fd");
+ } else {
+ gf_log (frame->this->name, GF_LOG_INFO,
+ "need to attempt lock recovery on %"PRIu64
+ " open fds", fd_count);
}
} else {
fd_count = decrement_reopen_fd_count (frame->this, conf);
}
-
out:
- if (fdctx) {
- clnt_release_reopen_fd (this, fdctx);
- } else if ((ret < 0) && frame && frame->this && conf) {
+
+ if (fdctx)
+ client_fdctx_destroy (frame->this, fdctx);
+
+ if ((ret < 0) && frame && frame->this && conf)
decrement_reopen_fd_count (frame->this, conf);
- }
- if (frame) {
- frame->local = NULL;
- STACK_DESTROY (frame->root);
- }
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
client_local_wipe (local);
@@ -997,7 +493,7 @@ out:
}
int
-client3_3_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+client3_1_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
void *myframe)
{
int32_t ret = -1;
@@ -1022,7 +518,7 @@ client3_3_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_opendir_rsp);
+ ret = xdr_to_opendir_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
rsp.op_ret = -1;
@@ -1089,25 +585,34 @@ protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx)
int ret = -1;
gfs3_opendir_req req = {{0,},};
clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ char *path = NULL;
call_frame_t *frame = NULL;
clnt_conf_t *conf = NULL;
if (!this || !fdctx)
goto out;
+ inode = fdctx->inode;
conf = this->private;
- local = mem_get0 (this->local_pool);
+ ret = inode_path (inode, NULL, &path);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "couldn't build path from inode %s",
+ uuid_utoa (inode->gfid));
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
if (!local) {
ret = -1;
goto out;
}
- local->fdctx = fdctx;
- uuid_copy (local->loc.gfid, fdctx->gfid);
- ret = loc_path (&local->loc, NULL);
- if (ret < 0)
- goto out;
+ local->fdctx = fdctx;
+ local->loc.path = path;
+ path = NULL;
frame = create_frame (this, this->ctx->pool);
if (!frame) {
@@ -1115,7 +620,8 @@ protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx)
goto out;
}
- memcpy (req.gfid, fdctx->gfid, 16);
+ memcpy (req.gfid, inode->gfid, 16);
+ req.path = (char *)local->loc.path;
gf_log (frame->this->name, GF_LOG_DEBUG,
"attempting reopen on %s", local->loc.path);
@@ -1124,17 +630,17 @@ protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx)
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_OPENDIR,
- client3_3_reopendir_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_opendir_req);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to send the re-opendir request");
- }
+ client3_1_reopendir_cbk, NULL,
+ xdr_from_opendir_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret)
+ goto out;
return ret;
out:
+ gf_log ("", GF_LOG_ERROR, "failed to send the re-opendir request");
+
if (frame) {
frame->local = NULL;
STACK_DESTROY (frame->root);
@@ -1143,6 +649,8 @@ out:
if (local)
client_local_wipe (local);
+ if (path)
+ GF_FREE (path);
if ((ret < 0) && this && conf) {
decrement_reopen_fd_count (this, conf);
}
@@ -1157,54 +665,62 @@ protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx)
int ret = -1;
gfs3_open_req req = {{0,},};
clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ char *path = NULL;
call_frame_t *frame = NULL;
clnt_conf_t *conf = NULL;
if (!this || !fdctx)
goto out;
+ inode = fdctx->inode;
conf = this->private;
+ ret = inode_path (inode, NULL, &path);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "couldn't build path from inode %s",
+ uuid_utoa (inode->gfid));
+ goto out;
+ }
+
frame = create_frame (this, this->ctx->pool);
if (!frame) {
ret = -1;
goto out;
}
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
if (!local) {
ret = -1;
goto out;
}
local->fdctx = fdctx;
- uuid_copy (local->loc.gfid, fdctx->gfid);
- ret = loc_path (&local->loc, NULL);
- if (ret < 0)
- goto out;
-
+ local->loc.path = path;
+ path = NULL;
frame->local = local;
- memcpy (req.gfid, fdctx->gfid, 16);
+ memcpy (req.gfid, inode->gfid, 16);
req.flags = gf_flags_from_flags (fdctx->flags);
- req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL));
+ req.wbflags = fdctx->wbflags;
+ req.path = (char *)local->loc.path;
gf_log (frame->this->name, GF_LOG_DEBUG,
"attempting reopen on %s", local->loc.path);
local = NULL;
ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_OPEN, client3_3_reopen_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_open_req);
- if (ret) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to send the re-open request");
- }
+ GFS3_OP_OPEN, client3_1_reopen_cbk, NULL,
+ xdr_from_open_req, NULL, 0, NULL, 0, NULL);
+ if (ret)
+ goto out;
return ret;
out:
+ gf_log ("", GF_LOG_ERROR, "failed to send the re-open request");
+
if (frame) {
frame->local = NULL;
STACK_DESTROY (frame->root);
@@ -1213,6 +729,9 @@ out:
if (local)
client_local_wipe (local);
+ if (path)
+ GF_FREE (path);
+
if ((ret < 0) && this && conf) {
decrement_reopen_fd_count (this, conf);
}
@@ -1270,8 +789,7 @@ client_post_handshake (call_frame_t *frame, xlator_t *this)
}
} else {
gf_log (this->name, GF_LOG_DEBUG,
- "No fds to open - notifying all parents child up");
- client_set_lk_version (this);
+ "no open fds - notifying all parents child up");
client_notify_parents_child_up (this);
}
out:
@@ -1291,9 +809,7 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
gf_setvolume_rsp rsp = {0,};
int ret = 0;
int32_t op_ret = 0;
- int32_t op_errno = 0;
- gf_boolean_t auth_fail = _gf_false;
- uint32_t lk_ver = 0;
+ int32_t op_errno = 0;
frame = myframe;
this = frame->this;
@@ -1306,7 +822,7 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_setvolume_rsp);
+ ret = xdr_to_setvolume_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
op_ret = -1;
@@ -1351,11 +867,6 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
"SETVOLUME on remote-host failed: %s",
remote_error ? remote_error : strerror (op_errno));
errno = op_errno;
- if (remote_error &&
- (strcmp ("Authentication failed", remote_error) == 0)) {
- auth_fail = _gf_true;
- op_ret = 0;
- }
if (op_errno == ESTALE) {
ret = default_notify (this, GF_EVENT_VOLFILE_MODIFIED, NULL);
if (ret)
@@ -1374,15 +885,6 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
goto out;
}
- ret = dict_get_uint32 (reply, "clnt-lk-version", &lk_ver);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to find key 'clnt-lk-version' in the options");
- goto out;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "clnt-lk-version = %d, "
- "server-lk-version = %d", client_get_lk_ver (conf), lk_ver);
/* TODO: currently setpeer path is broken */
/*
if (process_uuid && req->conn &&
@@ -1416,34 +918,11 @@ client_setvolume_cbk (struct rpc_req *req, struct iovec *iov, int count, void *m
conf->connecting = 0;
conf->connected = 1;
- conf->need_different_port = 0;
-
- if (lk_ver != client_get_lk_ver (conf)) {
- gf_log (this->name, GF_LOG_INFO, "Server and Client "
- "lk-version numbers are not same, reopening the fds");
- client_mark_fd_bad (this);
- client_post_handshake (frame, frame->this);
- } else {
- /*TODO: Traverse the saved fd list, and send
- release to the server on fd's that were closed
- during grace period */
- gf_log (this->name, GF_LOG_INFO, "Server and Client "
- "lk-version numbers are same, no need to "
- "reopen the fds");
- }
+ /* TODO: more to test */
+ client_post_handshake (frame, frame->this);
out:
- if (auth_fail) {
- gf_log (this->name, GF_LOG_INFO, "sending AUTH_FAILED event");
- ret = default_notify (this, GF_EVENT_AUTH_FAILED, NULL);
- if (ret)
- gf_log (this->name, GF_LOG_INFO,
- "notify of AUTH_FAILED failed");
- conf->connecting = 0;
- conf->connected = 0;
- conf->last_sent_event = GF_EVENT_AUTH_FAILED;
- ret = -1;
- }
+
if (-1 == op_ret) {
/* Let the connection/re-connection happen in
* background, for now, don't hang here,
@@ -1456,17 +935,17 @@ out:
"notify of CHILD_CONNECTING failed");
conf->last_sent_event = GF_EVENT_CHILD_CONNECTING;
conf->connecting= 1;
- ret = 0;
}
- free (rsp.dict.dict_val);
+ if (rsp.dict.dict_val)
+ free (rsp.dict.dict_val);
STACK_DESTROY (frame->root);
if (reply)
dict_unref (reply);
- return ret;
+ return 0;
}
int
@@ -1479,6 +958,9 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
clnt_conf_t *conf = NULL;
dict_t *options = NULL;
+ struct rpc_clnt_config config = {0, };
+
+
options = this->options;
conf = this->private;
@@ -1503,19 +985,13 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
}
}
- /* With multiple graphs possible in the same process, we need a
- field to bring the uniqueness. Graph-ID should be enough to get the
- job done
- */
- ret = gf_asprintf (&process_uuid_xl, "%s-%s-%d",
- this->ctx->process_uuid, this->name,
- this->graph->id);
+ ret = gf_asprintf (&process_uuid_xl, "%s-%s", this->ctx->process_uuid,
+ this->name);
if (-1 == ret) {
gf_log (this->name, GF_LOG_ERROR,
"asprintf failed while setting process_uuid");
goto fail;
}
-
ret = dict_set_dynstr (options, "process-uuid", process_uuid_xl);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1524,13 +1000,6 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
goto fail;
}
- ret = dict_set_str (options, "client-version", PACKAGE_VERSION);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set client-version(%s) in handshake msg",
- PACKAGE_VERSION);
- }
-
if (this->ctx->cmd_args.volfile_server) {
if (this->ctx->cmd_args.volfile_id) {
ret = dict_set_str (options, "volfile-key",
@@ -1546,14 +1015,6 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
"failed to set 'volfile-checksum'");
}
- ret = dict_set_int16 (options, "clnt-lk-version",
- client_get_lk_ver (conf));
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set clnt-lk-version(%"PRIu32") in handshake msg",
- client_get_lk_ver (conf));
- }
-
req.dict.dict_len = dict_serialized_length (options);
if (req.dict.dict_len < 0) {
gf_log (this->name, GF_LOG_ERROR,
@@ -1576,11 +1037,18 @@ client_setvolume (xlator_t *this, struct rpc_clnt *rpc)
ret = client_submit_request (this, &req, fr, conf->handshake,
GF_HNDSK_SETVOLUME, client_setvolume_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_setvolume_req);
+ NULL, xdr_from_setvolume_req, NULL, 0,
+ NULL, 0, NULL);
fail:
- GF_FREE (req.dict.dict_val);
+
+ if (ret) {
+ config.remote_port = -1;
+ rpc_clnt_reconfig (conf->rpc, &config);
+ }
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
return ret;
}
@@ -1593,7 +1061,7 @@ select_server_supported_programs (xlator_t *this, gf_prog_detail *prog)
int ret = -1;
if (!this || !prog) {
- gf_log (THIS->name, GF_LOG_WARNING,
+ gf_log ("", GF_LOG_WARNING,
"xlator not found OR RPC program not found");
goto out;
}
@@ -1603,9 +1071,9 @@ select_server_supported_programs (xlator_t *this, gf_prog_detail *prog)
while (trav) {
/* Select 'programs' */
- if ((clnt3_3_fop_prog.prognum == trav->prognum) &&
- (clnt3_3_fop_prog.progver == trav->progver)) {
- conf->fops = &clnt3_3_fop_prog;
+ if ((clnt3_1_fop_prog.prognum == trav->prognum) &&
+ (clnt3_1_fop_prog.progver == trav->progver)) {
+ conf->fops = &clnt3_1_fop_prog;
gf_log (this->name, GF_LOG_INFO,
"Using Program %s, Num (%"PRId64"), "
"Version (%"PRId64")",
@@ -1632,7 +1100,7 @@ server_has_portmap (xlator_t *this, gf_prog_detail *prog)
int ret = -1;
if (!this || !prog) {
- gf_log (THIS->name, GF_LOG_WARNING,
+ gf_log ("", GF_LOG_WARNING,
"xlator not found OR RPC program not found");
goto out;
}
@@ -1667,7 +1135,7 @@ client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, voi
frame = myframe;
if (!frame || !frame->this || !frame->this->private) {
- gf_log (THIS->name, GF_LOG_WARNING,
+ gf_log ("", GF_LOG_WARNING,
"frame not found with rpc request");
goto out;
}
@@ -1680,7 +1148,7 @@ client_query_portmap_cbk (struct rpc_req *req, struct iovec *iov, int count, voi
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_pmap_port_by_brick_rsp);
+ ret = xdr_to_pmap_port_by_brick_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
goto out;
@@ -1725,8 +1193,6 @@ client_query_portmap (xlator_t *this, struct rpc_clnt *rpc)
clnt_conf_t *conf = NULL;
dict_t *options = NULL;
char *remote_subvol = NULL;
- char *xprt = NULL;
- char brick_name[PATH_MAX] = {0,};
options = this->options;
conf = this->private;
@@ -1740,25 +1206,6 @@ client_query_portmap (xlator_t *this, struct rpc_clnt *rpc)
req.brick = remote_subvol;
- /* FIXME: Dirty work around */
- if (!dict_get_str (options, "transport-type", &xprt)) {
- /* This logic is required only in case of 'rdma' client
- transport-type and the volume is of 'tcp,rdma'
- transport type. */
- if (!strcmp (xprt, "rdma")) {
- if (!conf->need_different_port) {
- snprintf (brick_name, PATH_MAX, "%s.rdma",
- remote_subvol);
- req.brick = brick_name;
- conf->need_different_port = 1;
- conf->skip_notify = 1;
- } else {
- conf->need_different_port = 0;
- conf->skip_notify = 0;
- }
- }
- }
-
fr = create_frame (this, this->ctx->pool);
if (!fr) {
ret = -1;
@@ -1768,8 +1215,8 @@ client_query_portmap (xlator_t *this, struct rpc_clnt *rpc)
ret = client_submit_request (this, &req, fr, &clnt_pmap_prog,
GF_PMAP_PORTBYBRICK,
client_query_portmap_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_pmap_port_by_brick_req);
+ NULL, xdr_from_pmap_port_by_brick_req,
+ NULL, 0, NULL, 0, NULL);
fail:
return ret;
@@ -1796,7 +1243,7 @@ client_dump_version_cbk (struct rpc_req *req, struct iovec *iov, int count,
goto out;
}
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_dump_rsp);
+ ret = xdr_to_dump_rsp (*iov, &rsp);
if (ret < 0) {
gf_log (frame->this->name, GF_LOG_ERROR, "XDR decoding failed");
goto out;
@@ -1864,8 +1311,8 @@ client_handshake (xlator_t *this, struct rpc_clnt *rpc)
req.gfs_id = 0xbabe;
ret = client_submit_request (this, &req, frame, conf->dump,
GF_DUMP_DUMP, client_dump_version_cbk,
- NULL, NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gf_dump_req);
+ NULL, xdr_from_dump_req, NULL, 0, NULL, 0,
+ NULL);
out:
return ret;
@@ -1876,7 +1323,6 @@ char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = {
[GF_HNDSK_SETVOLUME] = "SETVOLUME",
[GF_HNDSK_GETSPEC] = "GETSPEC",
[GF_HNDSK_PING] = "PING",
- [GF_HNDSK_SET_LK_VER] = "SET_LK_VER"
};
rpc_clnt_prog_t clnt_handshake_prog = {
diff --git a/xlators/protocol/client/src/client-helpers.c b/xlators/protocol/client/src/client-helpers.c
index 77b416c47..85a9f89ed 100644
--- a/xlators/protocol/client/src/client-helpers.c
+++ b/xlators/protocol/client/src/client-helpers.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFIG_H
@@ -17,32 +26,6 @@
#include "fd.h"
-int
-client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t try_lock)
-{
- int ret = 1;
-
- if (!lk_ctx) {
- ret = -1;
- goto out;
- }
-
- if (try_lock) {
- ret = TRY_LOCK (&lk_ctx->lock);
- if (ret != 0) {
- ret = -1;
- goto out;
- }
- } else {
- LOCK (&lk_ctx->lock);
- }
-
- ret = list_empty (&lk_ctx->lk_list);
- UNLOCK (&lk_ctx->lock);
-out:
- return ret;
-}
-
clnt_fd_ctx_t *
this_fd_del_ctx (fd_t *file, xlator_t *this)
{
@@ -96,8 +79,8 @@ this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, clnt_fd_ctx_t *ctx)
if (ret >= 0) {
if (loc)
gf_log (this->name, GF_LOG_INFO,
- "%s (%s): trying duplicate remote fd set. ",
- loc->path, uuid_utoa (loc->inode->gfid));
+ "%s (%"PRId64"): trying duplicate remote fd set. ",
+ loc->path, loc->inode->ino);
else
gf_log (this->name, GF_LOG_INFO,
"%p: trying duplicate remote fd set. ", file);
@@ -107,8 +90,8 @@ this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, clnt_fd_ctx_t *ctx)
if (ret < 0) {
if (loc)
gf_log (this->name, GF_LOG_WARNING,
- "%s (%s): failed to set remote fd",
- loc->path, uuid_utoa (loc->inode->gfid));
+ "%s (%"PRId64"): failed to set remote fd",
+ loc->path, loc->inode->ino);
else
gf_log (this->name, GF_LOG_WARNING,
"%p: failed to set remote fd", file);
@@ -123,7 +106,6 @@ client_local_wipe (clnt_local_t *local)
{
if (local) {
loc_wipe (&local->loc);
- loc_wipe (&local->loc2);
if (local->fd) {
fd_unref (local->fd);
@@ -133,9 +115,7 @@ client_local_wipe (clnt_local_t *local)
iobref_unref (local->iobref);
}
- GF_FREE (local->name);
-
- mem_put (local);
+ GF_FREE (local);
}
return 0;
@@ -174,21 +154,15 @@ out:
}
int
-unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
- struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries)
+unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries)
{
struct gfs3_dirplist *trav = NULL;
- char *buf = NULL;
gf_dirent_t *entry = NULL;
- inode_table_t *itable = NULL;
int entry_len = 0;
int ret = -1;
trav = rsp->reply;
- if (fd)
- itable = fd->inode->table;
-
while (trav) {
entry_len = gf_dirent_size (trav->name);
entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t);
@@ -204,30 +178,6 @@ unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
strcpy (entry->d_name, trav->name);
- if (trav->dict.dict_val) {
- /* Dictionary is sent along with response */
- buf = memdup (trav->dict.dict_val, trav->dict.dict_len);
- if (!buf)
- goto out;
-
- entry->dict = dict_new ();
-
- ret = dict_unserialize (buf, trav->dict.dict_len,
- &entry->dict);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_WARNING,
- "failed to unserialize xattr dict");
- errno = EINVAL;
- goto out;
- }
- entry->dict->extra_free = buf;
- buf = NULL;
- }
-
- entry->inode = inode_find (itable, entry->d_stat.ia_gfid);
- if (!entry->inode)
- entry->inode = inode_new (itable);
-
list_add_tail (&entry->list, &entries->list);
trav = trav->nextentry;
@@ -249,7 +199,6 @@ clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
while (trav) {
trav = trav->nextentry;
/* on client, the rpc lib allocates this */
- free (prev->dict.dict_val);
free (prev->name);
free (prev);
prev = trav;
diff --git a/xlators/protocol/client/src/client-lk.c b/xlators/protocol/client/src/client-lk.c
index 5611c7b83..068d44609 100644
--- a/xlators/protocol/client/src/client-lk.c
+++ b/xlators/protocol/client/src/client-lk.c
@@ -1,17 +1,25 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#include "common-utils.h"
#include "xlator.h"
#include "client.h"
-#include "lkowner.h"
static void
__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock);
@@ -28,11 +36,11 @@ __dump_client_lock (client_posix_lock_t *lock)
gf_log (this->name, GF_LOG_INFO,
"{fd=%p}"
- "{%s lk-owner:%s %"PRId64" - %"PRId64"}"
+ "{%s lk-owner:%"PRIu64" %"PRId64" - %"PRId64"}"
"{start=%"PRId64" end=%"PRId64"}",
lock->fd,
lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock",
- lkowner_utoa (&lock->owner),
+ lock->owner,
lock->user_flock.l_start,
lock->user_flock.l_len,
lock->fl_start,
@@ -125,6 +133,12 @@ add_locks (client_posix_lock_t *l1, client_posix_lock_t *l2)
return sum;
}
+/* Return true if the locks have the same owner */
+static int
+same_owner (client_posix_lock_t *l1, client_posix_lock_t *l2)
+{
+ return ((l1->owner == l2->owner));
+}
/* Return true if the locks overlap, false otherwise */
static int
@@ -271,11 +285,11 @@ __insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
if (!locks_overlap (conf, lock))
continue;
- if (is_same_lkowner (&conf->owner, &lock->owner)) {
+ if (same_owner (conf, lock)) {
if (conf->fl_type == lock->fl_type) {
sum = add_locks (lock, conf);
- sum->fd = lock->fd;
+ sum->fd = lock->fd;
__delete_client_lock (conf);
__destroy_client_lock (conf);
@@ -287,8 +301,8 @@ __insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock)
} else {
sum = add_locks (lock, conf);
- sum->fd = conf->fd;
- sum->owner = conf->owner;
+ sum->fd = conf->fd;
+ sum->owner = conf->owner;
v = subtract_locks (sum, lock);
@@ -351,9 +365,9 @@ destroy_client_lock (client_posix_lock_t *lock)
}
int32_t
-delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
+delete_granted_locks_owner (fd_t *fd, uint64_t owner)
{
- clnt_fd_ctx_t *fdctx = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
client_posix_lock_t *lock = NULL;
client_posix_lock_t *tmp = NULL;
xlator_t *this = NULL;
@@ -366,7 +380,7 @@ delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
this = THIS;
fdctx = this_fd_get_ctx (fd, this);
if (!fdctx) {
- gf_log (this->name, GF_LOG_WARNING,
+ gf_log (this->name, GF_LOG_DEBUG,
"fdctx not valid");
ret = -1;
goto out;
@@ -375,7 +389,7 @@ delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
pthread_mutex_lock (&fdctx->mutex);
{
list_for_each_entry_safe (lock, tmp, &fdctx->lock_list, list) {
- if (!is_same_lkowner (&lock->owner, owner)) {
+ if (lock->owner == owner) {
list_del_init (&lock->list);
list_add_tail (&lock->list, &delete_list);
count++;
@@ -390,7 +404,7 @@ delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner)
}
/* FIXME: Need to actually print the locks instead of count */
- gf_log (this->name, GF_LOG_TRACE,
+ gf_log (this->name, GF_LOG_DEBUG,
"Number of locks cleared=%d", count);
out:
@@ -424,7 +438,7 @@ delete_granted_locks_fd (clnt_fd_ctx_t *fdctx)
}
/* FIXME: Need to actually print the locks instead of count */
- gf_log (this->name, GF_LOG_TRACE,
+ gf_log (this->name, GF_LOG_DEBUG,
"Number of locks cleared=%d", count);
return ret;
@@ -472,11 +486,14 @@ client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd)
}
static client_posix_lock_t *
-new_client_lock (struct gf_flock *flock, gf_lkowner_t *owner,
+new_client_lock (struct gf_flock *flock, uint64_t owner,
int32_t cmd, fd_t *fd)
{
client_posix_lock_t *new_lock = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
new_lock = GF_CALLOC (1, sizeof (*new_lock),
gf_client_mt_clnt_lock_t);
if (!new_lock) {
@@ -495,8 +512,7 @@ new_client_lock (struct gf_flock *flock, gf_lkowner_t *owner,
else
new_lock->fl_end = flock->l_start + flock->l_len - 1;
- new_lock->owner = *owner;
-
+ new_lock->owner = owner;
new_lock->cmd = cmd; /* Not really useful */
out:
@@ -514,8 +530,8 @@ client_save_number_fds (clnt_conf_t *conf, int count)
}
int
-client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock,
- gf_lkowner_t *owner, int32_t cmd)
+client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, uint64_t owner,
+ int32_t cmd)
{
clnt_fd_ctx_t *fdctx = NULL;
xlator_t *this = NULL;
@@ -559,13 +575,13 @@ construct_reserve_unlock (struct gf_flock *lock, call_frame_t *frame,
{
GF_ASSERT (lock);
GF_ASSERT (frame);
+ GF_ASSERT (frame->root->lk_owner);
lock->l_type = F_UNLCK;
lock->l_start = 0;
lock->l_whence = SEEK_SET;
lock->l_len = 0; /* Whole file */
lock->l_pid = (uint64_t)(unsigned long)frame->root;
- lock->l_owner = client_lock->owner;
frame->root->lk_owner = client_lock->owner;
@@ -599,7 +615,6 @@ decrement_reopen_fd_count (xlator_t *this, clnt_conf_t *conf)
if (fd_count == 0) {
gf_log (this->name, GF_LOG_INFO,
"last fd open'd/lock-self-heal'd - notifying CHILD-UP");
- client_set_lk_version (this);
client_notify_parents_child_up (this);
}
@@ -612,7 +627,7 @@ client_remove_reserve_lock_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
clnt_local_t *local = NULL;
clnt_conf_t *conf = NULL;
@@ -642,7 +657,7 @@ cleanup:
STACK_DESTROY (frame->root);
fd_count = decrement_reopen_fd_count (this, conf);
- gf_log (this->name, GF_LOG_TRACE,
+ gf_log (this->name, GF_LOG_DEBUG,
"Need to attempt lock recovery on %lld open fds",
(unsigned long long) fd_count);
return 0;
@@ -653,12 +668,14 @@ client_remove_reserve_lock (xlator_t *this, call_frame_t *frame,
client_posix_lock_t *lock)
{
struct gf_flock unlock;
+ clnt_local_t *local = NULL;
+ local = frame->local;
construct_reserve_unlock (&unlock, frame, lock);
STACK_WIND (frame, client_remove_reserve_lock_cbk,
this, this->fops->lk,
- lock->fd, F_RESLK_UNLCK, &unlock, NULL);
+ lock->fd, F_RESLK_UNLCK, &unlock);
}
static client_posix_lock_t *
@@ -690,7 +707,7 @@ client_reserve_lock_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
clnt_local_t *local = NULL;
@@ -746,7 +763,7 @@ client_recovery_lock_cbk (call_frame_t *frame,
xlator_t *this,
int32_t op_ret,
int32_t op_errno,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
clnt_local_t *local = NULL;
clnt_fd_ctx_t *fdctx = NULL;
@@ -786,7 +803,7 @@ client_recovery_lock_cbk (call_frame_t *frame,
STACK_WIND (frame, client_reserve_lock_cbk,
this, this->fops->lk,
- next_lock->fd, F_RESLK_LCK, &reserve_flock, NULL);
+ next_lock->fd, F_RESLK_LCK, &reserve_flock);
goto out;
}
@@ -815,6 +832,7 @@ static int
client_send_recovery_lock (call_frame_t *frame, xlator_t *this,
client_posix_lock_t *lock)
{
+
frame->root->lk_owner = lock->owner;
/* Send all locks as F_SETLK to prevent the frame
@@ -823,7 +841,7 @@ client_send_recovery_lock (call_frame_t *frame, xlator_t *this,
STACK_WIND (frame, client_recovery_lock_cbk,
this, this->fops->lk,
lock->fd, F_SETLK,
- &(lock->user_flock), NULL);
+ &(lock->user_flock));
return 0;
}
@@ -855,7 +873,7 @@ client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx)
struct gf_flock reserve_flock;
int ret = 0;
- local = mem_get0 (this->local_pool);
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
if (!local) {
ret = -ENOMEM;
goto out;
@@ -887,7 +905,7 @@ client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx)
STACK_WIND (frame, client_reserve_lock_cbk,
this, this->fops->lk,
- lock->fd, F_RESLK_LCK, &reserve_flock, NULL);
+ lock->fd, F_RESLK_LCK, &reserve_flock);
out:
return ret;
diff --git a/xlators/protocol/client/src/client-mem-types.h b/xlators/protocol/client/src/client-mem-types.h
index f6573da2d..7ef10a7e7 100644
--- a/xlators/protocol/client/src/client-mem-types.h
+++ b/xlators/protocol/client/src/client-mem-types.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -16,10 +25,10 @@
enum gf_client_mem_types_ {
gf_client_mt_clnt_conf_t = gf_common_mt_end + 1,
+ gf_client_mt_clnt_local_t,
gf_client_mt_clnt_req_buf_t,
gf_client_mt_clnt_fdctx_t,
gf_client_mt_clnt_lock_t,
- gf_client_mt_clnt_fd_lk_local_t,
gf_client_mt_end,
};
#endif /* __CLIENT_MEM_TYPES_H__ */
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
deleted file mode 100644
index d541c35eb..000000000
--- a/xlators/protocol/client/src/client-rpc-fops.c
+++ /dev/null
@@ -1,5867 +0,0 @@
-/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "client.h"
-#include "glusterfs3-xdr.h"
-#include "glusterfs3.h"
-#include "compat-errno.h"
-
-int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data);
-void client_start_ping (void *data);
-rpc_clnt_prog_t clnt3_3_fop_prog;
-
-
-int
-client_submit_vec_request (xlator_t *this, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog, int procnum,
- fop_cbk_fn_t cbkfn,
- struct iovec *payload, int payloadcnt,
- struct iobref *iobref, xdrproc_t xdrproc)
-{
- int ret = 0;
- clnt_conf_t *conf = NULL;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- int count = 0;
- int start_ping = 0;
- struct iobref *new_iobref = NULL;
- ssize_t xdr_size = 0;
- struct rpc_req rpcreq = {0, };
-
- start_ping = 0;
-
- conf = this->private;
-
- if (req && xdrproc) {
- xdr_size = xdr_sizeof (xdrproc, req);
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- goto unwind;
- };
-
- new_iobref = iobref_new ();
- if (!new_iobref) {
- goto unwind;
- }
-
- if (iobref != NULL) {
- ret = iobref_merge (new_iobref, iobref);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot merge iobref passed from caller "
- "into new_iobref");
- }
- }
-
- ret = iobref_add (new_iobref, iobuf);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot add iobuf into iobref");
- goto unwind;
- }
-
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_size (iobuf);
-
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
- if (ret == -1) {
- gf_log_callingfn ("", GF_LOG_WARNING,
- "XDR function failed");
- goto unwind;
- }
-
- iov.iov_len = ret;
- count = 1;
- }
-
- /* Send the msg */
- ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count,
- payload, payloadcnt, new_iobref, frame, NULL, 0,
- NULL, 0, NULL);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed");
- }
-
- if (ret == 0) {
- pthread_mutex_lock (&conf->rpc->conn.lock);
- {
- if (!conf->rpc->conn.ping_started) {
- start_ping = 1;
- }
- }
- pthread_mutex_unlock (&conf->rpc->conn.lock);
- }
-
- if (start_ping)
- client_start_ping ((void *) this);
-
- if (new_iobref)
- iobref_unref (new_iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return ret;
-
-unwind:
- rpcreq.rpc_status = -1;
- cbkfn (&rpcreq, NULL, 0, frame);
-
- if (new_iobref)
- iobref_unref (new_iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return ret;
-}
-
-/* CBK */
-
-int
-client3_3_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_symlink_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- clnt_local_t *local = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
-
- local = frame->local;
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_symlink_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- /* no need to print the gfid, because it will be null, since
- * symlink operation failed.
- */
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: (%s to %s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local) ? local->loc2.path: "--");
- }
-
- CLIENT_STACK_UNWIND (symlink, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), inode, &stbuf,
- &preparent, &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_mknod_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- clnt_local_t *local = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
-
- local = frame->local;
-
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_mknod_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
-
- CLIENT_STACK_UNWIND (mknod, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), inode,
- &stbuf, &preparent, &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_mkdir_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- clnt_local_t *local = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
-
- local = frame->local;
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_mkdir_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
-
- CLIENT_STACK_UNWIND (mkdir, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), inode,
- &stbuf, &preparent, &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-_copy_gfid_from_inode_holders (uuid_t gfid, loc_t *loc, fd_t *fd)
-{
- int ret = 0;
-
- if (fd && fd->inode && !uuid_is_null (fd->inode->gfid)) {
- uuid_copy (gfid, fd->inode->gfid);
- goto out;
- }
-
- if (!loc) {
- GF_ASSERT (0);
- ret = -1;
- goto out;
- }
-
- if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
- uuid_copy (gfid, loc->inode->gfid);
- } else if (!uuid_is_null (loc->gfid)) {
- uuid_copy (gfid, loc->gfid);
- } else {
- GF_ASSERT (0);
- ret = -1;
- }
-out:
- return ret;
-}
-
-int
-client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags,
- int64_t remote_fd, int is_dir)
-{
- int ret = 0;
- uuid_t gfid = {0};
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
-
- conf = this->private;
- ret = _copy_gfid_from_inode_holders (gfid, loc, fd);
- if (ret) {
- ret = -EINVAL;
- goto out;
- }
-
- fdctx = GF_CALLOC (1, sizeof (*fdctx),
- gf_client_mt_clnt_fdctx_t);
- if (!fdctx) {
- ret = -ENOMEM;
- goto out;
- }
-
- uuid_copy (fdctx->gfid, gfid);
- fdctx->is_dir = is_dir;
- fdctx->remote_fd = remote_fd;
- fdctx->flags = flags;
- fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx);
- fdctx->lk_heal_state = GF_LK_HEAL_DONE;
-
- INIT_LIST_HEAD (&fdctx->sfd_pos);
- INIT_LIST_HEAD (&fdctx->lock_list);
-
- this_fd_set_ctx (fd, this, loc, fdctx);
-
- pthread_mutex_lock (&conf->lock);
- {
- list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
- }
- pthread_mutex_unlock (&conf->lock);
-out:
- return ret;
-}
-
-int
-client3_3_open_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- call_frame_t *frame = NULL;
- fd_t *fd = NULL;
- int ret = 0;
- gfs3_open_rsp rsp = {0,};
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- conf = frame->this->private;
- fd = local->fd;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_open_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
- local->flags, rsp.fd, 0);
- if (ret) {
- rsp.op_ret = -1;
- rsp.op_errno = -ret;
- goto out;
- }
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
-
- CLIENT_STACK_UNWIND (open, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), fd, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_stat_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_stat_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt iatt = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_stat_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &iatt);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (stat, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &iatt, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_readlink_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt iatt = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readlink_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.buf, &iatt);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (readlink, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), rsp.path,
- &iatt, xdata);
-
- /* This is allocated by the libc while decoding RPC msg */
- /* Hence no 'GF_FREE', but just 'free' */
- free (rsp.path);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_unlink_rsp rsp = {0,};
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_unlink_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (unlink, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &preparent,
- &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_rmdir_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rmdir_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (rmdir, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &preparent,
- &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_truncate_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.prestat, &prestat);
- gf_stat_to_iatt (&rsp.poststat, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (truncate, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_statfs_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct statvfs statfs = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_statfs_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_statfs_to_statfs (&rsp.statfs, &statfs);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (statfs, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &statfs, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_writev_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_write_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.prestat, &prestat);
- gf_stat_to_iatt (&rsp.poststat, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (writev, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_flush_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- gf_common_rsp rsp = {0,};
- int ret = 0;
-
- frame = myframe;
- this = THIS;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (rsp.op_ret >= 0 && !fd_is_anonymous (local->fd)) {
- /* Delete all saved locks of the owner issuing flush */
- ret = delete_granted_locks_owner (local->fd, &local->owner);
- gf_log (this->name, GF_LOG_TRACE,
- "deleting locks of owner (%s) returned %d",
- lkowner_utoa (&local->owner), ret);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (flush, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_fsync_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_truncate_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.prestat, &prestat);
- gf_stat_to_iatt (&rsp.poststat, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (fsync, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
- int op_errno = EINVAL;
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- op_errno = gf_error_to_errno (rsp.op_errno);
- if (rsp.op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_WARNING),
- "remote operation failed: %s",
- strerror (op_errno));
- }
- CLIENT_STACK_UNWIND (setxattr, frame, rsp.op_ret, op_errno, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- int op_errno = EINVAL;
- gfs3_getxattr_rsp rsp = {0,};
- int ret = 0;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_getxattr_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- op_errno = gf_error_to_errno (rsp.op_errno);
- if (-1 != rsp.op_ret) {
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
- (rsp.dict.dict_val),
- (rsp.dict.dict_len), rsp.op_ret,
- op_errno, out);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, (((op_errno == ENOTSUP) || (op_errno == ENODATA)) ?
- GF_LOG_DEBUG : GF_LOG_WARNING),
- "remote operation failed: %s. Path: %s (%s). Key: %s",
- strerror (op_errno),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--",
- (local) ? local->name : "(null)");
- }
-
- CLIENT_STACK_UNWIND (getxattr, frame, rsp.op_ret, op_errno, dict, xdata);
-
- /* don't use GF_FREE, this memory was allocated by libc */
- free (rsp.dict.dict_val);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int
-client3_3_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- gfs3_fgetxattr_rsp rsp = {0,};
- int ret = 0;
- int op_errno = EINVAL;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- op_errno = gf_error_to_errno (rsp.op_errno);
- if (-1 != rsp.op_ret) {
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
- (rsp.dict.dict_val),
- (rsp.dict.dict_len), rsp.op_ret,
- op_errno, out);
- }
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_WARNING),
- "remote operation failed: %s",
- strerror (op_errno));
- }
-
- CLIENT_STACK_UNWIND (fgetxattr, frame, rsp.op_ret, op_errno, dict, xdata);
-
- free (rsp.dict.dict_val);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int
-client3_3_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (removexattr, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fremovexattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (fremovexattr, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (fsyncdir, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_access_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (access, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_ftruncate_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_ftruncate_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.prestat, &prestat);
- gf_stat_to_iatt (&rsp.poststat, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (ftruncate, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- gfs3_fstat_rsp rsp = {0,};
- call_frame_t *frame = NULL;
- struct iatt stat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fstat_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (fstat, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &stat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if ((rsp.op_ret == -1) &&
- (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (inodelk, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if ((rsp.op_ret == -1) &&
- (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (finodelk, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if ((rsp.op_ret == -1) &&
- (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (entrylk, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if ((rsp.op_ret == -1) &&
- (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (fentrylk, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- gfs3_xattrop_rsp rsp = {0,};
- int ret = 0;
- int op_errno = EINVAL;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_xattrop_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- op_errno = rsp.op_errno;
- if (-1 != rsp.op_ret) {
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
- (rsp.dict.dict_val),
- (rsp.dict.dict_len), rsp.op_ret,
- op_errno, out);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
-
- CLIENT_STACK_UNWIND (xattrop, frame, rsp.op_ret,
- gf_error_to_errno (op_errno), dict, xdata);
-
- free (rsp.dict.dict_val);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int
-client3_3_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- dict_t *dict = NULL;
- dict_t *xdata = NULL;
- gfs3_fxattrop_rsp rsp = {0,};
- int ret = 0;
- int op_errno = 0;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fxattrop_rsp);
- if (ret < 0) {
- rsp.op_ret = -1;
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- goto out;
- }
- op_errno = rsp.op_errno;
- if (-1 != rsp.op_ret) {
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, dict,
- (rsp.dict.dict_val),
- (rsp.dict.dict_len), rsp.op_ret,
- op_errno, out);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata,
- (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), rsp.op_ret,
- op_errno, out);
-out:
-
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s",
- strerror (gf_error_to_errno (op_errno)));
- }
- CLIENT_STACK_UNWIND (fxattrop, frame, rsp.op_ret,
- gf_error_to_errno (op_errno), dict, xdata);
-
- free (rsp.dict.dict_val);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- if (dict)
- dict_unref (dict);
-
- return 0;
-}
-
-int
-client3_3_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gf_common_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
- int op_errno = EINVAL;
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_common_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- op_errno = gf_error_to_errno (rsp.op_errno);
- if (rsp.op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_WARNING),
- "remote operation failed: %s",
- strerror (op_errno));
- }
-
- CLIENT_STACK_UNWIND (fsetxattr, frame, rsp.op_ret, op_errno, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_fsetattr_rsp rsp = {0,};
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_fsetattr_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.statpre, &prestat);
- gf_stat_to_iatt (&rsp.statpost, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (fsetattr, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_setattr_rsp rsp = {0,};
- struct iatt prestat = {0,};
- struct iatt poststat = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_setattr_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.statpre, &prestat);
- gf_stat_to_iatt (&rsp.statpost, &poststat);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (setattr, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &prestat,
- &poststat, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_create_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- fd_t *fd = NULL;
- inode_t *inode = NULL;
- struct iatt stbuf = {0, };
- struct iatt preparent = {0, };
- struct iatt postparent = {0, };
- int32_t ret = -1;
- clnt_local_t *local = NULL;
- gfs3_create_rsp rsp = {0,};
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
- fd = local->fd;
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_create_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- uuid_copy (local->loc.gfid, stbuf.ia_gfid);
- ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
- local->flags, rsp.fd, 0);
- if (ret) {
- rsp.op_ret = -1;
- rsp.op_errno = -ret;
- goto out;
- }
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
-
- CLIENT_STACK_UNWIND (create, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), fd, inode,
- &stbuf, &preparent, &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_rchecksum_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rchecksum_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (rchecksum, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno),
- rsp.weak_checksum,
- (uint8_t *)rsp.strong_checksum.strong_checksum_val,
- xdata);
-
- if (rsp.strong_checksum.strong_checksum_val) {
- /* This is allocated by the libc while decoding RPC msg */
- /* Hence no 'GF_FREE', but just 'free' */
- free (rsp.strong_checksum.strong_checksum_val);
- }
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_lk_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- clnt_local_t *local = NULL;
- struct gf_flock lock = {0,};
- gfs3_lk_rsp rsp = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lk_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (rsp.op_ret >= 0) {
- gf_proto_flock_to_flock (&rsp.flock, &lock);
- }
-
- /* Save the lock to the client lock cache to be able
- to recover in the case of server reboot.*/
- /*
- temporarily
- if (local->cmd == F_SETLK || local->cmd == F_SETLKW) {
- ret = client_add_lock_for_recovery (local->fd, &lock,
- local->owner, local->cmd);
- if (ret < 0) {
- rsp.op_ret = -1;
- rsp.op_errno = -ret;
- }
- }
- */
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if ((rsp.op_ret == -1) &&
- (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
-
- CLIENT_STACK_UNWIND (lk, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &lock, xdata);
-
- free (rsp.xdata.xdata_val);
-
- free (rsp.flock.lk_owner.lk_owner_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_readdir_rsp rsp = {0,};
- int32_t ret = 0;
- clnt_local_t *local = NULL;
- gf_dirent_t entries;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readdir_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- INIT_LIST_HEAD (&entries.list);
- if (rsp.op_ret > 0) {
- unserialize_rsp_dirent (&rsp, &entries);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata,
- (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), rsp.op_ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s remote_fd = %d",
- strerror (gf_error_to_errno (rsp.op_errno)),
- local->cmd);
- }
- CLIENT_STACK_UNWIND (readdir, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &entries, xdata);
-
- if (rsp.op_ret != -1) {
- gf_dirent_free (&entries);
- }
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- clnt_readdir_rsp_cleanup (&rsp);
-
- return 0;
-}
-
-
-int
-client3_3_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_readdirp_rsp rsp = {0,};
- int32_t ret = 0;
- clnt_local_t *local = NULL;
- gf_dirent_t entries;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_readdirp_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- INIT_LIST_HEAD (&entries.list);
- if (rsp.op_ret > 0) {
- unserialize_rsp_direntp (this, local->fd, &rsp, &entries);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (readdirp, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), &entries, xdata);
-
- if (rsp.op_ret != -1) {
- gf_dirent_free (&entries);
- }
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- clnt_readdirp_rsp_cleanup (&rsp);
-
- return 0;
-}
-
-
-int
-client3_3_rename_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_rename_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt preoldparent = {0,};
- struct iatt postoldparent = {0,};
- struct iatt prenewparent = {0,};
- struct iatt postnewparent = {0,};
- int ret = 0;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_rename_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preoldparent, &preoldparent);
- gf_stat_to_iatt (&rsp.postoldparent, &postoldparent);
-
- gf_stat_to_iatt (&rsp.prenewparent, &prenewparent);
- gf_stat_to_iatt (&rsp.postnewparent, &postnewparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING, "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (rename, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno),
- &stbuf, &preoldparent, &postoldparent,
- &prenewparent, &postnewparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_link_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- gfs3_link_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int ret = 0;
- clnt_local_t *local = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
-
- this = THIS;
-
- frame = myframe;
-
- local = frame->local;
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_link_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- gf_stat_to_iatt (&rsp.preparent, &preparent);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s (%s -> %s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? ((local->loc.path)? local->loc.path :
- uuid_utoa (local->loc.inode->gfid)) : "--",
- (local) ? ((local->loc2.path)? local->loc2.path :
- local->loc2.name) : "--");
- }
-
- CLIENT_STACK_UNWIND (link, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), inode,
- &stbuf, &preparent, &postparent, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- call_frame_t *frame = NULL;
- fd_t *fd = NULL;
- int ret = 0;
- gfs3_opendir_rsp rsp = {0,};
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
-
- conf = frame->this->private;
- fd = local->fd;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_opendir_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (-1 != rsp.op_ret) {
- ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc,
- 0, rsp.fd, 1);
- if (ret) {
- rsp.op_ret = -1;
- rsp.op_errno = -ret;
- goto out;
- }
- }
-
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (gf_error_to_errno (rsp.op_errno)),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- }
- CLIENT_STACK_UNWIND (opendir, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), fd, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-
-int
-client3_3_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- clnt_local_t *local = NULL;
- call_frame_t *frame = NULL;
- int ret = 0;
- gfs3_lookup_rsp rsp = {0,};
- struct iatt stbuf = {0,};
- struct iatt postparent = {0,};
- int op_errno = EINVAL;
- dict_t *xdata = NULL;
- inode_t *inode = NULL;
- xlator_t *this = NULL;
-
- this = THIS;
-
- frame = myframe;
- local = frame->local;
- inode = local->loc.inode;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_lookup_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- op_errno = EINVAL;
- goto out;
- }
-
- op_errno = gf_error_to_errno (rsp.op_errno);
- gf_stat_to_iatt (&rsp.postparent, &postparent);
-
- if (rsp.op_ret == -1)
- goto out;
-
- rsp.op_ret = -1;
- gf_stat_to_iatt (&rsp.stat, &stbuf);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (frame->this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), rsp.op_ret,
- op_errno, out);
-
- if ((!uuid_is_null (inode->gfid))
- && (uuid_compare (stbuf.ia_gfid, inode->gfid) != 0)) {
- gf_log (frame->this->name, GF_LOG_DEBUG,
- "gfid changed for %s", local->loc.path);
- rsp.op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- rsp.op_ret = 0;
-
-out:
- rsp.op_errno = op_errno;
- if (rsp.op_ret == -1) {
- /* any error other than ENOENT */
- if (rsp.op_errno != ENOENT)
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s. Path: %s (%s)",
- strerror (rsp.op_errno),
- (local) ? local->loc.path : "--",
- (local && local->loc.inode) ?
- uuid_utoa (local->loc.inode->gfid) : "--");
- else
- gf_log (this->name, GF_LOG_TRACE, "not found on remote node");
-
- }
-
- CLIENT_STACK_UNWIND (lookup, frame, rsp.op_ret, rsp.op_errno, inode,
- &stbuf, xdata, &postparent);
-
- if (xdata)
- dict_unref (xdata);
-
- free (rsp.xdata.xdata_val);
-
- return 0;
-}
-
-int
-client3_3_readv_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
- struct iobref *iobref = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
- struct iatt stat = {0,};
- gfs3_read_rsp rsp = {0,};
- int ret = 0, rspcount = 0;
- clnt_local_t *local = NULL;
- xlator_t *this = NULL;
- dict_t *xdata = NULL;
-
- this = THIS;
-
- memset (vector, 0, sizeof (vector));
-
- frame = myframe;
- local = frame->local;
-
- if (-1 == req->rpc_status) {
- rsp.op_ret = -1;
- rsp.op_errno = ENOTCONN;
- goto out;
- }
-
- ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_read_rsp);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "XDR decoding failed");
- rsp.op_ret = -1;
- rsp.op_errno = EINVAL;
- goto out;
- }
-
- if (rsp.op_ret != -1) {
- iobref = req->rsp_iobref;
- gf_stat_to_iatt (&rsp.stat, &stat);
-
- vector[0].iov_len = rsp.op_ret;
- if (rsp.op_ret > 0)
- vector[0].iov_base = req->rsp[1].iov_base;
- rspcount = 1;
- }
- GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
- (rsp.xdata.xdata_len), ret,
- rsp.op_errno, out);
-
-#ifdef GF_TESTING_IO_XDATA
- dict_dump (xdata);
-#endif
-
-out:
- if (rsp.op_ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "remote operation failed: %s",
- strerror (gf_error_to_errno (rsp.op_errno)));
- }
- CLIENT_STACK_UNWIND (readv, frame, rsp.op_ret,
- gf_error_to_errno (rsp.op_errno), vector, rspcount,
- &stat, iobref, xdata);
-
- free (rsp.xdata.xdata_val);
-
- if (xdata)
- dict_unref (xdata);
-
- return 0;
-}
-
-int
-client3_3_release_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
-
- frame = myframe;
- STACK_DESTROY (frame->root);
- return 0;
-}
-int
-client3_3_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count,
- void *myframe)
-{
- call_frame_t *frame = NULL;
-
- frame = myframe;
- STACK_DESTROY (frame->root);
- return 0;
-}
-
-int
-client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx)
-{
- clnt_conf_t *conf = NULL;
- call_frame_t *fr = NULL;
- int32_t ret = -1;
- char parent_down = 0;
- fd_lk_ctx_t *lk_ctx = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, fdctx, out);
-
- conf = (clnt_conf_t *) this->private;
-
- if (fdctx->remote_fd == -1) {
- gf_log (this->name, GF_LOG_DEBUG, "not a valid fd");
- goto out;
- }
-
- pthread_mutex_lock (&conf->lock);
- {
- parent_down = conf->parent_down;
- lk_ctx = fdctx->lk_ctx;
- fdctx->lk_ctx = NULL;
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (lk_ctx)
- fd_lk_ctx_unref (lk_ctx);
-
- if (!parent_down)
- rpc_clnt_ref (conf->rpc);
- else
- goto out;
-
- fr = create_frame (this, this->ctx->pool);
- if (fr == NULL) {
- goto out;
- }
-
- ret = 0;
-
- if (fdctx->is_dir) {
- gfs3_releasedir_req req = {{0,},};
- req.fd = fdctx->remote_fd;
- gf_log (this->name, GF_LOG_DEBUG, "sending releasedir on fd");
- client_submit_request (this, &req, fr, &clnt3_3_fop_prog,
- GFS3_OP_RELEASEDIR,
- client3_3_releasedir_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_releasedir_req);
- } else {
- gfs3_release_req req = {{0,},};
- req.fd = fdctx->remote_fd;
- gf_log (this->name, GF_LOG_DEBUG, "sending release on fd");
- client_submit_request (this, &req, fr, &clnt3_3_fop_prog,
- GFS3_OP_RELEASE,
- client3_3_release_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_release_req);
- }
-
- rpc_clnt_unref (conf->rpc);
-out:
- if (fdctx) {
- fdctx->remote_fd = -1;
- GF_FREE (fdctx);
- }
-
- if (ret && fr)
- STACK_DESTROY (fr->root);
-
- return ret;
-}
-
-int32_t
-client3_3_releasedir (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
-
- if (!this || !data)
- goto out;
-
- args = data;
- conf = this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_del_ctx (args->fd, this);
- if (fdctx != NULL) {
- remote_fd = fdctx->remote_fd;
-
- /* fdctx->remote_fd == -1 indicates a reopen attempt
- in progress. Just mark ->released = 1 and let
- reopen_cbk handle releasing
- */
-
- if (remote_fd != -1)
- list_del_init (&fdctx->sfd_pos);
-
- fdctx->released = 1;
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (remote_fd != -1)
- client_fdctx_destroy (this, fdctx);
-out:
-
- return 0;
-}
-
-int32_t
-client3_3_release (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
- clnt_args_t *args = NULL;
- lk_heal_state_t lk_heal_state = GF_LK_HEAL_DONE;
-
- if (!this || !data)
- goto out;
-
- args = data;
- conf = this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- fdctx = this_fd_del_ctx (args->fd, this);
- if (fdctx != NULL) {
- remote_fd = fdctx->remote_fd;
- lk_heal_state = fdctx->lk_heal_state;
-
- /* fdctx->remote_fd == -1 indicates a reopen attempt
- in progress. Just mark ->released = 1 and let
- reopen_cbk handle releasing
- */
-
- if (remote_fd != -1 &&
- lk_heal_state == GF_LK_HEAL_DONE)
- list_del_init (&fdctx->sfd_pos);
-
- fdctx->released = 1;
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- if (remote_fd != -1 && lk_heal_state == GF_LK_HEAL_DONE)
- client_fdctx_destroy (this, fdctx);
-out:
- return 0;
-}
-
-
-int32_t
-client3_3_lookup (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_local_t *local = NULL;
- clnt_args_t *args = NULL;
- gfs3_lookup_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
- data_t *content = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
- int count = 0;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
-
- if (!frame || !this || !data)
- goto unwind;
-
- memset (vector, 0, sizeof (vector));
-
- conf = this->private;
- args = data;
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (args->loc->parent) {
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
- } else {
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
- }
-
- if (args->xdata) {
- content = dict_get (args->xdata, GF_CONTENT_KEY);
- if (content != NULL) {
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- /* This change very much depends on quick-read
- changes */
- rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (rsp_iobuf == NULL) {
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata,
- (&req.xdata.xdata_val),
- req.xdata.xdata_len,
- op_errno, unwind);
- }
-
- if (args->loc->name)
- req.bname = (char *)args->loc->name;
- else
- req.bname = "";
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_LOOKUP, client3_3_lookup_cbk,
- NULL, rsphdr, count,
- NULL, 0, local->iobref,
- (xdrproc_t)xdr_gfs3_lookup_req);
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL,
- NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- return 0;
-}
-
-int32_t
-client3_3_stat (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_stat_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_STAT, client3_3_stat_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_stat_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (stat, frame, -1, op_errno, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_truncate (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_truncate_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.offset = args->offset;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_TRUNCATE,
- client3_3_truncate_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_truncate_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (truncate, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_ftruncate (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_ftruncate_req req = {{0,},};
- int op_errno = EINVAL;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.offset = args->offset;
- req.fd = remote_fd;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FTRUNCATE,
- client3_3_ftruncate_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_ftruncate_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (ftruncate, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_access (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_access_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.mask = args->mask;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_ACCESS,
- client3_3_access_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_access_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (access, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_readlink (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_readlink_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
- clnt_local_t *local = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iobref *rsp_iobref = NULL;
- struct iovec *rsphdr = NULL;
- int count = 0;
- struct iovec vector[MAX_IOVEC] = {{0}, };
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.size = args->size;
- conf = this->private;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- frame->local = local;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- goto unwind;
- }
-
- rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (rsp_iobuf == NULL) {
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_READLINK,
- client3_3_readlink_cbk, NULL,
- rsphdr, count, NULL, 0,
- local->iobref,
- (xdrproc_t)xdr_gfs3_readlink_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- if (rsp_iobref != NULL) {
- iobref_unref (rsp_iobref);
- }
-
- CLIENT_STACK_UNWIND (readlink, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-
-int32_t
-client3_3_unlink (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_unlink_req req = {{0,},};
- int ret = 0;
- int op_errno = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
- req.bname = (char *)args->loc->name;
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_UNLINK,
- client3_3_unlink_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_unlink_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (unlink, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_rmdir (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_rmdir_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
- req.bname = (char *)args->loc->name;
- req.xflags = args->flags;
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_RMDIR, client3_3_rmdir_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_rmdir_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (rmdir, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_symlink (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_symlink_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- frame->local = local;
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
- req.linkname = (char *)args->linkname;
- req.bname = (char *)args->loc->name;
- req.umask = args->umask;
- local->loc2.path = gf_strdup (req.linkname);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_SYMLINK, client3_3_symlink_cbk,
- NULL, NULL, 0, NULL,
- 0, NULL, (xdrproc_t)xdr_gfs3_symlink_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
-
- CLIENT_STACK_UNWIND (symlink, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_rename (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_rename_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->oldloc && args->newloc && args->oldloc->parent &&
- args->newloc->parent))
- goto unwind;
-
- if (!uuid_is_null (args->oldloc->parent->gfid))
- memcpy (req.oldgfid, args->oldloc->parent->gfid, 16);
- else
- memcpy (req.oldgfid, args->oldloc->pargfid, 16);
-
- if (!uuid_is_null (args->newloc->parent->gfid))
- memcpy (req.newgfid, args->newloc->parent->gfid, 16);
- else
- memcpy (req.newgfid, args->newloc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.oldgfid)),
- unwind, op_errno, EINVAL);
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.newgfid)),
- unwind, op_errno, EINVAL);
- req.oldbname = (char *)args->oldloc->name;
- req.newbname = (char *)args->newloc->name;
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_RENAME, client3_3_rename_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_rename_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (rename, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_link (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_link_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->oldloc && args->oldloc->inode && args->newloc &&
- args->newloc->parent))
- goto unwind;
-
- if (!uuid_is_null (args->oldloc->inode->gfid))
- memcpy (req.oldgfid, args->oldloc->inode->gfid, 16);
- else
- memcpy (req.oldgfid, args->oldloc->gfid, 16);
-
- if (!uuid_is_null (args->newloc->parent->gfid))
- memcpy (req.newgfid, args->newloc->parent->gfid, 16);
- else
- memcpy (req.newgfid, args->newloc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.oldgfid)),
- unwind, op_errno, EINVAL);
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.newgfid)),
- unwind, op_errno, EINVAL);
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- loc_copy (&local->loc, args->oldloc);
- loc_copy (&local->loc2, args->newloc);
- frame->local = local;
-
- req.newbname = (char *)args->newloc->name;
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_LINK, client3_3_link_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_link_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (link, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_mknod (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_mknod_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
- req.bname = (char *)args->loc->name;
- req.mode = args->mode;
- req.dev = args->rdev;
- req.umask = args->umask;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_MKNOD, client3_3_mknod_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_mknod_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (mknod, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_mkdir (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_mkdir_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
-
- req.bname = (char *)args->loc->name;
- req.mode = args->mode;
- req.umask = args->umask;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_MKDIR, client3_3_mkdir_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_mkdir_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (mkdir, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_create (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_create_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- if (!(args->loc && args->loc->parent))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- local->flags = args->flags;
-
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (!uuid_is_null (args->loc->parent->gfid))
- memcpy (req.pargfid, args->loc->parent->gfid, 16);
- else
- memcpy (req.pargfid, args->loc->pargfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.pargfid)),
- unwind, op_errno, EINVAL);
- req.bname = (char *)args->loc->name;
- req.mode = args->mode;
- req.flags = gf_flags_from_flags (args->flags);
- req.umask = args->umask;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_CREATE, client3_3_create_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_create_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (create, frame, -1, op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_open (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_open_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- local->flags = args->flags;
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.flags = gf_flags_from_flags (args->flags);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_OPEN, client3_3_open_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_open_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (open, frame, -1, op_errno, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_readv (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- gfs3_read_req req = {{0,},};
- int ret = 0;
- struct iovec rsp_vec = {0, };
- struct iobuf *rsp_iobuf = NULL;
- struct iobref *rsp_iobref = NULL;
- clnt_local_t *local = NULL;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.size = args->size;
- req.offset = args->offset;
- req.fd = remote_fd;
- req.flag = args->flags;
-
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, args->size);
- if (rsp_iobuf == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsp_vec.iov_base = iobuf_ptr (rsp_iobuf);
- rsp_vec.iov_len = iobuf_pagesize (rsp_iobuf);
-
- rsp_iobuf = NULL;
-
- if (args->size > rsp_vec.iov_len) {
- gf_log (this->name, GF_LOG_WARNING,
- "read-size (%lu) is bigger than iobuf size (%lu)",
- (unsigned long)args->size,
- (unsigned long)rsp_vec.iov_len);
- op_errno = EINVAL;
- goto unwind;
- }
-
- local = mem_get0 (this->local_pool);
- if (local == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- local->iobref = rsp_iobref;
- rsp_iobref = NULL;
- frame->local = local;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_READ, client3_3_readv_cbk, NULL,
- NULL, 0, &rsp_vec, 1,
- local->iobref,
- (xdrproc_t)xdr_gfs3_read_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- CLIENT_STACK_UNWIND (readv, frame, -1, op_errno, NULL, 0, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_writev (call_frame_t *frame, xlator_t *this, void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_write_req req = {{0,},};
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.size = args->size;
- req.offset = args->offset;
- req.fd = remote_fd;
- req.flag = args->flags;
-
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
-#ifdef GF_TESTING_IO_XDATA
- if (!args->xdata)
- args->xdata = dict_new ();
-
- ret = dict_set_str (args->xdata, "testing-the-xdata-key",
- "testing-the-xdata-value");
-#endif
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_vec_request (this, &req, frame, conf->fops,
- GFS3_OP_WRITE, client3_3_writev_cbk,
- args->vector, args->count,
- args->iobref,
- (xdrproc_t)xdr_gfs3_write_req);
- if (ret) {
- /*
- * If the lower layers fail to submit a request, they'll also
- * do the unwind for us (see rpc_clnt_submit), so don't unwind
- * here in such cases.
- */
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (writev, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_flush (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_flush_req req = {{0,},};
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- clnt_local_t *local = NULL;
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- conf = this->private;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- local->fd = fd_ref (args->fd);
- local->owner = frame->root->lk_owner;
- frame->local = local;
-
- req.fd = remote_fd;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FLUSH, client3_3_flush_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_flush_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (flush, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fsync (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_fsync_req req = {{0,},};
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = 0;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.data = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FSYNC, client3_3_fsync_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_fsync_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
-
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fstat (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_fstat_req req = {{0,},};
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FSTAT, client3_3_fstat_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_fstat_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (fstat, frame, -1, op_errno, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_opendir (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_opendir_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- local->fd = fd_ref (args->fd);
- loc_copy (&local->loc, args->loc);
- frame->local = local;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_OPENDIR, client3_3_opendir_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_opendir_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (opendir, frame, -1, op_errno, NULL, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fsyncdir (call_frame_t *frame, xlator_t *this, void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_fsyncdir_req req = {{0,},};
- int ret = 0;
- int32_t op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.data = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FSYNCDIR, client3_3_fsyncdir_cbk,
- NULL, NULL, 0,
- NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsyncdir_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (fsyncdir, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_statfs (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_statfs_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!args->loc)
- goto unwind;
-
- if (args->loc->inode) {
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
- } else
- req.gfid[15] = 1;
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_STATFS, client3_3_statfs_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_statfs_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-
-unwind:
- CLIENT_STACK_UNWIND (statfs, frame, -1, op_errno, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_setxattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_setxattr_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- if (args->xattr) {
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
- (&req.dict.dict_val),
- req.dict.dict_len,
- op_errno, unwind);
- }
-
- req.flags = args->flags;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_SETXATTR, client3_3_setxattr_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_setxattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL);
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fsetxattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_fsetxattr_req req = {{0,},};
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.flags = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- if (args->xattr) {
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
- (&req.dict.dict_val),
- req.dict.dict_len,
- op_errno, unwind);
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FSETXATTR, client3_3_fsetxattr_cbk,
- NULL, NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsetxattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL);
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-
-int32_t
-client3_3_fgetxattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_fgetxattr_req req = {{0,},};
- int op_errno = ESTALE;
- int ret = 0;
- int count = 0;
- clnt_local_t *local = NULL;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- frame->local = local;
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
- if (rsp_iobuf == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);;
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
-
- req.namelen = 1; /* Use it as a flag */
- req.fd = remote_fd;
- req.name = (char *)args->name;
- if (!req.name) {
- req.name = "";
- req.namelen = 0;
- }
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FGETXATTR,
- client3_3_fgetxattr_cbk, NULL,
- rsphdr, count,
- NULL, 0, local->iobref,
- (xdrproc_t)xdr_gfs3_fgetxattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fgetxattr, frame, -1, op_errno, NULL, NULL);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_getxattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_getxattr_req req = {{0,},};
- dict_t *dict = NULL;
- int ret = 0;
- int32_t op_ret = -1;
- int op_errno = ESTALE;
- int count = 0;
- clnt_local_t *local = NULL;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
-
- if (!frame || !this || !data) {
- op_errno = 0;
- goto unwind;
- }
- args = data;
-
- if (!args->loc) {
- op_errno = EINVAL;
- goto unwind;
- }
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- loc_copy (&local->loc, args->loc);
- if (args->name)
- local->name = gf_strdup (args->name);
-
- frame->local = local;
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
- if (rsp_iobuf == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
-
- if (args->loc->inode && !uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.namelen = 1; /* Use it as a flag */
-
- req.name = (char *)args->name;
- if (!req.name) {
- req.name = "";
- req.namelen = 0;
- }
-
- conf = this->private;
-
- if (args && args->name) {
- if (is_client_dump_locks_cmd ((char *)args->name)) {
- dict = dict_new ();
- ret = client_dump_locks ((char *)args->name,
- args->loc->inode,
- dict);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "Client dump locks failed");
- op_errno = EINVAL;
- }
-
- GF_ASSERT (dict);
- op_ret = 0;
- op_errno = 0;
- goto unwind;
- }
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_GETXATTR,
- client3_3_getxattr_cbk, NULL,
- rsphdr, count,
- NULL, 0, local->iobref,
- (xdrproc_t)xdr_gfs3_getxattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- CLIENT_STACK_UNWIND (getxattr, frame, op_ret, op_errno, dict, NULL);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_xattrop (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_xattrop_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
- int count = 0;
- clnt_local_t *local = NULL;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- frame->local = local;
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
- if (rsp_iobuf == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- if (args->xattr) {
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
- (&req.dict.dict_val),
- req.dict.dict_len,
- op_errno, unwind);
- }
-
- req.flags = args->flags;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_XATTROP,
- client3_3_xattrop_cbk, NULL,
- rsphdr, count,
- NULL, 0, local->iobref,
- (xdrproc_t)xdr_gfs3_xattrop_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (xattrop, frame, -1, op_errno, NULL, NULL);
-
- GF_FREE (req.dict.dict_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fxattrop (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_fxattrop_req req = {{0,},};
- int op_errno = ESTALE;
- int ret = 0;
- int count = 0;
- clnt_local_t *local = NULL;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.flags = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- frame->local = local;
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- rsp_iobuf = iobuf_get2 (this->ctx->iobuf_pool, 8 * GF_UNIT_KB);
- if (rsp_iobuf == NULL) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
-
- if (args->xattr) {
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xattr,
- (&req.dict.dict_val),
- req.dict.dict_len,
- op_errno, unwind);
- }
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FXATTROP,
- client3_3_fxattrop_cbk, NULL,
- rsphdr, count,
- NULL, 0, local->iobref,
- (xdrproc_t)xdr_gfs3_fxattrop_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.dict.dict_val);
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);
-
- GF_FREE (req.dict.dict_val);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_removexattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_removexattr_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.name = (char *)args->name;
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_REMOVEXATTR,
- client3_3_removexattr_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_removexattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_fremovexattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_fremovexattr_req req = {{0,},};
- int ret = 0;
- int64_t remote_fd = -1;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->fd && args->fd->inode))
- goto unwind;
-
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- memcpy (req.gfid, args->fd->inode->gfid, 16);
- req.name = (char *)args->name;
- req.fd = remote_fd;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FREMOVEXATTR,
- client3_3_fremovexattr_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fremovexattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_lk (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_lk_req req = {{0,},};
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- int64_t remote_fd = -1;
- clnt_local_t *local = NULL;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- ret = client_cmd_to_gf_cmd (args->cmd, &gf_cmd);
- if (ret) {
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown cmd (%d)!", gf_cmd);
- goto unwind;
- }
-
- switch (args->flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- local->owner = frame->root->lk_owner;
- local->cmd = args->cmd;
- local->fd = fd_ref (args->fd);
- frame->local = local;
-
- req.fd = remote_fd;
- req.cmd = gf_cmd;
- req.type = gf_type;
- gf_proto_flock_from_flock (&req.flock, args->flock);
-
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK,
- client3_3_lk_cbk, NULL,
- NULL, 0, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (lk, frame, -1, op_errno, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_inodelk (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_inodelk_req req = {{0,},};
- int ret = 0;
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
- gf_cmd = GF_LK_GETLK;
- else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
- gf_cmd = GF_LK_SETLK;
- else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
- gf_cmd = GF_LK_SETLKW;
- else {
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown cmd (%d)!", gf_cmd);
- op_errno = EINVAL;
- goto unwind;
- }
-
- switch (args->flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- req.volume = (char *)args->volume;
- req.cmd = gf_cmd;
- req.type = gf_type;
- gf_proto_flock_from_flock (&req.flock, args->flock);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_INODELK,
- client3_3_inodelk_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_inodelk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (inodelk, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_finodelk (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_finodelk_req req = {{0,},};
- int32_t gf_cmd = 0;
- int32_t gf_type = 0;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
- gf_cmd = GF_LK_GETLK;
- else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
- gf_cmd = GF_LK_SETLK;
- else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
- gf_cmd = GF_LK_SETLKW;
- else {
- gf_log (this->name, GF_LOG_WARNING,
- "Unknown cmd (%d)!", gf_cmd);
- goto unwind;
- }
-
- switch (args->flock->l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- req.volume = (char *)args->volume;
- req.fd = remote_fd;
- req.cmd = gf_cmd;
- req.type = gf_type;
- gf_proto_flock_from_flock (&req.flock, args->flock);
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FINODELK,
- client3_3_finodelk_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_finodelk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (finodelk, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_entrylk (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_entrylk_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.cmd = args->cmd_entrylk;
- req.type = args->type;
- req.volume = (char *)args->volume;
- req.name = "";
- if (args->basename) {
- req.name = (char *)args->basename;
- req.namelen = 1;
- }
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_ENTRYLK,
- client3_3_entrylk_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_entrylk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (entrylk, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_fentrylk (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_fentrylk_req req = {{0,},};
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.cmd = args->cmd_entrylk;
- req.type = args->type;
- req.volume = (char *)args->volume;
- req.name = "";
- if (args->basename) {
- req.name = (char *)args->basename;
- req.namelen = 1;
- }
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FENTRYLK,
- client3_3_fentrylk_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_fentrylk_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fentrylk, frame, -1, op_errno, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_rchecksum (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_rchecksum_req req = {0,};
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.len = args->len;
- req.offset = args->offset;
- req.fd = remote_fd;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_RCHECKSUM,
- client3_3_rchecksum_cbk, NULL,
- NULL, 0, NULL,
- 0, NULL,
- (xdrproc_t)xdr_gfs3_rchecksum_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (rchecksum, frame, -1, op_errno, 0, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-int32_t
-client3_3_readdir (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_readdir_req req = {{0,},};
- gfs3_readdir_rsp rsp = {0, };
- clnt_local_t *local = NULL;
- int op_errno = ESTALE;
- int ret = 0;
- int count = 0;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
- int readdir_rsp_size = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- readdir_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdir_rsp, &rsp)
- + args->size;
-
- if ((readdir_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
- > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- frame->local = local;
-
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- /* This iobuf will live for only receiving the response,
- so not harmful */
- rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (rsp_iobuf == NULL) {
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
- }
-
- req.size = args->size;
- req.offset = args->offset;
- req.fd = remote_fd;
-
- local->cmd = remote_fd;
-
- memcpy (req.gfid, args->fd->inode->gfid, 16);
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_READDIR,
- client3_3_readdir_cbk, NULL,
- rsphdr, count,
- NULL, 0, rsp_iobref,
- (xdrproc_t)xdr_gfs3_readdir_req);
-
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-
-unwind:
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- CLIENT_STACK_UNWIND (readdir, frame, -1, op_errno, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-int32_t
-client3_3_readdirp (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_args_t *args = NULL;
- gfs3_readdirp_req req = {{0,},};
- gfs3_readdirp_rsp rsp = {0,};
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- int op_errno = ESTALE;
- int ret = 0;
- int count = 0;
- int readdirp_rsp_size = 0;
- struct iobref *rsp_iobref = NULL;
- struct iobuf *rsp_iobuf = NULL;
- struct iovec *rsphdr = NULL;
- struct iovec vector[MAX_IOVEC] = {{0}, };
- clnt_local_t *local = NULL;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp)
- + args->size;
-
- local = mem_get0 (this->local_pool);
- if (!local) {
- op_errno = ENOMEM;
- goto unwind;
- }
- frame->local = local;
-
- if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE
- + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
- > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
- rsp_iobref = iobref_new ();
- if (rsp_iobref == NULL) {
- goto unwind;
- }
-
- /* TODO: what is the size we should send ? */
- /* This iobuf will live for only receiving the response,
- so not harmful */
- rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
- if (rsp_iobuf == NULL) {
- goto unwind;
- }
-
- iobref_add (rsp_iobref, rsp_iobuf);
- iobuf_unref (rsp_iobuf);
-
- rsphdr = &vector[0];
- rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
- rsphdr->iov_len = iobuf_pagesize (rsp_iobuf);
- count = 1;
- local->iobref = rsp_iobref;
- rsp_iobuf = NULL;
- rsp_iobref = NULL;
- }
-
- local->fd = fd_ref (args->fd);
-
- req.size = args->size;
- req.offset = args->offset;
- req.fd = remote_fd;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
-
- /* dict itself is 'xdata' here */
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.dict.dict_val),
- req.dict.dict_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_READDIRP,
- client3_3_readdirp_cbk, NULL,
- rsphdr, count, NULL,
- 0, rsp_iobref,
- (xdrproc_t)xdr_gfs3_readdirp_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.dict.dict_val);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- return 0;
-unwind:
- if (rsp_iobref)
- iobref_unref (rsp_iobref);
-
- if (rsp_iobuf)
- iobuf_unref (rsp_iobuf);
-
- GF_FREE (req.dict.dict_val);
-
- CLIENT_STACK_UNWIND (readdirp, frame, -1, op_errno, NULL, NULL);
- return 0;
-}
-
-
-int32_t
-client3_3_setattr (call_frame_t *frame, xlator_t *this,
- void *data)
-{
- clnt_conf_t *conf = NULL;
- clnt_args_t *args = NULL;
- gfs3_setattr_req req = {{0,},};
- int ret = 0;
- int op_errno = ESTALE;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
-
- if (!(args->loc && args->loc->inode))
- goto unwind;
-
- if (!uuid_is_null (args->loc->inode->gfid))
- memcpy (req.gfid, args->loc->inode->gfid, 16);
- else
- memcpy (req.gfid, args->loc->gfid, 16);
-
- GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
- !uuid_is_null (*((uuid_t*)req.gfid)),
- unwind, op_errno, EINVAL);
- req.valid = args->valid;
- gf_stat_from_iatt (&req.stbuf, args->stbuf);
-
- conf = this->private;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_SETATTR,
- client3_3_setattr_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_setattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (setattr, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-int32_t
-client3_3_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
-{
- clnt_args_t *args = NULL;
- int64_t remote_fd = -1;
- clnt_conf_t *conf = NULL;
- gfs3_fsetattr_req req = {0,};
- int op_errno = ESTALE;
- int ret = 0;
-
- if (!frame || !this || !data)
- goto unwind;
-
- args = data;
- conf = this->private;
-
- CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, op_errno, unwind);
-
- req.fd = remote_fd;
- req.valid = args->valid;
- gf_stat_from_iatt (&req.stbuf, args->stbuf);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
- req.xdata.xdata_len, op_errno, unwind);
-
- ret = client_submit_request (this, &req, frame, conf->fops,
- GFS3_OP_FSETATTR,
- client3_3_fsetattr_cbk, NULL,
- NULL, 0, NULL, 0,
- NULL, (xdrproc_t)xdr_gfs3_fsetattr_req);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING, "failed to send the fop");
- }
-
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-unwind:
- CLIENT_STACK_UNWIND (fsetattr, frame, -1, op_errno, NULL, NULL, NULL);
- GF_FREE (req.xdata.xdata_val);
-
- return 0;
-}
-
-
-
-/* Table Specific to FOPS */
-
-
-rpc_clnt_procedure_t clnt3_3_fop_actors[GF_FOP_MAXVALUE] = {
- [GF_FOP_NULL] = { "NULL", NULL},
- [GF_FOP_STAT] = { "STAT", client3_3_stat },
- [GF_FOP_READLINK] = { "READLINK", client3_3_readlink },
- [GF_FOP_MKNOD] = { "MKNOD", client3_3_mknod },
- [GF_FOP_MKDIR] = { "MKDIR", client3_3_mkdir },
- [GF_FOP_UNLINK] = { "UNLINK", client3_3_unlink },
- [GF_FOP_RMDIR] = { "RMDIR", client3_3_rmdir },
- [GF_FOP_SYMLINK] = { "SYMLINK", client3_3_symlink },
- [GF_FOP_RENAME] = { "RENAME", client3_3_rename },
- [GF_FOP_LINK] = { "LINK", client3_3_link },
- [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_3_truncate },
- [GF_FOP_OPEN] = { "OPEN", client3_3_open },
- [GF_FOP_READ] = { "READ", client3_3_readv },
- [GF_FOP_WRITE] = { "WRITE", client3_3_writev },
- [GF_FOP_STATFS] = { "STATFS", client3_3_statfs },
- [GF_FOP_FLUSH] = { "FLUSH", client3_3_flush },
- [GF_FOP_FSYNC] = { "FSYNC", client3_3_fsync },
- [GF_FOP_SETXATTR] = { "SETXATTR", client3_3_setxattr },
- [GF_FOP_GETXATTR] = { "GETXATTR", client3_3_getxattr },
- [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_3_removexattr },
- [GF_FOP_OPENDIR] = { "OPENDIR", client3_3_opendir },
- [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_3_fsyncdir },
- [GF_FOP_ACCESS] = { "ACCESS", client3_3_access },
- [GF_FOP_CREATE] = { "CREATE", client3_3_create },
- [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_3_ftruncate },
- [GF_FOP_FSTAT] = { "FSTAT", client3_3_fstat },
- [GF_FOP_LK] = { "LK", client3_3_lk },
- [GF_FOP_LOOKUP] = { "LOOKUP", client3_3_lookup },
- [GF_FOP_READDIR] = { "READDIR", client3_3_readdir },
- [GF_FOP_INODELK] = { "INODELK", client3_3_inodelk },
- [GF_FOP_FINODELK] = { "FINODELK", client3_3_finodelk },
- [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_3_entrylk },
- [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_3_fentrylk },
- [GF_FOP_XATTROP] = { "XATTROP", client3_3_xattrop },
- [GF_FOP_FXATTROP] = { "FXATTROP", client3_3_fxattrop },
- [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_3_fgetxattr },
- [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_3_fsetxattr },
- [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_3_rchecksum },
- [GF_FOP_SETATTR] = { "SETATTR", client3_3_setattr },
- [GF_FOP_FSETATTR] = { "FSETATTR", client3_3_fsetattr },
- [GF_FOP_READDIRP] = { "READDIRP", client3_3_readdirp },
- [GF_FOP_RELEASE] = { "RELEASE", client3_3_release },
- [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_3_releasedir },
- [GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec },
- [GF_FOP_FREMOVEXATTR] = { "FREMOVEXATTR", client3_3_fremovexattr },
-};
-
-/* Used From RPC-CLNT library to log proper name of procedure based on number */
-char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {
- [GFS3_OP_NULL] = "NULL",
- [GFS3_OP_STAT] = "STAT",
- [GFS3_OP_READLINK] = "READLINK",
- [GFS3_OP_MKNOD] = "MKNOD",
- [GFS3_OP_MKDIR] = "MKDIR",
- [GFS3_OP_UNLINK] = "UNLINK",
- [GFS3_OP_RMDIR] = "RMDIR",
- [GFS3_OP_SYMLINK] = "SYMLINK",
- [GFS3_OP_RENAME] = "RENAME",
- [GFS3_OP_LINK] = "LINK",
- [GFS3_OP_TRUNCATE] = "TRUNCATE",
- [GFS3_OP_OPEN] = "OPEN",
- [GFS3_OP_READ] = "READ",
- [GFS3_OP_WRITE] = "WRITE",
- [GFS3_OP_STATFS] = "STATFS",
- [GFS3_OP_FLUSH] = "FLUSH",
- [GFS3_OP_FSYNC] = "FSYNC",
- [GFS3_OP_SETXATTR] = "SETXATTR",
- [GFS3_OP_GETXATTR] = "GETXATTR",
- [GFS3_OP_REMOVEXATTR] = "REMOVEXATTR",
- [GFS3_OP_OPENDIR] = "OPENDIR",
- [GFS3_OP_FSYNCDIR] = "FSYNCDIR",
- [GFS3_OP_ACCESS] = "ACCESS",
- [GFS3_OP_CREATE] = "CREATE",
- [GFS3_OP_FTRUNCATE] = "FTRUNCATE",
- [GFS3_OP_FSTAT] = "FSTAT",
- [GFS3_OP_LK] = "LK",
- [GFS3_OP_LOOKUP] = "LOOKUP",
- [GFS3_OP_READDIR] = "READDIR",
- [GFS3_OP_INODELK] = "INODELK",
- [GFS3_OP_FINODELK] = "FINODELK",
- [GFS3_OP_ENTRYLK] = "ENTRYLK",
- [GFS3_OP_FENTRYLK] = "FENTRYLK",
- [GFS3_OP_XATTROP] = "XATTROP",
- [GFS3_OP_FXATTROP] = "FXATTROP",
- [GFS3_OP_FGETXATTR] = "FGETXATTR",
- [GFS3_OP_FSETXATTR] = "FSETXATTR",
- [GFS3_OP_RCHECKSUM] = "RCHECKSUM",
- [GFS3_OP_SETATTR] = "SETATTR",
- [GFS3_OP_FSETATTR] = "FSETATTR",
- [GFS3_OP_READDIRP] = "READDIRP",
- [GFS3_OP_RELEASE] = "RELEASE",
- [GFS3_OP_RELEASEDIR] = "RELEASEDIR",
- [GFS3_OP_FREMOVEXATTR] = "FREMOVEXATTR",
-};
-
-rpc_clnt_prog_t clnt3_3_fop_prog = {
- .progname = "GlusterFS 3.3",
- .prognum = GLUSTER_FOP_PROGRAM,
- .progver = GLUSTER_FOP_VERSION,
- .numproc = GLUSTER_FOP_PROCCNT,
- .proctable = clnt3_3_fop_actors,
- .procnames = clnt3_3_fop_names,
-};
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index 16c7dee5e..ff766844d 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
@@ -31,134 +40,22 @@ int client_handshake (xlator_t *this, struct rpc_clnt *rpc);
void client_start_ping (void *data);
int client_init_rpc (xlator_t *this);
int client_destroy_rpc (xlator_t *this);
-int client_mark_fd_bad (xlator_t *this);
-
-int32_t
-client_type_to_gf_type (short l_type)
-{
- int32_t gf_type = GF_LK_EOL;
-
- switch (l_type) {
- case F_RDLCK:
- gf_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- gf_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- gf_type = GF_LK_F_UNLCK;
- break;
- }
-
- return gf_type;
-}
-
-uint32_t
-client_get_lk_ver (clnt_conf_t *conf)
-{
- uint32_t lk_ver = 0;
-
- GF_VALIDATE_OR_GOTO ("client", conf, out);
-
- pthread_mutex_lock (&conf->lock);
- {
- lk_ver = conf->lk_version;
- }
- pthread_mutex_unlock (&conf->lock);
-out:
- return lk_ver;
-}
-
-void
-client_grace_timeout (void *data)
-{
- int ver = 0;
- xlator_t *this = NULL;
- struct clnt_conf *conf = NULL;
- struct rpc_clnt *rpc = NULL;
-
- GF_VALIDATE_OR_GOTO ("client", data, out);
-
- this = THIS;
-
- rpc = (struct rpc_clnt *) data;
-
- conf = (struct clnt_conf *) this->private;
-
- pthread_mutex_lock (&conf->lock);
- {
- ver = ++conf->lk_version;
- /* ver == 0 is a special value used by server
- to notify client that this is a fresh connect.*/
- if (ver == 0)
- ver = ++conf->lk_version;
-
- gf_timer_call_cancel (this->ctx, conf->grace_timer);
- conf->grace_timer = NULL;
- }
- pthread_mutex_unlock (&conf->lock);
-
- gf_log (this->name, GF_LOG_WARNING,
- "client grace timer expired, updating "
- "the lk-version to %d", ver);
-
- client_mark_fd_bad (this);
-out:
- return;
-}
-
-int32_t
-client_register_grace_timer (xlator_t *this, clnt_conf_t *conf)
-{
- int32_t ret = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
-
- pthread_mutex_lock (&conf->lock);
- {
- if (conf->grace_timer || !conf->grace_timer_needed) {
- gf_log (this->name, GF_LOG_TRACE,
- "Client grace timer is already set "
- "or a grace-timer has already time out, "
- "not registering a new timer");
- } else {
- gf_log (this->name, GF_LOG_INFO,
- "Registering a grace timer");
-
- conf->grace_timer_needed = _gf_false;
-
- conf->grace_timer =
- gf_timer_call_after (this->ctx,
- conf->grace_tv,
- client_grace_timeout,
- conf->rpc);
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
- ret = 0;
-out:
- return ret;
-}
int
client_submit_request (xlator_t *this, void *req, call_frame_t *frame,
- rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbkfn,
- struct iobref *iobref, struct iovec *rsphdr,
- int rsphdr_count, struct iovec *rsp_payload,
- int rsp_payload_count, struct iobref *rsp_iobref,
- xdrproc_t xdrproc)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
- struct iovec iov = {0, };
- struct iobuf *iobuf = NULL;
- int count = 0;
- char start_ping = 0;
- struct iobref *new_iobref = NULL;
- ssize_t xdr_size = 0;
- struct rpc_req rpcreq = {0, };
+ rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbk,
+ struct iobref *iobref, gfs_serialize_t sfunc,
+ struct iovec *rsphdr, int rsphdr_count,
+ struct iovec *rsp_payload, int rsp_payload_count,
+ struct iobref *rsp_iobref)
+{
+ int ret = -1;
+ clnt_conf_t *conf = NULL;
+ struct iovec iov = {0, };
+ struct iobuf *iobuf = NULL;
+ int count = 0;
+ char start_ping = 0;
+ struct iobref *new_iobref = NULL;
GF_VALIDATE_OR_GOTO ("client", this, out);
GF_VALIDATE_OR_GOTO (this->name, prog, out);
@@ -181,39 +78,38 @@ client_submit_request (xlator_t *this, void *req, call_frame_t *frame,
goto out;
}
- if (req && xdrproc) {
- xdr_size = xdr_sizeof (xdrproc, req);
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size);
- if (!iobuf) {
- goto out;
- };
-
- new_iobref = iobref_new ();
- if (!new_iobref) {
- goto out;
- }
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ goto out;
+ };
- if (iobref != NULL) {
- ret = iobref_merge (new_iobref, iobref);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "cannot merge iobref passed from caller "
- "into new_iobref");
- }
- }
+ new_iobref = iobref_new ();
+ if (!new_iobref) {
+ goto out;
+ }
- ret = iobref_add (new_iobref, iobuf);
+ if (iobref != NULL) {
+ ret = iobref_merge (new_iobref, iobref);
if (ret != 0) {
gf_log (this->name, GF_LOG_WARNING,
- "cannot add iobuf into iobref");
- goto out;
+ "cannot merge iobref passed from caller "
+ "into new_iobref");
}
+ }
+
+ ret = iobref_add (new_iobref, iobuf);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot add iobuf into iobref");
+ goto out;
+ }
- iov.iov_base = iobuf->ptr;
- iov.iov_len = iobuf_size (iobuf);
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = 128 * GF_UNIT_KB;
- /* Create the xdr payload */
- ret = xdr_serialize_generic (iov, req, xdrproc);
+ /* Create the xdr payload */
+ if (req && sfunc) {
+ ret = sfunc (iov, req);
if (ret == -1) {
/* callingfn so that, we can get to know which xdr
function was called */
@@ -224,10 +120,9 @@ client_submit_request (xlator_t *this, void *req, call_frame_t *frame,
iov.iov_len = ret;
count = 1;
}
-
/* Send the msg */
- ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbkfn, &iov, count,
- NULL, 0, new_iobref, frame, rsphdr, rsphdr_count,
+ ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &iov, count, NULL,
+ 0, new_iobref, frame, rsphdr, rsphdr_count,
rsp_payload, rsp_payload_count, rsp_iobref);
if (ret < 0) {
@@ -248,27 +143,14 @@ client_submit_request (xlator_t *this, void *req, call_frame_t *frame,
client_start_ping ((void *) this);
ret = 0;
-
- if (new_iobref)
- iobref_unref (new_iobref);
-
- if (iobuf)
- iobuf_unref (iobuf);
-
- return ret;
-
out:
- rpcreq.rpc_status = -1;
-
- cbkfn (&rpcreq, NULL, 0, frame);
-
- if (new_iobref)
+ if (new_iobref != NULL)
iobref_unref (new_iobref);
if (iobuf)
iobuf_unref (iobuf);
- return 0;
+ return ret;
}
@@ -286,6 +168,7 @@ client_releasedir (xlator_t *this, fd_t *fd)
clnt_conf_t *conf = NULL;
rpc_clnt_procedure_t *proc = NULL;
clnt_args_t args = {0,};
+ call_frame_t *frame = NULL;
conf = this->private;
if (!conf || !conf->fops)
@@ -301,7 +184,11 @@ client_releasedir (xlator_t *this, fd_t *fd)
goto out;
}
if (proc->fn) {
- ret = proc->fn (NULL, this, &args);
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+ ret = proc->fn (frame, this, &args);
}
out:
if (ret)
@@ -317,6 +204,7 @@ client_release (xlator_t *this, fd_t *fd)
clnt_conf_t *conf = NULL;
rpc_clnt_procedure_t *proc = NULL;
clnt_args_t args = {0,};
+ call_frame_t *frame = NULL;
conf = this->private;
if (!conf || !conf->fops)
@@ -331,7 +219,11 @@ client_release (xlator_t *this, fd_t *fd)
goto out;
}
if (proc->fn) {
- ret = proc->fn (NULL, this, &args);
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+ ret = proc->fn (frame, this, &args);
}
out:
if (ret)
@@ -343,7 +235,7 @@ out:
int32_t
client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
- dict_t *xdata)
+ dict_t *xattr_req)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -355,7 +247,7 @@ client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
args.loc = loc;
- args.xdata = xdata;
+ args.dict = xattr_req;
proc = &conf->fops->proctable[GF_FOP_LOOKUP];
if (!proc) {
@@ -377,7 +269,7 @@ out:
int32_t
-client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -389,7 +281,6 @@ client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
args.loc = loc;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_STAT];
if (!proc) {
@@ -402,15 +293,14 @@ client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (stat, frame, -1, ENOTCONN, NULL);
return 0;
}
int32_t
-client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
- off_t offset, dict_t *xdata)
+client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -423,7 +313,6 @@ client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.offset = offset;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_TRUNCATE];
if (!proc) {
@@ -436,7 +325,7 @@ client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (truncate, frame, -1, ENOTCONN, NULL, NULL);
return 0;
@@ -444,8 +333,7 @@ out:
int32_t
-client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
- off_t offset, dict_t *xdata)
+client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -458,7 +346,6 @@ client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.offset = offset;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FTRUNCATE];
if (!proc) {
@@ -471,7 +358,7 @@ client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
@@ -479,8 +366,7 @@ out:
int32_t
-client_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t mask, dict_t *xdata)
+client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -493,7 +379,6 @@ client_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.mask = mask;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_ACCESS];
if (!proc) {
@@ -506,7 +391,7 @@ client_access (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (access, frame, -1, ENOTCONN);
return 0;
}
@@ -515,8 +400,7 @@ out:
int32_t
-client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- size_t size, dict_t *xdata)
+client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -529,7 +413,6 @@ client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.size = size;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_READLINK];
if (!proc) {
@@ -542,7 +425,7 @@ client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (readlink, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
@@ -550,7 +433,7 @@ out:
int
client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
- dev_t rdev, mode_t umask, dict_t *xdata)
+ dev_t rdev, dict_t *params)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -564,8 +447,7 @@ client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
args.loc = loc;
args.mode = mode;
args.rdev = rdev;
- args.umask = umask;
- args.xdata = xdata;
+ args.dict = params;
proc = &conf->fops->proctable[GF_FOP_MKNOD];
if (!proc) {
@@ -579,7 +461,7 @@ client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
out:
if (ret)
STACK_UNWIND_STRICT (mknod, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -587,7 +469,7 @@ out:
int
client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
- mode_t mode, mode_t umask, dict_t *xdata)
+ mode_t mode, dict_t *params)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -600,8 +482,7 @@ client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.mode = mode;
- args.umask = umask;
- args.xdata = xdata;
+ args.dict = params;
proc = &conf->fops->proctable[GF_FOP_MKDIR];
if (!proc) {
@@ -615,7 +496,7 @@ client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc,
out:
if (ret)
STACK_UNWIND_STRICT (mkdir, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -623,8 +504,7 @@ out:
int32_t
-client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int xflag, dict_t *xdata)
+client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -636,8 +516,6 @@ client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto out;
args.loc = loc;
- args.xdata = xdata;
- args.flags = xflag;
proc = &conf->fops->proctable[GF_FOP_UNLINK];
if (!proc) {
@@ -651,14 +529,13 @@ client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc,
out:
if (ret)
STACK_UNWIND_STRICT (unlink, frame, -1, ENOTCONN,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
int32_t
-client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
- dict_t *xdata)
+client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -671,7 +548,6 @@ client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
args.loc = loc;
args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_RMDIR];
if (!proc) {
@@ -686,7 +562,7 @@ out:
/* think of avoiding a missing frame */
if (ret)
STACK_UNWIND_STRICT (rmdir, frame, -1, ENOTCONN,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
@@ -694,7 +570,7 @@ out:
int
client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
- loc_t *loc, mode_t umask, dict_t *xdata)
+ loc_t *loc, dict_t *params)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -707,8 +583,7 @@ client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
args.linkname = linkpath;
args.loc = loc;
- args.umask = umask;
- args.xdata = xdata;
+ args.dict = params;
proc = &conf->fops->proctable[GF_FOP_SYMLINK];
if (!proc) {
@@ -722,7 +597,7 @@ client_symlink (call_frame_t *frame, xlator_t *this, const char *linkpath,
out:
if (ret)
STACK_UNWIND_STRICT (symlink, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -731,7 +606,7 @@ out:
int32_t
client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -744,8 +619,6 @@ client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
args.oldloc = oldloc;
args.newloc = newloc;
- args.xdata = xdata;
-
proc = &conf->fops->proctable[GF_FOP_RENAME];
if (!proc) {
gf_log (this->name, GF_LOG_ERROR,
@@ -758,7 +631,7 @@ client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
out:
if (ret)
STACK_UNWIND_STRICT (rename, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -767,7 +640,7 @@ out:
int32_t
client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
- loc_t *newloc, dict_t *xdata)
+ loc_t *newloc)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -780,7 +653,6 @@ client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
args.oldloc = oldloc;
args.newloc = newloc;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_LINK];
if (!proc) {
@@ -794,7 +666,7 @@ client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
out:
if (ret)
STACK_UNWIND_STRICT (link, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -802,8 +674,8 @@ out:
int32_t
-client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
- mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
+client_create (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ int32_t flags, mode_t mode, fd_t *fd, dict_t *params)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -818,8 +690,7 @@ client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
args.flags = flags;
args.mode = mode;
args.fd = fd;
- args.umask = umask;
- args.xdata = xdata;
+ args.dict = params;
proc = &conf->fops->proctable[GF_FOP_CREATE];
if (!proc) {
@@ -833,7 +704,7 @@ client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
out:
if (ret)
STACK_UNWIND_STRICT (create, frame, -1, ENOTCONN,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -842,7 +713,7 @@ out:
int32_t
client_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
- int32_t flags, fd_t *fd, dict_t *xdata)
+ int32_t flags, fd_t *fd, int32_t wbflags)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -856,7 +727,7 @@ client_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.flags = flags;
args.fd = fd;
- args.xdata = xdata;
+ args.wbflags = wbflags;
proc = &conf->fops->proctable[GF_FOP_OPEN];
if (!proc) {
@@ -870,7 +741,7 @@ client_open (call_frame_t *frame, xlator_t *this, loc_t *loc,
out:
if (ret)
- STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (open, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -879,7 +750,7 @@ out:
int32_t
client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata)
+ off_t offset)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -893,8 +764,6 @@ client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
args.fd = fd;
args.size = size;
args.offset = offset;
- args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_READ];
if (!proc) {
@@ -909,7 +778,7 @@ client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
out:
if (ret)
STACK_UNWIND_STRICT (readv, frame, -1, ENOTCONN,
- NULL, 0, NULL, NULL, NULL);
+ NULL, 0, NULL, NULL);
return 0;
}
@@ -920,7 +789,7 @@ out:
int32_t
client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
struct iovec *vector, int32_t count, off_t off,
- uint32_t flags, struct iobref *iobref, dict_t *xdata)
+ struct iobref *iobref)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -935,9 +804,7 @@ client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.vector = vector;
args.count = count;
args.offset = off;
- args.flags = flags;
args.iobref = iobref;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_WRITE];
if (!proc) {
@@ -950,14 +817,15 @@ client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (writev, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
+
int32_t
-client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -969,7 +837,6 @@ client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto out;
args.fd = fd;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FLUSH];
if (!proc) {
@@ -982,7 +849,7 @@ client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOTCONN);
return 0;
}
@@ -991,7 +858,7 @@ out:
int32_t
client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1004,7 +871,6 @@ client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FSYNC];
if (!proc) {
@@ -1017,7 +883,7 @@ client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsync, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
@@ -1025,7 +891,7 @@ out:
int32_t
-client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
+client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1037,7 +903,6 @@ client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
goto out;
args.fd = fd;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FSTAT];
if (!proc) {
@@ -1050,7 +915,7 @@ client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (fstat, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1058,8 +923,7 @@ out:
int32_t
-client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
- dict_t *xdata)
+client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1072,7 +936,6 @@ client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
args.loc = loc;
args.fd = fd;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_OPENDIR];
if (!proc) {
@@ -1085,7 +948,7 @@ client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (opendir, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1093,7 +956,7 @@ out:
int32_t
-client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, dict_t *xdata)
+client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1106,7 +969,6 @@ client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
args.fd = fd;
args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FSYNCDIR];
if (!proc) {
@@ -1119,7 +981,7 @@ client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags, d
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, ENOTCONN);
return 0;
}
@@ -1127,7 +989,7 @@ out:
int32_t
-client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1139,7 +1001,6 @@ client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
args.loc = loc;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_STATFS];
if (!proc) {
@@ -1152,7 +1013,7 @@ client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (statfs, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1211,6 +1072,7 @@ out:
static gf_boolean_t
client_set_remote_options (char *value, xlator_t *this)
{
+ clnt_conf_t *conf = NULL;
char *dup_value = NULL;
char *host = NULL;
char *subvol = NULL;
@@ -1221,6 +1083,8 @@ client_set_remote_options (char *value, xlator_t *this)
int remote_port = 0;
gf_boolean_t ret = _gf_false;
+ conf = this->private;
+
dup_value = gf_strdup (value);
host = strtok_r (dup_value, ":", &tmp);
subvol = strtok_r (NULL, ":", &tmp);
@@ -1269,7 +1133,8 @@ client_set_remote_options (char *value, xlator_t *this)
ret = _gf_true;
out:
- GF_FREE (dup_value);
+ if (dup_value)
+ GF_FREE (dup_value);
return ret;
}
@@ -1277,7 +1142,7 @@ out:
int32_t
client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
- int32_t flags, dict_t *xdata)
+ int32_t flags)
{
int ret = -1;
int op_ret = -1;
@@ -1293,10 +1158,8 @@ client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
GF_ASSERT (value);
gf_log (this->name, GF_LOG_INFO, "client rpc init command");
ret = client_set_remote_options (value, this);
- if (ret) {
- (void) client_destroy_rpc (this);
+ if (ret)
ret = client_init_rpc (this);
- }
if (!ret) {
op_ret = 0;
@@ -1325,9 +1188,8 @@ client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
}
args.loc = loc;
- args.xattr = dict;
+ args.dict = dict;
args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_SETXATTR];
if (!proc) {
@@ -1344,7 +1206,7 @@ client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
}
out:
if (need_unwind)
- STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);
return 0;
}
@@ -1353,7 +1215,7 @@ out:
int32_t
client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- dict_t *dict, int32_t flags, dict_t *xdata)
+ dict_t *dict, int32_t flags)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1364,10 +1226,9 @@ client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
if (!conf || !conf->fops)
goto out;
- args.fd = fd;
- args.xattr = dict;
+ args.fd = fd;
+ args.dict = dict;
args.flags = flags;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FSETXATTR];
if (!proc) {
@@ -1380,7 +1241,7 @@ client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, ENOTCONN);
return 0;
}
@@ -1390,7 +1251,7 @@ out:
int32_t
client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
+ const char *name)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1403,7 +1264,6 @@ client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.name = name;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FGETXATTR];
if (!proc) {
@@ -1416,7 +1276,7 @@ client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1425,7 +1285,7 @@ out:
int32_t
client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1438,7 +1298,6 @@ client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.name = name;
args.loc = loc;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_GETXATTR];
if (!proc) {
@@ -1451,7 +1310,7 @@ client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (getxattr, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1460,7 +1319,7 @@ out:
int32_t
client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1473,8 +1332,7 @@ client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.flags = flags;
- args.xattr = dict;
- args.xdata = xdata;
+ args.dict = dict;
proc = &conf->fops->proctable[GF_FOP_XATTROP];
if (!proc) {
@@ -1487,7 +1345,7 @@ client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (xattrop, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1496,7 +1354,7 @@ out:
int32_t
client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
- gf_xattrop_flags_t flags, dict_t *dict, dict_t *xdata)
+ gf_xattrop_flags_t flags, dict_t *dict)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1509,8 +1367,7 @@ client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.flags = flags;
- args.xattr = dict;
- args.xdata = xdata;
+ args.dict = dict;
proc = &conf->fops->proctable[GF_FOP_FXATTROP];
if (!proc) {
@@ -1523,7 +1380,7 @@ client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1532,7 +1389,7 @@ out:
int32_t
client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- const char *name, dict_t *xdata)
+ const char *name)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1545,7 +1402,6 @@ client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.name = name;
args.loc = loc;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_REMOVEXATTR];
if (!proc) {
@@ -1558,47 +1414,15 @@ client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (removexattr, frame, -1, ENOTCONN);
return 0;
}
-int32_t
-client_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- const char *name, dict_t *xdata)
-{
- int ret = -1;
- clnt_conf_t *conf = NULL;
- rpc_clnt_procedure_t *proc = NULL;
- clnt_args_t args = {0,};
-
- conf = this->private;
- if (!conf || !conf->fops)
- goto out;
-
- args.name = name;
- args.fd = fd;
- args.xdata = xdata;
-
- proc = &conf->fops->proctable[GF_FOP_FREMOVEXATTR];
- if (!proc) {
- gf_log (this->name, GF_LOG_ERROR,
- "rpc procedure not found for %s",
- gf_fop_list[GF_FOP_FREMOVEXATTR]);
- goto out;
- }
- if (proc->fn)
- ret = proc->fn (frame, this, &args);
-out:
- if (ret)
- STACK_UNWIND_STRICT (fremovexattr, frame, -1, ENOTCONN, NULL);
-
- return 0;
-}
int32_t
client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
- struct gf_flock *lock, dict_t *xdata)
+ struct gf_flock *lock)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1612,7 +1436,6 @@ client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
args.fd = fd;
args.cmd = cmd;
args.flock = lock;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_LK];
if (!proc) {
@@ -1625,7 +1448,7 @@ client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (lk, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1633,7 +1456,7 @@ out:
int32_t
client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- loc_t *loc, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ loc_t *loc, int32_t cmd, struct gf_flock *lock)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1648,7 +1471,6 @@ client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
args.cmd = cmd;
args.flock = lock;
args.volume = volume;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_INODELK];
if (!proc) {
@@ -1661,7 +1483,7 @@ client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (inodelk, frame, -1, ENOTCONN);
return 0;
}
@@ -1670,7 +1492,7 @@ out:
int32_t
client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
- fd_t *fd, int32_t cmd, struct gf_flock *lock, dict_t *xdata)
+ fd_t *fd, int32_t cmd, struct gf_flock *lock)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1685,7 +1507,6 @@ client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
args.cmd = cmd;
args.flock = lock;
args.volume = volume;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FINODELK];
if (!proc) {
@@ -1698,7 +1519,7 @@ client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (finodelk, frame, -1, ENOTCONN);
return 0;
}
@@ -1707,7 +1528,7 @@ out:
int32_t
client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
loc_t *loc, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
+ entrylk_type type)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1723,7 +1544,6 @@ client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
args.type = type;
args.volume = volume;
args.cmd_entrylk = cmd;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_ENTRYLK];
if (!proc) {
@@ -1736,7 +1556,7 @@ client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (entrylk, frame, -1, ENOTCONN);
return 0;
}
@@ -1746,7 +1566,7 @@ out:
int32_t
client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
fd_t *fd, const char *basename, entrylk_cmd cmd,
- entrylk_type type, dict_t *xdata)
+ entrylk_type type)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1762,7 +1582,6 @@ client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
args.type = type;
args.volume = volume;
args.cmd_entrylk = cmd;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FENTRYLK];
if (!proc) {
@@ -1775,7 +1594,7 @@ client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN, NULL);
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, ENOTCONN);
return 0;
}
@@ -1783,7 +1602,7 @@ out:
int32_t
client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
- int32_t len, dict_t *xdata)
+ int32_t len)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1797,7 +1616,6 @@ client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
args.fd = fd;
args.offset = offset;
args.len = len;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_RCHECKSUM];
if (!proc) {
@@ -1810,14 +1628,14 @@ client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL, NULL);
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, ENOTCONN, 0, NULL);
return 0;
}
int32_t
client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *xdata)
+ size_t size, off_t off)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1831,7 +1649,6 @@ client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.size = size;
args.offset = off;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_READDIR];
if (!proc) {
@@ -1844,7 +1661,7 @@ client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (readdir, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1852,7 +1669,7 @@ out:
int32_t
client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t off, dict_t *dict)
+ size_t size, off_t off)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1866,7 +1683,6 @@ client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.size = size;
args.offset = off;
- args.xdata = dict;
proc = &conf->fops->proctable[GF_FOP_READDIRP];
if (!proc) {
@@ -1879,7 +1695,7 @@ client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL, NULL);
+ STACK_UNWIND_STRICT (readdirp, frame, -1, ENOTCONN, NULL);
return 0;
}
@@ -1887,7 +1703,7 @@ out:
int32_t
client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1901,7 +1717,6 @@ client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
args.loc = loc;
args.stbuf = stbuf;
args.valid = valid;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_SETATTR];
if (!proc) {
@@ -1914,14 +1729,14 @@ client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (setattr, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
int32_t
client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ struct iatt *stbuf, int32_t valid)
{
int ret = -1;
clnt_conf_t *conf = NULL;
@@ -1935,7 +1750,6 @@ client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
args.fd = fd;
args.stbuf = stbuf;
args.valid = valid;
- args.xdata = xdata;
proc = &conf->fops->proctable[GF_FOP_FSETATTR];
if (!proc) {
@@ -1948,7 +1762,7 @@ client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
ret = proc->fn (frame, this, &args);
out:
if (ret)
- STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL, NULL);
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, ENOTCONN, NULL, NULL);
return 0;
}
@@ -1990,7 +1804,7 @@ out:
}
-int
+ int
client_mark_fd_bad (xlator_t *this)
{
clnt_conf_t *conf = NULL;
@@ -2057,31 +1871,11 @@ client_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event,
conf->last_sent_event = GF_EVENT_CHILD_UP;
}
}
-
- /* Cancel grace timer if set */
- pthread_mutex_lock (&conf->lock);
- {
- conf->grace_timer_needed = _gf_true;
-
- if (conf->grace_timer) {
- gf_log (this->name, GF_LOG_WARNING,
- "Cancelling the grace timer");
-
- gf_timer_call_cancel (this->ctx,
- conf->grace_timer);
-
- conf->grace_timer = NULL;
- }
- }
- pthread_mutex_unlock (&conf->lock);
-
break;
}
case RPC_CLNT_DISCONNECT:
- if (!conf->lk_heal)
- client_mark_fd_bad (this);
- else
- client_register_grace_timer (this, conf);
+
+ client_mark_fd_bad (this);
if (!conf->skip_notify) {
if (conf->connected)
@@ -2127,7 +1921,7 @@ out:
int
notify (xlator_t *this, int32_t event, void *data, ...)
{
- clnt_conf_t *conf = NULL;
+ clnt_conf_t *conf = NULL;
conf = this->private;
if (!conf)
@@ -2141,22 +1935,8 @@ notify (xlator_t *this, int32_t event, void *data, ...)
"on transport");
rpc_clnt_start (conf->rpc);
- break;
}
-
- case GF_EVENT_PARENT_DOWN:
- gf_log (this->name, GF_LOG_INFO,
- "current graph is no longer active, destroying "
- "rpc_client ");
-
- pthread_mutex_lock (&conf->lock);
- {
- conf->parent_down = 1;
- }
- pthread_mutex_unlock (&conf->lock);
-
- rpc_clnt_disable (conf->rpc);
- break;
+ break;
default:
gf_log (this->name, GF_LOG_DEBUG,
@@ -2173,25 +1953,53 @@ notify (xlator_t *this, int32_t event, void *data, ...)
int
build_client_config (xlator_t *this, clnt_conf_t *conf)
{
- int ret = -1;
+ int ret = -1;
if (!conf)
goto out;
- GF_OPTION_INIT ("frame-timeout", conf->rpc_conf.rpc_timeout,
- int32, out);
+ ret = dict_get_int32 (this->options, "frame-timeout",
+ &conf->rpc_conf.rpc_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "setting frame-timeout to %d",
+ conf->rpc_conf.rpc_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting frame-timeout to 30mins");
+ conf->rpc_conf.rpc_timeout = 1800;
+ }
- GF_OPTION_INIT ("remote-port", conf->rpc_conf.remote_port,
- int32, out);
+ ret = dict_get_int32 (this->options, "remote-port",
+ &conf->rpc_conf.remote_port);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "remote-port is %d", conf->rpc_conf.remote_port);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting remote-port to 'auto'");
+ }
- GF_OPTION_INIT ("ping-timeout", conf->opt.ping_timeout,
- int32, out);
+ ret = dict_get_int32 (this->options, "ping-timeout",
+ &conf->opt.ping_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_INFO,
+ "setting ping-timeout to %d", conf->opt.ping_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting ping-timeout to 42");
+ conf->opt.ping_timeout = GF_UNIVERSAL_ANSWER;
+ }
- GF_OPTION_INIT ("remote-subvolume", conf->opt.remote_subvolume,
- path, out);
- if (!conf->opt.remote_subvolume)
+ ret = dict_get_str (this->options, "remote-subvolume",
+ &conf->opt.remote_subvolume);
+ if (ret) {
+ /* This is valid only if 'cluster/pump' is the parent */
gf_log (this->name, GF_LOG_WARNING,
"option 'remote-subvolume' not given");
+ ret = 1;
+ goto out;
+ }
ret = 0;
out:
@@ -2229,9 +2037,6 @@ client_destroy_rpc (xlator_t *this)
goto out;
if (conf->rpc) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&conf->rpc->conn);
-
conf->rpc = rpc_clnt_unref (conf->rpc);
ret = 0;
gf_log (this->name, GF_LOG_DEBUG,
@@ -2240,7 +2045,7 @@ client_destroy_rpc (xlator_t *this)
}
gf_log (this->name, GF_LOG_WARNING,
- "RPC destroy called on already destroyed "
+ "RPC destory called on already destroyed "
"connection");
out:
@@ -2262,7 +2067,7 @@ client_init_rpc (xlator_t *this)
goto out;
}
- conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name, 0);
+ conf->rpc = rpc_clnt_new (this->options, this->ctx, this->name);
if (!conf->rpc) {
gf_log (this->name, GF_LOG_ERROR, "failed to initialize RPC");
goto out;
@@ -2277,8 +2082,7 @@ client_init_rpc (xlator_t *this)
conf->handshake = &clnt_handshake_prog;
conf->dump = &clnt_dump_prog;
- ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog,
- this);
+ ret = rpcclnt_cbk_program_register (conf->rpc, &gluster_cbk_prog);
if (ret) {
gf_log (this->name, GF_LOG_ERROR,
"failed to register callback program");
@@ -2292,41 +2096,32 @@ out:
return ret;
}
-
int
-client_init_grace_timer (xlator_t *this, dict_t *options,
- clnt_conf_t *conf)
+validate_options (xlator_t *this, char **op_errstr)
{
- char *lk_heal = NULL;
- int32_t ret = -1;
- int32_t grace_timeout = -1;
-
- GF_VALIDATE_OR_GOTO ("client", this, out);
- GF_VALIDATE_OR_GOTO (this->name, options, out);
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
-
- conf->lk_heal = _gf_false;
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
- ret = dict_get_str (options, "lk-heal", &lk_heal);
- if (!ret)
- gf_string2boolean (lk_heal, &conf->lk_heal);
-
- gf_log (this->name, GF_LOG_DEBUG, "lk-heal = %s",
- (conf->lk_heal) ? "on" : "off");
-
- ret = dict_get_int32 (options, "grace-timeout", &grace_timeout);
- if (!ret)
- conf->grace_tv.tv_sec = grace_timeout;
- else
- conf->grace_tv.tv_sec = 10;
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
- conf->grace_tv.tv_usec = 0;
+ if (list_empty (&this->volume_options))
+ goto out;
- gf_log (this->name, GF_LOG_DEBUG, "Client grace timeout "
- "value = %"PRIu64, conf->grace_tv.tv_sec);
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
- ret = 0;
out:
+
return ret;
}
@@ -2334,7 +2129,10 @@ int
reconfigure (xlator_t *this, dict_t *options)
{
clnt_conf_t *conf = NULL;
- int ret = -1;
+ int ret = 0;
+ int timeout_ret = 0;
+ int ping_timeout = 0;
+ int frame_timeout = 0;
int subvol_ret = 0;
char *old_remote_subvol = NULL;
char *new_remote_subvol = NULL;
@@ -2343,18 +2141,70 @@ reconfigure (xlator_t *this, dict_t *options)
conf = this->private;
- GF_OPTION_RECONF ("frame-timeout", conf->rpc_conf.rpc_timeout,
- options, int32, out);
+ timeout_ret = dict_get_int32 (options, "frame-timeout",
+ &frame_timeout);
+ if (timeout_ret == 0) {
+ if (frame_timeout < 5 ) {
+ gf_log (this->name, GF_LOG_ERROR, "Reconfiguration"
+ "'option frame-timeout %d failed , Min value"
+ " can be 5, Defaulting to old value (%d)"
+ , frame_timeout, conf->rpc_conf.rpc_timeout);
+ goto out;
+ }
+
+ if (frame_timeout > 3600 ) {
+ gf_log (this->name, GF_LOG_ERROR, "Reconfiguration"
+ "'option frame-timeout %d failed , Max value"
+ "can be 3600, Defaulting to old value (%d)"
+ , frame_timeout, conf->rpc_conf.rpc_timeout);
+ goto out;
+ }
+
- GF_OPTION_RECONF ("ping-timeout", conf->opt.ping_timeout,
- options, int32, out);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Reconfiguring otion frame-timeout to %d",
+ frame_timeout);
+
+ conf->rpc_conf.rpc_timeout = frame_timeout;
+ }
+ else
+ conf->rpc_conf.rpc_timeout = 1800;
+
+ timeout_ret = dict_get_int32 (options, "ping-timeout",
+ &ping_timeout);
+ if (timeout_ret == 0) {
+
+ if (ping_timeout < 5 ) {
+ gf_log (this->name, GF_LOG_WARNING, "Reconfiguration"
+ "'option ping-timeout %d failed , Min value"
+ " can be 5, Defaulting to old value (%d)"
+ , ping_timeout, conf->opt.ping_timeout);
+ goto out;
+ }
+
+ if (ping_timeout > 1013 ) {
+ gf_log (this->name, GF_LOG_WARNING, "Reconfiguration"
+ "'option ping-timeout %d failed , Max value"
+ "can be 1013, Defaulting to old value (%d)"
+ , ping_timeout, conf->opt.ping_timeout);
+ goto out;
+ }
+
+ gf_log (this->name, GF_LOG_DEBUG, "Reconfiguring "
+ "'option ping-timeout' to %d", ping_timeout);
+ conf->opt.ping_timeout = ping_timeout;
+ }
+ else
+ conf->opt.ping_timeout = GF_UNIVERSAL_ANSWER;
subvol_ret = dict_get_str (this->options, "remote-host",
&old_remote_host);
if (subvol_ret == 0) {
+
subvol_ret = dict_get_str (options, "remote-host",
&new_remote_host);
+
if (subvol_ret == 0) {
if (strcmp (old_remote_host, new_remote_host)) {
ret = 1;
@@ -2367,8 +2217,10 @@ reconfigure (xlator_t *this, dict_t *options)
&old_remote_subvol);
if (subvol_ret == 0) {
+
subvol_ret = dict_get_str (options, "remote-subvolume",
&new_remote_subvol);
+
if (subvol_ret == 0) {
if (strcmp (old_remote_subvol, new_remote_subvol)) {
ret = 1;
@@ -2377,23 +2229,18 @@ reconfigure (xlator_t *this, dict_t *options)
}
}
- ret = client_init_grace_timer (this, options, conf);
- if (ret)
- goto out;
-
- ret = 0;
out:
return ret;
}
-
int
init (xlator_t *this)
{
int ret = -1;
clnt_conf_t *conf = NULL;
+ /* */
if (this->children) {
gf_log (this->name, GF_LOG_ERROR,
"FATAL: client protocol translator cannot have any "
@@ -2413,15 +2260,6 @@ init (xlator_t *this)
pthread_mutex_init (&conf->lock, NULL);
INIT_LIST_HEAD (&conf->saved_fds);
- /* Initialize parameters for lock self healing*/
- conf->lk_version = 1;
- conf->grace_timer = NULL;
- conf->grace_timer_needed = _gf_true;
-
- ret = client_init_grace_timer (this, this->options, conf);
- if (ret)
- goto out;
-
LOCK_INIT (&conf->rec_lock);
conf->last_sent_event = -1; /* To start with we don't have any events */
@@ -2443,13 +2281,6 @@ init (xlator_t *this)
goto out;
}
- this->local_pool = mem_pool_new (clnt_local_t, 64);
- if (!this->local_pool) {
- ret = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to create local_t's memory pool");
- goto out;
- }
ret = client_init_rpc (this);
out:
@@ -2468,12 +2299,8 @@ fini (xlator_t *this)
this->private = NULL;
if (conf) {
- if (conf->rpc) {
- /* cleanup the saved-frames before last unref */
- rpc_clnt_connection_cleanup (&conf->rpc->conn);
-
- rpc_clnt_unref (conf->rpc);
- }
+ if (conf->rpc)
+ rpc_clnt_unref (conf->rpc);
/* Saved Fds */
/* TODO: */
@@ -2485,54 +2312,6 @@ fini (xlator_t *this)
return;
}
-static void
-client_fd_lk_ctx_dump (xlator_t *this, fd_lk_ctx_t *lk_ctx, int nth_fd)
-{
- gf_boolean_t use_try_lock = _gf_true;
- int ret = -1;
- int lock_no = 0;
- fd_lk_ctx_t *lk_ctx_ref = NULL;
- fd_lk_ctx_node_t *plock = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
-
- lk_ctx_ref = fd_lk_ctx_try_ref (lk_ctx);
- if (!lk_ctx_ref)
- return;
-
- ret = client_fd_lk_list_empty (lk_ctx_ref, (use_try_lock = _gf_true));
- if (ret != 0)
- return;
-
- ret = TRY_LOCK (&lk_ctx_ref->lock);
- if (ret)
- return;
-
- gf_proc_dump_write ("------","------");
-
- lock_no = 0;
- list_for_each_entry (plock, &lk_ctx_ref->lk_list, next) {
- snprintf (key, sizeof (key), "granted-posix-lock[%d]",
- lock_no++);
- gf_proc_dump_write (key, "owner = %s, cmd = %s "
- "fl_type = %s, fl_start = %"
- PRId64", fl_end = %"PRId64
- ", user_flock: l_type = %s, "
- "l_start = %"PRId64", l_len = %"PRId64,
- lkowner_utoa (&plock->user_flock.l_owner),
- get_lk_cmd (plock->cmd),
- get_lk_type (plock->fl_type),
- plock->fl_start, plock->fl_end,
- get_lk_type (plock->user_flock.l_type),
- plock->user_flock.l_start,
- plock->user_flock.l_len);
- }
- gf_proc_dump_write ("------","------");
-
- UNLOCK (&lk_ctx_ref->lock);
- fd_lk_ctx_unref (lk_ctx_ref);
-
-}
-
int
client_priv_dump (xlator_t *this)
{
@@ -2547,12 +2326,18 @@ client_priv_dump (xlator_t *this)
return -1;
conf = this->private;
- if (!conf)
+ if (!conf) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
return -1;
+ }
ret = pthread_mutex_trylock(&conf->lock);
- if (ret)
+ if (ret) {
+ gf_log(this->name, GF_LOG_WARNING, "Unable to lock client %s"
+ " errno: %d", this->name, errno);
return -1;
+ }
gf_proc_dump_build_key(key_prefix, "xlator.protocol.client",
"%s.priv", this->name);
@@ -2560,19 +2345,25 @@ client_priv_dump (xlator_t *this)
gf_proc_dump_add_section(key_prefix);
list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) {
- sprintf (key, "fd.%d.remote_fd", i);
+ gf_proc_dump_build_key(key, key_prefix,
+ "fd.%d.remote_fd", ++i);
gf_proc_dump_write(key, "%d", tmp->remote_fd);
- client_fd_lk_ctx_dump (this, tmp->lk_ctx, i);
- i++;
}
- gf_proc_dump_write("connecting", "%d", conf->connecting);
+ gf_proc_dump_build_key(key, key_prefix, "connecting");
+ gf_proc_dump_write(key, "%d", conf->connecting);
+ gf_proc_dump_build_key(key, key_prefix, "last_sent");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_sent.tv_sec));
+ gf_proc_dump_build_key(key, key_prefix, "last_received");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_received.tv_sec));
if (conf->rpc) {
- gf_proc_dump_write("total_bytes_read", "%"PRIu64,
+ gf_proc_dump_build_key(key, key_prefix, "total_bytes_read");
+ gf_proc_dump_write(key, "%"PRIu64,
conf->rpc->conn.trans->total_bytes_read);
- gf_proc_dump_write("total_bytes_written", "%"PRIu64,
+ gf_proc_dump_build_key(key, key_prefix, "total_bytes_written");
+ gf_proc_dump_write(key, "%"PRIu64,
conf->rpc->conn.trans->total_bytes_write);
}
pthread_mutex_unlock(&conf->lock);
@@ -2584,13 +2375,26 @@ client_priv_dump (xlator_t *this)
int32_t
client_inodectx_dump (xlator_t *this, inode_t *inode)
{
+ ino_t par = 0;
+ uint64_t gen = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+
if (!inode)
return -1;
if (!this)
return -1;
- /*TODO*/
+ ret = inode_ctx_get2 (inode, this, &par, &gen);
+
+ if (ret != 0)
+ return ret;
+
+ gf_proc_dump_build_key(key, "xlator.protocol.client",
+ "%s.inode.%ld.par",
+ this->name,inode->ino);
+ gf_proc_dump_write(key, "%ld, %ld", par, gen);
return 0;
}
@@ -2626,7 +2430,6 @@ struct xlator_fops fops = {
.fsetxattr = client_fsetxattr,
.fgetxattr = client_fgetxattr,
.removexattr = client_removexattr,
- .fremovexattr = client_fremovexattr,
.opendir = client_opendir,
.readdir = client_readdir,
.readdirp = client_readdirp,
@@ -2671,9 +2474,6 @@ struct volume_options options[] = {
{ .key = {"remote-host"},
.type = GF_OPTION_TYPE_INTERNET_ADDRESS
},
- { .key = {"remote-port"},
- .type = GF_OPTION_TYPE_INT,
- },
{ .key = {"remote-subvolume"},
.type = GF_OPTION_TYPE_ANY
},
@@ -2682,35 +2482,11 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_TIME,
.min = 0,
.max = 86400,
- .default_value = "1800",
- .description = "Time frame after which the (file) operation would be "
- "declared as dead, if the server does not respond for "
- "a particular (file) operation."
},
{ .key = {"ping-timeout"},
.type = GF_OPTION_TYPE_TIME,
.min = 1,
.max = 1013,
- .default_value = "42",
- .description = "Time duration for which the client waits to "
- "check if the server is responsive."
- },
- { .key = {"client-bind-insecure"},
- .type = GF_OPTION_TYPE_BOOL
- },
- { .key = {"lk-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- { .key = {"grace-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .min = 10,
- .max = 1800
- },
- {.key = {"tcp-window-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_MIN_SOCKET_WINDOW_SIZE,
- .max = GF_MAX_SOCKET_WINDOW_SIZE
},
{ .key = {NULL} },
};
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
index 9d8a818aa..40a3d5d3d 100644
--- a/xlators/protocol/client/src/client.h
+++ b/xlators/protocol/client/src/client.h
@@ -1,11 +1,20 @@
/*
- Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- This file is licensed to you under your choice of the GNU Lesser
- General Public License, version 3 or any later version (LGPLv3 or
- later), or the GNU General Public License, version 2 (GPLv2), in all
- cases as published by the Free Software Foundation.
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
*/
#ifndef _CLIENT_H
@@ -20,49 +29,11 @@
#include "client-mem-types.h"
#include "protocol-common.h"
#include "glusterfs3.h"
-#include "fd-lk.h"
/* FIXME: Needs to be defined in a common file */
#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect"
#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
#define CLIENT_DUMP_LOCKS "trusted.glusterfs.clientlk-dump"
-#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
-#define GF_MIN_SOCKET_WINDOW_SIZE (0)
-
-typedef enum {
- GF_LK_HEAL_IN_PROGRESS,
- GF_LK_HEAL_DONE,
-} lk_heal_state_t;
-
-#define CLIENT_GET_REMOTE_FD(conf, fd, remote_fd, op_errno, label) \
- do { \
- clnt_fd_ctx_t *fdctx = NULL; \
- pthread_mutex_lock (&conf->lock); \
- { \
- fdctx = this_fd_get_ctx (fd, THIS); \
- } \
- pthread_mutex_unlock (&conf->lock); \
- if (!fdctx) { \
- remote_fd = -2; \
- } else { \
- remote_fd = fdctx->remote_fd; \
- } \
- if (remote_fd == -1) { \
- gf_log (THIS->name, GF_LOG_WARNING, " (%s) " \
- "remote_fd is -1. EBADFD", \
- uuid_utoa (fd->inode->gfid)); \
- op_errno = EBADFD; \
- goto label; \
- } \
- } while (0);
-
-#define CLIENT_STACK_UNWIND(op, frame, params ...) do { \
- clnt_local_t *__local = frame->local; \
- frame->local = NULL; \
- STACK_UNWIND_STRICT (op, frame, params); \
- client_local_wipe (__local); \
- } while (0)
-
struct clnt_options {
char *remote_subvolume;
@@ -77,6 +48,8 @@ typedef struct clnt_conf {
pthread_mutex_t lock;
int connecting;
int connected;
+ struct timeval last_sent;
+ struct timeval last_received;
rpc_clnt_prog_t *fops;
rpc_clnt_prog_t *mgmt;
@@ -93,22 +66,6 @@ typedef struct clnt_conf {
which was sent earlier */
char portmap_err_logged; /* flag used to prevent
excessive logging */
- char need_different_port; /* flag used to change the
- portmap path in case of
- 'tcp,rdma' on server */
- gf_boolean_t lk_heal;
- uint16_t lk_version; /* this variable is used to distinguish
- client-server transaction while
- performing lock healing */
- struct timeval grace_tv;
- gf_timer_t *grace_timer;
- gf_boolean_t grace_timer_needed; /* The state of this flag will
- be used to decide whether
- a new grace-timer must be
- registered or not. False
- means dont register, true
- means register */
- char parent_down;
} clnt_conf_t;
typedef struct _client_fd_ctx {
@@ -116,13 +73,15 @@ typedef struct _client_fd_ctx {
fd's position in the saved_fds list.
*/
int64_t remote_fd;
+ inode_t *inode;
+ uint64_t ino;
+ uint64_t gen;
char is_dir;
char released;
int32_t flags;
- fd_lk_ctx_t *lk_ctx;
+ int32_t wbflags;
+
pthread_mutex_t mutex;
- lk_heal_state_t lk_heal_state;
- uuid_t gfid;
struct list_head lock_list; /* List of all granted locks on this fd */
} clnt_fd_ctx_t;
@@ -134,7 +93,8 @@ typedef struct _client_posix_lock {
off_t fl_end;
short fl_type;
int32_t cmd; /* the cmd for the lock call */
- gf_lkowner_t owner; /* lock owner from fuse */
+ uint64_t owner; /* lock owner from fuse */
+
struct list_head list; /* reference used to add to the fdctx list of locks */
} client_posix_lock_t;
@@ -144,24 +104,26 @@ typedef struct client_local {
fd_t *fd;
clnt_fd_ctx_t *fdctx;
uint32_t flags;
+ uint32_t wbflags;
struct iobref *iobref;
client_posix_lock_t *client_lock;
- gf_lkowner_t owner;
+ uint64_t owner;
int32_t cmd;
struct list_head lock_list;
pthread_mutex_t mutex;
- char *name;
} clnt_local_t;
typedef struct client_args {
loc_t *loc;
fd_t *fd;
+ dict_t *xattr_req;
const char *linkname;
struct iobref *iobref;
struct iovec *vector;
dict_t *xattr;
struct iatt *stbuf;
+ dict_t *dict;
loc_t *oldloc;
loc_t *newloc;
const char *name;
@@ -175,6 +137,7 @@ typedef struct client_args {
mode_t mode;
dev_t rdev;
int32_t flags;
+ int32_t wbflags;
int32_t count;
int32_t datasync;
entrylk_cmd cmd_entrylk;
@@ -182,9 +145,6 @@ typedef struct client_args {
gf_xattrop_flags_t optype;
int32_t valid;
int32_t len;
-
- mode_t umask;
- dict_t *xdata;
} clnt_args_t;
typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *args);
@@ -198,24 +158,23 @@ int client_local_wipe (clnt_local_t *local);
int client_submit_request (xlator_t *this, void *req,
call_frame_t *frame, rpc_clnt_prog_t *prog,
int procnum, fop_cbk_fn_t cbk,
- struct iobref *iobref,
+ struct iobref *iobref, gfs_serialize_t sfunc,
struct iovec *rsphdr, int rsphdr_count,
struct iovec *rsp_payload, int rsp_count,
- struct iobref *rsp_iobref, xdrproc_t xdrproc);
+ struct iobref *rsp_iobref);
int protocol_client_reopendir (xlator_t *this, clnt_fd_ctx_t *fdctx);
int protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx);
int unserialize_rsp_dirent (struct gfs3_readdir_rsp *rsp, gf_dirent_t *entries);
-int unserialize_rsp_direntp (xlator_t *this, fd_t *fd,
- struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries);
+int unserialize_rsp_direntp (struct gfs3_readdirp_rsp *rsp, gf_dirent_t *entries);
int clnt_readdir_rsp_cleanup (gfs3_readdir_rsp *rsp);
int clnt_readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp);
int client_attempt_lock_recovery (xlator_t *this, clnt_fd_ctx_t *fdctx);
-int32_t delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner);
-int client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock,
- gf_lkowner_t *owner, int32_t cmd);
+int32_t delete_granted_locks_owner (fd_t *fd, uint64_t owner);
+int client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, uint64_t owner,
+ int32_t cmd);
uint64_t decrement_reopen_fd_count (xlator_t *this, clnt_conf_t *conf);
int32_t delete_granted_locks_fd (clnt_fd_ctx_t *fdctx);
int32_t client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd);
@@ -227,13 +186,4 @@ int32_t client_dump_locks (char *name, inode_t *inode,
dict_t *dict);
int client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx);
-uint32_t client_get_lk_ver (clnt_conf_t *conf);
-
-int32_t client_type_to_gf_type (short l_type);
-
-int client_mark_fd_bad (xlator_t *this);
-
-int client_set_lk_version (xlator_t *this);
-
-int client_fd_lk_list_empty (fd_lk_ctx_t *lk_ctx, gf_boolean_t use_try_lock);
#endif /* !_CLIENT_H */
diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c
new file mode 100644
index 000000000..f1f6bd0a4
--- /dev/null
+++ b/xlators/protocol/client/src/client3_1-fops.c
@@ -0,0 +1,5446 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+#include "glusterfs3-xdr.h"
+#include "glusterfs3.h"
+#include "compat-errno.h"
+
+int32_t client3_getspec (call_frame_t *frame, xlator_t *this, void *data);
+void client_start_ping (void *data);
+rpc_clnt_prog_t clnt3_1_fop_prog;
+
+int
+client_submit_vec_request (xlator_t *this, void *req, call_frame_t *frame,
+ rpc_clnt_prog_t *prog, int procnum, fop_cbk_fn_t cbk,
+ struct iovec *payload, int payloadcnt,
+ struct iobref *iobref, gfs_serialize_t sfunc)
+{
+ int ret = 0;
+ clnt_conf_t *conf = NULL;
+ struct iovec iov = {0, };
+ struct iobuf *iobuf = NULL;
+ int count = 0;
+ int start_ping = 0;
+ struct iobref *new_iobref = NULL;
+
+ start_ping = 0;
+
+ conf = this->private;
+
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ goto out;
+ };
+
+ new_iobref = iobref_new ();
+ if (!new_iobref) {
+ goto out;
+ }
+
+ if (iobref != NULL) {
+ ret = iobref_merge (new_iobref, iobref);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot merge iobref passed from caller into "
+ "new_iobref");
+ goto out;
+ }
+ }
+
+ ret = iobref_add (new_iobref, iobuf);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "cannot add iobuf into iobref");
+ goto out;
+ }
+
+ iov.iov_base = iobuf->ptr;
+ iov.iov_len = 128 * GF_UNIT_KB;
+
+ /* Create the xdr payload */
+ if (req && sfunc) {
+ ret = sfunc (iov, req);
+ if (ret == -1) {
+ gf_log_callingfn ("", GF_LOG_WARNING,
+ "XDR function failed");
+ goto out;
+ }
+
+ iov.iov_len = ret;
+ count = 1;
+ }
+ /* Send the msg */
+ ret = rpc_clnt_submit (conf->rpc, prog, procnum, cbk, &iov, count,
+ payload, payloadcnt, new_iobref, frame, NULL, 0,
+ NULL, 0, NULL);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG, "rpc_clnt_submit failed");
+ }
+
+ if (ret == 0) {
+ pthread_mutex_lock (&conf->rpc->conn.lock);
+ {
+ if (!conf->rpc->conn.ping_started) {
+ start_ping = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->rpc->conn.lock);
+ }
+
+ if (start_ping)
+ client_start_ping ((void *) this);
+
+out:
+ if (new_iobref != NULL) {
+ iobref_unref (new_iobref);
+ }
+
+ iobuf_unref (iobuf);
+
+ return 0;
+}
+
+/* CBK */
+
+int
+client3_1_symlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_symlink_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_symlink_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (symlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode, &stbuf,
+ &preparent, &postparent);
+
+ if (local)
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+int
+client3_1_mknod_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_mknod_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_mknod_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (mknod, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent);
+
+ if (local)
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_1_mkdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_mkdir_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_mkdir_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (mkdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent);
+
+ if (local)
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ gfs3_open_rsp rsp = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_open_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_clnt_fdctx_t);
+ if (!fdctx) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOMEM;
+ goto out;
+ }
+
+ fdctx->remote_fd = rsp.fd;
+ fdctx->inode = inode_ref (fd->inode);
+ fdctx->flags = local->flags;
+ fdctx->wbflags = local->wbflags;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+ INIT_LIST_HEAD (&fdctx->lock_list);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->lock);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (open, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+int
+client3_1_stat_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_stat_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt iatt = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_stat_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &iatt);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (stat, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &iatt);
+
+ return 0;
+}
+
+int
+client3_1_readlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_readlink_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt iatt = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_readlink_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.buf, &iatt);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (readlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), rsp.path, &iatt);
+
+ /* This is allocated by the libc while decoding RPC msg */
+ /* Hence no 'GF_FREE', but just 'free' */
+ if (rsp.path)
+ free (rsp.path);
+
+ return 0;
+}
+
+int
+client3_1_unlink_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_unlink_rsp rsp = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_unlink_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (unlink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &preparent,
+ &postparent);
+
+ return 0;
+}
+
+int
+client3_1_rmdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_rmdir_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_rmdir_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (rmdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &preparent,
+ &postparent);
+
+ return 0;
+}
+
+
+int
+client3_1_truncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_truncate_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_truncate_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (truncate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+
+int
+client3_1_statfs_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_statfs_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct statvfs statfs = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_statfs_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_statfs_to_statfs (&rsp.statfs, &statfs);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (statfs, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &statfs);
+
+ return 0;
+}
+
+
+int
+client3_1_writev_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_write_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_truncate_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (writev, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+int
+client3_1_flush_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+
+ frame = myframe;
+ this = THIS;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret >= 0) {
+ /* Delete all saved locks of the owner issuing flush */
+ ret = delete_granted_locks_owner (local->fd, local->owner);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "deleting locks of owner (%llu) returned %d",
+ (long long unsigned) local->owner, ret);
+ }
+
+ frame->local = NULL;
+ if (local)
+ client_local_wipe (local);
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (flush, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_fsync_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_fsync_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_truncate_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fsync, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+int
+client3_1_setxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (setxattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_getxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ char *buf = NULL;
+ int dict_len = 0;
+ int op_ret = 0;
+ int op_errno = EINVAL;
+ gfs3_getxattr_rsp rsp = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_getxattr_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ op_ret = rsp.op_ret;
+ if (-1 != op_ret) {
+ op_ret = -1;
+ dict_len = rsp.dict.dict_len;
+
+ if (dict_len > 0) {
+ dict = dict_new();
+ buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len);
+
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, out);
+ GF_VALIDATE_OR_GOTO (frame->this->name, buf, out);
+
+ ret = dict_unserialize (buf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to unserialize xattr dict");
+ op_errno = EINVAL;
+ goto out;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+ }
+ op_ret = 0;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (op_errno));
+ }
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+
+ if (rsp.dict.dict_val) {
+ /* don't use GF_FREE, this memory was allocated by libc
+ */
+ free (rsp.dict.dict_val);
+ rsp.dict.dict_val = NULL;
+ }
+
+ if (buf)
+ GF_FREE (buf);
+
+ if (dict)
+ dict_unref (dict);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_1_fgetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ char *buf = NULL;
+ dict_t *dict = NULL;
+ gfs3_fgetxattr_rsp rsp = {0,};
+ int ret = 0;
+ int dict_len = 0;
+ int op_ret = 0;
+ int op_errno = EINVAL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_fgetxattr_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ op_ret = rsp.op_ret;
+ if (-1 != op_ret) {
+ op_ret = -1;
+ dict_len = rsp.dict.dict_len;
+
+ if (dict_len > 0) {
+ dict = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, out);
+ buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, buf, out);
+
+ ret = dict_unserialize (buf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to unserialize xattr dict");
+ op_errno = EINVAL;
+ goto out;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+ }
+ op_ret = 0;
+ }
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (op_errno));
+ }
+ STACK_UNWIND_STRICT (fgetxattr, frame, op_ret, op_errno, dict);
+ if (rsp.dict.dict_val) {
+ /* don't use GF_FREE, this memory was allocated by libc
+ */
+ free (rsp.dict.dict_val);
+ rsp.dict.dict_val = NULL;
+ }
+
+ if (buf)
+ GF_FREE (buf);
+
+ if (dict)
+ dict_unref (dict);
+
+ if (local)
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_1_removexattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (removexattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_fsyncdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fsyncdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_access_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (access, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+
+int
+client3_1_ftruncate_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_ftruncate_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_ftruncate_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.prestat, &prestat);
+ gf_stat_to_iatt (&rsp.poststat, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (ftruncate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+int
+client3_1_fstat_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ gfs3_fstat_rsp rsp = {0,};
+ call_frame_t *frame = NULL;
+ struct iatt stat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_fstat_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fstat, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &stat);
+
+ return 0;
+}
+
+
+int
+client3_1_inodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (inodelk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_finodelk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (finodelk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_entrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (entrylk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_fentrylk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fentrylk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_xattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ char *buf = NULL;
+ gfs3_xattrop_rsp rsp = {0,};
+ int ret = 0;
+ int op_ret = 0;
+ int dict_len = 0;
+ int op_errno = EINVAL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_xattrop_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = rsp.op_errno;
+ op_ret = rsp.op_ret;
+ if (-1 != op_ret) {
+ op_ret = -1;
+ dict_len = rsp.dict.dict_len;
+
+ if (dict_len > 0) {
+ dict = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, out);
+
+ buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, buf, out);
+ op_ret = dict_unserialize (buf, dict_len, &dict);
+ if (op_ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to unserialize xattr dict");
+ op_errno = EINVAL;
+ goto out;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+ }
+ op_ret = 0;
+ }
+
+out:
+
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (xattrop, frame, op_ret,
+ gf_error_to_errno (op_errno), dict);
+
+ if (rsp.dict.dict_val) {
+ /* don't use GF_FREE, this memory was allocated by libc
+ */
+ free (rsp.dict.dict_val);
+ rsp.dict.dict_val = NULL;
+ }
+
+ if (buf)
+ GF_FREE (buf);
+
+ if (dict)
+ dict_unref (dict);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client3_1_fxattrop_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ dict_t *dict = NULL;
+ char *buf = NULL;
+ gfs3_fxattrop_rsp rsp = {0,};
+ int ret = 0;
+ int op_ret = 0;
+ int dict_len = 0;
+ int op_errno = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_fxattrop_rsp (*iov, &rsp);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ goto out;
+ }
+ op_errno = rsp.op_errno;
+ op_ret = rsp.op_ret;
+ if (-1 != op_ret) {
+ op_ret = -1;
+ dict_len = rsp.dict.dict_len;
+
+ if (dict_len > 0) {
+ dict = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, out);
+
+ buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, buf, out);
+ op_ret = dict_unserialize (buf, dict_len, &dict);
+ if (op_ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "failed to unserialize xattr dict");
+ op_errno = EINVAL;
+ goto out;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+ }
+ op_ret = 0;
+ }
+
+out:
+
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fxattrop, frame, op_ret,
+ gf_error_to_errno (op_errno), dict);
+
+ if (rsp.dict.dict_val) {
+ /* don't use GF_FREE, this memory was allocated by libc
+ */
+ free (rsp.dict.dict_val);
+ rsp.dict.dict_val = NULL;
+ }
+
+ if (buf)
+ GF_FREE (buf);
+
+ if (dict)
+ dict_unref (dict);
+
+ client_local_wipe (local);
+ return 0;
+}
+
+int
+client3_1_fsetxattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gf_common_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_common_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fsetxattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno));
+
+ return 0;
+}
+
+int
+client3_1_fsetattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_fsetattr_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+ ret = xdr_to_fsetattr_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (fsetattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+
+int
+client3_1_setattr_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_setattr_rsp rsp = {0,};
+ struct iatt prestat = {0,};
+ struct iatt poststat = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_setattr_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.statpre, &prestat);
+ gf_stat_to_iatt (&rsp.statpost, &poststat);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (setattr, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &prestat,
+ &poststat);
+
+ return 0;
+}
+
+int
+client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ inode_t *inode = NULL;
+ struct iatt stbuf = {0, };
+ struct iatt preparent = {0, };
+ struct iatt postparent = {0, };
+ int32_t ret = -1;
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ gfs3_create_rsp rsp = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local; frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_create_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_clnt_fdctx_t);
+ if (!fdctx) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOMEM;
+ goto out;
+ }
+
+ fdctx->remote_fd = rsp.fd;
+ fdctx->inode = inode_ref (inode);
+ fdctx->flags = local->flags;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+ INIT_LIST_HEAD (&fdctx->lock_list);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->lock);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (create, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd, inode,
+ &stbuf, &preparent, &postparent);
+
+ client_local_wipe (local);
+ return 0;
+}
+
+
+int
+client3_1_rchecksum_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_rchecksum_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_rchecksum_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (rchecksum, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ rsp.weak_checksum,
+ (uint8_t *)rsp.strong_checksum.strong_checksum_val);
+
+ if (rsp.strong_checksum.strong_checksum_val) {
+ /* This is allocated by the libc while decoding RPC msg */
+ /* Hence no 'GF_FREE', but just 'free' */
+ free (rsp.strong_checksum.strong_checksum_val);
+ }
+
+ return 0;
+}
+
+int
+client3_1_lk_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ clnt_local_t *local = NULL;
+ struct gf_flock lock = {0,};
+ gfs3_lk_rsp rsp = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_lk_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret >= 0) {
+ gf_proto_flock_to_flock (&rsp.flock, &lock);
+ }
+
+ /* Save the lock to the client lock cache to be able
+ to recover in the case of server reboot.*/
+ /*
+ temporarily
+ if (local->cmd == F_SETLK || local->cmd == F_SETLKW) {
+ ret = client_add_lock_for_recovery (local->fd, &lock,
+ local->owner, local->cmd);
+ if (ret < 0) {
+ rsp.op_ret = -1;
+ rsp.op_errno = -ret;
+ }
+ }
+ */
+
+ frame->local = NULL;
+ client_local_wipe (local);
+
+out:
+ if ((rsp.op_ret == -1) &&
+ (EAGAIN != gf_error_to_errno (rsp.op_errno))) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (lk, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &lock);
+
+ return 0;
+}
+
+int
+client3_1_readdir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_readdir_rsp rsp = {0,};
+ int32_t ret = 0;
+ clnt_local_t *local = NULL;
+ gf_dirent_t entries;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_readdir_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&entries.list);
+ if (rsp.op_ret > 0) {
+ unserialize_rsp_dirent (&rsp, &entries);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (readdir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &entries);
+
+ client_local_wipe (local);
+
+ if (rsp.op_ret != -1) {
+ gf_dirent_free (&entries);
+ }
+
+ clnt_readdir_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+
+int
+client3_1_readdirp_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_readdirp_rsp rsp = {0,};
+ int32_t ret = 0;
+ clnt_local_t *local = NULL;
+ gf_dirent_t entries;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_readdirp_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&entries.list);
+ if (rsp.op_ret > 0) {
+ unserialize_rsp_direntp (&rsp, &entries);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (readdirp, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), &entries);
+
+ client_local_wipe (local);
+
+ if (rsp.op_ret != -1) {
+ gf_dirent_free (&entries);
+ }
+
+ clnt_readdirp_rsp_cleanup (&rsp);
+
+ return 0;
+}
+
+
+int
+client3_1_rename_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_rename_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preoldparent = {0,};
+ struct iatt postoldparent = {0,};
+ struct iatt prenewparent = {0,};
+ struct iatt postnewparent = {0,};
+ int ret = 0;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_rename_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preoldparent, &preoldparent);
+ gf_stat_to_iatt (&rsp.postoldparent, &postoldparent);
+
+ gf_stat_to_iatt (&rsp.prenewparent, &prenewparent);
+ gf_stat_to_iatt (&rsp.postnewparent, &postnewparent);
+ }
+
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (rename, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ &stbuf, &preoldparent, &postoldparent,
+ &prenewparent, &postnewparent);
+
+ return 0;
+}
+
+int
+client3_1_link_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ gfs3_link_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ int ret = 0;
+ clnt_local_t *local = NULL;
+ inode_t *inode = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_link_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp.preparent, &preparent);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (link, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), inode,
+ &stbuf, &preparent, &postparent);
+
+ client_local_wipe (local);
+ return 0;
+}
+
+
+int
+client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+ fd_t *fd = NULL;
+ int ret = 0;
+ gfs3_opendir_rsp rsp = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+
+ frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_opendir_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (-1 != rsp.op_ret) {
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_clnt_fdctx_t);
+ if (!fdctx) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOMEM;
+ goto out;
+ }
+
+ fdctx->remote_fd = rsp.fd;
+ fdctx->inode = inode_ref (fd->inode);
+ fdctx->is_dir = 1;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+ INIT_LIST_HEAD (&fdctx->lock_list);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->lock);
+ }
+
+out:
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (opendir, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), fd);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+int
+client3_1_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ int ret = 0;
+ gfs3_lookup_rsp rsp = {0,};
+ struct iatt stbuf = {0,};
+ struct iatt postparent = {0,};
+ int op_errno = EINVAL;
+ dict_t *xattr = NULL;
+ inode_t *inode = NULL;
+ char *buf = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ frame = myframe;
+ local = frame->local;
+ inode = local->loc.inode;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_lookup_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ op_errno = gf_error_to_errno (rsp.op_errno);
+ gf_stat_to_iatt (&rsp.postparent, &postparent);
+
+ if (rsp.op_ret == -1)
+ goto out;
+
+ rsp.op_ret = -1;
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ if (rsp.dict.dict_len > 0) {
+ xattr = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, xattr, out);
+
+ buf = memdup (rsp.dict.dict_val, rsp.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, buf, out);
+
+ ret = dict_unserialize (buf, rsp.dict.dict_len, &xattr);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "%s (%"PRId64"): failed to "
+ "unserialize dictionary",
+ local->loc.path, inode->ino);
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ xattr->extra_free = buf;
+ buf = NULL;
+ }
+
+ if ((!uuid_is_null (inode->gfid))
+ && (uuid_compare (stbuf.ia_gfid, inode->gfid) != 0)) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "gfid changed for %s", local->loc.path);
+ rsp.op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
+
+ rsp.op_ret = 0;
+
+out:
+ rsp.op_errno = op_errno;
+ frame->local = NULL;
+ if (rsp.op_ret == -1) {
+ /* any error other than ENOENT */
+ if (rsp.op_errno != ENOENT)
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (rsp.op_errno));
+ else
+ gf_log (this->name, GF_LOG_TRACE, "not found on remote node");
+
+ }
+ STACK_UNWIND_STRICT (lookup, frame, rsp.op_ret, rsp.op_errno, inode,
+ &stbuf, xattr, &postparent);
+
+ client_local_wipe (local);
+
+ if (xattr)
+ dict_unref (xattr);
+
+ if (rsp.dict.dict_val) {
+ /* don't use GF_FREE, this memory was allocated by libc
+ */
+ free (rsp.dict.dict_val);
+ rsp.dict.dict_val = NULL;
+ }
+
+ if (buf) {
+ GF_FREE (buf);
+ }
+
+ return 0;
+}
+
+int
+client3_1_readv_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+ struct iobref *iobref = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ struct iatt stat = {0,};
+ gfs3_read_rsp rsp = {0,};
+ int ret = 0, rspcount = 0;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ memset (vector, 0, sizeof (vector));
+
+ frame = myframe;
+ local = frame->local;
+ frame->local = NULL;
+
+ if (-1 == req->rpc_status) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_readv_rsp (*iov, &rsp);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret != -1) {
+ iobref = req->rsp_iobref;
+ gf_stat_to_iatt (&rsp.stat, &stat);
+
+ vector[0].iov_len = rsp.op_ret;
+ if (rsp.op_ret > 0)
+ vector[0].iov_base = req->rsp[1].iov_base;
+ rspcount = 1;
+ }
+out:
+ if (rsp.op_ret == -1) {
+ gf_log (this->name, GF_LOG_INFO, "remote operation failed: %s",
+ strerror (gf_error_to_errno (rsp.op_errno)));
+ }
+ STACK_UNWIND_STRICT (readv, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno), vector, rspcount,
+ &stat, iobref);
+
+ if (local) {
+ client_local_wipe (local);
+ }
+
+ return 0;
+}
+
+int
+client3_1_release_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+int
+client3_1_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+int
+client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx)
+{
+ call_frame_t *fr = NULL;
+ int32_t ret = -1;
+
+ if (!fdctx)
+ goto out;
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_DEBUG, "not a valid fd");
+ goto out;
+ }
+
+ fr = create_frame (this, this->ctx->pool);
+
+ if (fdctx->is_dir) {
+ gfs3_releasedir_req req = {{0,},};
+ req.fd = fdctx->remote_fd;
+ gf_log (this->name, GF_LOG_INFO, "sending releasedir on fd");
+ ret = client_submit_request (this, &req, fr, &clnt3_1_fop_prog,
+ GFS3_OP_RELEASEDIR,
+ client3_1_releasedir_cbk,
+ NULL, xdr_from_releasedir_req,
+ NULL, 0, NULL, 0, NULL);
+ } else {
+ gfs3_release_req req = {{0,},};
+ req.fd = fdctx->remote_fd;
+ gf_log (this->name, GF_LOG_INFO, "sending release on fd");
+ ret = client_submit_request (this, &req, fr, &clnt3_1_fop_prog,
+ GFS3_OP_RELEASE,
+ client3_1_release_cbk, NULL,
+ xdr_from_release_req, NULL, 0,
+ NULL, 0, NULL);
+ }
+
+out:
+ if (!ret && fdctx) {
+ fdctx->remote_fd = -1;
+ inode_unref (fdctx->inode);
+ GF_FREE (fdctx);
+ }
+
+ if (ret && fr)
+ STACK_DESTROY (fr->root);
+
+ return ret;
+}
+
+int32_t
+client3_1_releasedir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_releasedir_req req = {{0,},};
+ int64_t remote_fd = -1;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_del_ctx (args->fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (remote_fd != -1) {
+ req.fd = remote_fd;
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RELEASEDIR,
+ client3_1_releasedir_cbk,
+ NULL, xdr_from_releasedir_req,
+ NULL, 0, NULL, 0, NULL);
+ inode_unref (fdctx->inode);
+ GF_FREE (fdctx);
+ }
+
+unwind:
+ if (ret)
+ STACK_DESTROY (frame->root);
+
+ return 0;
+}
+
+int32_t
+client3_1_release (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ int64_t remote_fd = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_release_req req = {{0,},};
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_del_ctx (args->fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (remote_fd != -1) {
+ req.fd = remote_fd;
+
+ delete_granted_locks_fd (fdctx);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RELEASE,
+ client3_1_release_cbk, NULL,
+ xdr_from_release_req, NULL, 0,
+ NULL, 0, NULL);
+ inode_unref (fdctx->inode);
+ GF_FREE (fdctx);
+ }
+unwind:
+ if (ret)
+ STACK_DESTROY (frame->root);
+
+ return 0;
+}
+
+
+int32_t
+client3_1_lookup (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_lookup_req req = {{0,},};
+ int ret = 0;
+ size_t dict_len = 0;
+ int op_errno = ESTALE;
+ data_t *content = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ int count = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ memset (vector, 0, sizeof (vector));
+
+ conf = this->private;
+ args = data;
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ if (args->loc->parent)
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ else
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+
+ if (args->dict) {
+ content = dict_get (args->dict, GF_CONTENT_KEY);
+ if (content != NULL) {
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len
+ = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+ }
+
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized length of dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ }
+
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ req.dict.dict_len = dict_len;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_LOOKUP, client3_1_lookup_cbk,
+ NULL, xdr_from_lookup_req, rsphdr, count,
+ NULL, 0, local->iobref);
+
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ if (rsp_iobref != NULL) {
+ iobref_unref (rsp_iobref);
+ }
+
+ return 0;
+
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (lookup, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+
+ if (local)
+ client_local_wipe (local);
+
+ if (req.dict.dict_val)
+ GF_FREE (req.dict.dict_val);
+
+ if (rsp_iobref != NULL) {
+ iobref_unref (rsp_iobref);
+ }
+
+ if (rsp_iobuf != NULL) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ return 0;
+}
+
+
+
+int32_t
+client3_1_stat (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_stat_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_STAT, client3_1_stat_cbk, NULL,
+ xdr_from_stat_req, NULL, 0, NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop %s",
+ strerror (op_errno));
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_truncate (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_truncate_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.offset = args->offset;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_TRUNCATE,
+ client3_1_truncate_cbk, NULL,
+ xdr_from_truncate_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (truncate, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_ftruncate (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_ftruncate_req req = {{0,},};
+ int op_errno = EINVAL;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FTRUNCATE,
+ client3_1_ftruncate_cbk, NULL,
+ xdr_from_ftruncate_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (ftruncate, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_access (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_access_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.mask = args->mask;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_ACCESS,
+ client3_1_access_cbk, NULL,
+ xdr_from_access_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (access, frame, -1, op_errno);
+ return 0;
+}
+
+int32_t
+client3_1_readlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_readlink_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.size = args->size;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READLINK,
+ client3_1_readlink_cbk, NULL,
+ xdr_from_readlink_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (readlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+
+int32_t
+client3_1_unlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_unlink_req req = {{0,},};
+ int ret = 0;
+ int op_errno = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_UNLINK,
+ client3_1_unlink_cbk, NULL,
+ xdr_from_unlink_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_rmdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_rmdir_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ req.flags = args->flags;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RMDIR, client3_1_rmdir_cbk, NULL,
+ xdr_from_rmdir_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_symlink (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_symlink_req req = {{0,},};
+ size_t dict_len = 0;
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.linkname = (char *)args->linkname;
+ req.bname = (char *)args->loc->name;
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized length of dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ }
+ req.dict.dict_len = dict_len;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SYMLINK, client3_1_symlink_cbk,
+ NULL, xdr_from_symlink_req, NULL, 0, NULL,
+ 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (symlink, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+
+ if (local)
+ client_local_wipe (local);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+
+int32_t
+client3_1_rename (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_rename_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->oldloc && args->newloc && args->oldloc->parent &&
+ args->newloc->parent))
+ goto unwind;
+
+ memcpy (req.oldgfid, args->oldloc->parent->gfid, 16);
+ memcpy (req.newgfid, args->newloc->parent->gfid, 16);
+
+ req.oldpath = (char *)args->oldloc->path;
+ req.oldbname = (char *)args->oldloc->name;
+ req.newpath = (char *)args->newloc->path;
+ req.newbname = (char *)args->newloc->name;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RENAME, client3_1_rename_cbk, NULL,
+ xdr_from_rename_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_link (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_link_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->oldloc && args->oldloc->inode && args->newloc &&
+ args->newloc->parent))
+ goto unwind;
+
+ memcpy (req.oldgfid, args->oldloc->inode->gfid, 16);
+ memcpy (req.newgfid, args->newloc->parent->gfid, 16);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ loc_copy (&local->loc, args->oldloc);
+ frame->local = local;
+
+ req.oldpath = (char *)args->oldloc->path;
+ req.newpath = (char *)args->newloc->path;
+ req.newbname = (char *)args->newloc->name;
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_LINK, client3_1_link_cbk, NULL,
+ xdr_from_link_req, NULL, 0, NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_mknod (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_mknod_req req = {{0,},};
+ size_t dict_len = 0;
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ req.dev = args->rdev;
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized length of dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ }
+ req.dict.dict_len = dict_len;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_MKNOD, client3_1_mknod_cbk, NULL,
+ xdr_from_mknod_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (mknod, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+
+ if (local)
+ client_local_wipe (local);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+
+int32_t
+client3_1_mkdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_mkdir_req req = {{0,},};
+ size_t dict_len = 0;
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized length of dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ }
+ req.dict.dict_len = dict_len;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_MKDIR, client3_1_mkdir_cbk, NULL,
+ xdr_from_mkdir_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (mkdir, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+
+ if (local)
+ client_local_wipe (local);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+int32_t
+client3_1_create (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_create_req req = {{0,},};
+ size_t dict_len = 0;
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ local->flags = args->flags;
+
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.pargfid, args->loc->parent->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.bname = (char *)args->loc->name;
+ req.mode = args->mode;
+ req.flags = gf_flags_from_flags (args->flags);
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized length of dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ }
+ req.dict.dict_len = dict_len;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_CREATE, client3_1_create_cbk, NULL,
+ xdr_from_create_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (create, frame, -1, op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+ if (local)
+ client_local_wipe (local);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+
+int32_t
+client3_1_open (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_open_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ local->flags = args->flags;
+ local->wbflags = args->wbflags;
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.flags = gf_flags_from_flags (args->flags);
+ req.wbflags = args->wbflags;
+ req.path = (char *)args->loc->path;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPEN, client3_1_open_cbk, NULL,
+ xdr_from_open_req, NULL, 0, NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (open, frame, -1, op_errno, NULL);
+
+ if (local)
+ client_local_wipe (local);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_readv (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ gfs3_read_req req = {{0,},};
+ int ret = 0;
+ struct iovec rsp_vec = {0, };
+ struct iobuf *rsp_iobuf = NULL;
+ struct iobref *rsp_iobref = NULL;
+ clnt_local_t *local = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsp_vec.iov_base = iobuf_ptr (rsp_iobuf);
+ rsp_vec.iov_len = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+
+ rsp_iobuf = NULL;
+
+ if (args->size > rsp_vec.iov_len) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "read-size (%lu) is bigger than iobuf size (%lu)",
+ (unsigned long)args->size,
+ (unsigned long)rsp_vec.iov_len);
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (local == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+ frame->local = local;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READ, client3_1_readv_cbk, NULL,
+ xdr_from_readv_req, NULL, 0, &rsp_vec, 1,
+ local->iobref);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_writev (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_write_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_vec_request (this, &req, frame, conf->fops, GFS3_OP_WRITE,
+ client3_1_writev_cbk,
+ args->vector, args->count,
+ args->iobref, xdr_from_writev_req);
+ if (ret)
+ goto unwind;
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (writev, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_flush (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_flush_req req = {{0,},};
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_local_t *local = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ conf = this->private;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ STACK_UNWIND (frame, -1, ENOMEM);
+ return 0;
+
+ }
+
+ local->fd = fd_ref (args->fd);
+ local->owner = frame->root->lk_owner;
+ frame->local = local;
+
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FLUSH, client3_1_flush_cbk, NULL,
+ xdr_from_flush_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (flush, frame, -1, op_errno);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fsync (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fsync_req req = {{0,},};
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = 0;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.data = args->flags;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSYNC, client3_1_fsync_cbk, NULL,
+ xdr_from_fsync_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fsync, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fstat (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fstat_req req = {{0,},};
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSTAT, client3_1_fstat_cbk, NULL,
+ xdr_from_fstat_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fstat, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_opendir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_opendir_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local->fd = fd_ref (args->fd);
+ loc_copy (&local->loc, args->loc);
+ frame->local = local;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPENDIR, client3_1_opendir_cbk,
+ NULL, xdr_from_opendir_req,
+ NULL, 0, NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ if (frame)
+ frame->local = NULL;
+ STACK_UNWIND_STRICT (opendir, frame, -1, op_errno, NULL);
+ if (local)
+ client_local_wipe (local);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ gfs3_fsyncdir_req req = {{0,},};
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.data = args->flags;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSYNCDIR, client3_1_fsyncdir_cbk,
+ NULL, xdr_from_fsyncdir_req, NULL, 0,
+ NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fsyncdir, frame, -1, op_errno);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_statfs (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_statfs_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!args->loc)
+ goto unwind;
+
+ if (args->loc->inode)
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ else
+ req.gfid[15] = 1;
+
+ req.path = (char *)args->loc->path;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_STATFS, client3_1_statfs_cbk, NULL,
+ xdr_from_statfs_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (statfs, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_setxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_setxattr_req req = {{0,},};
+ int ret = 0;
+ size_t dict_len = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ req.dict.dict_len = dict_len;
+ }
+ req.flags = args->flags;
+ req.path = (char *)args->loc->path;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SETXATTR, client3_1_setxattr_cbk,
+ NULL, xdr_from_setxattr_req, NULL, 0,
+ NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fsetxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_fsetxattr_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+ size_t dict_len = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.flags = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized dict");
+ goto unwind;
+ }
+ req.dict.dict_len = dict_len;
+ }
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSETXATTR, client3_1_fsetxattr_cbk,
+ NULL, xdr_from_fsetxattr_req, NULL, 0,
+ NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, op_errno);
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+}
+
+
+
+
+int32_t
+client3_1_fgetxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_fgetxattr_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+
+ req.namelen = 1; /* Use it as a flag */
+ req.fd = fdctx->remote_fd;
+ req.name = (char *)args->name;
+ if (!req.name) {
+ req.name = "";
+ req.namelen = 0;
+ }
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FGETXATTR,
+ client3_1_fgetxattr_cbk, NULL,
+ xdr_from_fgetxattr_req, rsphdr, count,
+ NULL, 0, local->iobref);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, op_errno, NULL);
+
+ client_local_wipe (local);
+
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ return 0;
+}
+
+
+
+int32_t
+client3_1_getxattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_getxattr_req req = {{0,},};
+ dict_t *dict = NULL;
+ int ret = 0;
+ int32_t op_ret = 0;
+ int op_errno = ESTALE;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data) {
+ op_ret = -1;
+ op_errno = 0;
+ goto unwind;
+ }
+ args = data;
+
+ if (!(args->loc && args->loc->inode)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.namelen = 1; /* Use it as a flag */
+ req.path = (char *)args->loc->path;
+ req.name = (char *)args->name;
+ if (!req.name) {
+ req.name = "";
+ req.namelen = 0;
+ }
+
+ conf = this->private;
+
+ if (args && args->name) {
+ if (is_client_dump_locks_cmd ((char *)args->name)) {
+ dict = dict_new ();
+ ret = client_dump_locks ((char *)args->name,
+ args->loc->inode,
+ dict);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Client dump locks failed");
+ op_ret = -1;
+ op_errno = EINVAL;
+ }
+
+ GF_ASSERT (dict);
+ op_ret = 0;
+ op_errno = 0;
+ goto unwind;
+ }
+ }
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_GETXATTR,
+ client3_1_getxattr_cbk, NULL,
+ xdr_from_getxattr_req, rsphdr, count,
+ NULL, 0, local->iobref);
+ if (ret) {
+ op_ret = -1;
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+ client_local_wipe (local);
+
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict);
+
+ return 0;
+}
+
+
+
+int32_t
+client3_1_xattrop (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_xattrop_req req = {{0,},};
+ int ret = 0;
+ size_t dict_len = 0;
+ int op_errno = ESTALE;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized dict");
+ op_errno = EINVAL;
+ goto unwind;
+ }
+ req.dict.dict_len = dict_len;
+ }
+ req.flags = args->flags;
+ req.path = (char *)args->loc->path;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_XATTROP,
+ client3_1_xattrop_cbk, NULL,
+ xdr_from_xattrop_req, rsphdr, count,
+ NULL, 0, local->iobref);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (xattrop, frame, -1, op_errno, NULL);
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ client_local_wipe (local);
+
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fxattrop (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_fxattrop_req req = {{0,},};
+ int op_errno = ESTALE;
+ int ret = 0;
+ size_t dict_len = 0;
+ int count = 0;
+ clnt_local_t *local = NULL;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.flags = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
+
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+
+ if (args->dict) {
+ ret = dict_allocate_and_serialize (args->dict,
+ &req.dict.dict_val,
+ &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to get serialized dict");
+ goto unwind;
+ }
+ req.dict.dict_len = dict_len;
+ }
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FXATTROP,
+ client3_1_fxattrop_cbk, NULL,
+ xdr_from_fxattrop_req, rsphdr, count,
+ NULL, 0, local->iobref);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+
+ STACK_UNWIND_STRICT (fxattrop, frame, -1, op_errno, NULL);
+
+ if (req.dict.dict_val) {
+ GF_FREE (req.dict.dict_val);
+ }
+
+ client_local_wipe (local);
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ return 0;
+}
+
+
+
+int32_t
+client3_1_removexattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_removexattr_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.name = (char *)args->name;
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_REMOVEXATTR,
+ client3_1_removexattr_cbk, NULL,
+ xdr_from_removexattr_req, NULL, 0, NULL,
+ 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+client3_1_lk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_lk_req req = {{0,},};
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_local_t *local = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ ret = client_cmd_to_gf_cmd (args->cmd, &gf_cmd);
+ if (ret) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ local->owner = frame->root->lk_owner;
+ local->cmd = args->cmd;
+ local->fd = fd_ref (args->fd);
+ frame->local = local;
+
+ req.fd = fdctx->remote_fd;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+
+ ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK,
+ client3_1_lk_cbk, NULL, xdr_from_lk_req,
+ NULL, 0, NULL, 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (lk, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_inodelk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_inodelk_req req = {{0,},};
+ int ret = 0;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ req.path = (char *)args->loc->path;
+ req.volume = (char *)args->volume;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_INODELK,
+ client3_1_inodelk_cbk, NULL,
+ xdr_from_inodelk_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (inodelk, frame, -1, op_errno);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_finodelk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_finodelk_req req = {{0,},};
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (args->cmd == F_SETLK || args->cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (args->cmd == F_SETLKW || args->cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (args->flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ req.volume = (char *)args->volume;
+ req.fd = fdctx->remote_fd;
+ req.cmd = gf_cmd;
+ req.type = gf_type;
+ gf_proto_flock_from_flock (&req.flock, args->flock);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FINODELK,
+ client3_1_finodelk_cbk, NULL,
+ xdr_from_finodelk_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (finodelk, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+client3_1_entrylk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_entrylk_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.cmd = args->cmd_entrylk;
+ req.type = args->type;
+ req.volume = (char *)args->volume;
+ req.name = "";
+ if (args->basename) {
+ req.name = (char *)args->basename;
+ req.namelen = 1;
+ }
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_ENTRYLK,
+ client3_1_entrylk_cbk, NULL,
+ xdr_from_entrylk_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (entrylk, frame, -1, op_errno);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_fentrylk (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_fentrylk_req req = {{0,},};
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.cmd = args->cmd_entrylk;
+ req.type = args->type;
+ req.volume = (char *)args->volume;
+ req.name = "";
+ if (args->basename) {
+ req.name = (char *)args->basename;
+ req.namelen = 1;
+ }
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FENTRYLK,
+ client3_1_fentrylk_cbk, NULL,
+ xdr_from_fentrylk_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fentrylk, frame, -1, op_errno);
+ return 0;
+}
+
+
+int32_t
+client3_1_rchecksum (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_rchecksum_req req = {0,};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.len = args->len;
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_RCHECKSUM,
+ client3_1_rchecksum_cbk, NULL,
+ xdr_from_rchecksum_req, NULL, 0, NULL,
+ 0, NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (rchecksum, frame, -1, op_errno, 0, NULL);
+ return 0;
+}
+
+
+
+int32_t
+client3_1_readdir (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_readdir_req req = {{0,},};
+ gfs3_readdir_rsp rsp = {0, };
+ clnt_local_t *local = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ int readdir_rsp_size = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ readdir_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdir_rsp, &rsp)
+ + args->size;
+
+ if ((readdir_rsp_size + GLUSTERFS_RPC_REPLY_SIZE + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
+ > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len
+ = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READDIR,
+ client3_1_readdir_cbk, NULL,
+ xdr_from_readdir_req, rsphdr, count,
+ NULL, 0, rsp_iobref);
+ rsp_iobref = NULL;
+
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+ client_local_wipe (local);
+
+ if (rsp_iobref != NULL) {
+ iobref_unref (rsp_iobref);
+ }
+
+ if (rsp_iobuf != NULL) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ STACK_UNWIND_STRICT (readdir, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_readdirp (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_args_t *args = NULL;
+ gfs3_readdirp_req req = {{0,},};
+ gfs3_readdirp_rsp rsp = {0,};
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ int op_errno = ESTALE;
+ int ret = 0;
+ int count = 0;
+ int readdirp_rsp_size = 0;
+ struct iobref *rsp_iobref = NULL;
+ struct iobuf *rsp_iobuf = NULL;
+ struct iovec *rsphdr = NULL;
+ struct iovec vector[MAX_IOVEC] = {{0}, };
+ clnt_local_t *local = NULL;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp)
+ + args->size;
+
+ if ((readdirp_rsp_size + GLUSTERFS_RPC_REPLY_SIZE
+ + GLUSTERFS_RDMA_MAX_HEADER_SIZE)
+ > (GLUSTERFS_RDMA_INLINE_THRESHOLD)) {
+ local = GF_CALLOC (1, sizeof (*local),
+ gf_client_mt_clnt_local_t);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ rsp_iobref = iobref_new ();
+ if (rsp_iobref == NULL) {
+ goto unwind;
+ }
+
+ rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (rsp_iobuf == NULL) {
+ goto unwind;
+ }
+
+ iobref_add (rsp_iobref, rsp_iobuf);
+ iobuf_unref (rsp_iobuf);
+ rsphdr = &vector[0];
+ rsphdr->iov_base = iobuf_ptr (rsp_iobuf);
+ rsphdr->iov_len
+ = rsp_iobuf->iobuf_arena->iobuf_pool->page_size;
+ count = 1;
+ rsp_iobuf = NULL;
+ local->iobref = rsp_iobref;
+ rsp_iobref = NULL;
+ }
+
+ req.size = args->size;
+ req.offset = args->offset;
+ req.fd = fdctx->remote_fd;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_READDIRP,
+ client3_1_readdirp_cbk, NULL,
+ xdr_from_readdirp_req, rsphdr, count, NULL,
+ 0, rsp_iobref);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ local = frame->local;
+ frame->local = NULL;
+ client_local_wipe (local);
+
+ if (rsp_iobref) {
+ iobref_unref (rsp_iobref);
+ }
+
+ if (rsp_iobuf) {
+ iobuf_unref (rsp_iobuf);
+ }
+
+ STACK_UNWIND_STRICT (readdirp, frame, -1, op_errno, NULL);
+ return 0;
+}
+
+
+int32_t
+client3_1_setattr (call_frame_t *frame, xlator_t *this,
+ void *data)
+{
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs3_setattr_req req = {{0,},};
+ int ret = 0;
+ int op_errno = ESTALE;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ memcpy (req.gfid, args->loc->inode->gfid, 16);
+ req.path = (char *)args->loc->path;
+ req.valid = args->valid;
+ gf_stat_from_iatt (&req.stbuf, args->stbuf);
+
+ conf = this->private;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_SETATTR,
+ client3_1_setattr_cbk, NULL,
+ xdr_from_setattr_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+int32_t
+client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
+{
+ clnt_args_t *args = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ clnt_conf_t *conf = NULL;
+ gfs3_fsetattr_req req = {0,};
+ int op_errno = ESTALE;
+ int ret = 0;
+
+ if (!frame || !this || !data)
+ goto unwind;
+
+ args = data;
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->lock);
+ {
+ fdctx = this_fd_get_ctx (args->fd, this);
+ }
+ pthread_mutex_unlock (&conf->lock);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_WARNING, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", args->fd->inode->ino);
+ op_errno = EBADFD;
+ goto unwind;
+ }
+
+ req.fd = fdctx->remote_fd;
+ req.valid = args->valid;
+ gf_stat_from_iatt (&req.stbuf, args->stbuf);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_FSETATTR,
+ client3_1_fsetattr_cbk, NULL,
+ xdr_from_fsetattr_req, NULL, 0, NULL, 0,
+ NULL);
+ if (ret) {
+ op_errno = ENOTCONN;
+ goto unwind;
+ }
+
+ return 0;
+unwind:
+ gf_log (this->name, GF_LOG_WARNING, "failed to send the fop: %s", strerror (op_errno));
+ STACK_UNWIND_STRICT (fsetattr, frame, -1, op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+/* Table Specific to FOPS */
+
+
+rpc_clnt_procedure_t clnt3_1_fop_actors[GF_FOP_MAXVALUE] = {
+ [GF_FOP_NULL] = { "NULL", NULL},
+ [GF_FOP_STAT] = { "STAT", client3_1_stat },
+ [GF_FOP_READLINK] = { "READLINK", client3_1_readlink },
+ [GF_FOP_MKNOD] = { "MKNOD", client3_1_mknod },
+ [GF_FOP_MKDIR] = { "MKDIR", client3_1_mkdir },
+ [GF_FOP_UNLINK] = { "UNLINK", client3_1_unlink },
+ [GF_FOP_RMDIR] = { "RMDIR", client3_1_rmdir },
+ [GF_FOP_SYMLINK] = { "SYMLINK", client3_1_symlink },
+ [GF_FOP_RENAME] = { "RENAME", client3_1_rename },
+ [GF_FOP_LINK] = { "LINK", client3_1_link },
+ [GF_FOP_TRUNCATE] = { "TRUNCATE", client3_1_truncate },
+ [GF_FOP_OPEN] = { "OPEN", client3_1_open },
+ [GF_FOP_READ] = { "READ", client3_1_readv },
+ [GF_FOP_WRITE] = { "WRITE", client3_1_writev },
+ [GF_FOP_STATFS] = { "STATFS", client3_1_statfs },
+ [GF_FOP_FLUSH] = { "FLUSH", client3_1_flush },
+ [GF_FOP_FSYNC] = { "FSYNC", client3_1_fsync },
+ [GF_FOP_SETXATTR] = { "SETXATTR", client3_1_setxattr },
+ [GF_FOP_GETXATTR] = { "GETXATTR", client3_1_getxattr },
+ [GF_FOP_REMOVEXATTR] = { "REMOVEXATTR", client3_1_removexattr },
+ [GF_FOP_OPENDIR] = { "OPENDIR", client3_1_opendir },
+ [GF_FOP_FSYNCDIR] = { "FSYNCDIR", client3_1_fsyncdir },
+ [GF_FOP_ACCESS] = { "ACCESS", client3_1_access },
+ [GF_FOP_CREATE] = { "CREATE", client3_1_create },
+ [GF_FOP_FTRUNCATE] = { "FTRUNCATE", client3_1_ftruncate },
+ [GF_FOP_FSTAT] = { "FSTAT", client3_1_fstat },
+ [GF_FOP_LK] = { "LK", client3_1_lk },
+ [GF_FOP_LOOKUP] = { "LOOKUP", client3_1_lookup },
+ [GF_FOP_READDIR] = { "READDIR", client3_1_readdir },
+ [GF_FOP_INODELK] = { "INODELK", client3_1_inodelk },
+ [GF_FOP_FINODELK] = { "FINODELK", client3_1_finodelk },
+ [GF_FOP_ENTRYLK] = { "ENTRYLK", client3_1_entrylk },
+ [GF_FOP_FENTRYLK] = { "FENTRYLK", client3_1_fentrylk },
+ [GF_FOP_XATTROP] = { "XATTROP", client3_1_xattrop },
+ [GF_FOP_FXATTROP] = { "FXATTROP", client3_1_fxattrop },
+ [GF_FOP_FGETXATTR] = { "FGETXATTR", client3_1_fgetxattr },
+ [GF_FOP_FSETXATTR] = { "FSETXATTR", client3_1_fsetxattr },
+ [GF_FOP_RCHECKSUM] = { "RCHECKSUM", client3_1_rchecksum },
+ [GF_FOP_SETATTR] = { "SETATTR", client3_1_setattr },
+ [GF_FOP_FSETATTR] = { "FSETATTR", client3_1_fsetattr },
+ [GF_FOP_READDIRP] = { "READDIRP", client3_1_readdirp },
+ [GF_FOP_RELEASE] = { "RELEASE", client3_1_release },
+ [GF_FOP_RELEASEDIR] = { "RELEASEDIR", client3_1_releasedir },
+ [GF_FOP_GETSPEC] = { "GETSPEC", client3_getspec },
+};
+
+/* Used From RPC-CLNT library to log proper name of procedure based on number */
+char *clnt3_1_fop_names[GFS3_OP_MAXVALUE] = {
+ [GFS3_OP_NULL] = "NULL",
+ [GFS3_OP_STAT] = "STAT",
+ [GFS3_OP_READLINK] = "READLINK",
+ [GFS3_OP_MKNOD] = "MKNOD",
+ [GFS3_OP_MKDIR] = "MKDIR",
+ [GFS3_OP_UNLINK] = "UNLINK",
+ [GFS3_OP_RMDIR] = "RMDIR",
+ [GFS3_OP_SYMLINK] = "SYMLINK",
+ [GFS3_OP_RENAME] = "RENAME",
+ [GFS3_OP_LINK] = "LINK",
+ [GFS3_OP_TRUNCATE] = "TRUNCATE",
+ [GFS3_OP_OPEN] = "OPEN",
+ [GFS3_OP_READ] = "READ",
+ [GFS3_OP_WRITE] = "WRITE",
+ [GFS3_OP_STATFS] = "STATFS",
+ [GFS3_OP_FLUSH] = "FLUSH",
+ [GFS3_OP_FSYNC] = "FSYNC",
+ [GFS3_OP_SETXATTR] = "SETXATTR",
+ [GFS3_OP_GETXATTR] = "GETXATTR",
+ [GFS3_OP_REMOVEXATTR] = "REMOVEXATTR",
+ [GFS3_OP_OPENDIR] = "OPENDIR",
+ [GFS3_OP_FSYNCDIR] = "FSYNCDIR",
+ [GFS3_OP_ACCESS] = "ACCESS",
+ [GFS3_OP_CREATE] = "CREATE",
+ [GFS3_OP_FTRUNCATE] = "FTRUNCATE",
+ [GFS3_OP_FSTAT] = "FSTAT",
+ [GFS3_OP_LK] = "LK",
+ [GFS3_OP_LOOKUP] = "LOOKUP",
+ [GFS3_OP_READDIR] = "READDIR",
+ [GFS3_OP_INODELK] = "INODELK",
+ [GFS3_OP_FINODELK] = "FINODELK",
+ [GFS3_OP_ENTRYLK] = "ENTRYLK",
+ [GFS3_OP_FENTRYLK] = "FENTRYLK",
+ [GFS3_OP_XATTROP] = "XATTROP",
+ [GFS3_OP_FXATTROP] = "FXATTROP",
+ [GFS3_OP_FGETXATTR] = "FGETXATTR",
+ [GFS3_OP_FSETXATTR] = "FSETXATTR",
+ [GFS3_OP_RCHECKSUM] = "RCHECKSUM",
+ [GFS3_OP_SETATTR] = "SETATTR",
+ [GFS3_OP_FSETATTR] = "FSETATTR",
+ [GFS3_OP_READDIRP] = "READDIRP",
+ [GFS3_OP_RELEASE] = "RELEASE",
+ [GFS3_OP_RELEASEDIR] = "RELEASEDIR",
+};
+
+rpc_clnt_prog_t clnt3_1_fop_prog = {
+ .progname = "GlusterFS 3.1",
+ .prognum = GLUSTER3_1_FOP_PROGRAM,
+ .progver = GLUSTER3_1_FOP_VERSION,
+ .numproc = GLUSTER3_1_FOP_PROCCNT,
+ .proctable = clnt3_1_fop_actors,
+ .procnames = clnt3_1_fop_names,
+};
diff --git a/xlators/protocol/legacy/Makefile.am b/xlators/protocol/legacy/Makefile.am
new file mode 100644
index 000000000..991486302
--- /dev/null
+++ b/xlators/protocol/legacy/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = lib transport client server
+
+CLEANFILES =
diff --git a/xlators/protocol/legacy/client/Makefile.am b/xlators/protocol/legacy/client/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/protocol/legacy/client/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/protocol/legacy/client/src/Makefile.am b/xlators/protocol/legacy/client/src/Makefile.am
new file mode 100644
index 000000000..2ae64ebd0
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/Makefile.am
@@ -0,0 +1,21 @@
+
+xlator_LTLIBRARIES = client-old.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/protocol
+
+client_old_la_LDFLAGS = -module -avoidversion
+
+client_old_la_SOURCES = client-protocol.c saved-frames.c
+
+client_old_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la
+
+noinst_HEADERS = client-protocol.h saved-frames.h client-mem-types.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
+ -I$(top_srcdir)/xlators/protocol/legacy/lib/src
+
+CLEANFILES =
+
+install-data-hook:
+ ln -sf client-old.so $(DESTDIR)$(xlatordir)/client.so
diff --git a/xlators/protocol/legacy/client/src/client-mem-types.h b/xlators/protocol/legacy/client/src/client-mem-types.h
new file mode 100644
index 000000000..ae889939f
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/client-mem-types.h
@@ -0,0 +1,43 @@
+
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __CLIENT_MEM_TYPES_H__
+#define __CLIENT_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_client_mem_types_ {
+ gf_client_mt_dir_entry_t = gf_common_mt_end + 1,
+ gf_client_mt_volfile_ctx,
+ gf_client_mt_client_state_t,
+ gf_client_mt_client_conf_t,
+ gf_client_mt_locker,
+ gf_client_mt_lock_table,
+ gf_client_mt_char,
+ gf_client_mt_client_connection_t,
+ gf_client_mt_client_fd_ctx_t,
+ gf_client_mt_client_local_t,
+ gf_client_mt_saved_frames,
+ gf_client_mt_saved_frame,
+ gf_client_mt_end
+};
+#endif
+
diff --git a/xlators/protocol/legacy/client/src/client-protocol.c b/xlators/protocol/legacy/client/src/client-protocol.c
new file mode 100644
index 000000000..6a5b14c65
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/client-protocol.c
@@ -0,0 +1,6683 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+#include <inttypes.h>
+
+
+#include "glusterfs.h"
+#include "client-protocol.h"
+#include "compat.h"
+#include "dict.h"
+#include "protocol.h"
+#include "transport.h"
+#include "xlator.h"
+#include "logging.h"
+#include "timer.h"
+#include "defaults.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "statedump.h"
+#include "client-mem-types.h"
+
+#include <sys/resource.h>
+#include <inttypes.h>
+
+/* for default_*_cbk functions */
+#include "defaults.c"
+#include "saved-frames.h"
+#include "common-utils.h"
+
+int protocol_client_cleanup (transport_t *trans);
+int protocol_client_interpret (xlator_t *this, transport_t *trans,
+ char *hdr_p, size_t hdrlen,
+ struct iobuf *iobuf);
+int
+protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans,
+ int type, int op,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iovec *vector, int count,
+ struct iobref *iobref);
+
+int
+protocol_client_post_handshake (call_frame_t *frame, xlator_t *this);
+
+static gf_op_t gf_fops[GF_PROTO_FOP_MAXVALUE];
+static gf_op_t gf_mops[GF_MOP_MAXVALUE];
+static gf_op_t gf_cbks[GF_CBK_MAXVALUE];
+
+
+transport_t *
+client_channel (xlator_t *this, int id)
+{
+ transport_t *trans = NULL;
+ client_conf_t *conf = NULL;
+ int i = 0;
+ struct client_connection *conn = NULL;
+
+ conf = this->private;
+
+ trans = conf->transport[id];
+ conn = trans->xl_private;
+
+ if (conn->connected == 1)
+ goto ret;
+
+ for (i = 0; i < CHANNEL_MAX; i++) {
+ trans = conf->transport[i];
+ conn = trans->xl_private;
+ if (conn->connected == 1)
+ break;
+ }
+
+ret:
+ return trans;
+}
+
+
+client_fd_ctx_t *
+this_fd_del_ctx (fd_t *file, xlator_t *this)
+{
+ int dict_ret = -1;
+ uint64_t ctxaddr = 0;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ dict_ret = fd_ctx_del (file, this, &ctxaddr);
+
+ if (dict_ret < 0) {
+ ctxaddr = 0;
+ }
+
+out:
+ return (client_fd_ctx_t *)(unsigned long)ctxaddr;
+}
+
+
+client_fd_ctx_t *
+this_fd_get_ctx (fd_t *file, xlator_t *this)
+{
+ int dict_ret = -1;
+ uint64_t ctxaddr = 0;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ dict_ret = fd_ctx_get (file, this, &ctxaddr);
+
+ if (dict_ret < 0) {
+ ctxaddr = 0;
+ }
+
+out:
+ return (client_fd_ctx_t *)(unsigned long)ctxaddr;
+}
+
+
+static void
+this_fd_set_ctx (fd_t *file, xlator_t *this, loc_t *loc, client_fd_ctx_t *ctx)
+{
+ uint64_t oldaddr = 0;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, file, out);
+
+ ret = fd_ctx_get (file, this, &oldaddr);
+ if (ret >= 0) {
+ if (loc)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): trying duplicate remote fd set. ",
+ loc->path, loc->inode->ino);
+ else
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%p: trying duplicate remote fd set. ",
+ file);
+ }
+
+ ret = fd_ctx_set (file, this, (uint64_t)(unsigned long)ctx);
+ if (ret < 0) {
+ if (loc)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): failed to set remote fd",
+ loc->path, loc->inode->ino);
+ else
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%p: failed to set remote fd",
+ file);
+ }
+out:
+ return;
+}
+
+
+static int
+client_local_wipe (client_local_t *local)
+{
+ if (local) {
+ loc_wipe (&local->loc);
+
+ if (local->fd)
+ fd_unref (local->fd);
+
+ GF_FREE (local);
+ }
+
+ return 0;
+}
+
+/*
+ * lookup_frame - lookup call frame corresponding to a given callid
+ * @trans: transport object
+ * @callid: call id of the frame
+ *
+ * not for external reference
+ */
+
+static call_frame_t *
+lookup_frame (transport_t *trans, int32_t op, int8_t type, int64_t callid)
+{
+ client_connection_t *conn = NULL;
+ call_frame_t *frame = NULL;
+
+ conn = trans->xl_private;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ frame = saved_frames_get (conn->saved_frames,
+ op, type, callid);
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ return frame;
+}
+
+
+static void
+call_bail (void *data)
+{
+ client_connection_t *conn = NULL;
+ struct timeval current;
+ transport_t *trans = NULL;
+ struct list_head list;
+ struct saved_frame *saved_frame = NULL;
+ struct saved_frame *trav = NULL;
+ struct saved_frame *tmp = NULL;
+ call_frame_t *frame = NULL;
+ gf_hdr_common_t hdr = {0, };
+ char **gf_op_list = NULL;
+ gf_op_t *gf_ops = NULL;
+ struct tm frame_sent_tm;
+ char frame_sent[32] = {0,};
+ struct timeval timeout = {0,};
+ gf_timer_cbk_t timer_cbk = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", data, out);
+ trans = data;
+
+ conn = trans->xl_private;
+
+ gettimeofday (&current, NULL);
+ INIT_LIST_HEAD (&list);
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ /* Chaining to get call-always functionality from
+ call-once timer */
+ if (conn->timer) {
+ timer_cbk = conn->timer->callbk;
+
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ gf_timer_call_cancel (trans->xl->ctx, conn->timer);
+ conn->timer = gf_timer_call_after (trans->xl->ctx,
+ timeout,
+ timer_cbk,
+ trans);
+ if (conn->timer == NULL) {
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "Cannot create bailout timer");
+ }
+ }
+
+ do {
+ saved_frame =
+ saved_frames_get_timedout (conn->saved_frames,
+ GF_OP_TYPE_MOP_REQUEST,
+ conn->frame_timeout,
+ &current);
+ if (saved_frame)
+ list_add (&saved_frame->list, &list);
+
+ } while (saved_frame);
+
+ do {
+ saved_frame =
+ saved_frames_get_timedout (conn->saved_frames,
+ GF_OP_TYPE_FOP_REQUEST,
+ conn->frame_timeout,
+ &current);
+ if (saved_frame)
+ list_add (&saved_frame->list, &list);
+ } while (saved_frame);
+
+ do {
+ saved_frame =
+ saved_frames_get_timedout (conn->saved_frames,
+ GF_OP_TYPE_CBK_REQUEST,
+ conn->frame_timeout,
+ &current);
+ if (saved_frame)
+ list_add (&saved_frame->list, &list);
+ } while (saved_frame);
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ hdr.rsp.op_ret = hton32 (-1);
+ hdr.rsp.op_errno = hton32 (ENOTCONN);
+
+ list_for_each_entry_safe (trav, tmp, &list, list) {
+ switch (trav->type)
+ {
+ case GF_OP_TYPE_FOP_REQUEST:
+ gf_ops = gf_fops;
+ gf_op_list = gf_fop_list;
+ break;
+ case GF_OP_TYPE_MOP_REQUEST:
+ gf_ops = gf_mops;
+ gf_op_list = gf_mop_list;
+ break;
+ case GF_OP_TYPE_CBK_REQUEST:
+ gf_ops = gf_cbks;
+ gf_op_list = gf_cbk_list;
+ break;
+ default:
+ goto out;
+ }
+
+ localtime_r (&trav->saved_at.tv_sec, &frame_sent_tm);
+ strftime (frame_sent, 32, "%Y-%m-%d %H:%M:%S", &frame_sent_tm);
+
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "bailing out frame %s(%d) "
+ "frame sent = %s. frame-timeout = %d",
+ gf_op_list[trav->op], trav->op,
+ frame_sent, conn->frame_timeout);
+
+ hdr.type = hton32 (trav->type);
+ hdr.op = hton32 (trav->op);
+
+ frame = trav->frame;
+
+ gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL);
+
+ list_del_init (&trav->list);
+ GF_FREE (trav);
+ }
+out:
+ return;
+}
+
+
+void
+save_frame (transport_t *trans, call_frame_t *frame,
+ int32_t op, int8_t type, uint64_t callid)
+{
+ client_connection_t *conn = NULL;
+ struct timeval timeout = {0, };
+
+
+ conn = trans->xl_private;
+
+ saved_frames_put (conn->saved_frames, frame, op, type, callid);
+
+ if (conn->timer == NULL && conn->frame_timeout) {
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+ conn->timer = gf_timer_call_after (trans->xl->ctx, timeout,
+ call_bail, (void *) trans);
+ }
+}
+
+
+
+void
+client_ping_timer_expired (void *data)
+{
+ xlator_t *this = NULL;
+ transport_t *trans = NULL;
+ client_conf_t *conf = NULL;
+ client_connection_t *conn = NULL;
+ int disconnect = 0;
+ int transport_activity = 0;
+ struct timeval timeout = {0, };
+ struct timeval current = {0, };
+
+ trans = data;
+ this = trans->xl;
+ conf = this->private;
+ conn = trans->xl_private;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->ping_timer)
+ gf_timer_call_cancel (trans->xl->ctx,
+ conn->ping_timer);
+ gettimeofday (&current, NULL);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ if (((current.tv_sec - conf->last_received.tv_sec) <
+ conn->ping_timeout)
+ || ((current.tv_sec - conf->last_sent.tv_sec) <
+ conn->ping_timeout)) {
+ transport_activity = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (transport_activity) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "ping timer expired but transport activity "
+ "detected - not bailing transport");
+ conn->transport_activity = 0;
+ timeout.tv_sec = conn->ping_timeout;
+ timeout.tv_usec = 0;
+
+ conn->ping_timer =
+ gf_timer_call_after (trans->xl->ctx, timeout,
+ client_ping_timer_expired,
+ (void *) trans);
+ if (conn->ping_timer == NULL)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unable to setup timer");
+
+ } else {
+ conn->ping_started = 0;
+ conn->ping_timer = NULL;
+ disconnect = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+ if (disconnect) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Server %s has not responded in the last %d "
+ "seconds, disconnecting.",
+ conf->transport[0]->peerinfo.identifier,
+ conn->ping_timeout);
+
+ transport_disconnect (conf->transport[0]);
+ transport_disconnect (conf->transport[1]);
+ }
+}
+
+
+void
+client_start_ping (void *data)
+{
+ xlator_t *this = NULL;
+ transport_t *trans = NULL;
+ client_conf_t *conf = NULL;
+ client_connection_t *conn = NULL;
+ int32_t ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ struct timeval timeout = {0, };
+ call_frame_t *dummy_frame = NULL;
+ size_t hdrlen = -1;
+ gf_mop_ping_req_t *req = NULL;
+ int frame_count = 0;
+
+
+ trans = data;
+ this = trans->xl;
+ conf = this->private;
+ conn = trans->xl_private;
+
+ if (!conn->ping_timeout)
+ return;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->ping_timer)
+ gf_timer_call_cancel (trans->xl->ctx, conn->ping_timer);
+
+ conn->ping_timer = NULL;
+ conn->ping_started = 0;
+
+ if (conn->saved_frames)
+ /* treat the case where conn->saved_frames is NULL
+ as no pending frames */
+ frame_count = conn->saved_frames->count;
+
+ if ((frame_count == 0) || !conn->connected) {
+ /* using goto looked ugly here,
+ * hence getting out this way */
+ /* unlock */
+ pthread_mutex_unlock (&conn->lock);
+ return;
+ }
+
+ if (frame_count < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "saved_frames->count is %"PRId64,
+ conn->saved_frames->count);
+ conn->saved_frames->count = 0;
+ }
+
+ timeout.tv_sec = conn->ping_timeout;
+ timeout.tv_usec = 0;
+
+ conn->ping_timer =
+ gf_timer_call_after (trans->xl->ctx, timeout,
+ client_ping_timer_expired,
+ (void *) trans);
+
+ if (conn->ping_timer == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "unable to setup timer");
+ } else {
+ conn->ping_started = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ if (!hdr)
+ goto err;
+
+ dummy_frame = create_frame (this, this->ctx->pool);
+
+ if (!dummy_frame)
+ goto err;
+
+ dummy_frame->local = trans;
+
+ ret = protocol_client_xfer (dummy_frame, this, trans,
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_PING,
+ hdr, hdrlen, NULL, 0, NULL);
+ return;
+err:
+ if (hdr)
+ GF_FREE (hdr);
+
+ if (dummy_frame)
+ STACK_DESTROY (dummy_frame->root);
+
+ return;
+}
+
+
+int
+client_ping_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ xlator_t *this = NULL;
+ transport_t *trans = NULL;
+ client_connection_t *conn = NULL;
+ struct timeval timeout = {0, };
+ int op_ret = 0;
+
+ trans = frame->local; frame->local = NULL;
+ this = trans->xl;
+ conn = trans->xl_private;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+
+ if (op_ret == -1) {
+ /* timer expired and transport bailed out */
+ gf_log (this->name, GF_LOG_DEBUG, "timer must have expired");
+ goto out;
+ }
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ timeout.tv_sec = conn->ping_timeout;
+ timeout.tv_usec = 0;
+
+ gf_timer_call_cancel (trans->xl->ctx,
+ conn->ping_timer);
+
+ conn->ping_timer =
+ gf_timer_call_after (trans->xl->ctx, timeout,
+ client_start_ping, (void *)trans);
+ if (conn->ping_timer == NULL)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "gf_timer_call_after() returned NULL");
+ }
+ pthread_mutex_unlock (&conn->lock);
+out:
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+int
+client_encode_groups (call_frame_t *frame, gf_hdr_common_t *hdr)
+{
+ int i = 0;
+ if ((!frame) || (!hdr))
+ return -1;
+
+ hdr->req.ngrps = hton32 (frame->root->ngrps);
+ if (frame->root->ngrps == 0)
+ return 0;
+
+ for (; i < frame->root->ngrps; ++i)
+ hdr->req.groups[i] = hton32 (frame->root->groups[i]);
+
+ return 0;
+}
+
+
+int
+protocol_client_xfer (call_frame_t *frame, xlator_t *this, transport_t *trans,
+ int type, int op,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iovec *vector, int count,
+ struct iobref *iobref)
+{
+ client_conf_t *conf = NULL;
+ client_connection_t *conn = NULL;
+ uint64_t callid = 0;
+ int32_t ret = -1;
+ int start_ping = 0;
+ gf_hdr_common_t rsphdr = {0, };
+
+ conf = this->private;
+
+ if (!trans) {
+ /* default to bulk op since it is 'safer' */
+ trans = conf->transport[CHANNEL_BULK];
+ }
+ conn = trans->xl_private;
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ callid = ++conn->callid;
+
+ hdr->callid = hton64 (callid);
+ hdr->op = hton32 (op);
+ hdr->type = hton32 (type);
+
+ if (frame) {
+ hdr->req.uid = hton32 (frame->root->uid);
+ hdr->req.gid = hton32 (frame->root->gid);
+ hdr->req.pid = hton32 (frame->root->pid);
+ hdr->req.lk_owner = hton64 (frame->root->lk_owner);
+ client_encode_groups (frame, hdr);
+ }
+
+ if (conn->connected == 0)
+ transport_connect (trans);
+
+ ret = -1;
+
+ if (conn->connected ||
+ ((type == GF_OP_TYPE_MOP_REQUEST) &&
+ (op == GF_MOP_SETVOLUME))) {
+ ret = transport_submit (trans, (char *)hdr, hdrlen,
+ vector, count, iobref);
+ }
+
+ if ((ret >= 0) && frame) {
+ pthread_mutex_lock (&conf->mutex);
+ {
+ gettimeofday (&conf->last_sent, NULL);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ save_frame (trans, frame, op, type, callid);
+ }
+
+ if (!conn->ping_started && (ret >= 0)) {
+ start_ping = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (start_ping)
+ client_start_ping ((void *) trans);
+
+ if (frame && (ret < 0)) {
+ rsphdr.op = op;
+ rsphdr.rsp.op_ret = hton32 (-1);
+ rsphdr.rsp.op_errno = hton32 (ENOTCONN);
+
+ if (type == GF_OP_TYPE_FOP_REQUEST) {
+ rsphdr.type = GF_OP_TYPE_FOP_REPLY;
+ gf_fops[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
+ } else if (type == GF_OP_TYPE_MOP_REQUEST) {
+ rsphdr.type = GF_OP_TYPE_MOP_REPLY;
+ gf_mops[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
+ } else {
+ rsphdr.type = GF_OP_TYPE_CBK_REPLY;
+ gf_cbks[op] (frame, &rsphdr, sizeof (rsphdr), NULL);
+ }
+
+ GF_FREE (hdr);
+ }
+
+ return ret;
+}
+
+
+
+/**
+ * client_create - create function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @path: complete path to file
+ * @flags: create flags
+ * @mode: create mode
+ *
+ * external reference through client_protocol_xlator->fops->create
+ */
+
+int
+client_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, fd_t *fd, dict_t *params)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_create_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ int32_t ret = -1;
+ ino_t par = 0;
+ uint64_t gen = 0;
+ client_local_t *local = NULL;
+
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ local->fd = fd_ref (fd);
+ loc_copy (&local->loc, loc);
+ local->flags = flags;
+
+ frame->local = local;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): failed to get remote inode "
+ "number for parent inode",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen);
+ hdr = gf_hdr_new (req, pathlen + baselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->flags = hton32 (gf_flags_from_flags (flags));
+ req->mode = hton32 (mode);
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_CREATE,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, fd, NULL, NULL);
+ return 0;
+
+}
+
+/**
+ * client_open - open function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location of file
+ * @flags: open flags
+ * @mode: open modes
+ *
+ * external reference through client_protocol_xlator->fops->open
+ */
+
+int
+client_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd, int32_t wbflags)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ size_t hdrlen = 0;
+ gf_fop_open_req_t *req = NULL;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ local->fd = fd_ref (fd);
+ loc_copy (&local->loc, loc);
+ local->flags = flags;
+ local->wbflags = wbflags;
+
+ frame->local = local;
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPEN %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->flags = hton32 (gf_flags_from_flags (flags));
+ req->wbflags = hton32 (wbflags);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPEN,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, fd);
+ return 0;
+
+}
+
+
+/**
+ * client_stat - stat function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ *
+ * external reference through client_protocol_xlator->fops->stat
+ */
+
+int
+client_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_stat_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int32_t ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ ino_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "STAT %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_STAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_readlink - readlink function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ * @size:
+ *
+ * external reference through client_protocol_xlator->fops->readlink
+ */
+int
+client_readlink (call_frame_t *frame, xlator_t *this, loc_t *loc, size_t size)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readlink_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READLINK %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->size = hton32 (size);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND_STRICT (readlink, frame, -1, EINVAL,
+ NULL, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_mknod - mknod function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @path: pathname of node
+ * @mode:
+ * @dev:
+ *
+ * external reference through client_protocol_xlator->fops->mknod
+ */
+int
+client_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t dev, dict_t *params)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_mknod_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+
+ frame->local = local;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): failed to get remote inode "
+ "number for parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen);
+ hdr = gf_hdr_new (req, pathlen + baselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ req->mode = hton32 (mode);
+ req->dev = hton64 (dev);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_MKNOD,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_mkdir - mkdir function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @path: pathname of directory
+ * @mode:
+ *
+ * external reference through client_protocol_xlator->fops->mkdir
+ */
+int
+client_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dict_t *params)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_mkdir_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+
+ frame->local = local;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64"/%s (%s): failed to get remote inode "
+ "number for parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen);
+ hdr = gf_hdr_new (req, pathlen + baselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ req->mode = hton32 (mode);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_MKDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL);
+ return 0;
+
+}
+
+/**
+ * client_unlink - unlink function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location of file
+ *
+ * external reference through client_protocol_xlator->fops->unlink
+ */
+
+int
+client_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_unlink_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "UNLINK %"PRId64"/%s (%s): failed to get remote inode "
+ "number for parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen);
+ hdr = gf_hdr_new (req, pathlen + baselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_UNLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+/**
+ * client_rmdir - rmdir function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ *
+ * external reference through client_protocol_xlator->fops->rmdir
+ */
+
+int
+client_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rmdir_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RMDIR %"PRId64"/%s (%s): failed to get remote inode "
+ "number for parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen);
+ hdr = gf_hdr_new (req, pathlen + baselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RMDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+
+/**
+ * client_symlink - symlink function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @oldpath: pathname of target
+ * @newpath: pathname of symlink
+ *
+ * external reference through client_protocol_xlator->fops->symlink
+ */
+
+int
+client_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, dict_t *params)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_symlink_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t pathlen = 0;
+ size_t newlen = 0;
+ size_t baselen = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+
+ frame->local = local;
+
+ pathlen = STRLEN_0 (loc->path);
+ baselen = STRLEN_0 (loc->name);
+ newlen = STRLEN_0 (linkname);
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SYMLINK %"PRId64"/%s (%s): failed to get remote inode"
+ " number parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen + newlen);
+ hdr = gf_hdr_new (req, pathlen + baselen + newlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->par = hton64 (par);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+ strcpy (req->bname + pathlen, loc->name);
+ strcpy (req->linkname + pathlen + baselen, linkname);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SYMLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, loc->inode, NULL);
+ return 0;
+
+}
+
+/**
+ * client_rename - rename function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @oldloc: location of old pathname
+ * @newloc: location of new pathname
+ *
+ * external reference through client_protocol_xlator->fops->rename
+ */
+
+int
+client_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
+ loc_t *newloc)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rename_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t oldpathlen = 0;
+ size_t oldbaselen = 0;
+ size_t newpathlen = 0;
+ size_t newbaselen = 0;
+ ino_t oldpar = 0;
+ uint64_t oldgen = 0;
+ ino_t newpar = 0;
+ uint64_t newgen = 0;
+
+ oldpathlen = STRLEN_0 (oldloc->path);
+ oldbaselen = STRLEN_0 (oldloc->name);
+ newpathlen = STRLEN_0 (newloc->path);
+ newbaselen = STRLEN_0 (newloc->name);
+ ret = inode_ctx_get2 (oldloc->parent, this, &oldpar, &oldgen);
+ if (oldloc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RENAME %"PRId64"/%s (%s): failed to get remote inode "
+ "number for source parent",
+ oldloc->parent->ino, oldloc->name, oldloc->path);
+ goto unwind;
+ }
+
+ ret = inode_ctx_get2 (newloc->parent, this, &newpar, &newgen);
+ if (newloc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): failed to get remote inode "
+ "number for destination parent",
+ newloc->parent->ino, newloc->name, newloc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, (oldpathlen + oldbaselen +
+ newpathlen + newbaselen));
+ hdr = gf_hdr_new (req, (oldpathlen + oldbaselen +
+ newpathlen + newbaselen));
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->oldpar = hton64 (oldpar);
+ req->oldgen = hton64 (oldgen);
+ req->newpar = hton64 (newpar);
+ req->newgen = hton64 (newgen);
+
+ strcpy (req->oldpath, oldloc->path);
+ strcpy (req->oldbname + oldpathlen, oldloc->name);
+ strcpy (req->newpath + oldpathlen + oldbaselen, newloc->path);
+ strcpy (req->newbname + oldpathlen + oldbaselen + newpathlen,
+ newloc->name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RENAME,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+/**
+ * client_link - link function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @oldloc: location of old pathname
+ * @newpath: new pathname
+ *
+ * external reference through client_protocol_xlator->fops->link
+ */
+
+int
+client_link (call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_link_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t oldpathlen = 0;
+ size_t newpathlen = 0;
+ size_t newbaselen = 0;
+ ino_t oldino = 0;
+ uint64_t oldgen = 0;
+ ino_t newpar = 0;
+ uint64_t newgen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, oldloc);
+
+ frame->local = local;
+
+ oldpathlen = STRLEN_0 (oldloc->path);
+ newpathlen = STRLEN_0 (newloc->path);
+ newbaselen = STRLEN_0 (newloc->name);
+
+ ret = inode_ctx_get2 (oldloc->inode, this, &oldino, &oldgen);
+ if (oldloc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): "
+ "failed to get remote inode number for source inode",
+ newloc->parent->ino, newloc->name, newloc->path,
+ oldloc->ino, oldloc->path);
+ goto unwind;
+ }
+
+ ret = inode_ctx_get2 (newloc->parent, this, &newpar, &newgen);
+ if (newloc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LINK %"PRId64"/%s (%s) ==> %"PRId64" (%s): "
+ "failed to get remote inode number destination parent",
+ newloc->parent->ino, newloc->name, newloc->path,
+ oldloc->ino, oldloc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, oldpathlen + newpathlen + newbaselen);
+ hdr = gf_hdr_new (req, oldpathlen + newpathlen + newbaselen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ strcpy (req->oldpath, oldloc->path);
+ strcpy (req->newpath + oldpathlen, newloc->path);
+ strcpy (req->newbname + oldpathlen + newpathlen, newloc->name);
+
+ req->oldino = hton64 (oldino);
+ req->oldgen = hton64 (oldgen);
+ req->newpar = hton64 (newpar);
+ req->newgen = hton64 (newgen);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LINK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, oldloc->inode, NULL);
+ return 0;
+}
+
+
+/**
+ * client_truncate - truncate function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ * @offset:
+ *
+ * external reference through client_protocol_xlator->fops->truncate
+ */
+
+int
+client_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_truncate_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "TRUNCATE %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->offset = hton64 (offset);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_TRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_readv - readv function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @size:
+ * @offset:
+ *
+ * external reference through client_protocol_xlator->fops->readv
+ */
+
+int
+client_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_read_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx, EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL, 0, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx, EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL, 0, NULL);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->size = hton32 (size);
+ req->offset = hton64 (offset);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READ,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL, 0, NULL);
+ return 0;
+
+}
+
+/**
+ * client_writev - writev function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @vector:
+ * @count:
+ * @offset:
+ *
+ * external reference through client_protocol_xlator->fops->writev
+ */
+
+int
+client_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t offset,
+ struct iobref *iobref)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_write_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->size = hton32 (iov_length (vector, count));
+ req->offset = hton64 (offset);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_WRITE,
+ hdr, hdrlen, vector, count, iobref);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_statfs - statfs function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ *
+ * external reference through client_protocol_xlator->fops->statfs
+ */
+
+int
+client_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_statfs_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ ino_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+
+ if (loc->inode) {
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "STATFS %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_STATFS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_flush - flush function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ *
+ * external reference through client_protocol_xlator->fops->flush
+ */
+
+int
+client_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_flush_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FLUSH,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+/**
+ * client_fsync - fsync function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @flags:
+ *
+ * external reference through client_protocol_xlator->fops->fsync
+ */
+
+int
+client_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsync_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int32_t ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->data = hton32 (flags);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSYNC,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+int
+client_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_xattrop_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t dict_len = 0;
+ int32_t ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ char *buf = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", this, unwind);
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+
+ if (dict) {
+ ret = dict_allocate_and_serialize (dict, &buf, &dict_len);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ dict);
+ goto unwind;
+ }
+ }
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "XATTROP %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, dict_len + pathlen);
+ hdr = gf_hdr_new (req, dict_len + pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->flags = hton32 (flags);
+ req->dict_len = hton32 (dict_len);
+ if (dict) {
+ memcpy (req->dict, buf, dict_len);
+ GF_FREE (buf);
+ }
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path + dict_len, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_XATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+int
+client_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ gf_xattrop_flags_t flags, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fxattrop_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t dict_len = 0;
+ int64_t remote_fd = -1;
+ int32_t ret = -1;
+ ino_t ino = 0;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ if (dict) {
+ dict_len = dict_serialized_length (dict);
+ if (dict_len < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ dict);
+ goto unwind;
+ }
+ }
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. "
+ "returning EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ ino = fd->inode->ino;
+ remote_fd = fdctx->remote_fd;
+
+ hdrlen = gf_hdr_len (req, dict_len);
+ hdr = gf_hdr_new (req, dict_len);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->flags = hton32 (flags);
+ req->dict_len = hton32 (dict_len);
+ if (dict) {
+ ret = dict_serialize (dict, req->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ dict);
+ goto unwind;
+ }
+ }
+ req->fd = hton64 (remote_fd);
+ req->ino = hton64 (ino);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FXATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+
+}
+
+/**
+ * client_setxattr - setxattr function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location
+ * @dict: dictionary which contains key:value to be set.
+ * @flags:
+ *
+ * external reference through client_protocol_xlator->fops->setxattr
+ */
+
+int
+client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_setxattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t dict_len = 0;
+ int ret = -1;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ dict_len = dict_serialized_length (dict);
+ if (dict_len < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ dict);
+ goto unwind;
+ }
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETXATTR %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, dict_len + pathlen);
+ hdr = gf_hdr_new (req, dict_len + pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->flags = hton32 (flags);
+ req->dict_len = hton32 (dict_len);
+
+ ret = dict_serialize (dict, req->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ dict);
+ goto unwind;
+ }
+
+ strcpy (req->path + dict_len, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+}
+
+/**
+ * client_fsetxattr - fsetxattr function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: fd
+ * @dict: dictionary which contains key:value to be set.
+ * @flags:
+ *
+ * external reference through client_protocol_xlator->fops->fsetxattr
+ */
+
+int
+client_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsetxattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t dict_len = 0;
+ ino_t ino;
+ int ret = -1;
+ int64_t remote_fd = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ dict_len = dict_serialized_length (dict);
+ if (dict_len < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ dict);
+ goto unwind;
+ }
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ ino = fd->inode->ino;
+ remote_fd = fdctx->remote_fd;
+
+ hdrlen = gf_hdr_len (req, dict_len);
+ hdr = gf_hdr_new (req, dict_len);
+
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->fd = hton64 (remote_fd);
+ req->flags = hton32 (flags);
+ req->dict_len = hton32 (dict_len);
+
+ ret = dict_serialize (dict, req->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ dict);
+ goto unwind;
+ }
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+}
+
+/**
+ * client_getxattr - getxattr function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location structure
+ *
+ * external reference through client_protocol_xlator->fops->getxattr
+ */
+
+int
+client_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_getxattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t pathlen = 0;
+ size_t namelen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ if (name)
+ namelen = STRLEN_0 (name);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + namelen);
+ hdr = gf_hdr_new (req, pathlen + namelen);
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->namelen = hton32 (namelen);
+ strcpy (req->path, loc->path);
+ if (name)
+ strcpy (req->name + pathlen, name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_GETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+/**
+ * client_fgetxattr - fgetxattr function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: fd
+ *
+ * external reference through client_protocol_xlator->fops->fgetxattr
+ */
+
+int
+client_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fgetxattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ size_t namelen = 0;
+ ino_t ino = 0;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ if (name)
+ namelen = STRLEN_0 (name);
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get remote fd. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ ino = fd->inode->ino;
+ remote_fd = fdctx->remote_fd;
+
+ hdrlen = gf_hdr_len (req, namelen);
+ hdr = gf_hdr_new (req, namelen);
+
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->fd = hton64 (remote_fd);
+ req->namelen = hton32 (namelen);
+
+ if (name)
+ strcpy (req->name, name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FGETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+/**
+ * client_removexattr - removexattr function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location structure
+ * @name:
+ *
+ * external reference through client_protocol_xlator->fops->removexattr
+ */
+
+int
+client_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_removexattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t namelen = 0;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ namelen = STRLEN_0 (name);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + namelen);
+ hdr = gf_hdr_new (req, pathlen + namelen);
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+ strcpy (req->name + pathlen, name);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_REMOVEXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+}
+
+/**
+ * client_opendir - opendir function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location structure
+ *
+ * external reference through client_protocol_xlator->fops->opendir
+ */
+
+int
+client_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ fd_t *fd)
+{
+ gf_fop_opendir_req_t *req = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ size_t hdrlen = 0;
+ int ret = -1;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ size_t pathlen = 0;
+ client_local_t *local = NULL;
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+ local->fd = fd_ref (fd);
+
+ frame->local = local;
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPENDIR %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ pathlen = STRLEN_0 (loc->path);
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (frame->this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPENDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, fd);
+ return 0;
+
+}
+
+/**
+ * client_readdirp - readdirp function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ *
+ * external reference through client_protocol_xlator->fops->readdirp
+ */
+
+int
+client_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readdirp_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req->fd = hton64 (remote_fd);
+ req->size = hton32 (size);
+ req->offset = hton64 (offset);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READDIRP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+
+}
+
+
+/**
+ * client_readdir - readdir function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ *
+ * external reference through client_protocol_xlator->fops->readdir
+ */
+
+int
+client_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readdir_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req->fd = hton64 (remote_fd);
+ req->size = hton32 (size);
+ req->offset = hton64 (offset);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_READDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+
+}
+
+/**
+ * client_fsyncdir - fsyncdir function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @flags:
+ *
+ * external reference through client_protocol_xlator->fops->fsyncdir
+ */
+
+int
+client_fsyncdir (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsyncdir_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int32_t ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ goto unwind;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->data = hton32 (flags);
+ req->fd = hton64 (remote_fd);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSYNCDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+}
+
+/**
+ * client_access - access function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @loc: location structure
+ * @mode:
+ *
+ * external reference through client_protocol_xlator->fops->access
+ */
+
+int
+client_access (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t mask)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_access_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ size_t pathlen = 0;
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "ACCESS %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ pathlen = STRLEN_0 (loc->path);
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->mask = hton32 (mask);
+ strcpy (req->path, loc->path);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_ACCESS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+/**
+ * client_ftrucate - ftruncate function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @offset: offset to truncate to
+ *
+ * external reference through client_protocol_xlator->fops->ftruncate
+ */
+
+int
+client_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_ftruncate_req_t *req = NULL;
+ int64_t remote_fd = -1;
+ size_t hdrlen = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->offset = hton64 (offset);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FTRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+/**
+ * client_fstat - fstat function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ *
+ * external reference through client_protocol_xlator->fops->fstat
+ */
+
+int
+client_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fstat_req_t *req = NULL;
+ int64_t remote_fd = -1;
+ size_t hdrlen = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ goto unwind;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSTAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+
+}
+
+/**
+ * client_lk - lk function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ * @cmd: lock command
+ * @lock:
+ *
+ * external reference through client_protocol_xlator->fops->lk
+ */
+
+int
+client_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct gf_flock *flock)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_lk_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int64_t remote_fd = -1;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE, "(%"PRId64"): failed to get"
+ " fd ctx. EBADFD", fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ if (cmd == F_GETLK || cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (cmd == F_SETLK || cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (cmd == F_SETLKW || cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->cmd = hton32 (gf_cmd);
+ req->type = hton32 (gf_type);
+ gf_flock_from_flock (&req->flock, flock);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+/**
+ * client_inodelk - inodelk function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @inode: inode structure
+ * @cmd: lock command
+ * @lock: flock struct
+ *
+ * external reference through client_protocol_xlator->fops->inodelk
+ */
+
+int
+client_inodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, int32_t cmd, struct gf_flock *flock)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_inodelk_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ size_t pathlen = 0;
+ size_t vollen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ vollen = STRLEN_0 (volume);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "INODELK %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ if (cmd == F_GETLK || cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (cmd == F_SETLK || cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (cmd == F_SETLKW || cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + vollen);
+ hdr = gf_hdr_new (req, pathlen + vollen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ strcpy (req->path, loc->path);
+ strcpy (req->path + pathlen, volume);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+
+ req->cmd = hton32 (gf_cmd);
+ req->type = hton32 (gf_type);
+ gf_flock_from_flock (&req->flock, flock);
+
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST,
+ GF_PROTO_FOP_INODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+
+/**
+ * client_finodelk - finodelk function for client protocol
+ * @frame: call frame
+ * @this: this translator structure
+ * @inode: inode structure
+ * @cmd: lock command
+ * @lock: flock struct
+ *
+ * external reference through client_protocol_xlator->fops->finodelk
+ */
+
+int
+client_finodelk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct gf_flock *flock)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_finodelk_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t vollen = 0;
+ int32_t gf_cmd = 0;
+ int32_t gf_type = 0;
+ int64_t remote_fd = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ vollen = STRLEN_0 (volume);
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ if (cmd == F_GETLK || cmd == F_GETLK64)
+ gf_cmd = GF_LK_GETLK;
+ else if (cmd == F_SETLK || cmd == F_SETLK64)
+ gf_cmd = GF_LK_SETLK;
+ else if (cmd == F_SETLKW || cmd == F_SETLKW64)
+ gf_cmd = GF_LK_SETLKW;
+ else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Unknown cmd (%d)!", gf_cmd);
+ goto unwind;
+ }
+
+ switch (flock->l_type) {
+ case F_RDLCK:
+ gf_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ gf_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ gf_type = GF_LK_F_UNLCK;
+ break;
+ }
+
+ hdrlen = gf_hdr_len (req, vollen);
+ hdr = gf_hdr_new (req, vollen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ strcpy (req->volume, volume);
+
+ req->fd = hton64 (remote_fd);
+
+ req->cmd = hton32 (gf_cmd);
+ req->type = hton32 (gf_type);
+ gf_flock_from_flock (&req->flock, flock);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST,
+ GF_PROTO_FOP_FINODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+}
+
+
+int
+client_entrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ loc_t *loc, const char *name, entrylk_cmd cmd,
+ entrylk_type type)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_entrylk_req_t *req = NULL;
+ size_t pathlen = 0;
+ size_t vollen = 0;
+ size_t hdrlen = -1;
+ int ret = -1;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ size_t namelen = 0;
+
+ pathlen = STRLEN_0 (loc->path);
+ vollen = STRLEN_0 (volume);
+
+ if (name)
+ namelen = STRLEN_0 (name);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "ENTRYLK %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + vollen + namelen);
+ hdr = gf_hdr_new (req, pathlen + vollen + namelen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->namelen = hton64 (namelen);
+
+ strcpy (req->path, loc->path);
+ if (name)
+ strcpy (req->name + pathlen, name);
+ strcpy (req->volume + pathlen + namelen, volume);
+
+ req->cmd = hton32 (cmd);
+ req->type = hton32 (type);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_ENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+
+}
+
+
+int
+client_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, const char *name, entrylk_cmd cmd,
+ entrylk_type type)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fentrylk_req_t *req = NULL;
+ int64_t remote_fd = -1;
+ size_t vollen = 0;
+ size_t namelen = 0;
+ size_t hdrlen = -1;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ if (name)
+ namelen = STRLEN_0 (name);
+
+ conf = this->private;
+
+ vollen = STRLEN_0 (volume);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, namelen + vollen);
+ hdr = gf_hdr_new (req, namelen + vollen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+ req->namelen = hton64 (namelen);
+
+ if (name)
+ strcpy (req->name, name);
+
+ strcpy (req->volume + namelen, volume);
+
+ req->cmd = hton32 (cmd);
+ req->type = hton32 (type);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+
+ STACK_UNWIND (frame, -1, EINVAL);
+ return 0;
+}
+
+/*
+ * client_lookup - lookup function for client protocol
+ * @frame: call frame
+ * @this:
+ * @loc: location
+ *
+ * not for external reference
+ */
+
+int
+client_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *xattr_req)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_lookup_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+ ino_t ino = 0;
+ ino_t par = 0;
+ uint64_t gen = 0;
+ size_t dictlen = 0;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ client_local_t *local = NULL;
+ char *buf = NULL;
+
+ GF_VALIDATE_OR_GOTO (this->name, loc, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, loc->path, unwind);
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ GF_VALIDATE_OR_GOTO (this->name, local, unwind);
+
+ loc_copy (&local->loc, loc);
+
+ frame->local = local;
+
+ if (loc->ino != 1 && loc->parent) {
+ ret = inode_ctx_get2 (loc->parent, this, &par, &gen);
+ if (loc->parent->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "LOOKUP %"PRId64"/%s (%s): failed to get "
+ "remote inode number for parent",
+ loc->parent->ino, loc->name, loc->path);
+ goto unwind;
+ }
+ GF_VALIDATE_OR_GOTO (this->name, loc->name, unwind);
+ baselen = STRLEN_0 (loc->name);
+ } else {
+ ino = 1;
+ }
+
+ pathlen = STRLEN_0 (loc->path);
+
+ if (xattr_req) {
+ ret = dict_allocate_and_serialize (xattr_req, &buf, &dictlen);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ xattr_req);
+ goto unwind;
+ }
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen + baselen + dictlen);
+ hdr = gf_hdr_new (req, pathlen + baselen + dictlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ req->par = hton64 (par);
+ strcpy (req->path, loc->path);
+ if (baselen)
+ strcpy (req->path + pathlen, loc->name);
+
+ if (dictlen > 0) {
+ memcpy (req->dict + pathlen + baselen, buf, dictlen);
+ GF_FREE (buf);
+ }
+
+ req->dictlen = hton32 (dictlen);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_LOOKUP,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+
+unwind:
+ STACK_UNWIND (frame, op_ret, op_errno, (loc)?loc->inode:NULL, NULL, NULL);
+ return ret;
+}
+
+
+int
+client_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ struct iatt *stbuf, int32_t valid)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_setattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ size_t pathlen = 0;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("client", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, frame, unwind);
+
+ pathlen = STRLEN_0 (loc->path);
+
+ ret = inode_ctx_get2 (loc->inode, this, &ino, &gen);
+ if (loc->inode->ino && ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "SETATTR %"PRId64" (%s): "
+ "failed to get remote inode number",
+ loc->inode->ino, loc->path);
+ goto unwind;
+ }
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (ino);
+ req->gen = hton64 (gen);
+ strcpy (req->path, loc->path);
+
+ gf_stat_from_iatt (&req->stbuf, stbuf);
+ req->valid = hton32 (valid);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_SETATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+int
+client_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iatt *stbuf, int32_t valid)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsetattr_req_t *req = NULL;
+ size_t hdrlen = 0;
+ int ret = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
+ client_conf_t *conf = NULL;
+
+ GF_VALIDATE_OR_GOTO ("client", this, unwind);
+ GF_VALIDATE_OR_GOTO (this->name, frame, unwind);
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, NULL, NULL);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+
+ req->fd = hton64 (remote_fd);
+
+ gf_stat_from_iatt (&req->stbuf, stbuf);
+ req->valid = hton32 (valid);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_FSETATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ STACK_UNWIND (frame, -1, EINVAL, NULL, NULL);
+ return 0;
+}
+
+
+int
+client_fdctx_destroy (xlator_t *this, client_fd_ctx_t *fdctx)
+{
+ call_frame_t *fr = NULL;
+ int32_t ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ size_t hdrlen = 0;
+ gf_cbk_release_req_t *req = NULL;
+ gf_cbk_releasedir_req_t *reqdir = NULL;
+ int64_t remote_fd = -1;
+ int op = 0;
+
+ remote_fd = fdctx->remote_fd;
+
+ if (remote_fd == -1)
+ goto out;
+
+ if (fdctx->is_dir) {
+ hdrlen = gf_hdr_len (reqdir, 0);
+ hdr = gf_hdr_new (reqdir, 0);
+ op = GF_CBK_RELEASEDIR;
+ reqdir = gf_param (hdr);
+ reqdir->fd = hton64 (remote_fd);
+ } else {
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ op = GF_CBK_RELEASE;
+ req = gf_param (hdr);
+ req->fd = hton64 (remote_fd);
+ }
+
+ fr = create_frame (this, this->ctx->pool);
+
+ ret = protocol_client_xfer (fr, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_CBK_REQUEST, op,
+ hdr, hdrlen, NULL, 0, NULL);
+
+out:
+ inode_unref (fdctx->inode);
+ GF_FREE (fdctx);
+
+ return ret;
+}
+
+
+/**
+ * client_releasedir - releasedir function for client protocol
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ *
+ * external reference through client_protocol_xlator->cbks->releasedir
+ */
+
+int
+client_releasedir (xlator_t *this, fd_t *fd)
+{
+ int64_t remote_fd = -1;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_del_ctx (fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (remote_fd != -1)
+ client_fdctx_destroy (this, fdctx);
+
+ return 0;
+}
+
+
+/**
+ * client_release - release function for client protocol
+ * @this: this translator structure
+ * @fd: file descriptor structure
+ *
+ * external reference through client_protocol_xlator->cbks->release
+ *
+ */
+int
+client_release (xlator_t *this, fd_t *fd)
+{
+ int64_t remote_fd = -1;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_del_ctx (fd, this);
+ if (fdctx != NULL) {
+ remote_fd = fdctx->remote_fd;
+
+ /* fdctx->remote_fd == -1 indicates a reopen attempt
+ in progress. Just mark ->released = 1 and let
+ reopen_cbk handle releasing
+ */
+
+ if (remote_fd != -1)
+ list_del_init (&fdctx->sfd_pos);
+
+ fdctx->released = 1;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (remote_fd != -1)
+ client_fdctx_destroy (this, fdctx);
+
+ return 0;
+}
+
+/*
+ * MGMT_OPS
+ */
+
+/* Callbacks */
+
+int
+client_fxattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_xattrop_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t gf_errno = 0;
+ int32_t op_errno = 0;
+ int32_t dict_len = 0;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ char *dictbuf = NULL;
+
+ rsp = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+
+ if (op_ret >= 0) {
+ op_ret = -1;
+ dict_len = ntoh32 (rsp->dict_len);
+
+ if (dict_len > 0) {
+ dictbuf = memdup (rsp->dict, dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail);
+
+ dict = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail);
+
+ ret = dict_unserialize (dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ dict);
+ op_errno = -ret;
+ goto fail;
+ } else {
+ dict->extra_free = dictbuf;
+ dictbuf = NULL;
+ }
+ }
+ op_ret = 0;
+ }
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+
+fail:
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+
+ if (dictbuf)
+ GF_FREE (dictbuf);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+
+int
+client_xattrop_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_xattrop_rsp_t *rsp = NULL;
+ int32_t op_ret = -1;
+ int32_t gf_errno = EINVAL;
+ int32_t op_errno = 0;
+ int32_t dict_len = 0;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ char *dictbuf = NULL;
+
+ rsp = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ if (op_ret >= 0) {
+ op_ret = -1;
+ dict_len = ntoh32 (rsp->dict_len);
+
+ if (dict_len > 0) {
+ dictbuf = memdup (rsp->dict, dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail);
+
+ dict = get_new_dict();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail);
+ dict_ref (dict);
+
+ ret = dict_unserialize (dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ dict);
+ goto fail;
+ } else {
+ dict->extra_free = dictbuf;
+ dictbuf = NULL;
+ }
+ }
+ op_ret = 0;
+ }
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+
+
+fail:
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+
+ if (dictbuf)
+ GF_FREE (dictbuf);
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+/*
+ * client_create_cbk - create callback function for client protocol
+ * @frame: call frame
+ * @args: arguments in dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_create_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_create_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ fd_t *fd = NULL;
+ inode_t *inode = NULL;
+ struct iatt stbuf = {0, };
+ struct iatt preparent = {0, };
+ struct iatt postparent = {0, };
+ int64_t remote_fd = 0;
+ int32_t ret = -1;
+ client_local_t *local = NULL;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+ local = frame->local; frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+ inode = local->loc.inode;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ if (op_ret >= 0) {
+ remote_fd = ntoh64 (rsp->fd);
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+
+ ino = stbuf.ia_ino;
+ gen = stbuf.ia_gen;
+ }
+
+ if (op_ret >= 0) {
+ ret = inode_ctx_put2 (local->loc.inode, frame->this, ino, gen);
+
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): failed to set "
+ "remote inode number to inode ctx",
+ local->loc.parent->ino, local->loc.name,
+ local->loc.path);
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind_out;
+ }
+
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_client_fd_ctx_t);
+ if (!fdctx) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind_out;
+ }
+
+ fdctx->remote_fd = remote_fd;
+ fdctx->inode = inode_ref (fd->inode);
+ fdctx->ino = ino;
+ fdctx->gen = gen;
+ fdctx->flags = local->flags;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ }
+unwind_out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd, inode, &stbuf,
+ &preparent, &postparent);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+/*
+ * client_open_cbk - open callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+int
+client_open_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOTCONN;
+ fd_t *fd = NULL;
+ int64_t remote_fd = 0;
+ gf_fop_open_rsp_t *rsp = NULL;
+ client_local_t *local = NULL;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+
+ local = frame->local;
+
+ if (local->op) {
+ local->op (frame, hdr, hdrlen, iobuf);
+ return 0;
+ }
+
+ frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ if (op_ret >= 0) {
+ remote_fd = ntoh64 (rsp->fd);
+ }
+
+ if (op_ret >= 0) {
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_client_fd_ctx_t);
+ if (!fdctx) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind_out;
+ }
+
+ inode_ctx_get2 (fd->inode, frame->this, &ino, &gen);
+
+ fdctx->remote_fd = remote_fd;
+ fdctx->inode = inode_ref (fd->inode);
+ fdctx->ino = ino;
+ fdctx->gen = gen;
+ fdctx->flags = local->flags;
+ fdctx->wbflags = local->wbflags;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ }
+unwind_out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_stat_cbk - stat callback for client protocol
+ * @frame: call frame
+ * @args: arguments dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_stat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt stbuf = {0, };
+ gf_fop_stat_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
+}
+
+
+/*
+ * client_mknod_cbk - mknod callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_mknod_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_mknod_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ int ret = 0;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (local->loc.inode, frame->this,
+ stbuf.ia_ino, stbuf.ia_gen);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): failed to set remote"
+ " inode number to inode ctx",
+ local->loc.parent->ino, local->loc.name,
+ local->loc.path);
+
+ STACK_UNWIND (frame, -1, EINVAL, inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf,
+ &preparent, &postparent);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_symlink_cbk - symlink callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_symlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_symlink_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt stbuf = {0, };
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ int ret = 0;
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (inode, frame->this,
+ stbuf.ia_ino, stbuf.ia_gen);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "SYMLINK %"PRId64"/%s (%s): failed to set "
+ "remote inode number to inode ctx",
+ local->loc.parent->ino, local->loc.name,
+ local->loc.path);
+ STACK_UNWIND (frame, -1, EINVAL, inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf,
+ &preparent, &postparent);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_link_cbk - link callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_link_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_link_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+
+ local = frame->local;
+ frame->local = NULL;
+ inode = local->loc.inode;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf,
+ &preparent, &postparent);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_truncate_cbk - truncate callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_truncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_truncate_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt prestat = {0, };
+ struct iatt poststat = {0, };
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->prestat, &prestat);
+ gf_stat_to_iatt (&rsp->poststat, &poststat);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat);
+
+ return 0;
+}
+
+/* client_fstat_cbk - fstat callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_fstat_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt stbuf = {0, };
+ gf_fop_fstat_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
+}
+
+/*
+ * client_ftruncate_cbk - ftruncate callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+int
+client_ftruncate_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_ftruncate_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt prestat = {0, };
+ struct iatt poststat = {0, };
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->prestat, &prestat);
+ gf_stat_to_iatt (&rsp->poststat, &poststat);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat);
+
+ return 0;
+}
+
+
+/* client_readv_cbk - readv callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external referece
+ */
+
+int
+client_readv_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_read_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iovec vector = {0, };
+ struct iatt stbuf = {0, };
+ struct iobref *iobref = NULL;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret != -1) {
+ iobref = iobref_new ();
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+ vector.iov_len = op_ret;
+
+ if (op_ret > 0) {
+ vector.iov_base = iobuf->ptr;
+ iobref_add (iobref, iobuf);
+ }
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &vector, 1, &stbuf, iobref);
+
+ if (iobref)
+ iobref_unref (iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return 0;
+}
+
+/*
+ * client_write_cbk - write callback for client protocol
+ * @frame: cal frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_write_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_write_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt prestat = {0, };
+ struct iatt poststat = {0, };
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_to_iatt (&rsp->prestat, &prestat);
+ gf_stat_to_iatt (&rsp->poststat, &poststat);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat);
+
+ return 0;
+}
+
+
+int
+client_readdirp_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_readdirp_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ uint32_t buf_size = 0;
+ gf_dirent_t entries;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ INIT_LIST_HEAD (&entries.list);
+ if (op_ret > 0) {
+ buf_size = ntoh32 (rsp->size);
+ gf_dirent_unserialize (&entries, rsp->buf, buf_size);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &entries);
+
+ gf_dirent_free (&entries);
+
+ return 0;
+}
+
+
+int
+client_readdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_readdir_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ uint32_t buf_size = 0;
+ gf_dirent_t entries;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ INIT_LIST_HEAD (&entries.list);
+ if (op_ret > 0) {
+ buf_size = ntoh32 (rsp->size);
+ gf_dirent_unserialize (&entries, rsp->buf, buf_size);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &entries);
+
+ gf_dirent_free (&entries);
+
+ return 0;
+}
+
+/*
+ * client_fsync_cbk - fsync callback for client protocol
+ *
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_fsync_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt prestat = {0, };
+ struct iatt poststat = {0,};
+ gf_fop_fsync_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->prestat, &prestat);
+ gf_stat_to_iatt (&rsp->poststat, &poststat);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &prestat, &poststat);
+
+ return 0;
+}
+
+/*
+ * client_unlink_cbk - unlink callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_unlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_unlink_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &preparent, &postparent);
+
+ return 0;
+}
+
+/*
+ * client_rename_cbk - rename callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_rename_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt stbuf = {0, };
+ gf_fop_rename_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt preoldparent = {0, };
+ struct iatt postoldparent = {0, };
+ struct iatt prenewparent = {0, };
+ struct iatt postnewparent = {0, };
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+ gf_stat_to_iatt (&rsp->preoldparent, &preoldparent);
+ gf_stat_to_iatt (&rsp->postoldparent, &postoldparent);
+ gf_stat_to_iatt (&rsp->prenewparent, &prenewparent);
+ gf_stat_to_iatt (&rsp->postnewparent, &postnewparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf, &preoldparent,
+ &postoldparent, &prenewparent, &postnewparent);
+
+ return 0;
+}
+
+
+/*
+ * client_readlink_cbk - readlink callback for client protocol
+ *
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+int
+client_readlink_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_readlink_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ char *link = NULL;
+ struct iatt stbuf = {0,};
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret > 0) {
+ link = rsp->path;
+ gf_stat_to_iatt (&rsp->buf, &stbuf);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, link, &stbuf);
+ return 0;
+}
+
+/*
+ * client_mkdir_cbk - mkdir callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_mkdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_mkdir_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt stbuf = {0, };
+ inode_t *inode = NULL;
+ client_local_t *local = NULL;
+ int ret = 0;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+
+ local = frame->local;
+ inode = local->loc.inode;
+ frame->local = NULL;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_put2 (inode, frame->this, stbuf.ia_ino,
+ stbuf.ia_gen);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64"/%s (%s): failed to set "
+ "remote inode number to inode ctx",
+ local->loc.parent->ino, local->loc.name,
+ local->loc.path);
+ STACK_UNWIND (frame, -1, EINVAL, inode, NULL,
+ NULL, NULL);
+ return 0;
+ }
+
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf,
+ &preparent, &postparent);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_flush_cbk - flush callback for client protocol
+ *
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_flush_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/*
+ * client_opendir_cbk - opendir callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_opendir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOTCONN;
+ fd_t *fd = NULL;
+ int64_t remote_fd = 0;
+ gf_fop_opendir_rsp_t *rsp = NULL;
+ client_local_t *local = NULL;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+ ino_t ino = 0;
+ uint64_t gen = 0;
+
+
+ local = frame->local;
+
+ if (local->op) {
+ local->op (frame, hdr, hdrlen, iobuf);
+ return 0;
+ }
+
+ frame->local = NULL;
+ conf = frame->this->private;
+ fd = local->fd;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ if (op_ret >= 0) {
+ remote_fd = ntoh64 (rsp->fd);
+ }
+
+ if (op_ret >= 0) {
+ fdctx = GF_CALLOC (1, sizeof (*fdctx),
+ gf_client_mt_client_fd_ctx_t);
+ if (!fdctx) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind_out;
+ }
+
+ inode_ctx_get2 (fd->inode, frame->this, &ino, &gen);
+
+ fdctx->remote_fd = remote_fd;
+ fdctx->inode = inode_ref (fd->inode);
+ fdctx->ino = ino;
+ fdctx->gen = gen;
+
+ fdctx->is_dir = 1;
+
+ INIT_LIST_HEAD (&fdctx->sfd_pos);
+
+ this_fd_set_ctx (fd, frame->this, &local->loc, fdctx);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ }
+unwind_out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+/*
+ * client_rmdir_cbk - rmdir callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_rmdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_rmdir_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->preparent, &preparent);
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &preparent, &postparent);
+
+ return 0;
+}
+
+/*
+ * client_access_cbk - access callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_access_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_access_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/*
+ * client_lookup_cbk - lookup callback for client protocol
+ *
+ * @frame: call frame
+ * @args: arguments dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_lookup_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt stbuf = {0, };
+ struct iatt postparent = {0, };
+ inode_t *inode = NULL;
+ dict_t *xattr = NULL;
+ gf_fop_lookup_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ size_t dict_len = 0;
+ char *dictbuf = NULL;
+ int32_t ret = -1;
+ int32_t gf_errno = 0;
+ client_local_t *local = NULL;
+ ino_t oldino = 0;
+ uint64_t oldgen = 0;
+
+ local = frame->local;
+ inode = local->loc.inode;
+ frame->local = NULL;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+
+ gf_stat_to_iatt (&rsp->postparent, &postparent);
+
+ if (op_ret == 0) {
+ op_ret = -1;
+ gf_stat_to_iatt (&rsp->stat, &stbuf);
+
+ ret = inode_ctx_get2 (inode, frame->this, &oldino, &oldgen);
+ if (oldino != stbuf.ia_ino || oldgen != stbuf.ia_gen) {
+ if (oldino) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): "
+ "inode number changed from "
+ "{%"PRId64",%"PRId64"} to {%"PRId64",%"PRId64"}",
+ local->loc.parent ?
+ local->loc.parent->ino : (uint64_t) 0,
+ local->loc.name,
+ local->loc.path,
+ oldgen, oldino, stbuf.ia_gen, stbuf.ia_ino);
+ op_errno = ESTALE;
+ goto fail;
+ }
+
+ ret = inode_ctx_put2 (inode, frame->this,
+ stbuf.ia_ino, stbuf.ia_gen);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s) : "
+ "failed to set remote inode "
+ "number to inode ctx",
+ local->loc.parent ?
+ local->loc.parent->ino : (uint64_t) 0,
+ local->loc.name,
+ local->loc.path);
+ op_errno = EINVAL;
+ goto fail;
+ }
+ }
+
+ dict_len = ntoh32 (rsp->dict_len);
+
+ if (dict_len > 0) {
+ dictbuf = memdup (rsp->dict, dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail);
+
+ xattr = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, xattr, fail);
+
+ ret = dict_unserialize (dictbuf, dict_len, &xattr);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): failed to "
+ "unserialize dictionary",
+ local->loc.path, inode->ino);
+ goto fail;
+ } else {
+ xattr->extra_free = dictbuf;
+ dictbuf = NULL;
+ }
+ }
+ op_ret = 0;
+ }
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+
+fail:
+ STACK_UNWIND (frame, op_ret, op_errno, inode, &stbuf, xattr,
+ &postparent);
+
+ client_local_wipe (local);
+
+ if (dictbuf)
+ GF_FREE (dictbuf);
+
+ if (xattr)
+ dict_unref (xattr);
+
+ return 0;
+}
+
+static int32_t
+client_setattr_cbk (call_frame_t *frame,gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt statpre = {0, };
+ struct iatt statpost = {0, };
+ gf_fop_setattr_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->statpre, &statpre);
+ gf_stat_to_iatt (&rsp->statpost, &statpost);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost);
+
+ return 0;
+}
+
+static int32_t
+client_fsetattr_cbk (call_frame_t *frame,gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct iatt statpre = {0, };
+ struct iatt statpost = {0, };
+ gf_fop_setattr_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_to_iatt (&rsp->statpre, &statpre);
+ gf_stat_to_iatt (&rsp->statpost, &statpost);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost);
+
+ return 0;
+}
+
+
+int
+gf_free_direntry (dir_entry_t *head)
+{
+ dir_entry_t *prev = NULL;
+ dir_entry_t *trav = NULL;
+
+ prev = head;
+ GF_VALIDATE_OR_GOTO ("client-protocol", prev, fail);
+
+ trav = head->next;
+ while (trav) {
+ prev->next = trav->next;
+ GF_FREE (trav->name);
+ if (IA_ISLNK (trav->buf.ia_type))
+ GF_FREE (trav->link);
+ GF_FREE (trav);
+ trav = prev->next;
+ }
+ GF_FREE (head);
+fail:
+ return 0;
+}
+
+/*
+ * client_statfs_cbk - statfs callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_statfs_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct statvfs stbuf = {0, };
+ gf_fop_statfs_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret == 0) {
+ gf_statfs_to_statfs (&rsp->statfs, &stbuf);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
+}
+
+/*
+ * client_fsyncdir_cbk - fsyncdir callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_fsyncdir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/*
+ * client_setxattr_cbk - setxattr callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_setxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_setxattr_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/*
+ * client_getxattr_cbk - getxattr callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_getxattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_getxattr_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t gf_errno = 0;
+ int32_t op_errno = 0;
+ int32_t dict_len = 0;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ char *dictbuf = NULL;
+ client_local_t *local = NULL;
+
+ local = frame->local;
+ frame->local = NULL;
+
+ rsp = gf_param (hdr);
+ GF_VALIDATE_OR_GOTO (frame->this->name, rsp, fail);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+
+ if (op_ret >= 0) {
+ op_ret = -1;
+ dict_len = ntoh32 (rsp->dict_len);
+
+ if (dict_len > 0) {
+ dictbuf = memdup (rsp->dict, dict_len);
+ GF_VALIDATE_OR_GOTO (frame->this->name, dictbuf, fail);
+
+ dict = dict_new();
+ GF_VALIDATE_OR_GOTO (frame->this->name, dict, fail);
+
+ ret = dict_unserialize (dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "%s (%"PRId64"): failed to "
+ "unserialize xattr dictionary",
+ local->loc.path,
+ local->loc.inode->ino);
+ goto fail;
+ } else {
+ dict->extra_free = dictbuf;
+ dictbuf = NULL;
+ }
+ }
+ op_ret = 0;
+ }
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+fail:
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+
+ client_local_wipe (local);
+
+ if (dictbuf)
+ GF_FREE (dictbuf);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}
+
+/*
+ * client_removexattr_cbk - removexattr callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_removexattr_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
+ size_t hdrlen, struct iobuf *iobuf)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+/*
+ * client_lk_cbk - lk callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_lk_common_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ struct gf_flock lock = {0,};
+ gf_fop_lk_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret >= 0) {
+ gf_flock_to_flock (&rsp->flock, &lock);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &lock);
+ return 0;
+}
+
+/*
+ * client_gf_file_lk_cbk - gf_file_lk callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_inodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_inodelk_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int
+client_finodelk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_finodelk_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+/*
+ * client_entrylk_cbk - entrylk callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_entrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_entrylk_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int
+client_fentrylk_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fentrylk_rsp_t *rsp = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+
+/*
+ * client_getspec - getspec function for client protocol
+ * @frame: call frame
+ * @this: client protocol xlator structure
+ * @flag:
+ *
+ * external reference through client_protocol_xlator->fops->getspec
+ */
+
+int
+client_getspec (call_frame_t *frame, xlator_t *this, const char *key,
+ int32_t flag)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_getspec_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int keylen = 0;
+ int ret = -1;
+
+ if (key)
+ keylen = STRLEN_0 (key);
+
+ hdrlen = gf_hdr_len (req, keylen);
+ hdr = gf_hdr_new (req, keylen);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, unwind);
+
+ req = gf_param (hdr);
+ req->flags = hton32 (flag);
+ req->keylen = hton32 (keylen);
+ if (keylen)
+ strcpy (req->key, key);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_GETSPEC,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+unwind:
+ if (hdr)
+ GF_FREE (hdr);
+ STACK_UNWIND (frame, -1, EINVAL, NULL);
+ return 0;
+}
+
+/*
+ * client_getspec_cbk - getspec callback for client protocol
+ *
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_getspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_mop_getspec_rsp_t *rsp = NULL;
+ char *spec_data = NULL;
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ int32_t gf_errno = 0;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+ rsp = gf_param (hdr);
+
+ if (op_ret >= 0) {
+ spec_data = rsp->spec;
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, spec_data);
+ return 0;
+}
+
+
+int
+client_rchecksum (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
+ int32_t len)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rchecksum_req_t *req = NULL;
+ size_t hdrlen = -1;
+ int ret = -1;
+
+ int64_t remote_fd = -1;
+ client_fd_ctx_t *fdctx = NULL;
+ client_conf_t *conf = NULL;
+
+ hdrlen = gf_hdr_len (req, 0);
+ hdr = gf_hdr_new (req, 0);
+ req = gf_param (hdr);
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx = this_fd_get_ctx (fd, this);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, 0, NULL);
+ return 0;
+ }
+
+ if (fdctx->remote_fd == -1) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "(%"PRId64"): failed to get fd ctx. EBADFD",
+ fd->inode->ino);
+ STACK_UNWIND (frame, -1, EBADFD, 0, NULL);
+ return 0;
+ }
+
+ remote_fd = fdctx->remote_fd;
+
+ req->fd = hton64 (remote_fd);
+ req->offset = hton64 (offset);
+ req->len = hton32 (len);
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_BULK),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_RCHECKSUM,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+}
+
+
+int
+client_rchecksum_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_rchecksum_rsp_t *rsp = NULL;
+
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ int32_t gf_errno = 0;
+ uint32_t weak_checksum = 0;
+ unsigned char *strong_checksum = NULL;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ gf_errno = ntoh32 (hdr->rsp.op_errno);
+ op_errno = gf_error_to_errno (gf_errno);
+
+ if (op_ret >= 0) {
+ weak_checksum = rsp->weak_checksum;
+ strong_checksum = rsp->strong_checksum;
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, weak_checksum, strong_checksum);
+
+ return 0;
+}
+
+
+/*
+ * client_setspec_cbk - setspec callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_setspec_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}
+
+
+
+int
+protocol_client_reopendir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
+ size_t hdrlen, struct iobuf *iobuf)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOTCONN;
+ int64_t remote_fd = -1;
+ gf_fop_open_rsp_t *rsp = NULL;
+ client_local_t *local = NULL;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+
+
+ local = frame->local; frame->local = NULL;
+ conf = frame->this->private;
+ fdctx = local->fdctx;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ if (op_ret >= 0)
+ remote_fd = ntoh64 (rsp->fd);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "reopendir on %s returned %d (%"PRId64")",
+ local->loc.path, op_ret, remote_fd);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx->remote_fd = remote_fd;
+
+ if (!fdctx->released) {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ fdctx = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx)
+ client_fdctx_destroy (frame->this, fdctx);
+
+ STACK_DESTROY (frame->root);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+
+int
+protocol_client_reopendir (xlator_t *this, client_fd_ctx_t *fdctx)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ size_t hdrlen = 0;
+ gf_fop_opendir_req_t *req = NULL;
+ size_t pathlen = 0;
+ client_local_t *local = NULL;
+ inode_t *inode = NULL;
+ char *path = NULL;
+ call_frame_t *frame = NULL;
+
+ inode = fdctx->inode;
+
+ ret = inode_path (inode, NULL, &path);
+ if (ret < 0) {
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ if (!local) {
+ goto out;
+ }
+
+ local->fdctx = fdctx;
+ local->op = protocol_client_reopendir_cbk;
+ local->loc.path = path; path = NULL;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+
+ pathlen = STRLEN_0 (local->loc.path);
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (fdctx->ino);
+ req->gen = hton64 (fdctx->gen);
+
+ strcpy (req->path, local->loc.path);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "attempting reopendir on %s", local->loc.path);
+
+ frame->local = local; local = NULL;
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPENDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+
+ if (local)
+ client_local_wipe (local);
+
+ if (path)
+ GF_FREE (path);
+
+ return 0;
+}
+
+
+int
+protocol_client_reopen_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
+ size_t hdrlen, struct iobuf *iobuf)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOTCONN;
+ int64_t remote_fd = -1;
+ gf_fop_open_rsp_t *rsp = NULL;
+ client_local_t *local = NULL;
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+
+
+ local = frame->local; frame->local = NULL;
+ conf = frame->this->private;
+ fdctx = local->fdctx;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = ntoh32 (hdr->rsp.op_errno);
+
+ if (op_ret >= 0)
+ remote_fd = ntoh64 (rsp->fd);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "reopen on %s returned %d (%"PRId64")",
+ local->loc.path, op_ret, remote_fd);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ fdctx->remote_fd = remote_fd;
+
+ if (!fdctx->released) {
+ list_add_tail (&fdctx->sfd_pos, &conf->saved_fds);
+ fdctx = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (fdctx)
+ client_fdctx_destroy (frame->this, fdctx);
+
+ STACK_DESTROY (frame->root);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+
+int
+protocol_client_reopen (xlator_t *this, client_fd_ctx_t *fdctx)
+{
+ int ret = -1;
+ gf_hdr_common_t *hdr = NULL;
+ size_t hdrlen = 0;
+ gf_fop_open_req_t *req = NULL;
+ size_t pathlen = 0;
+ client_local_t *local = NULL;
+ inode_t *inode = NULL;
+ char *path = NULL;
+ call_frame_t *frame = NULL;
+
+ inode = fdctx->inode;
+
+ ret = inode_path (inode, NULL, &path);
+ if (ret < 0) {
+ goto out;
+ }
+
+ local = GF_CALLOC (1, sizeof (*local), gf_client_mt_client_local_t);
+ if (!local) {
+ goto out;
+ }
+
+ local->fdctx = fdctx;
+ local->op = protocol_client_reopen_cbk;
+ local->loc.path = path; path = NULL;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ goto out;
+ }
+
+ pathlen = STRLEN_0 (local->loc.path);
+
+ hdrlen = gf_hdr_len (req, pathlen);
+ hdr = gf_hdr_new (req, pathlen);
+
+ req = gf_param (hdr);
+
+ req->ino = hton64 (fdctx->ino);
+ req->gen = hton64 (fdctx->gen);
+ req->flags = hton32 (gf_flags_from_flags (fdctx->flags));
+ req->wbflags = hton32 (fdctx->wbflags);
+ strcpy (req->path, local->loc.path);
+
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "attempting reopen on %s", local->loc.path);
+
+ frame->local = local; local = NULL;
+
+ ret = protocol_client_xfer (frame, this,
+ CLIENT_CHANNEL (this, CHANNEL_LOWLAT),
+ GF_OP_TYPE_FOP_REQUEST, GF_PROTO_FOP_OPEN,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return ret;
+
+out:
+ if (frame)
+ STACK_DESTROY (frame->root);
+
+ if (local)
+ client_local_wipe (local);
+
+ if (path)
+ GF_FREE (path);
+
+ return 0;
+
+}
+
+
+int
+protocol_client_post_handshake (call_frame_t *frame, xlator_t *this)
+{
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *tmp = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+ xlator_list_t *parent = NULL;
+ struct list_head reopen_head;
+
+ conf = this->private;
+ INIT_LIST_HEAD (&reopen_head);
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
+ sfd_pos) {
+ if (fdctx->remote_fd != -1)
+ continue;
+
+ list_del (&fdctx->sfd_pos);
+ list_add_tail (&fdctx->sfd_pos, &reopen_head);
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ list_for_each_entry_safe (fdctx, tmp, &reopen_head, sfd_pos) {
+ list_del_init (&fdctx->sfd_pos);
+
+ if (fdctx->is_dir)
+ protocol_client_reopendir (this, fdctx);
+ else
+ protocol_client_reopen (this, fdctx);
+ }
+
+ parent = this->parents;
+
+ while (parent) {
+ xlator_notify (parent->xlator, GF_EVENT_CHILD_UP,
+ this);
+ parent = parent->next;
+ }
+
+ return 0;
+}
+
+/*
+ * client_setvolume_cbk - setvolume callback for client protocol
+ * @frame: call frame
+ * @args: argument dictionary
+ *
+ * not for external reference
+ */
+
+int
+client_setvolume_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ client_conf_t *conf = NULL;
+ gf_mop_setvolume_rsp_t *rsp = NULL;
+ client_connection_t *conn = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ xlator_t *this = NULL;
+ xlator_list_t *parent = NULL;
+ transport_t *trans = NULL;
+ dict_t *reply = NULL;
+ char *remote_subvol = NULL;
+ char *remote_error = NULL;
+ char *process_uuid = NULL;
+ int32_t ret = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t dict_len = 0;
+ transport_t *peer_trans = NULL;
+ uint64_t peer_trans_int = 0;
+
+ trans = frame->local; frame->local = NULL;
+ this = frame->this;
+ conn = trans->xl_private;
+ conf = this->private;
+
+ rsp = gf_param (hdr);
+
+ op_ret = ntoh32 (hdr->rsp.op_ret);
+ op_errno = gf_error_to_errno (ntoh32 (hdr->rsp.op_errno));
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setvolume failed (%s)",
+ strerror (op_errno));
+ goto out;
+ }
+
+ reply = dict_new ();
+ GF_VALIDATE_OR_GOTO (this->name, reply, out);
+
+ dict_len = ntoh32 (rsp->dict_len);
+ ret = dict_unserialize (rsp->buf, dict_len, &reply);
+ if (ret < 0) {
+ gf_log (frame->this->name, GF_LOG_DEBUG,
+ "failed to unserialize buffer(%p) to dictionary",
+ rsp->buf);
+ goto out;
+ }
+
+ ret = dict_get_str (reply, "ERROR", &remote_error);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get ERROR string from reply dictionary");
+ }
+
+ ret = dict_get_str (reply, "process-uuid", &process_uuid);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get 'process-uuid' from reply dictionary");
+ }
+
+ if (op_ret < 0) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "SETVOLUME on remote-host failed: %s",
+ remote_error ? remote_error : strerror (op_errno));
+ errno = op_errno;
+ if (op_errno == ESTALE) {
+ parent = trans->xl->parents;
+ while (parent) {
+ xlator_notify (parent->xlator,
+ GF_EVENT_VOLFILE_MODIFIED,
+ trans->xl);
+ parent = parent->next;
+ }
+ }
+
+ } else {
+ ret = dict_get_str (this->options, "remote-subvolume",
+ &remote_subvol);
+ if (!remote_subvol)
+ goto out;
+
+ ctx = this->ctx;
+
+ if (process_uuid && !strcmp (ctx->process_uuid,process_uuid)) {
+ ret = dict_get_uint64 (reply, "transport-ptr",
+ &peer_trans_int);
+
+ peer_trans = (void *) (long) (peer_trans_int);
+
+ gf_log (this->name, GF_LOG_WARNING,
+ "attaching to the local volume '%s'",
+ remote_subvol);
+
+ transport_setpeer (trans, peer_trans);
+
+ }
+
+ gf_log (trans->xl->name, GF_LOG_INFO,
+ "Connected to %s, attached "
+ "to remote volume '%s'.",
+ trans->peerinfo.identifier, remote_subvol);
+
+ pthread_mutex_lock (&(conn->lock));
+ {
+ conn->connected = 1;
+ }
+ pthread_mutex_unlock (&(conn->lock));
+
+ protocol_client_post_handshake (frame, frame->this);
+ }
+
+ conf->connecting = 0;
+out:
+
+ if (-1 == op_ret) {
+ /* Let the connection/re-connection happen in
+ * background, for now, don't hang here,
+ * tell the parents that i am all ok..
+ */
+ parent = trans->xl->parents;
+ while (parent) {
+ xlator_notify (parent->xlator,
+ GF_EVENT_CHILD_CONNECTING, trans->xl);
+ parent = parent->next;
+ }
+ conf->connecting= 1;
+ }
+
+ STACK_DESTROY (frame->root);
+
+ if (reply)
+ dict_unref (reply);
+
+ return op_ret;
+}
+
+/*
+ * client_enosys_cbk -
+ * @frame: call frame
+ *
+ * not for external reference
+ */
+
+int
+client_enosys_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+void
+client_protocol_reconnect (void *trans_ptr)
+{
+ transport_t *trans = NULL;
+ client_connection_t *conn = NULL;
+ struct timeval tv = {0, 0};
+ int32_t ret = 0;
+
+ trans = trans_ptr;
+ conn = trans->xl_private;
+ pthread_mutex_lock (&conn->lock);
+ {
+ if (conn->reconnect)
+ gf_timer_call_cancel (trans->xl->ctx,
+ conn->reconnect);
+ conn->reconnect = 0;
+
+ if (conn->connected == 0) {
+ tv.tv_sec = 10;
+
+ gf_log (trans->xl->name, GF_LOG_TRACE,
+ "attempting reconnect");
+ ret = transport_connect (trans);
+
+ conn->reconnect =
+ gf_timer_call_after (trans->xl->ctx, tv,
+ client_protocol_reconnect,
+ trans);
+ } else {
+ gf_log (trans->xl->name, GF_LOG_TRACE,
+ "breaking reconnect chain");
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (ret == -1 && errno != EINPROGRESS) {
+ default_notify (trans->xl, GF_EVENT_CHILD_DOWN, NULL);
+ }
+}
+
+int
+protocol_client_mark_fd_bad (xlator_t *this)
+{
+ client_conf_t *conf = NULL;
+ client_fd_ctx_t *tmp = NULL;
+ client_fd_ctx_t *fdctx = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry_safe (fdctx, tmp, &conf->saved_fds,
+ sfd_pos) {
+ fdctx->remote_fd = -1;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ return 0;
+}
+
+/*
+ * client_protocol_cleanup - cleanup function
+ * @trans: transport object
+ *
+ */
+
+int
+protocol_client_cleanup (transport_t *trans)
+{
+ client_connection_t *conn = NULL;
+ struct saved_frames *saved_frames = NULL;
+
+ conn = trans->xl_private;
+
+ gf_log (trans->xl->name, GF_LOG_TRACE,
+ "cleaning up state in transport object %p", trans);
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ saved_frames = conn->saved_frames;
+ conn->saved_frames = gf_client_saved_frames_new ();
+
+ /* bailout logic cleanup */
+ if (conn->timer) {
+ gf_timer_call_cancel (trans->xl->ctx, conn->timer);
+ conn->timer = NULL;
+ }
+
+ if (conn->reconnect == NULL) {
+ /* :O This part is empty.. any thing missing? */
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ gf_client_saved_frames_destroy (trans->xl, saved_frames,
+ gf_fops, gf_mops, gf_cbks);
+
+ return 0;
+}
+
+
+/* cbk callbacks */
+int
+client_releasedir_cbk (call_frame_t *frame, gf_hdr_common_t *hdr,
+ size_t hdrlen, struct iobuf *iobuf)
+{
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+int
+client_release_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+int
+client_forget_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_log ("", GF_LOG_CRITICAL, "fop not implemented");
+ return 0;
+}
+
+
+int
+client_log_cbk (call_frame_t *frame, gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_log ("", GF_LOG_CRITICAL, "fop not implemented");
+ return 0;
+}
+
+
+static gf_op_t gf_fops[] = {
+ [GF_PROTO_FOP_STAT] = client_stat_cbk,
+ [GF_PROTO_FOP_READLINK] = client_readlink_cbk,
+ [GF_PROTO_FOP_MKNOD] = client_mknod_cbk,
+ [GF_PROTO_FOP_MKDIR] = client_mkdir_cbk,
+ [GF_PROTO_FOP_UNLINK] = client_unlink_cbk,
+ [GF_PROTO_FOP_RMDIR] = client_rmdir_cbk,
+ [GF_PROTO_FOP_SYMLINK] = client_symlink_cbk,
+ [GF_PROTO_FOP_RENAME] = client_rename_cbk,
+ [GF_PROTO_FOP_LINK] = client_link_cbk,
+ [GF_PROTO_FOP_TRUNCATE] = client_truncate_cbk,
+ [GF_PROTO_FOP_OPEN] = client_open_cbk,
+ [GF_PROTO_FOP_READ] = client_readv_cbk,
+ [GF_PROTO_FOP_WRITE] = client_write_cbk,
+ [GF_PROTO_FOP_STATFS] = client_statfs_cbk,
+ [GF_PROTO_FOP_FLUSH] = client_flush_cbk,
+ [GF_PROTO_FOP_FSYNC] = client_fsync_cbk,
+ [GF_PROTO_FOP_SETXATTR] = client_setxattr_cbk,
+ [GF_PROTO_FOP_GETXATTR] = client_getxattr_cbk,
+ [GF_PROTO_FOP_REMOVEXATTR] = client_removexattr_cbk,
+ [GF_PROTO_FOP_OPENDIR] = client_opendir_cbk,
+ [GF_PROTO_FOP_FSYNCDIR] = client_fsyncdir_cbk,
+ [GF_PROTO_FOP_ACCESS] = client_access_cbk,
+ [GF_PROTO_FOP_CREATE] = client_create_cbk,
+ [GF_PROTO_FOP_FTRUNCATE] = client_ftruncate_cbk,
+ [GF_PROTO_FOP_FSTAT] = client_fstat_cbk,
+ [GF_PROTO_FOP_LK] = client_lk_common_cbk,
+ [GF_PROTO_FOP_LOOKUP] = client_lookup_cbk,
+ [GF_PROTO_FOP_READDIR] = client_readdir_cbk,
+ [GF_PROTO_FOP_READDIRP] = client_readdirp_cbk,
+ [GF_PROTO_FOP_INODELK] = client_inodelk_cbk,
+ [GF_PROTO_FOP_FINODELK] = client_finodelk_cbk,
+ [GF_PROTO_FOP_ENTRYLK] = client_entrylk_cbk,
+ [GF_PROTO_FOP_FENTRYLK] = client_fentrylk_cbk,
+ [GF_PROTO_FOP_RCHECKSUM] = client_rchecksum_cbk,
+ [GF_PROTO_FOP_XATTROP] = client_xattrop_cbk,
+ [GF_PROTO_FOP_FXATTROP] = client_fxattrop_cbk,
+ [GF_PROTO_FOP_SETATTR] = client_setattr_cbk,
+ [GF_PROTO_FOP_FSETATTR] = client_fsetattr_cbk
+};
+
+static gf_op_t gf_mops[] = {
+ [GF_MOP_SETVOLUME] = client_setvolume_cbk,
+ [GF_MOP_GETVOLUME] = client_enosys_cbk,
+ [GF_MOP_SETSPEC] = client_setspec_cbk,
+ [GF_MOP_GETSPEC] = client_getspec_cbk,
+ [GF_MOP_PING] = client_ping_cbk,
+ [GF_MOP_LOG] = client_log_cbk
+};
+
+static gf_op_t gf_cbks[] = {
+ [GF_CBK_FORGET] = client_forget_cbk,
+ [GF_CBK_RELEASE] = client_release_cbk,
+ [GF_CBK_RELEASEDIR] = client_releasedir_cbk
+};
+
+/*
+ * client_protocol_interpret - protocol interpreter
+ * @trans: transport object
+ * @blk: data block
+ *
+ */
+int
+protocol_client_interpret (xlator_t *this, transport_t *trans,
+ char *hdr_p, size_t hdrlen, struct iobuf *iobuf)
+{
+ int ret = -1;
+ call_frame_t *frame = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ uint64_t callid = 0;
+ int type = -1;
+ int op = -1;
+ client_connection_t *conn = NULL;
+
+ conn = trans->xl_private;
+
+ hdr = (gf_hdr_common_t *)hdr_p;
+
+ type = ntoh32 (hdr->type);
+ op = ntoh32 (hdr->op);
+ callid = ntoh64 (hdr->callid);
+
+ frame = lookup_frame (trans, op, type, callid);
+ if (frame == NULL) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "no frame for callid=%"PRId64" type=%d op=%d",
+ callid, type, op);
+ return 0;
+ }
+
+ switch (type) {
+ case GF_OP_TYPE_FOP_REPLY:
+ if ((op > GF_PROTO_FOP_MAXVALUE) ||
+ (op < 0)) {
+ gf_log (trans->xl->name, GF_LOG_WARNING,
+ "invalid fop '%d'", op);
+ } else {
+ ret = gf_fops[op] (frame, hdr, hdrlen, iobuf);
+ }
+ break;
+ case GF_OP_TYPE_MOP_REPLY:
+ if ((op > GF_MOP_MAXVALUE) ||
+ (op < 0)) {
+ gf_log (trans->xl->name, GF_LOG_WARNING,
+ "invalid fop '%d'", op);
+ } else {
+ ret = gf_mops[op] (frame, hdr, hdrlen, iobuf);
+ }
+ break;
+ case GF_OP_TYPE_CBK_REPLY:
+ if ((op > GF_CBK_MAXVALUE) ||
+ (op < 0)) {
+ gf_log (trans->xl->name, GF_LOG_WARNING,
+ "invalid cbk '%d'", op);
+ } else {
+ ret = gf_cbks[op] (frame, hdr, hdrlen, iobuf);
+ }
+ break;
+ default:
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "invalid packet type: %d", type);
+ break;
+ }
+
+ return ret;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_client_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+
+/*
+ * init - initiliazation function. called during loading of client protocol
+ * @this:
+ *
+ */
+
+int
+init (xlator_t *this)
+{
+ transport_t *trans = NULL;
+ client_conf_t *conf = NULL;
+ client_connection_t *conn = NULL;
+ int32_t frame_timeout = 0;
+ int32_t ping_timeout = 0;
+ data_t *remote_subvolume = NULL;
+ int32_t ret = -1;
+ int i = 0;
+
+ if (this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: client protocol translator cannot have any "
+ "subvolumes");
+ goto out;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Volume is dangling. ");
+ }
+
+ remote_subvolume = dict_get (this->options, "remote-subvolume");
+ if (remote_subvolume == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Option 'remote-subvolume' is not specified.");
+ goto out;
+ }
+
+ ret = dict_get_int32 (this->options, "frame-timeout",
+ &frame_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting frame-timeout to %d", frame_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting frame-timeout to 30mins");
+ frame_timeout = 1800;
+ }
+
+ ret = dict_get_int32 (this->options, "ping-timeout",
+ &ping_timeout);
+ if (ret >= 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "setting ping-timeout to %d", ping_timeout);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "defaulting ping-timeout to 42");
+ ping_timeout = GF_UNIVERSAL_ANSWER;
+ }
+
+ conf = GF_CALLOC (1, sizeof (client_conf_t),
+ gf_client_mt_client_conf_t);
+
+ protocol_common_init ();
+
+ pthread_mutex_init (&conf->mutex, NULL);
+ INIT_LIST_HEAD (&conf->saved_fds);
+
+ this->private = conf;
+
+ for (i = 0; i < CHANNEL_MAX; i++) {
+ if (CHANNEL_LOWLAT == i) {
+ dict_set (this->options, "transport.socket.lowlat",
+ data_from_dynstr (gf_strdup ("true")));
+ }
+ trans = transport_load (this->options, this);
+ if (trans == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Failed to load transport");
+ ret = -1;
+ goto out;
+ }
+
+ conn = GF_CALLOC (1, sizeof (*conn),
+ gf_client_mt_client_connection_t);
+
+ conn->saved_frames = gf_client_saved_frames_new ();
+
+ conn->callid = 1;
+
+ conn->frame_timeout = frame_timeout;
+ conn->ping_timeout = ping_timeout;
+
+ pthread_mutex_init (&conn->lock, NULL);
+
+ trans->xl_private = conn;
+ conf->transport[i] = transport_ref (trans);
+ }
+
+#ifndef GF_DARWIN_HOST_OS
+ {
+ struct rlimit lim;
+
+ lim.rlim_cur = 1048576;
+ lim.rlim_max = 1048576;
+
+ ret = setrlimit (RLIMIT_NOFILE, &lim);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "WARNING: Failed to set 'ulimit -n 1M': %s",
+ strerror(errno));
+ lim.rlim_cur = 65536;
+ lim.rlim_max = 65536;
+
+ ret = setrlimit (RLIMIT_NOFILE, &lim);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Failed to set max open fd to 64k: %s",
+ strerror(errno));
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "max open fd set to 64k");
+ }
+
+ }
+ }
+#endif
+ ret = 0;
+out:
+ return ret;
+}
+
+/*
+ * fini - finish function called during unloading of client protocol
+ * @this:
+ *
+ */
+void
+fini (xlator_t *this)
+{
+ /* TODO: Check if its enough.. how to call transport's fini () */
+ client_conf_t *conf = NULL;
+
+ conf = this->private;
+ this->private = NULL;
+
+ if (conf) {
+ GF_FREE (conf);
+ }
+ return;
+}
+
+
+int
+protocol_client_handshake (xlator_t *this, transport_t *trans)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_mop_setvolume_req_t *req = NULL;
+ dict_t *options = NULL;
+ int32_t ret = -1;
+ int hdrlen = 0;
+ int dict_len = 0;
+ call_frame_t *fr = NULL;
+ char *process_uuid_xl;
+
+ options = this->options;
+ ret = dict_set_str (options, "protocol-version", GF_PROTOCOL_VERSION);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set protocol version(%s) in handshake msg",
+ GF_PROTOCOL_VERSION);
+ }
+
+ ret = gf_asprintf (&process_uuid_xl, "%s-%s", this->ctx->process_uuid,
+ this->name);
+ if (-1 == ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "asprintf failed while setting process_uuid");
+ goto fail;
+ }
+ ret = dict_set_dynstr (options, "process-uuid",
+ process_uuid_xl);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set process-uuid(%s) in handshake msg",
+ process_uuid_xl);
+ }
+
+ if (this->ctx->cmd_args.volfile_server) {
+ if (this->ctx->cmd_args.volfile_id)
+ ret = dict_set_str (options, "volfile-key",
+ this->ctx->cmd_args.volfile_id);
+ ret = dict_set_uint32 (options, "volfile-checksum",
+ this->graph->volfile_checksum);
+ }
+
+ dict_len = dict_serialized_length (options);
+ if (dict_len < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get serialized length of dict(%p)",
+ options);
+ ret = dict_len;
+ goto fail;
+ }
+
+ hdrlen = gf_hdr_len (req, dict_len);
+ hdr = gf_hdr_new (req, dict_len);
+ GF_VALIDATE_OR_GOTO (this->name, hdr, fail);
+
+ req = gf_param (hdr);
+
+ ret = dict_serialize (options, req->buf);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to serialize dictionary(%p)",
+ options);
+ goto fail;
+ }
+
+ req->dict_len = hton32 (dict_len);
+ fr = create_frame (this, this->ctx->pool);
+ GF_VALIDATE_OR_GOTO (this->name, fr, fail);
+
+ fr->local = trans;
+ ret = protocol_client_xfer (fr, this, trans,
+ GF_OP_TYPE_MOP_REQUEST, GF_MOP_SETVOLUME,
+ hdr, hdrlen, NULL, 0, NULL);
+ return ret;
+fail:
+ if (hdr)
+ GF_FREE (hdr);
+ return ret;
+}
+
+
+int
+protocol_client_pollout (xlator_t *this, transport_t *trans)
+{
+ client_conf_t *conf = NULL;
+
+ conf = trans->xl->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ gettimeofday (&conf->last_sent, NULL);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ return 0;
+}
+
+
+int
+protocol_client_pollin (xlator_t *this, transport_t *trans)
+{
+ client_conf_t *conf = NULL;
+ int ret = -1;
+ struct iobuf *iobuf = NULL;
+ char *hdr = NULL;
+ size_t hdrlen = 0;
+
+ conf = trans->xl->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ gettimeofday (&conf->last_received, NULL);
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ ret = transport_receive (trans, &hdr, &hdrlen, &iobuf);
+
+ if (ret == 0)
+ {
+ ret = protocol_client_interpret (this, trans, hdr, hdrlen,
+ iobuf);
+ }
+
+ /* TODO: use mem-pool */
+ GF_FREE (hdr);
+
+ return ret;
+}
+
+int
+client_priv_dump (xlator_t *this)
+{
+ client_conf_t *conf = NULL;
+ int ret = -1;
+ client_fd_ctx_t *tmp = NULL;
+ int i = 0;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ char key_prefix[GF_DUMP_MAX_BUF_LEN];
+
+ if (!this)
+ return -1;
+
+ conf = this->private;
+ if (!conf) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
+ }
+
+ ret = pthread_mutex_trylock(&conf->mutex);
+ if (ret) {
+ gf_log("", GF_LOG_WARNING, "Unable to lock client %s"
+ " errno: %d", this->name, errno);
+ return -1;
+ }
+
+ gf_proc_dump_build_key(key_prefix, "xlator.protocol.client",
+ "%s.priv", this->name);
+
+ gf_proc_dump_add_section(key_prefix);
+
+ list_for_each_entry(tmp, &conf->saved_fds, sfd_pos) {
+ gf_proc_dump_build_key(key, key_prefix,
+ "fd.%d.remote_fd", ++i);
+ gf_proc_dump_write(key, "%d", tmp->remote_fd);
+ }
+
+ gf_proc_dump_build_key(key, key_prefix, "connecting");
+ gf_proc_dump_write(key, "%d", conf->connecting);
+ gf_proc_dump_build_key(key, key_prefix, "last_sent");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_sent.tv_sec));
+ gf_proc_dump_build_key(key, key_prefix, "last_received");
+ gf_proc_dump_write(key, "%s", ctime(&conf->last_received.tv_sec));
+
+ pthread_mutex_unlock(&conf->mutex);
+
+ return 0;
+
+}
+
+int32_t
+client_inodectx_dump (xlator_t *this, inode_t *inode)
+{
+ ino_t par = 0;
+ int ret = -1;
+ char key[GF_DUMP_MAX_BUF_LEN];
+
+ if (!inode)
+ return -1;
+
+ if (!this)
+ return -1;
+
+ ret = inode_ctx_get (inode, this, &par);
+
+ if (ret != 0)
+ return ret;
+
+ gf_proc_dump_build_key(key, "xlator.protocol.client",
+ "%s.inode.%ld.par",
+ this->name,inode->ino);
+ gf_proc_dump_write(key, "%ld", par);
+
+ return 0;
+}
+
+/*
+ * client_protocol_notify - notify function for client protocol
+ * @this:
+ * @trans: transport object
+ * @event
+ *
+ */
+
+int
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ int i = 0;
+ int ret = 0;
+ int child_down = 1;
+ int was_not_down = 0;
+ transport_t *trans = NULL;
+ client_connection_t *conn = NULL;
+ client_conf_t *conf = NULL;
+ xlator_list_t *parent = NULL;
+
+ conf = this->private;
+ trans = data;
+
+ switch (event) {
+ case GF_EVENT_POLLOUT:
+ {
+ ret = protocol_client_pollout (this, trans);
+
+ break;
+ }
+ case GF_EVENT_POLLIN:
+ {
+ ret = protocol_client_pollin (this, trans);
+
+ break;
+ }
+ /* no break for ret check to happen below */
+ case GF_EVENT_POLLERR:
+ {
+ ret = -1;
+ protocol_client_cleanup (trans);
+
+ if (conf->connecting == 0) {
+ /* Let the connection/re-connection happen in
+ * background, for now, don't hang here,
+ * tell the parents that i am all ok..
+ */
+ parent = trans->xl->parents;
+ while (parent) {
+ parent->xlator->notify (parent->xlator,
+ GF_EVENT_CHILD_CONNECTING,
+ trans->xl);
+ parent = parent->next;
+ }
+ conf->connecting = 1;
+ }
+
+ was_not_down = 0;
+ for (i = 0; i < CHANNEL_MAX; i++) {
+ conn = conf->transport[i]->xl_private;
+ if (conn->connected == 1)
+ was_not_down = 1;
+ }
+
+ conn = trans->xl_private;
+ if (conn->connected) {
+ conn->connected = 0;
+ if (conn->reconnect == 0)
+ client_protocol_reconnect (trans);
+ }
+
+ child_down = 1;
+ for (i = 0; i < CHANNEL_MAX; i++) {
+ trans = conf->transport[i];
+ conn = trans->xl_private;
+ if (conn->connected == 1)
+ child_down = 0;
+ }
+
+ if (child_down && was_not_down) {
+ gf_log (this->name, GF_LOG_INFO, "disconnected");
+
+ protocol_client_mark_fd_bad (this);
+
+ parent = this->parents;
+ while (parent) {
+ xlator_notify (parent->xlator,
+ GF_EVENT_CHILD_DOWN, this);
+ parent = parent->next;
+ }
+ }
+ }
+ break;
+
+ case GF_EVENT_PARENT_UP:
+ {
+ client_conf_t *conf = NULL;
+ int i = 0;
+ transport_t *trans = NULL;
+
+ conf = this->private;
+ for (i = 0; i < CHANNEL_MAX; i++) {
+ trans = conf->transport[i];
+ if (!trans) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "transport init failed");
+ return -1;
+ }
+
+ conn = trans->xl_private;
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got GF_EVENT_PARENT_UP, attempting connect "
+ "on transport");
+
+ client_protocol_reconnect (trans);
+ }
+ }
+ break;
+
+ case GF_EVENT_CHILD_UP:
+ {
+ char *handshake = NULL;
+
+ ret = dict_get_str (this->options, "disable-handshake",
+ &handshake);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got GF_EVENT_CHILD_UP");
+ if ((ret < 0) ||
+ (strcasecmp (handshake, "on"))) {
+ ret = protocol_client_handshake (this, trans);
+ } else {
+ conn = trans->xl_private;
+ conn->connected = 1;
+ ret = default_notify (this, event, trans);
+ }
+
+ if (ret)
+ transport_disconnect (trans);
+
+ }
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_DEBUG,
+ "got %d, calling default_notify ()", event);
+
+ default_notify (this, event, data);
+ break;
+ }
+
+ return ret;
+}
+
+
+struct xlator_fops fops = {
+ .stat = client_stat,
+ .readlink = client_readlink,
+ .mknod = client_mknod,
+ .mkdir = client_mkdir,
+ .unlink = client_unlink,
+ .rmdir = client_rmdir,
+ .symlink = client_symlink,
+ .rename = client_rename,
+ .link = client_link,
+ .truncate = client_truncate,
+ .open = client_open,
+ .readv = client_readv,
+ .writev = client_writev,
+ .statfs = client_statfs,
+ .flush = client_flush,
+ .fsync = client_fsync,
+ .setxattr = client_setxattr,
+ .getxattr = client_getxattr,
+ .fsetxattr = client_fsetxattr,
+ .fgetxattr = client_fgetxattr,
+ .removexattr = client_removexattr,
+ .opendir = client_opendir,
+ .readdir = client_readdir,
+ .readdirp = client_readdirp,
+ .fsyncdir = client_fsyncdir,
+ .access = client_access,
+ .ftruncate = client_ftruncate,
+ .fstat = client_fstat,
+ .create = client_create,
+ .lk = client_lk,
+ .inodelk = client_inodelk,
+ .finodelk = client_finodelk,
+ .entrylk = client_entrylk,
+ .fentrylk = client_fentrylk,
+ .lookup = client_lookup,
+ .rchecksum = client_rchecksum,
+ .xattrop = client_xattrop,
+ .fxattrop = client_fxattrop,
+ .setattr = client_setattr,
+ .fsetattr = client_fsetattr,
+ .getspec = client_getspec,
+};
+
+struct xlator_cbks cbks = {
+ .release = client_release,
+ .releasedir = client_releasedir
+};
+
+
+struct xlator_dumpops dumpops = {
+ .priv = client_priv_dump,
+ .inodectx = client_inodectx_dump,
+};
+
+struct volume_options options[] = {
+ { .key = {"username"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"password"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport-type"},
+ .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp",
+ "tcp/client", "ib-verbs/client"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"remote-host"},
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS
+ },
+ { .key = {"remote-subvolume"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"frame-timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 86400,
+ },
+ { .key = {"ping-timeout"},
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 1,
+ .max = 1013,
+ },
+ { .key = {NULL} },
+};
diff --git a/xlators/protocol/legacy/client/src/client-protocol.h b/xlators/protocol/legacy/client/src/client-protocol.h
new file mode 100644
index 000000000..81c5a2520
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/client-protocol.h
@@ -0,0 +1,178 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CLIENT_PROTOCOL_H
+#define _CLIENT_PROTOCOL_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <arpa/inet.h>
+#include "inode.h"
+#include "timer.h"
+#include "byte-order.h"
+#include "saved-frames.h"
+
+#define CLIENT_PORT_CEILING 1023
+
+#define GF_CLIENT_INODE_SELF 0
+#define GF_CLIENT_INODE_PARENT 1
+
+#define CLIENT_CONF(this) ((client_conf_t *)(this->private))
+
+#define RECEIVE_TIMEOUT(_cprivate,_current) \
+ ((_cprivate->last_received.tv_sec + \
+ _cprivate->frame_timeout) < \
+ _current.tv_sec)
+
+#define SEND_TIMEOUT(_cprivate,_current) \
+ ((_cprivate->last_sent.tv_sec + \
+ _cprivate->frame_timeout) < \
+ _current.tv_sec)
+
+enum {
+ CHANNEL_BULK = 0,
+ CHANNEL_LOWLAT = 1,
+ CHANNEL_MAX
+};
+
+#define CLIENT_CHANNEL client_channel
+
+struct client_connection;
+typedef struct client_connection client_connection_t;
+
+#include "stack.h"
+#include "xlator.h"
+#include "transport.h"
+#include "protocol.h"
+
+typedef struct _client_fd_ctx {
+ struct list_head sfd_pos; /* Stores the reference to this
+ fd's position in the saved_fds list.
+ */
+ int64_t remote_fd;
+ inode_t *inode;
+ uint64_t ino;
+ uint64_t gen;
+ char is_dir;
+ char released;
+ int32_t flags;
+ int32_t wbflags;
+} client_fd_ctx_t;
+
+struct _client_conf {
+ transport_t *transport[CHANNEL_MAX];
+ struct list_head saved_fds;
+ struct timeval last_sent;
+ struct timeval last_received;
+ pthread_mutex_t mutex;
+ int connecting;
+};
+typedef struct _client_conf client_conf_t;
+
+/* This will be stored in transport_t->xl_private */
+struct client_connection {
+ pthread_mutex_t lock;
+ uint64_t callid;
+ struct saved_frames *saved_frames;
+ int32_t frame_timeout;
+ int32_t ping_started;
+ int32_t ping_timeout;
+ int32_t transport_activity;
+ gf_timer_t *reconnect;
+ char connected;
+ uint64_t max_block_size;
+ gf_timer_t *timer;
+ gf_timer_t *ping_timer;
+};
+
+typedef struct {
+ loc_t loc;
+ loc_t loc2;
+ fd_t *fd;
+ gf_op_t op;
+ client_fd_ctx_t *fdctx;
+ uint32_t flags;
+ uint32_t wbflags;
+} client_local_t;
+
+
+static inline void
+gf_string_to_stat(char *string, struct iatt *stbuf)
+{
+ uint64_t dev = 0;
+ uint64_t ino = 0;
+ uint32_t mode = 0;
+ uint32_t nlink = 0;
+ uint32_t uid = 0;
+ uint32_t gid = 0;
+ uint64_t rdev = 0;
+ uint64_t size = 0;
+ uint32_t blksize = 0;
+ uint64_t blocks = 0;
+ uint32_t atime = 0;
+ uint32_t atime_nsec = 0;
+ uint32_t mtime = 0;
+ uint32_t mtime_nsec = 0;
+ uint32_t ctime = 0;
+ uint32_t ctime_nsec = 0;
+
+ sscanf (string, GF_STAT_PRINT_FMT_STR,
+ &dev,
+ &ino,
+ &mode,
+ &nlink,
+ &uid,
+ &gid,
+ &rdev,
+ &size,
+ &blksize,
+ &blocks,
+ &atime,
+ &atime_nsec,
+ &mtime,
+ &mtime_nsec,
+ &ctime,
+ &ctime_nsec);
+
+ stbuf->ia_gen = dev;
+ stbuf->ia_ino = ino;
+ stbuf->ia_prot = ia_prot_from_st_mode (mode);
+ stbuf->ia_type = ia_type_from_st_mode (mode);
+ stbuf->ia_nlink = nlink;
+ stbuf->ia_uid = uid;
+ stbuf->ia_gid = gid;
+ stbuf->ia_rdev = rdev;
+ stbuf->ia_size = size;
+ stbuf->ia_blksize = blksize;
+ stbuf->ia_blocks = blocks;
+
+ stbuf->ia_atime = atime;
+ stbuf->ia_mtime = mtime;
+ stbuf->ia_ctime = ctime;
+
+ stbuf->ia_atime_nsec = atime_nsec;
+ stbuf->ia_mtime_nsec = mtime_nsec;
+ stbuf->ia_ctime_nsec = ctime_nsec;
+}
+
+#endif
diff --git a/xlators/protocol/legacy/client/src/saved-frames.c b/xlators/protocol/legacy/client/src/saved-frames.c
new file mode 100644
index 000000000..b54495f25
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/saved-frames.c
@@ -0,0 +1,196 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "saved-frames.h"
+#include "common-utils.h"
+#include "protocol.h"
+#include "xlator.h"
+#include "client-mem-types.h"
+
+
+
+struct saved_frames *
+gf_client_saved_frames_new (void)
+{
+ struct saved_frames *saved_frames = NULL;
+
+ saved_frames = GF_CALLOC (sizeof (*saved_frames), 1,
+ gf_client_mt_saved_frames);
+ if (!saved_frames) {
+ return NULL;
+ }
+
+ gf_log ("", 1, "here");
+ INIT_LIST_HEAD (&saved_frames->fops.list);
+ INIT_LIST_HEAD (&saved_frames->mops.list);
+ INIT_LIST_HEAD (&saved_frames->cbks.list);
+
+ return saved_frames;
+}
+
+
+struct saved_frame *
+get_head_frame_for_type (struct saved_frames *frames, int8_t type)
+{
+ struct saved_frame *head_frame = NULL;
+
+ switch (type) {
+ case GF_OP_TYPE_FOP_REQUEST:
+ case GF_OP_TYPE_FOP_REPLY:
+ head_frame = &frames->fops;
+ break;
+ case GF_OP_TYPE_MOP_REQUEST:
+ case GF_OP_TYPE_MOP_REPLY:
+ head_frame = &frames->mops;
+ break;
+ case GF_OP_TYPE_CBK_REQUEST:
+ case GF_OP_TYPE_CBK_REPLY:
+ head_frame = &frames->cbks;
+ break;
+ }
+
+ return head_frame;
+}
+
+
+int
+saved_frames_put (struct saved_frames *frames, call_frame_t *frame,
+ int32_t op, int8_t type, int64_t callid)
+{
+ struct saved_frame *saved_frame = NULL;
+ struct saved_frame *head_frame = NULL;
+
+ head_frame = get_head_frame_for_type (frames, type);
+
+ saved_frame = GF_CALLOC (sizeof (*saved_frame), 1,
+ gf_client_mt_saved_frame);
+ if (!saved_frame) {
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD (&saved_frame->list);
+ saved_frame->frame = frame;
+ saved_frame->op = op;
+ saved_frame->type = type;
+ saved_frame->callid = callid;
+
+ gettimeofday (&saved_frame->saved_at, NULL);
+
+ list_add_tail (&saved_frame->list, &head_frame->list);
+ frames->count++;
+
+ return 0;
+}
+
+
+call_frame_t *
+saved_frames_get (struct saved_frames *frames, int32_t op,
+ int8_t type, int64_t callid)
+{
+ struct saved_frame *saved_frame = NULL;
+ struct saved_frame *tmp = NULL;
+ struct saved_frame *head_frame = NULL;
+ call_frame_t *frame = NULL;
+
+ head_frame = get_head_frame_for_type (frames, type);
+
+ list_for_each_entry (tmp, &head_frame->list, list) {
+ if (tmp->callid == callid) {
+ list_del_init (&tmp->list);
+ frames->count--;
+ saved_frame = tmp;
+ break;
+ }
+ }
+
+ if (saved_frame)
+ frame = saved_frame->frame;
+
+ GF_FREE (saved_frame);
+
+ return frame;
+}
+
+struct saved_frame *
+saved_frames_get_timedout (struct saved_frames *frames, int8_t type,
+ uint32_t timeout, struct timeval *current)
+{
+ struct saved_frame *bailout_frame = NULL, *tmp = NULL;
+ struct saved_frame *head_frame = NULL;
+
+ head_frame = get_head_frame_for_type (frames, type);
+
+ if (!list_empty(&head_frame->list)) {
+ tmp = list_entry (head_frame->list.next, typeof (*tmp), list);
+ if ((tmp->saved_at.tv_sec + timeout) < current->tv_sec) {
+ bailout_frame = tmp;
+ list_del_init (&bailout_frame->list);
+ frames->count--;
+ }
+ }
+
+ return bailout_frame;
+}
+
+void
+saved_frames_unwind (xlator_t *this, struct saved_frames *saved_frames,
+ struct saved_frame *head,
+ gf_op_t gf_ops[], char *gf_op_list[])
+{
+ struct saved_frame *trav = NULL;
+ struct saved_frame *tmp = NULL;
+
+ gf_hdr_common_t hdr = {0, };
+ call_frame_t *frame = NULL;
+
+ hdr.rsp.op_ret = hton32 (-1);
+ hdr.rsp.op_errno = hton32 (ENOTCONN);
+
+ list_for_each_entry_safe (trav, tmp, &head->list, list) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "forced unwinding frame type(%d) op(%s)",
+ trav->type, gf_op_list[trav->op]);
+
+ hdr.type = hton32 (trav->type);
+ hdr.op = hton32 (trav->op);
+
+ frame = trav->frame;
+
+ saved_frames->count--;
+
+ gf_ops[trav->op] (frame, &hdr, sizeof (hdr), NULL);
+
+ list_del_init (&trav->list);
+ GF_FREE (trav);
+ }
+}
+
+
+void
+gf_client_saved_frames_destroy (xlator_t *this, struct saved_frames *frames,
+ gf_op_t gf_fops[], gf_op_t gf_mops[],
+ gf_op_t gf_cbks[])
+{
+ saved_frames_unwind (this, frames, &frames->fops, gf_fops, gf_fop_list);
+ saved_frames_unwind (this, frames, &frames->mops, gf_mops, gf_mop_list);
+ saved_frames_unwind (this, frames, &frames->cbks, gf_cbks, gf_cbk_list);
+
+ GF_FREE (frames);
+}
diff --git a/xlators/protocol/legacy/client/src/saved-frames.h b/xlators/protocol/legacy/client/src/saved-frames.h
new file mode 100644
index 000000000..a62e328f9
--- /dev/null
+++ b/xlators/protocol/legacy/client/src/saved-frames.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAVED_FRAMES_H
+#define _SAVED_FRAMES_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+#include <sys/time.h>
+#include "stack.h"
+#include "list.h"
+#include "protocol.h"
+
+/* UGLY: have common typedef b/w saved-frames.c and protocol-client.c */
+typedef int32_t (*gf_op_t) (call_frame_t *frame,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf);
+
+
+struct saved_frame {
+ union {
+ struct list_head list;
+ struct {
+ struct saved_frame *frame_next;
+ struct saved_frame *frame_prev;
+ };
+ };
+
+ struct timeval saved_at;
+ call_frame_t *frame;
+ int32_t op;
+ int8_t type;
+ uint64_t callid;
+};
+
+
+struct saved_frames {
+ int64_t count;
+ struct saved_frame fops;
+ struct saved_frame mops;
+ struct saved_frame cbks;
+};
+
+
+struct saved_frames *gf_client_saved_frames_new ();
+int saved_frames_put (struct saved_frames *frames, call_frame_t *frame,
+ int32_t op, int8_t type, int64_t callid);
+call_frame_t *saved_frames_get (struct saved_frames *frames, int32_t op,
+ int8_t type, int64_t callid);
+
+struct saved_frame *
+saved_frames_get_timedout (struct saved_frames *frames, int8_t type,
+ uint32_t timeout, struct timeval *current);
+
+void gf_client_saved_frames_destroy (xlator_t *this, struct saved_frames *frames,
+ gf_op_t gf_fops[], gf_op_t gf_mops[],
+ gf_op_t gf_cbks[]);
+
+#endif /* _SAVED_FRAMES_H */
diff --git a/xlators/protocol/legacy/lib/Makefile.am b/xlators/protocol/legacy/lib/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/protocol/legacy/lib/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/protocol/legacy/lib/src/Makefile.am b/xlators/protocol/legacy/lib/src/Makefile.am
new file mode 100644
index 000000000..1f0e93e30
--- /dev/null
+++ b/xlators/protocol/legacy/lib/src/Makefile.am
@@ -0,0 +1,14 @@
+lib_LTLIBRARIES = libgfproto.la
+
+libgfproto_la_CFLAGS = -fPIC -Wall -g -shared -nostartfiles $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS)
+
+libgfproto_la_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE \
+ -D$(GF_HOST_OS) -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
+ -DTRANSPORTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/transport\" \
+ -I$(CONTRIBDIR)/rbtree -I$(top_srcdir)/libglusterfs/src/
+
+libgfproto_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+libgfproto_la_SOURCES = transport.c protocol.c
+
+noinst_HEADERS = transport.h protocol.h
diff --git a/xlators/protocol/legacy/lib/src/protocol.c b/xlators/protocol/legacy/lib/src/protocol.c
new file mode 100644
index 000000000..63950f43d
--- /dev/null
+++ b/xlators/protocol/legacy/lib/src/protocol.c
@@ -0,0 +1,108 @@
+
+#include "globals.h"
+#include "compat.h"
+#include "protocol.h"
+
+char *gf_mop_list[GF_MOP_MAXVALUE];
+char *gf_cbk_list[GF_CBK_MAXVALUE];
+
+static int
+gf_dirent_nb_size (gf_dirent_t *entries)
+{
+ return (sizeof (struct gf_dirent_nb) + strlen (entries->d_name) + 1);
+}
+
+int
+gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size)
+{
+ struct gf_dirent_nb *entry_nb = NULL;
+ gf_dirent_t *entry = NULL;
+ int size = 0;
+ int entry_size = 0;
+
+
+ list_for_each_entry (entry, &entries->list, list) {
+ entry_size = gf_dirent_nb_size (entry);
+
+ if (buf && (size + entry_size <= buf_size)) {
+ entry_nb = (void *) (buf + size);
+
+ entry_nb->d_ino = hton64 (entry->d_ino);
+ entry_nb->d_off = hton64 (entry->d_off);
+ entry_nb->d_len = hton32 (entry->d_len);
+ entry_nb->d_type = hton32 (entry->d_type);
+
+ gf_stat_from_iatt (&entry_nb->d_stat, &entry->d_stat);
+
+ strcpy (entry_nb->d_name, entry->d_name);
+ }
+ size += entry_size;
+ }
+
+ return size;
+}
+
+
+int
+gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size)
+{
+ struct gf_dirent_nb *entry_nb = NULL;
+ int remaining_size = 0;
+ int least_dirent_size = 0;
+ int count = 0;
+ gf_dirent_t *entry = NULL;
+ int entry_strlen = 0;
+ int entry_len = 0;
+
+
+ remaining_size = buf_size;
+ least_dirent_size = (sizeof (struct gf_dirent_nb) + 2);
+
+ while (remaining_size >= least_dirent_size) {
+ entry_nb = (void *)(buf + (buf_size - remaining_size));
+
+ entry_strlen = strnlen (entry_nb->d_name, remaining_size);
+ if (entry_strlen == remaining_size) {
+ break;
+ }
+
+ entry_len = sizeof (gf_dirent_t) + entry_strlen + 1;
+ entry = GF_CALLOC (1, entry_len, gf_common_mt_gf_dirent_t);
+ if (!entry) {
+ break;
+ }
+
+ entry->d_ino = ntoh64 (entry_nb->d_ino);
+ entry->d_off = ntoh64 (entry_nb->d_off);
+ entry->d_len = ntoh32 (entry_nb->d_len);
+ entry->d_type = ntoh32 (entry_nb->d_type);
+
+ gf_stat_to_iatt (&entry_nb->d_stat, &entry->d_stat);
+
+ strcpy (entry->d_name, entry_nb->d_name);
+
+ list_add_tail (&entry->list, &entries->list);
+
+ remaining_size -= (sizeof (*entry_nb) + entry_strlen + 1);
+ count++;
+ }
+
+ return count;
+}
+
+int
+protocol_common_init (void)
+{
+ gf_mop_list[GF_MOP_SETVOLUME] = "SETVOLUME";
+ gf_mop_list[GF_MOP_GETVOLUME] = "GETVOLUME";
+ gf_mop_list[GF_MOP_SETSPEC] = "SETSPEC";
+ gf_mop_list[GF_MOP_GETSPEC] = "GETSPEC";
+ gf_mop_list[GF_MOP_LOG] = "LOG";
+ gf_mop_list[GF_MOP_PING] = "PING";
+
+ gf_cbk_list[GF_CBK_FORGET] = "FORGET";
+ gf_cbk_list[GF_CBK_RELEASE] = "RELEASE";
+ gf_cbk_list[GF_CBK_RELEASEDIR] = "RELEASEDIR";
+
+ return 0;
+}
diff --git a/xlators/protocol/legacy/lib/src/protocol.h b/xlators/protocol/legacy/lib/src/protocol.h
new file mode 100644
index 000000000..fe1f5d29a
--- /dev/null
+++ b/xlators/protocol/legacy/lib/src/protocol.h
@@ -0,0 +1,1118 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _PROTOCOL_H
+#define _PROTOCOL_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "byte-order.h"
+#include "iatt.h"
+
+/* Any changes in the protocol structure or adding new '[f,m]ops' needs to
+ * bump the protocol version by "0.1"
+ */
+
+#define GF_PROTOCOL_VERSION "3.0"
+
+extern char *gf_mop_list[];
+extern char *gf_cbk_list[];
+
+/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
+typedef enum {
+ GF_PROTO_FOP_STAT, /* 0 */
+ GF_PROTO_FOP_READLINK, /* 1 */
+ GF_PROTO_FOP_MKNOD, /* 2 */
+ GF_PROTO_FOP_MKDIR,
+ GF_PROTO_FOP_UNLINK,
+ GF_PROTO_FOP_RMDIR, /* 5 */
+ GF_PROTO_FOP_SYMLINK,
+ GF_PROTO_FOP_RENAME,
+ GF_PROTO_FOP_LINK,
+ GF_PROTO_FOP_TRUNCATE,
+ GF_PROTO_FOP_OPEN, /* 10 */
+ GF_PROTO_FOP_READ,
+ GF_PROTO_FOP_WRITE,
+ GF_PROTO_FOP_STATFS, /* 15 */
+ GF_PROTO_FOP_FLUSH,
+ GF_PROTO_FOP_FSYNC,
+ GF_PROTO_FOP_SETXATTR,
+ GF_PROTO_FOP_GETXATTR,
+ GF_PROTO_FOP_REMOVEXATTR,/* 20 */
+ GF_PROTO_FOP_OPENDIR,
+ GF_PROTO_FOP_GETDENTS,
+ GF_PROTO_FOP_FSYNCDIR,
+ GF_PROTO_FOP_ACCESS,
+ GF_PROTO_FOP_CREATE, /* 25 */
+ GF_PROTO_FOP_FTRUNCATE,
+ GF_PROTO_FOP_FSTAT,
+ GF_PROTO_FOP_LK,
+ GF_PROTO_FOP_LOOKUP,
+ GF_PROTO_FOP_SETDENTS,
+ GF_PROTO_FOP_READDIR,
+ GF_PROTO_FOP_INODELK, /* 35 */
+ GF_PROTO_FOP_FINODELK,
+ GF_PROTO_FOP_ENTRYLK,
+ GF_PROTO_FOP_FENTRYLK,
+ GF_PROTO_FOP_CHECKSUM,
+ GF_PROTO_FOP_XATTROP, /* 40 */
+ GF_PROTO_FOP_FXATTROP,
+ GF_PROTO_FOP_LOCK_NOTIFY,
+ GF_PROTO_FOP_LOCK_FNOTIFY,
+ GF_PROTO_FOP_FGETXATTR,
+ GF_PROTO_FOP_FSETXATTR, /* 45 */
+ GF_PROTO_FOP_RCHECKSUM,
+ GF_PROTO_FOP_SETATTR,
+ GF_PROTO_FOP_FSETATTR,
+ GF_PROTO_FOP_READDIRP,
+ GF_PROTO_FOP_MAXVALUE,
+} glusterfs_proto_fop_t;
+
+/* NOTE: add members ONLY at the end (just before _MAXVALUE) */
+typedef enum {
+ GF_MOP_SETVOLUME, /* 0 */
+ GF_MOP_GETVOLUME, /* 1 */
+ GF_MOP_STATS,
+ GF_MOP_SETSPEC,
+ GF_MOP_GETSPEC,
+ GF_MOP_PING, /* 5 */
+ GF_MOP_LOG,
+ GF_MOP_NOTIFY,
+ GF_MOP_MAXVALUE, /* 8 */
+} glusterfs_mop_t;
+
+typedef enum {
+ GF_CBK_FORGET, /* 0 */
+ GF_CBK_RELEASE, /* 1 */
+ GF_CBK_RELEASEDIR, /* 2 */
+ GF_CBK_MAXVALUE /* 3 */
+} glusterfs_cbk_t;
+
+typedef enum {
+ GF_OP_TYPE_FOP_REQUEST = 1,
+ GF_OP_TYPE_MOP_REQUEST,
+ GF_OP_TYPE_CBK_REQUEST,
+ GF_OP_TYPE_FOP_REPLY,
+ GF_OP_TYPE_MOP_REPLY,
+ GF_OP_TYPE_CBK_REPLY
+} glusterfs_op_type_t;
+
+
+struct gf_stat {
+ uint64_t ino;
+ uint64_t size;
+ uint64_t blocks;
+ uint64_t dev;
+ uint32_t rdev;
+ uint32_t mode;
+ uint32_t nlink;
+ uint32_t uid;
+ uint32_t gid;
+ uint32_t blksize;
+ uint32_t atime;
+ uint32_t atime_nsec;
+ uint32_t mtime ;
+ uint32_t mtime_nsec;
+ uint32_t ctime;
+ uint32_t ctime_nsec;
+} __attribute__((packed));
+
+
+static inline void
+gf_stat_to_stat (struct gf_stat *gf_stat, struct stat *stat)
+{
+ stat->st_dev = ntoh64 (gf_stat->dev);
+ stat->st_ino = ntoh64 (gf_stat->ino);
+ stat->st_mode = ntoh32 (gf_stat->mode);
+ stat->st_nlink = ntoh32 (gf_stat->nlink);
+ stat->st_uid = ntoh32 (gf_stat->uid);
+ stat->st_gid = ntoh32 (gf_stat->gid);
+ stat->st_rdev = ntoh32 (gf_stat->rdev);
+ stat->st_size = ntoh64 (gf_stat->size);
+ stat->st_blksize = ntoh32 (gf_stat->blksize);
+ stat->st_blocks = ntoh64 (gf_stat->blocks);
+ stat->st_atime = ntoh32 (gf_stat->atime);
+ stat->st_mtime = ntoh32 (gf_stat->mtime);
+ stat->st_ctime = ntoh32 (gf_stat->ctime);
+ ST_ATIM_NSEC_SET(stat, ntoh32 (gf_stat->atime_nsec));
+ ST_MTIM_NSEC_SET(stat, ntoh32 (gf_stat->mtime_nsec));
+ ST_CTIM_NSEC_SET(stat, ntoh32 (gf_stat->ctime_nsec));
+}
+
+
+static inline void
+gf_stat_from_stat (struct gf_stat *gf_stat, struct stat *stat)
+{
+ gf_stat->dev = hton64 (stat->st_dev);
+ gf_stat->ino = hton64 (stat->st_ino);
+ gf_stat->mode = hton32 (stat->st_mode);
+ gf_stat->nlink = hton32 (stat->st_nlink);
+ gf_stat->uid = hton32 (stat->st_uid);
+ gf_stat->gid = hton32 (stat->st_gid);
+ gf_stat->rdev = hton32 (stat->st_rdev);
+ gf_stat->size = hton64 (stat->st_size);
+ gf_stat->blksize = hton32 (stat->st_blksize);
+ gf_stat->blocks = hton64 (stat->st_blocks);
+ gf_stat->atime = hton32 (stat->st_atime);
+ gf_stat->mtime = hton32 (stat->st_mtime);
+ gf_stat->ctime = hton32 (stat->st_ctime);
+ gf_stat->atime_nsec = hton32 (ST_ATIM_NSEC(stat));
+ gf_stat->mtime_nsec = hton32 (ST_MTIM_NSEC(stat));
+ gf_stat->ctime_nsec = hton32 (ST_CTIM_NSEC(stat));
+}
+
+
+static inline void
+gf_stat_to_iatt (struct gf_stat *gf_stat, struct iatt *iatt)
+{
+ iatt->ia_ino = ntoh64 (gf_stat->ino);
+ iatt->ia_dev = ntoh64 (gf_stat->dev);
+ iatt->ia_type = ia_type_from_st_mode (ntoh32 (gf_stat->mode));
+ iatt->ia_prot = ia_prot_from_st_mode (ntoh32 (gf_stat->mode));
+ iatt->ia_nlink = ntoh32 (gf_stat->nlink);
+ iatt->ia_uid = ntoh32 (gf_stat->uid);
+ iatt->ia_gid = ntoh32 (gf_stat->gid);
+ iatt->ia_rdev = ntoh64 (gf_stat->rdev);
+ iatt->ia_size = ntoh64 (gf_stat->size);
+ iatt->ia_blksize = ntoh32 (gf_stat->blksize);
+ iatt->ia_blocks = ntoh64 (gf_stat->blocks);
+ iatt->ia_atime = ntoh32 (gf_stat->atime);
+ iatt->ia_atime_nsec = ntoh32 (gf_stat->atime_nsec);
+ iatt->ia_mtime = ntoh32 (gf_stat->mtime);
+ iatt->ia_mtime_nsec = ntoh32 (gf_stat->mtime_nsec);
+ iatt->ia_ctime = ntoh32 (gf_stat->ctime);
+ iatt->ia_ctime_nsec = ntoh32 (gf_stat->ctime_nsec);
+
+ iatt->ia_gen = ntoh64 (gf_stat->dev);
+}
+
+
+static inline void
+gf_stat_from_iatt (struct gf_stat *gf_stat, struct iatt *iatt)
+{
+ gf_stat->ino = hton64 (iatt->ia_ino);
+ gf_stat->dev = hton64 (iatt->ia_dev);
+ gf_stat->mode = hton32 (st_mode_from_ia (iatt->ia_prot,
+ iatt->ia_type));
+ gf_stat->nlink = hton32 (iatt->ia_nlink);
+ gf_stat->uid = hton32 (iatt->ia_uid);
+ gf_stat->gid = hton32 (iatt->ia_gid);
+ gf_stat->rdev = hton32 (iatt->ia_rdev);
+ gf_stat->size = hton64 (iatt->ia_size);
+ gf_stat->blksize = hton32 (iatt->ia_blksize);
+ gf_stat->blocks = hton64 (iatt->ia_blocks);
+ gf_stat->atime = hton32 (iatt->ia_atime);
+ gf_stat->atime_nsec = hton32 (iatt->ia_atime_nsec);
+ gf_stat->mtime = hton32 (iatt->ia_mtime);
+ gf_stat->mtime_nsec = hton32 (iatt->ia_mtime_nsec);
+ gf_stat->ctime = hton32 (iatt->ia_ctime);
+ gf_stat->ctime_nsec = hton32 (iatt->ia_ctime_nsec);
+
+ gf_stat->dev = hton64 (iatt->ia_gen);
+
+}
+
+
+struct gf_statfs {
+ uint64_t bsize;
+ uint64_t frsize;
+ uint64_t blocks;
+ uint64_t bfree;
+ uint64_t bavail;
+ uint64_t files;
+ uint64_t ffree;
+ uint64_t favail;
+ uint64_t fsid;
+ uint64_t flag;
+ uint64_t namemax;
+} __attribute__((packed));
+
+
+static inline void
+gf_statfs_to_statfs (struct gf_statfs *gf_stat, struct statvfs *stat)
+{
+ stat->f_bsize = ntoh64 (gf_stat->bsize);
+ stat->f_frsize = ntoh64 (gf_stat->frsize);
+ stat->f_blocks = ntoh64 (gf_stat->blocks);
+ stat->f_bfree = ntoh64 (gf_stat->bfree);
+ stat->f_bavail = ntoh64 (gf_stat->bavail);
+ stat->f_files = ntoh64 (gf_stat->files);
+ stat->f_ffree = ntoh64 (gf_stat->ffree);
+ stat->f_favail = ntoh64 (gf_stat->favail);
+ stat->f_fsid = ntoh64 (gf_stat->fsid);
+ stat->f_flag = ntoh64 (gf_stat->flag);
+ stat->f_namemax = ntoh64 (gf_stat->namemax);
+}
+
+
+static inline void
+gf_statfs_from_statfs (struct gf_statfs *gf_stat, struct statvfs *stat)
+{
+ gf_stat->bsize = hton64 (stat->f_bsize);
+ gf_stat->frsize = hton64 (stat->f_frsize);
+ gf_stat->blocks = hton64 (stat->f_blocks);
+ gf_stat->bfree = hton64 (stat->f_bfree);
+ gf_stat->bavail = hton64 (stat->f_bavail);
+ gf_stat->files = hton64 (stat->f_files);
+ gf_stat->ffree = hton64 (stat->f_ffree);
+ gf_stat->favail = hton64 (stat->f_favail);
+ gf_stat->fsid = hton64 (stat->f_fsid);
+ gf_stat->flag = hton64 (stat->f_flag);
+ gf_stat->namemax = hton64 (stat->f_namemax);
+}
+
+
+struct gf_flock {
+ uint16_t type;
+ uint16_t whence;
+ uint64_t start;
+ uint64_t len;
+ uint32_t pid;
+} __attribute__((packed));
+
+
+static inline void
+gf_flock_to_flock (struct gf_flock *gf_flock, struct gf_flock *flock)
+{
+ flock->l_type = ntoh16 (gf_flock->type);
+ flock->l_whence = ntoh16 (gf_flock->whence);
+ flock->l_start = ntoh64 (gf_flock->start);
+ flock->l_len = ntoh64 (gf_flock->len);
+ flock->l_pid = ntoh32 (gf_flock->pid);
+}
+
+
+static inline void
+gf_flock_from_flock (struct gf_flock *gf_flock, struct gf_flock *flock)
+{
+ gf_flock->type = hton16 (flock->l_type);
+ gf_flock->whence = hton16 (flock->l_whence);
+ gf_flock->start = hton64 (flock->l_start);
+ gf_flock->len = hton64 (flock->l_len);
+ gf_flock->pid = hton32 (flock->l_pid);
+}
+
+
+struct gf_timespec {
+ uint32_t tv_sec;
+ uint32_t tv_nsec;
+} __attribute__((packed));
+
+
+static inline void
+gf_timespec_to_timespec (struct gf_timespec *gf_ts, struct timespec *ts)
+{
+
+ ts[0].tv_sec = ntoh32 (gf_ts[0].tv_sec);
+ ts[0].tv_nsec = ntoh32 (gf_ts[0].tv_nsec);
+ ts[1].tv_sec = ntoh32 (gf_ts[1].tv_sec);
+ ts[1].tv_nsec = ntoh32 (gf_ts[1].tv_nsec);
+}
+
+
+static inline void
+gf_timespec_from_timespec (struct gf_timespec *gf_ts, struct timespec *ts)
+{
+ gf_ts[0].tv_sec = hton32 (ts[0].tv_sec);
+ gf_ts[0].tv_nsec = hton32 (ts[0].tv_nsec);
+ gf_ts[1].tv_sec = hton32 (ts[1].tv_sec);
+ gf_ts[1].tv_nsec = hton32 (ts[1].tv_nsec);
+}
+
+
+#define GF_O_ACCMODE 003
+#define GF_O_RDONLY 00
+#define GF_O_WRONLY 01
+#define GF_O_RDWR 02
+#define GF_O_CREAT 0100
+#define GF_O_EXCL 0200
+#define GF_O_NOCTTY 0400
+#define GF_O_TRUNC 01000
+#define GF_O_APPEND 02000
+#define GF_O_NONBLOCK 04000
+#define GF_O_SYNC 010000
+#define GF_O_ASYNC 020000
+
+#define GF_O_DIRECT 040000
+#define GF_O_DIRECTORY 0200000
+#define GF_O_NOFOLLOW 0400000
+#define GF_O_NOATIME 01000000
+#define GF_O_CLOEXEC 02000000
+
+#define GF_O_LARGEFILE 0100000
+
+#define XLATE_BIT(from, to, bit) do { \
+ if (from & bit) \
+ to = to | GF_##bit; \
+ } while (0)
+
+#define UNXLATE_BIT(from, to, bit) do { \
+ if (from & GF_##bit) \
+ to = to | bit; \
+ } while (0)
+
+#define XLATE_ACCESSMODE(from, to) do { \
+ switch (from & O_ACCMODE) { \
+ case O_RDONLY: to |= GF_O_RDONLY; \
+ break; \
+ case O_WRONLY: to |= GF_O_WRONLY; \
+ break; \
+ case O_RDWR: to |= GF_O_RDWR; \
+ break; \
+ } \
+ } while (0)
+
+#define UNXLATE_ACCESSMODE(from, to) do { \
+ switch (from & GF_O_ACCMODE) { \
+ case GF_O_RDONLY: to |= O_RDONLY; \
+ break; \
+ case GF_O_WRONLY: to |= O_WRONLY; \
+ break; \
+ case GF_O_RDWR: to |= O_RDWR; \
+ break; \
+ } \
+ } while (0)
+
+static inline uint32_t
+gf_flags_from_flags (uint32_t flags)
+{
+ uint32_t gf_flags = 0;
+
+ XLATE_ACCESSMODE (flags, gf_flags);
+
+ XLATE_BIT (flags, gf_flags, O_CREAT);
+ XLATE_BIT (flags, gf_flags, O_EXCL);
+ XLATE_BIT (flags, gf_flags, O_NOCTTY);
+ XLATE_BIT (flags, gf_flags, O_TRUNC);
+ XLATE_BIT (flags, gf_flags, O_APPEND);
+ XLATE_BIT (flags, gf_flags, O_NONBLOCK);
+ XLATE_BIT (flags, gf_flags, O_SYNC);
+ XLATE_BIT (flags, gf_flags, O_ASYNC);
+
+ XLATE_BIT (flags, gf_flags, O_DIRECT);
+ XLATE_BIT (flags, gf_flags, O_DIRECTORY);
+ XLATE_BIT (flags, gf_flags, O_NOFOLLOW);
+#ifdef O_NOATIME
+ XLATE_BIT (flags, gf_flags, O_NOATIME);
+#endif
+#ifdef O_CLOEXEC
+ XLATE_BIT (flags, gf_flags, O_CLOEXEC);
+#endif
+ XLATE_BIT (flags, gf_flags, O_LARGEFILE);
+
+ return gf_flags;
+}
+
+static inline uint32_t
+gf_flags_to_flags (uint32_t gf_flags)
+{
+ uint32_t flags = 0;
+
+ UNXLATE_ACCESSMODE (gf_flags, flags);
+
+ UNXLATE_BIT (gf_flags, flags, O_CREAT);
+ UNXLATE_BIT (gf_flags, flags, O_EXCL);
+ UNXLATE_BIT (gf_flags, flags, O_NOCTTY);
+ UNXLATE_BIT (gf_flags, flags, O_TRUNC);
+ UNXLATE_BIT (gf_flags, flags, O_APPEND);
+ UNXLATE_BIT (gf_flags, flags, O_NONBLOCK);
+ UNXLATE_BIT (gf_flags, flags, O_SYNC);
+ UNXLATE_BIT (gf_flags, flags, O_ASYNC);
+
+ UNXLATE_BIT (gf_flags, flags, O_DIRECT);
+ UNXLATE_BIT (gf_flags, flags, O_DIRECTORY);
+ UNXLATE_BIT (gf_flags, flags, O_NOFOLLOW);
+#ifdef O_NOATIME
+ UNXLATE_BIT (gf_flags, flags, O_NOATIME);
+#endif
+#ifdef O_CLOEXEC
+ UNXLATE_BIT (gf_flags, flags, O_CLOEXEC);
+#endif
+ UNXLATE_BIT (gf_flags, flags, O_LARGEFILE);
+
+ return flags;
+}
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ char path[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_stat_req_t;;
+typedef struct {
+ struct gf_stat stat;
+} __attribute__((packed)) gf_fop_stat_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t size;
+ char path[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_readlink_req_t;
+typedef struct {
+ struct gf_stat buf;
+ char path[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_readlink_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ uint64_t dev;
+ uint32_t mode;
+ char path[0]; /* NULL terminated */
+ char bname[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_mknod_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_mknod_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ uint32_t mode;
+ char path[0]; /* NULL terminated */
+ char bname[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_mkdir_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_mkdir_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ char path[0]; /* NULL terminated */
+ char bname[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_unlink_req_t;
+typedef struct {
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_unlink_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ char path[0];
+ char bname[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_rmdir_req_t;
+typedef struct {
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_rmdir_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ char path[0];
+ char bname[0];
+ char linkname[0];
+} __attribute__((packed)) gf_fop_symlink_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+}__attribute__((packed)) gf_fop_symlink_rsp_t;
+
+
+typedef struct {
+ uint64_t oldpar;
+ uint64_t oldgen;
+ uint64_t newpar;
+ uint64_t newgen;
+ char oldpath[0];
+ char oldbname[0]; /* NULL terminated */
+ char newpath[0];
+ char newbname[0]; /* NULL terminated */
+} __attribute__((packed)) gf_fop_rename_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat preoldparent;
+ struct gf_stat postoldparent;
+ struct gf_stat prenewparent;
+ struct gf_stat postnewparent;
+} __attribute__((packed)) gf_fop_rename_rsp_t;
+
+
+typedef struct {
+ uint64_t oldino;
+ uint64_t oldgen;
+ uint64_t newpar;
+ uint64_t newgen;
+ char oldpath[0];
+ char newpath[0];
+ char newbname[0];
+}__attribute__((packed)) gf_fop_link_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_link_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint64_t offset;
+ char path[0];
+} __attribute__((packed)) gf_fop_truncate_req_t;
+typedef struct {
+ struct gf_stat prestat;
+ struct gf_stat poststat;
+} __attribute__((packed)) gf_fop_truncate_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t flags;
+ uint32_t wbflags;
+ char path[0];
+} __attribute__((packed)) gf_fop_open_req_t;
+typedef struct {
+ int64_t fd;
+} __attribute__((packed)) gf_fop_open_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint64_t offset;
+ uint32_t size;
+} __attribute__((packed)) gf_fop_read_req_t;
+typedef struct {
+ struct gf_stat stat;
+ char buf[0];
+} __attribute__((packed)) gf_fop_read_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint64_t offset;
+ uint32_t size;
+} __attribute__((packed)) gf_fop_write_req_t;
+typedef struct {
+ struct gf_stat prestat;
+ struct gf_stat poststat;
+} __attribute__((packed)) gf_fop_write_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ char path[0];
+} __attribute__((packed)) gf_fop_statfs_req_t;
+typedef struct {
+ struct gf_statfs statfs;
+} __attribute__((packed)) gf_fop_statfs_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+} __attribute__((packed)) gf_fop_flush_req_t;
+typedef struct { } __attribute__((packed)) gf_fop_flush_rsp_t;
+
+
+typedef struct fsync_req {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t data;
+} __attribute__((packed)) gf_fop_fsync_req_t;
+typedef struct {
+ struct gf_stat prestat;
+ struct gf_stat poststat;
+} __attribute__((packed)) gf_fop_fsync_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t flags;
+ uint32_t dict_len;
+ char dict[0];
+ char path[0];
+} __attribute__((packed)) gf_fop_setxattr_req_t;
+typedef struct { } __attribute__((packed)) gf_fop_setxattr_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t flags;
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_fsetxattr_req_t;
+typedef struct { } __attribute__((packed)) gf_fop_fsetxattr_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t flags;
+ uint32_t dict_len;
+ char dict[0];
+ char path[0];
+} __attribute__((packed)) gf_fop_xattrop_req_t;
+
+typedef struct {
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_xattrop_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t flags;
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_fxattrop_req_t;
+
+typedef struct {
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_fxattrop_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t namelen;
+ char path[0];
+ char name[0];
+} __attribute__((packed)) gf_fop_getxattr_req_t;
+typedef struct {
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_getxattr_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t namelen;
+ char name[0];
+} __attribute__((packed)) gf_fop_fgetxattr_req_t;
+typedef struct {
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_fgetxattr_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ char path[0];
+ char name[0];
+} __attribute__((packed)) gf_fop_removexattr_req_t;
+typedef struct { } __attribute__((packed)) gf_fop_removexattr_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ char path[0];
+} __attribute__((packed)) gf_fop_opendir_req_t;
+typedef struct {
+ int64_t fd;
+} __attribute__((packed)) gf_fop_opendir_rsp_t;
+
+
+typedef struct fsyncdir_req {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ int32_t data;
+} __attribute__((packed)) gf_fop_fsyncdir_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_fsyncdir_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint64_t offset;
+ uint32_t size;
+} __attribute__((packed)) gf_fop_readdir_req_t;
+typedef struct {
+ uint32_t size;
+ char buf[0];
+} __attribute__((packed)) gf_fop_readdir_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint64_t offset;
+ uint32_t size;
+} __attribute__((packed)) gf_fop_readdirp_req_t;
+typedef struct {
+ uint32_t size;
+ char buf[0];
+} __attribute__((packed)) gf_fop_readdirp_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t mask;
+ char path[0];
+} __attribute__((packed)) gf_fop_access_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_access_rsp_t;
+
+
+typedef struct {
+ uint64_t par;
+ uint64_t gen;
+ uint32_t flags;
+ uint32_t mode;
+ char path[0];
+ char bname[0];
+} __attribute__((packed)) gf_fop_create_req_t;
+typedef struct {
+ struct gf_stat stat;
+ uint64_t fd;
+ struct gf_stat preparent;
+ struct gf_stat postparent;
+} __attribute__((packed)) gf_fop_create_rsp_t;
+
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint64_t offset;
+} __attribute__((packed)) gf_fop_ftruncate_req_t;
+typedef struct {
+ struct gf_stat prestat;
+ struct gf_stat poststat;
+} __attribute__((packed)) gf_fop_ftruncate_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+} __attribute__((packed)) gf_fop_fstat_req_t;
+typedef struct {
+ struct gf_stat stat;
+} __attribute__((packed)) gf_fop_fstat_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t cmd;
+ uint32_t type;
+ struct gf_flock flock;
+} __attribute__((packed)) gf_fop_lk_req_t;
+typedef struct {
+ struct gf_flock flock;
+} __attribute__((packed)) gf_fop_lk_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t cmd;
+ uint32_t type;
+ struct gf_flock flock;
+ char path[0];
+ char volume[0];
+} __attribute__((packed)) gf_fop_inodelk_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_inodelk_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t cmd;
+ uint32_t type;
+ struct gf_flock flock;
+ char volume[0];
+} __attribute__((packed)) gf_fop_finodelk_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_finodelk_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t cmd;
+ uint32_t type;
+ uint64_t namelen;
+ char path[0];
+ char name[0];
+ char volume[0];
+} __attribute__((packed)) gf_fop_entrylk_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_entrylk_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+ uint32_t cmd;
+ uint32_t type;
+ uint64_t namelen;
+ char name[0];
+ char volume[0];
+} __attribute__((packed)) gf_fop_fentrylk_req_t;
+typedef struct {
+} __attribute__((packed)) gf_fop_fentrylk_rsp_t;
+
+typedef struct {
+ uint64_t ino; /* NOTE: used only in case of 'root' lookup */
+ uint64_t par;
+ uint64_t gen;
+ uint32_t flags;
+ uint32_t dictlen;
+ char path[0];
+ char bname[0];
+ char dict[0];
+} __attribute__((packed)) gf_fop_lookup_req_t;
+typedef struct {
+ struct gf_stat stat;
+ struct gf_stat postparent;
+ uint32_t dict_len;
+ char dict[0];
+} __attribute__((packed)) gf_fop_lookup_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ uint32_t flag;
+ char path[0];
+} __attribute__((packed)) gf_fop_checksum_req_t;
+typedef struct {
+ unsigned char fchecksum[0];
+ unsigned char dchecksum[0];
+} __attribute__((packed)) gf_fop_checksum_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ struct gf_stat stbuf;
+ int32_t valid;
+ char path[0];
+} __attribute__((packed)) gf_fop_setattr_req_t;
+typedef struct {
+ struct gf_stat statpre;
+ struct gf_stat statpost;
+} __attribute__((packed)) gf_fop_setattr_rsp_t;
+
+typedef struct {
+ int64_t fd;
+ struct gf_stat stbuf;
+ int32_t valid;
+} __attribute__((packed)) gf_fop_fsetattr_req_t;
+typedef struct {
+ struct gf_stat statpre;
+ struct gf_stat statpost;
+} __attribute__((packed)) gf_fop_fsetattr_rsp_t;
+
+typedef struct {
+ int64_t fd;
+ uint64_t offset;
+ uint32_t len;
+} __attribute__((packed)) gf_fop_rchecksum_req_t;
+typedef struct {
+ uint32_t weak_checksum;
+ unsigned char strong_checksum[0];
+} __attribute__((packed)) gf_fop_rchecksum_rsp_t;
+
+typedef struct {
+ uint32_t flags;
+ uint32_t keylen;
+ char key[0];
+} __attribute__((packed)) gf_mop_getspec_req_t;
+typedef struct {
+ char spec[0];
+} __attribute__((packed)) gf_mop_getspec_rsp_t;
+
+
+typedef struct {
+ uint32_t msglen;
+ char msg[0];
+} __attribute__((packed)) gf_mop_log_req_t;
+typedef struct {
+} __attribute__((packed)) gf_mop_log_rsp_t;
+
+
+typedef struct {
+ uint32_t dict_len;
+ char buf[0];
+} __attribute__((packed)) gf_mop_setvolume_req_t;
+typedef struct {
+ uint32_t dict_len;
+ char buf[0];
+} __attribute__((packed)) gf_mop_setvolume_rsp_t;
+
+
+typedef struct {
+} __attribute__((packed)) gf_mop_ping_req_t;
+typedef struct {
+} __attribute__((packed)) gf_mop_ping_rsp_t;
+
+typedef struct {
+ uint32_t flags;
+ char buf[0];
+} __attribute__((packed)) gf_mop_notify_req_t;
+typedef struct {
+ uint32_t flags;
+ char buf[0];
+} __attribute__((packed)) gf_mop_notify_rsp_t;
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+} __attribute__((packed)) gf_cbk_releasedir_req_t;
+typedef struct {
+} __attribute__((packed)) gf_cbk_releasedir_rsp_t;
+
+
+typedef struct {
+ uint64_t ino;
+ uint64_t gen;
+ int64_t fd;
+} __attribute__((packed)) gf_cbk_release_req_t;
+typedef struct {
+} __attribute__((packed)) gf_cbk_release_rsp_t;
+
+
+typedef struct {
+ uint32_t count;
+ uint64_t ino_array[0];
+} __attribute__((packed)) gf_cbk_forget_req_t;
+typedef struct { } __attribute__((packed)) gf_cbk_forget_rsp_t;
+
+typedef struct {
+ uint32_t pid;
+ uint32_t uid;
+ uint32_t gid;
+
+ /* Number of groups being sent through the array above. */
+ uint32_t ngrps;
+
+ /* Array of groups to which the uid belongs apart from the primary group
+ * in gid.
+ */
+ uint32_t groups[GF_REQUEST_MAXGROUPS];
+
+ uint64_t lk_owner;
+} __attribute__ ((packed)) gf_hdr_req_t;
+
+
+typedef struct {
+ uint32_t op_ret;
+ uint32_t op_errno;
+} __attribute__ ((packed)) gf_hdr_rsp_t;
+
+
+typedef struct {
+ uint64_t callid;
+ uint32_t type;
+ uint32_t op;
+ uint32_t size;
+ union {
+ gf_hdr_req_t req;
+ gf_hdr_rsp_t rsp;
+ } __attribute__ ((packed));
+} __attribute__ ((packed)) gf_hdr_common_t;
+
+
+static inline gf_hdr_common_t *
+__gf_hdr_new (int size)
+{
+ gf_hdr_common_t *hdr = NULL;
+
+ /* TODO: use mem-pool */
+ hdr = GF_CALLOC (sizeof (gf_hdr_common_t) + size, 1,
+ gf_common_mt_gf_hdr_common_t);
+
+ if (!hdr) {
+ return NULL;
+ }
+
+ hdr->size = hton32 (size);
+
+ return hdr;
+}
+
+
+#define gf_hdr_len(type, x) (sizeof (gf_hdr_common_t) + sizeof (*type) + x)
+#define gf_hdr_new(type, x) __gf_hdr_new (sizeof (*type) + x)
+
+
+static inline void *
+gf_param (gf_hdr_common_t *hdr)
+{
+ return ((void *)hdr) + sizeof (*hdr);
+}
+
+
+struct gf_dirent_nb {
+ uint64_t d_ino;
+ uint64_t d_off;
+ uint32_t d_len;
+ uint32_t d_type;
+ struct gf_stat d_stat;
+ char d_name[0];
+} __attribute__((packed));
+
+int
+gf_dirent_unserialize (gf_dirent_t *entries, const char *buf, size_t buf_size);
+int
+gf_dirent_serialize (gf_dirent_t *entries, char *buf, size_t buf_size);
+
+int protocol_common_init (void);
+
+#endif
diff --git a/xlators/protocol/legacy/lib/src/transport.c b/xlators/protocol/legacy/lib/src/transport.c
new file mode 100644
index 000000000..d55ce69da
--- /dev/null
+++ b/xlators/protocol/legacy/lib/src/transport.c
@@ -0,0 +1,422 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/poll.h>
+#include <fnmatch.h>
+#include <stdint.h>
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "logging.h"
+#include "transport.h"
+#include "glusterfs.h"
+#include "xlator.h"
+#include "list.h"
+
+
+transport_t *
+transport_load (dict_t *options,
+ xlator_t *xl)
+{
+ struct transport *trans = NULL, *return_trans = NULL;
+ char *name = NULL;
+ void *handle = NULL;
+ char *type = NULL;
+ char str[] = "ERROR";
+ int32_t ret = -1;
+ int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0;
+ volume_opt_list_t *vol_opt = NULL;
+
+ GF_VALIDATE_OR_GOTO("transport", options, fail);
+ GF_VALIDATE_OR_GOTO("transport", xl, fail);
+
+ trans = GF_CALLOC (1, sizeof (struct transport),
+ gf_common_mt_transport);
+ GF_VALIDATE_OR_GOTO("transport", trans, fail);
+
+ trans->xl = xl;
+ type = str;
+
+ /* Backward compatibility */
+ ret = dict_get_str (options, "transport-type", &type);
+ if (ret < 0) {
+ ret = dict_set_str (options, "transport-type", "socket");
+ if (ret < 0)
+ gf_log ("dict", GF_LOG_DEBUG,
+ "setting transport-type failed");
+ gf_log ("transport", GF_LOG_WARNING,
+ "missing 'option transport-type'. defaulting to "
+ "\"socket\"");
+ } else {
+ {
+ /* Backword compatibility to handle * /client,
+ * * /server.
+ */
+ char *tmp = strchr (type, '/');
+ if (tmp)
+ *tmp = '\0';
+ }
+
+ is_tcp = strcmp (type, "tcp");
+ is_unix = strcmp (type, "unix");
+ is_ibsdp = strcmp (type, "ib-sdp");
+ if ((is_tcp == 0) ||
+ (is_unix == 0) ||
+ (is_ibsdp == 0)) {
+ if (is_unix == 0)
+ ret = dict_set_str (options,
+ "transport.address-family",
+ "unix");
+ if (is_ibsdp == 0)
+ ret = dict_set_str (options,
+ "transport.address-family",
+ "inet-sdp");
+
+ if (ret < 0)
+ gf_log ("dict", GF_LOG_DEBUG,
+ "setting address-family failed");
+
+ ret = dict_set_str (options,
+ "transport-type", "socket");
+ if (ret < 0)
+ gf_log ("dict", GF_LOG_DEBUG,
+ "setting transport-type failed");
+ }
+ }
+
+ ret = dict_get_str (options, "transport-type", &type);
+ if (ret < 0) {
+ GF_FREE (trans);
+ gf_log ("transport", GF_LOG_ERROR,
+ "'option transport-type <xx>' missing in volume '%s'",
+ xl->name);
+ goto fail;
+ }
+
+ ret = gf_asprintf (&name, "%s/%s.so", TRANSPORTDIR, type);
+ if (-1 == ret) {
+ gf_log ("transport", GF_LOG_ERROR, "asprintf failed");
+ goto fail;
+ }
+ gf_log ("transport", GF_LOG_DEBUG,
+ "attempt to load file %s", name);
+
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (handle == NULL) {
+ gf_log ("transport", GF_LOG_ERROR, "%s", dlerror ());
+ gf_log ("transport", GF_LOG_ERROR,
+ "volume '%s': transport-type '%s' is not valid or "
+ "not found on this machine",
+ xl->name, type);
+ GF_FREE (name);
+ GF_FREE (trans);
+ goto fail;
+ }
+ GF_FREE (name);
+
+ trans->ops = dlsym (handle, "tops");
+ if (trans->ops == NULL) {
+ gf_log ("transport", GF_LOG_ERROR,
+ "dlsym (transport_ops) on %s", dlerror ());
+ GF_FREE (trans);
+ goto fail;
+ }
+
+ trans->init = dlsym (handle, "init");
+ if (trans->init == NULL) {
+ gf_log ("transport", GF_LOG_ERROR,
+ "dlsym (gf_transport_init) on %s", dlerror ());
+ GF_FREE (trans);
+ goto fail;
+ }
+
+ trans->fini = dlsym (handle, "fini");
+ if (trans->fini == NULL) {
+ gf_log ("transport", GF_LOG_ERROR,
+ "dlsym (gf_transport_fini) on %s", dlerror ());
+ GF_FREE (trans);
+ goto fail;
+ }
+
+ vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ gf_common_mt_volume_opt_list_t);
+ vol_opt->given_opt = dlsym (handle, "options");
+ if (vol_opt->given_opt == NULL) {
+ gf_log ("transport", GF_LOG_DEBUG,
+ "volume option validation not specified");
+ } else {
+ list_add_tail (&vol_opt->list, &xl->volume_options);
+ if (-1 ==
+ validate_xlator_volume_options (xl,
+ vol_opt->given_opt)) {
+ gf_log ("transport", GF_LOG_ERROR,
+ "volume option validation failed");
+ GF_FREE (trans);
+ goto fail;
+ }
+ }
+
+ ret = trans->init (trans);
+ if (ret != 0) {
+ gf_log ("transport", GF_LOG_ERROR,
+ "'%s' initialization failed", type);
+ GF_FREE (trans);
+ goto fail;
+ }
+
+ pthread_mutex_init (&trans->lock, NULL);
+ return_trans = trans;
+fail:
+ return return_trans;
+}
+
+
+int32_t
+transport_submit (transport_t *this, char *buf, int32_t len,
+ struct iovec *vector, int count,
+ struct iobref *iobref)
+{
+ int32_t ret = -1;
+ transport_t *peer_trans = NULL;
+ struct iobuf *iobuf = NULL;
+ struct transport_msg *msg = NULL;
+
+ if (this->peer_trans) {
+ peer_trans = this->peer_trans;
+
+ msg = GF_CALLOC (1, sizeof (*msg),
+ gf_common_mt_transport_msg);
+ if (!msg) {
+ return -ENOMEM;
+ }
+
+ msg->hdr = buf;
+ msg->hdrlen = len;
+
+ if (vector) {
+ iobuf = iobuf_get (this->xl->ctx->iobuf_pool);
+ if (!iobuf) {
+ GF_FREE (msg->hdr);
+ GF_FREE (msg);
+ return -ENOMEM;
+ }
+
+ iov_unload (iobuf->ptr, vector, count);
+ msg->iobuf = iobuf;
+ }
+
+ pthread_mutex_lock (&peer_trans->handover.mutex);
+ {
+ list_add_tail (&msg->list, &peer_trans->handover.msgs);
+ pthread_cond_broadcast (&peer_trans->handover.cond);
+ }
+ pthread_mutex_unlock (&peer_trans->handover.mutex);
+
+ return 0;
+ }
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+ GF_VALIDATE_OR_GOTO("transport", this->ops, fail);
+
+ ret = this->ops->submit (this, buf, len, vector, count, iobref);
+fail:
+ return ret;
+}
+
+
+int32_t
+transport_connect (transport_t *this)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ ret = this->ops->connect (this);
+fail:
+ return ret;
+}
+
+
+int32_t
+transport_listen (transport_t *this)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ ret = this->ops->listen (this);
+fail:
+ return ret;
+}
+
+
+int32_t
+transport_disconnect (transport_t *this)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ ret = this->ops->disconnect (this);
+fail:
+ return ret;
+}
+
+
+int32_t
+transport_destroy (transport_t *this)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ if (this->fini)
+ this->fini (this);
+
+ pthread_mutex_destroy (&this->lock);
+ GF_FREE (this);
+fail:
+ return ret;
+}
+
+
+transport_t *
+transport_ref (transport_t *this)
+{
+ transport_t *return_this = NULL;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ pthread_mutex_lock (&this->lock);
+ {
+ this->refcount ++;
+ }
+ pthread_mutex_unlock (&this->lock);
+
+ return_this = this;
+fail:
+ return return_this;
+}
+
+
+int32_t
+transport_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ if (this->peer_trans) {
+ *hdr_p = this->handover.msg->hdr;
+ *hdrlen_p = this->handover.msg->hdrlen;
+ *iobuf_p = this->handover.msg->iobuf;
+
+ return 0;
+ }
+
+ ret = this->ops->receive (this, hdr_p, hdrlen_p, iobuf_p);
+fail:
+ return ret;
+}
+
+
+int32_t
+transport_unref (transport_t *this)
+{
+ int32_t refcount = 0;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO("transport", this, fail);
+
+ pthread_mutex_lock (&this->lock);
+ {
+ refcount = --this->refcount;
+ }
+ pthread_mutex_unlock (&this->lock);
+
+ if (refcount == 0) {
+ xlator_notify (this->xl, GF_EVENT_TRANSPORT_CLEANUP, this);
+ transport_destroy (this);
+ }
+
+ ret = 0;
+fail:
+ return ret;
+}
+
+
+void *
+transport_peerproc (void *trans_data)
+{
+ transport_t *trans = NULL;
+ struct transport_msg *msg = NULL;
+
+ trans = trans_data;
+
+ while (1) {
+ pthread_mutex_lock (&trans->handover.mutex);
+ {
+ while (list_empty (&trans->handover.msgs))
+ pthread_cond_wait (&trans->handover.cond,
+ &trans->handover.mutex);
+
+ msg = list_entry (trans->handover.msgs.next,
+ struct transport_msg, list);
+
+ list_del_init (&msg->list);
+ }
+ pthread_mutex_unlock (&trans->handover.mutex);
+
+ trans->handover.msg = msg;
+
+ xlator_notify (trans->xl, GF_EVENT_POLLIN, trans);
+
+ GF_FREE (msg);
+ }
+}
+
+
+int
+transport_setpeer (transport_t *trans, transport_t *peer_trans)
+{
+ trans->peer_trans = transport_ref (peer_trans);
+
+ INIT_LIST_HEAD (&trans->handover.msgs);
+ pthread_cond_init (&trans->handover.cond, NULL);
+ pthread_mutex_init (&trans->handover.mutex, NULL);
+ pthread_create (&trans->handover.thread, NULL,
+ transport_peerproc, trans);
+
+ peer_trans->peer_trans = transport_ref (trans);
+
+ INIT_LIST_HEAD (&peer_trans->handover.msgs);
+ pthread_cond_init (&peer_trans->handover.cond, NULL);
+ pthread_mutex_init (&peer_trans->handover.mutex, NULL);
+ pthread_create (&peer_trans->handover.thread, NULL,
+ transport_peerproc, peer_trans);
+
+ return 0;
+}
diff --git a/xlators/protocol/legacy/lib/src/transport.h b/xlators/protocol/legacy/lib/src/transport.h
new file mode 100644
index 000000000..bb3b452d5
--- /dev/null
+++ b/xlators/protocol/legacy/lib/src/transport.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __TRANSPORT_H__
+#define __TRANSPORT_H__
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+
+struct transport_ops;
+typedef struct transport transport_t;
+
+#include "xlator.h"
+#include "dict.h"
+#include "compat.h"
+
+typedef struct peer_info {
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ char identifier[UNIX_PATH_MAX];
+}peer_info_t;
+
+struct transport_msg {
+ struct list_head list;
+ char *hdr;
+ int hdrlen;
+ struct iobuf *iobuf;
+};
+
+struct transport {
+ struct transport_ops *ops;
+ void *private;
+ void *xl_private;
+ pthread_mutex_t lock;
+ int32_t refcount;
+
+ xlator_t *xl;
+ void *dnscache;
+ data_t *buf;
+ int32_t (*init) (transport_t *this);
+ void (*fini) (transport_t *this);
+ /* int (*notify) (transport_t *this, int event, void *data); */
+ peer_info_t peerinfo;
+ peer_info_t myinfo;
+
+ transport_t *peer_trans;
+ struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ pthread_t thread;
+ struct list_head msgs;
+ struct transport_msg *msg;
+ } handover;
+
+};
+
+struct transport_ops {
+ int32_t (*receive) (transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p);
+ int32_t (*submit) (transport_t *this, char *buf, int len,
+ struct iovec *vector, int count,
+ struct iobref *iobref);
+ int32_t (*connect) (transport_t *this);
+ int32_t (*listen) (transport_t *this);
+ int32_t (*disconnect) (transport_t *this);
+};
+
+
+int32_t transport_listen (transport_t *this);
+int32_t transport_connect (transport_t *this);
+int32_t transport_disconnect (transport_t *this);
+int32_t transport_notify (transport_t *this, int event);
+int32_t transport_submit (transport_t *this, char *buf, int len,
+ struct iovec *vector, int count,
+ struct iobref *iobref);
+int32_t transport_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p);
+int32_t transport_destroy (transport_t *this);
+
+transport_t *transport_load (dict_t *options, xlator_t *xl);
+transport_t *transport_ref (transport_t *trans);
+int32_t transport_unref (transport_t *trans);
+
+int transport_setpeer (transport_t *trans, transport_t *trans_peer);
+
+#endif /* __TRANSPORT_H__ */
diff --git a/xlators/protocol/legacy/server/Makefile.am b/xlators/protocol/legacy/server/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/protocol/legacy/server/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/protocol/legacy/server/src/Makefile.am b/xlators/protocol/legacy/server/src/Makefile.am
new file mode 100644
index 000000000..262fec9ea
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/Makefile.am
@@ -0,0 +1,27 @@
+
+xlator_LTLIBRARIES = server-old.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/legacy/protocol
+
+server_old_la_LDFLAGS = -module -avoidversion
+
+server_old_la_SOURCES = server-protocol.c server-resolve.c server-helpers.c \
+ authenticate.c
+
+server_old_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la
+
+noinst_HEADERS = server-protocol.h server-helpers.h server-mem-types.h \
+ authenticate.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles \
+ -I$(top_srcdir)/contrib/md5/ \
+ -DDATADIR=\"$(localstatedir)\" -DCONFDIR=\"$(sysconfdir)/glusterfs\" \
+ -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
+ $(GF_CFLAGS) -I$(top_srcdir)/xlators/protocol/legacy/lib/src \
+ -I$(top_srcdir)/xlators/protocol/lib/src
+
+CLEANFILES =
+
+install-data-hook:
+ ln -sf server-old.so $(DESTDIR)$(xlatordir)/server.so
diff --git a/xlators/protocol/legacy/server/src/authenticate.c b/xlators/protocol/legacy/server/src/authenticate.c
new file mode 100644
index 000000000..bcdf06910
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/authenticate.c
@@ -0,0 +1,249 @@
+/*
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include "authenticate.h"
+
+static void
+init (dict_t *this,
+ char *key,
+ data_t *value,
+ void *data)
+{
+ void *handle = NULL;
+ char *auth_file = NULL;
+ auth_handle_t *auth_handle = NULL;
+ auth_fn_t authenticate = NULL;
+ int *error = NULL;
+ int ret = 0;
+
+ /* It gets over written */
+ error = data;
+
+ if (!strncasecmp (key, "ip", strlen ("ip"))) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "AUTHENTICATION MODULE \"IP\" HAS BEEN REPLACED "
+ "BY \"ADDR\"");
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ /* TODO: 1.3.x backword compatibility */
+ // *error = -1;
+ // return;
+ key = "addr";
+ }
+
+ ret = gf_asprintf (&auth_file, "%s/%s.so", LIBDIR, key);
+ if (-1 == ret) {
+ gf_log ("authenticate", GF_LOG_ERROR, "asprintf failed");
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ return;
+ }
+
+ handle = dlopen (auth_file, RTLD_LAZY);
+ if (!handle) {
+ gf_log ("authenticate", GF_LOG_ERROR, "dlopen(%s): %s\n",
+ auth_file, dlerror ());
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ GF_FREE (auth_file);
+ *error = -1;
+ return;
+ }
+ GF_FREE (auth_file);
+
+ authenticate = dlsym (handle, "gf_auth");
+ if (!authenticate) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "dlsym(gf_auth) on %s\n", dlerror ());
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ return;
+ }
+
+ auth_handle = GF_CALLOC (1, sizeof (*auth_handle),
+ gf_common_mt_auth_handle_t);
+ if (!auth_handle) {
+ gf_log ("authenticate", GF_LOG_ERROR, "Out of memory");
+ dict_set (this, key, data_from_dynptr (NULL, 0));
+ *error = -1;
+ return;
+ }
+ auth_handle->vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ gf_common_mt_volume_opt_list_t);
+ auth_handle->vol_opt->given_opt = dlsym (handle, "options");
+ if (auth_handle->vol_opt->given_opt == NULL) {
+ gf_log ("authenticate", GF_LOG_DEBUG,
+ "volume option validation not specified");
+ }
+
+ auth_handle->authenticate = authenticate;
+ auth_handle->handle = handle;
+
+ dict_set (this, key,
+ data_from_dynptr (auth_handle, sizeof (*auth_handle)));
+}
+
+static void
+fini (dict_t *this,
+ char *key,
+ data_t *value,
+ void *data)
+{
+ auth_handle_t *handle = data_to_ptr (value);
+ if (handle) {
+ dlclose (handle->handle);
+ }
+}
+
+int32_t
+gf_auth_init (xlator_t *xl, dict_t *auth_modules)
+{
+ int ret = 0;
+ auth_handle_t *handle = NULL;
+ data_pair_t *pair = NULL;
+ dict_foreach (auth_modules, init, &ret);
+ if (!ret) {
+ pair = auth_modules->members_list;
+ while (pair) {
+ handle = data_to_ptr (pair->value);
+ if (handle) {
+ list_add_tail (&(handle->vol_opt->list),
+ &(xl->volume_options));
+ if (-1 ==
+ validate_xlator_volume_options (xl,
+ handle->vol_opt->given_opt)) {
+ gf_log ("authenticate", GF_LOG_ERROR,
+ "volume option validation "
+ "failed");
+ ret = -1;
+ }
+ }
+ pair = pair->next;
+ }
+ }
+ if (ret) {
+ gf_log (xl->name, GF_LOG_ERROR, "authentication init failed");
+ dict_foreach (auth_modules, fini, &ret);
+ ret = -1;
+ }
+ return ret;
+}
+
+static dict_t *__input_params;
+static dict_t *__config_params;
+
+void
+map (dict_t *this,
+ char *key,
+ data_t *value,
+ void *data)
+{
+ dict_t *res = data;
+ auth_fn_t authenticate;
+ auth_handle_t *handle = NULL;
+
+ if (value && (handle = data_to_ptr (value)) &&
+ (authenticate = handle->authenticate)) {
+ dict_set (res, key,
+ int_to_data (authenticate (__input_params,
+ __config_params)));
+ } else {
+ dict_set (res, key, int_to_data (AUTH_DONT_CARE));
+ }
+}
+
+void
+reduce (dict_t *this,
+ char *key,
+ data_t *value,
+ void *data)
+{
+ int64_t val = 0;
+ int64_t *res = data;
+ if (!data)
+ return;
+
+ val = data_to_int64 (value);
+ switch (val)
+ {
+ case AUTH_ACCEPT:
+ if (AUTH_DONT_CARE == *res)
+ *res = AUTH_ACCEPT;
+ break;
+
+ case AUTH_REJECT:
+ *res = AUTH_REJECT;
+ break;
+
+ case AUTH_DONT_CARE:
+ break;
+ }
+}
+
+
+auth_result_t
+gf_authenticate (dict_t *input_params,
+ dict_t *config_params,
+ dict_t *auth_modules)
+{
+ dict_t *results = NULL;
+ int64_t result = AUTH_DONT_CARE;
+
+ results = get_new_dict ();
+ __input_params = input_params;
+ __config_params = config_params;
+
+ dict_foreach (auth_modules, map, results);
+
+ dict_foreach (results, reduce, &result);
+ if (AUTH_DONT_CARE == result) {
+ data_t *peerinfo_data = dict_get (input_params, "peer-info-name");
+ char *name = NULL;
+
+ if (peerinfo_data) {
+ name = peerinfo_data->data;
+ }
+
+ gf_log ("auth", GF_LOG_ERROR,
+ "no authentication module is interested in "
+ "accepting remote-client %s", name);
+ result = AUTH_REJECT;
+ }
+
+ dict_destroy (results);
+ return result;
+}
+
+void
+gf_auth_fini (dict_t *auth_modules)
+{
+ int32_t dummy;
+
+ dict_foreach (auth_modules, fini, &dummy);
+}
diff --git a/xlators/protocol/legacy/server/src/authenticate.h b/xlators/protocol/legacy/server/src/authenticate.h
new file mode 100644
index 000000000..49480a6b8
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/authenticate.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _AUTHENTICATE_H
+#define _AUTHENTICATE_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <fnmatch.h>
+#include "dict.h"
+#include "compat.h"
+#include "list.h"
+#include "xlator.h"
+
+typedef enum {
+ AUTH_ACCEPT,
+ AUTH_REJECT,
+ AUTH_DONT_CARE
+} auth_result_t;
+
+typedef auth_result_t (*auth_fn_t) (dict_t *input_params,
+ dict_t *config_params);
+
+typedef struct {
+ void *handle;
+ auth_fn_t authenticate;
+ volume_opt_list_t *vol_opt;
+} auth_handle_t;
+
+auth_result_t gf_authenticate (dict_t *input_params,
+ dict_t *config_params,
+ dict_t *auth_modules);
+int32_t gf_auth_init (xlator_t *xl, dict_t *auth_modules);
+void gf_auth_fini (dict_t *auth_modules);
+
+#endif /* _AUTHENTICATE_H */
diff --git a/xlators/protocol/legacy/server/src/server-helpers.c b/xlators/protocol/legacy/server/src/server-helpers.c
new file mode 100644
index 000000000..a813f5169
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-helpers.c
@@ -0,0 +1,622 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "server-protocol.h"
+#include "server-helpers.h"
+
+
+
+void
+old_server_loc_wipe (loc_t *loc)
+{
+ if (loc->parent) {
+ inode_unref (loc->parent);
+ loc->parent = NULL;
+ }
+
+ if (loc->inode) {
+ inode_unref (loc->inode);
+ loc->inode = NULL;
+ }
+
+ if (loc->path)
+ GF_FREE ((char *)loc->path);
+}
+
+
+static void
+old_server_resolve_wipe (server_resolve_t *resolve)
+{
+ struct resolve_comp *comp = NULL;
+ int i = 0;
+
+ if (resolve->path)
+ GF_FREE (resolve->path);
+
+ if (resolve->bname)
+ GF_FREE (resolve->bname);
+
+ if (resolve->resolved)
+ GF_FREE (resolve->resolved);
+
+ loc_wipe (&resolve->deep_loc);
+
+ comp = resolve->components;
+ if (comp) {
+ for (i = 0; comp[i].basename; i++) {
+ if (comp[i].inode)
+ inode_unref (comp[i].inode);
+ }
+ GF_FREE (resolve->components);
+ }
+}
+
+
+void
+free_old_server_state (server_state_t *state)
+{
+ if (state->trans) {
+ transport_unref (state->trans);
+ state->trans = NULL;
+ }
+
+ if (state->fd) {
+ fd_unref (state->fd);
+ state->fd = NULL;
+ }
+
+ if (state->params) {
+ dict_unref (state->params);
+ state->params = NULL;
+ }
+
+ if (state->iobref) {
+ iobref_unref (state->iobref);
+ state->iobref = NULL;
+ }
+
+ if (state->iobuf) {
+ iobuf_unref (state->iobuf);
+ state->iobuf = NULL;
+ }
+
+ if (state->dict) {
+ dict_unref (state->dict);
+ state->dict = NULL;
+ }
+
+ if (state->volume)
+ GF_FREE ((char *)state->volume);
+
+ if (state->name)
+ GF_FREE (state->name);
+
+ old_server_loc_wipe (&state->loc);
+ old_server_loc_wipe (&state->loc2);
+
+ old_server_resolve_wipe (&state->resolve);
+ old_server_resolve_wipe (&state->resolve2);
+
+ GF_FREE (state);
+}
+
+static struct _lock_table *
+gf_lock_table_new (void)
+{
+ struct _lock_table *new = NULL;
+
+ new = GF_CALLOC (1, sizeof (struct _lock_table),
+ gf_server_mt_lock_table);
+ if (new == NULL) {
+ gf_log ("server-protocol", GF_LOG_CRITICAL,
+ "failed to allocate memory for new lock table");
+ goto out;
+ }
+ INIT_LIST_HEAD (&new->dir_lockers);
+ INIT_LIST_HEAD (&new->file_lockers);
+ LOCK_INIT (&new->lock);
+out:
+ return new;
+}
+
+
+static int
+gf_server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE(frame);
+
+ if (state)
+ free_old_server_state (state);
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+static int
+do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
+ call_frame_t *frame, struct _lock_table *ltable)
+{
+ struct list_head file_lockers, dir_lockers;
+ call_frame_t *tmp_frame = NULL;
+ struct gf_flock flock = {0, };
+ xlator_t *bound_xl = NULL;
+ struct _locker *locker = NULL, *tmp = NULL;
+ int ret = -1;
+
+ bound_xl = conn->bound_xl;
+ INIT_LIST_HEAD (&file_lockers);
+ INIT_LIST_HEAD (&dir_lockers);
+
+ LOCK (&ltable->lock);
+ {
+ list_splice_init (&ltable->file_lockers,
+ &file_lockers);
+
+ list_splice_init (&ltable->dir_lockers, &dir_lockers);
+ }
+ UNLOCK (&ltable->lock);
+
+ GF_FREE (ltable);
+
+ flock.l_type = F_UNLCK;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ list_for_each_entry_safe (locker,
+ tmp, &file_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
+ if (tmp_frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto out;
+ }
+ /*
+ pid = 0 is a special case that tells posix-locks
+ to release all locks from this transport
+ */
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->finodelk,
+ locker->volume,
+ locker->fd, F_SETLK, &flock);
+ fd_unref (locker->fd);
+ } else {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->inodelk,
+ locker->volume,
+ &(locker->loc), F_SETLK, &flock);
+ loc_wipe (&locker->loc);
+ }
+
+ GF_FREE (locker->volume);
+
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
+ }
+
+ tmp = NULL;
+ locker = NULL;
+ list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
+
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->fentrylk,
+ locker->volume,
+ locker->fd, NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ fd_unref (locker->fd);
+ } else {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->entrylk,
+ locker->volume,
+ &(locker->loc), NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ loc_wipe (&locker->loc);
+ }
+
+ GF_FREE (locker->volume);
+
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
+ }
+ ret = 0;
+
+out:
+ return ret;
+}
+
+
+static int
+server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
+{
+ fd_t *fd = NULL;
+
+ fd = frame->local;
+
+ fd_unref (fd);
+ frame->local = NULL;
+
+ STACK_DESTROY (frame->root);
+ return 0;
+}
+
+
+static int
+do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame,
+ fdentry_t *fdentries, int fd_count)
+{
+ fd_t *fd = NULL;
+ int i = 0, ret = -1;
+ call_frame_t *tmp_frame = NULL;
+ xlator_t *bound_xl = NULL;
+
+ bound_xl = conn->bound_xl;
+ for (i = 0;i < fd_count; i++) {
+ fd = fdentries[i].fd;
+
+ if (fd != NULL) {
+ tmp_frame = copy_frame (frame);
+ if (tmp_frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto out;
+ }
+ tmp_frame->local = fd;
+
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+ tmp_frame->root->lk_owner = 0;
+ STACK_WIND (tmp_frame,
+ server_connection_cleanup_flush_cbk,
+ bound_xl, bound_xl->fops->flush, fd);
+ }
+ }
+
+ GF_FREE (fdentries);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+do_connection_cleanup (xlator_t *this, server_connection_t *conn,
+ struct _lock_table *ltable, fdentry_t *fdentries, int fd_count)
+{
+ int ret = 0;
+ int saved_ret = 0;
+ call_frame_t *frame = NULL;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto out;
+ }
+
+ saved_ret = do_lock_table_cleanup (this, conn, frame, ltable);
+
+ if (fdentries != NULL) {
+ ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count);
+ }
+
+ STACK_DESTROY (frame->root);
+
+ if (saved_ret || ret) {
+ ret = -1;
+ }
+
+out:
+ return ret;
+}
+
+
+int
+gf_server_connection_cleanup (xlator_t *this, server_connection_t *conn)
+{
+ char do_cleanup = 0;
+ struct _lock_table *ltable = NULL;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ int ret = 0;
+
+ if (conn == NULL) {
+ goto out;
+ }
+
+ pthread_mutex_lock (&conn->lock);
+ {
+ conn->active_transports--;
+ if (conn->active_transports == 0) {
+ if (conn->ltable) {
+ ltable = conn->ltable;
+ conn->ltable = gf_lock_table_new ();
+ }
+
+ if (conn->fdtable) {
+ fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
+ &fd_count);
+ }
+ do_cleanup = 1;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (do_cleanup && conn->bound_xl)
+ ret = do_connection_cleanup (this, conn, ltable, fdentries, fd_count);
+
+out:
+ return ret;
+}
+
+
+static int
+server_connection_destroy (xlator_t *this, server_connection_t *conn)
+{
+ call_frame_t *frame = NULL, *tmp_frame = NULL;
+ xlator_t *bound_xl = NULL;
+ int32_t ret = -1;
+ struct list_head file_lockers;
+ struct list_head dir_lockers;
+ struct _lock_table *ltable = NULL;
+ struct _locker *locker = NULL, *tmp = NULL;
+ struct gf_flock flock = {0,};
+ fd_t *fd = NULL;
+ int32_t i = 0;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+
+ if (conn == NULL) {
+ ret = 0;
+ goto out;
+ }
+
+ bound_xl = (xlator_t *) (conn->bound_xl);
+
+ if (bound_xl) {
+ /* trans will have ref_count = 1 after this call, but its
+ ok since this function is called in
+ GF_EVENT_TRANSPORT_CLEANUP */
+ frame = create_frame (this, this->ctx->pool);
+
+ pthread_mutex_lock (&(conn->lock));
+ {
+ if (conn->ltable) {
+ ltable = conn->ltable;
+ conn->ltable = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ INIT_LIST_HEAD (&file_lockers);
+ INIT_LIST_HEAD (&dir_lockers);
+
+ if (ltable) {
+ LOCK (&ltable->lock);
+ {
+ list_splice_init (&ltable->file_lockers,
+ &file_lockers);
+
+ list_splice_init (&ltable->dir_lockers, &dir_lockers);
+ }
+ UNLOCK (&ltable->lock);
+ GF_FREE (ltable);
+ }
+
+ flock.l_type = F_UNLCK;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ list_for_each_entry_safe (locker,
+ tmp, &file_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
+ /*
+ pid = 0 is a special case that tells posix-locks
+ to release all locks from this transport
+ */
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->finodelk,
+ locker->volume,
+ locker->fd, F_SETLK, &flock);
+ fd_unref (locker->fd);
+ } else {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->inodelk,
+ locker->volume,
+ &(locker->loc), F_SETLK, &flock);
+ loc_wipe (&locker->loc);
+ }
+
+ GF_FREE (locker->volume);
+
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
+ }
+
+ tmp = NULL;
+ locker = NULL;
+ list_for_each_entry_safe (locker, tmp, &dir_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
+
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->fentrylk,
+ locker->volume,
+ locker->fd, NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ fd_unref (locker->fd);
+ } else {
+ STACK_WIND (tmp_frame, gf_server_nop_cbk,
+ bound_xl,
+ bound_xl->fops->entrylk,
+ locker->volume,
+ &(locker->loc), NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ loc_wipe (&locker->loc);
+ }
+
+ GF_FREE (locker->volume);
+
+
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
+ }
+
+ pthread_mutex_lock (&(conn->lock));
+ {
+ if (conn->fdtable) {
+ fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
+ &fd_count);
+ gf_fd_fdtable_destroy (conn->fdtable);
+ conn->fdtable = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (fdentries != NULL) {
+ for (i = 0; i < fd_count; i++) {
+ fd = fdentries[i].fd;
+ if (fd != NULL) {
+ tmp_frame = copy_frame (frame);
+ tmp_frame->local = fd;
+
+ STACK_WIND (tmp_frame,
+ server_connection_cleanup_flush_cbk,
+ bound_xl,
+ bound_xl->fops->flush,
+ fd);
+ }
+ }
+ GF_FREE (fdentries);
+ }
+ }
+
+ if (frame) {
+ STACK_DESTROY (frame->root);
+ }
+
+ gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
+ conn->id);
+
+ GF_FREE (conn->id);
+ GF_FREE (conn);
+
+out:
+ return ret;
+}
+
+
+server_connection_t *
+gf_server_connection_get (xlator_t *this, const char *id)
+{
+ server_connection_t *conn = NULL;
+ server_connection_t *trav = NULL;
+ server_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (trav, &conf->conns, list) {
+ if (!strcmp (id, trav->id)) {
+ conn = trav;
+ break;
+ }
+ }
+
+ if (!conn) {
+ conn = (void *) GF_CALLOC (1, sizeof (*conn),
+ gf_server_mt_server_connection_t);
+
+ conn->id = gf_strdup (id);
+ conn->fdtable = gf_fd_fdtable_alloc ();
+ conn->ltable = gf_lock_table_new ();
+
+ pthread_mutex_init (&conn->lock, NULL);
+
+ list_add (&conn->list, &conf->conns);
+ }
+
+ conn->ref++;
+ conn->active_transports++;
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ return conn;
+}
+
+
+void
+gf_server_connection_put (xlator_t *this, server_connection_t *conn)
+{
+ server_conf_t *conf = NULL;
+ server_connection_t *todel = NULL;
+
+ if (conn == NULL) {
+ goto out;
+ }
+
+ conf = this->private;
+
+ pthread_mutex_lock (&conf->mutex);
+ {
+ conn->ref--;
+
+ if (!conn->ref) {
+ list_del_init (&conn->list);
+ todel = conn;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+ if (todel) {
+ server_connection_destroy (this, todel);
+ }
+
+out:
+ return;
+}
diff --git a/xlators/protocol/legacy/server/src/server-helpers.h b/xlators/protocol/legacy/server/src/server-helpers.h
new file mode 100644
index 000000000..ef25e753b
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-helpers.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SERVER_HELPERS_H__
+#define __SERVER_HELPERS_H__
+
+#define CALL_STATE(frame) ((server_state_t *)frame->root->state)
+
+#define BOUND_XL(frame) ((xlator_t *) CALL_STATE(frame)->bound_xl)
+
+#define TRANSPORT_FROM_FRAME(frame) ((transport_t *) CALL_STATE(frame)->trans)
+
+#define SERVER_CONNECTION(frame) \
+ ((server_connection_t *) TRANSPORT_FROM_FRAME(frame)->xl_private)
+
+#define SERVER_CONF(frame) \
+ ((server_conf_t *)TRANSPORT_FROM_FRAME(frame)->xl->private)
+
+#define TRANSPORT_FROM_XLATOR(this) ((((server_conf_t *)this->private))->trans)
+
+#define INODE_LRU_LIMIT(this) \
+ (((server_conf_t *)(this->private))->inode_lru_limit)
+
+#define IS_ROOT_INODE(inode) (inode == inode->table->root)
+
+#define IS_NOT_ROOT(pathlen) ((pathlen > 2)? 1 : 0)
+
+void free_old_server_state (server_state_t *state);
+
+void old_server_loc_wipe (loc_t *loc);
+
+#endif /* __SERVER_HELPERS_H__ */
diff --git a/xlators/protocol/legacy/server/src/server-mem-types.h b/xlators/protocol/legacy/server/src/server-mem-types.h
new file mode 100644
index 000000000..63ede1374
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-mem-types.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __AFR_MEM_TYPES_H__
+#define __AFR_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_server_mem_types_ {
+ gf_server_mt_dir_entry_t = gf_common_mt_end + 1,
+ gf_server_mt_volfile_ctx,
+ gf_server_mt_server_state_t,
+ gf_server_mt_server_conf_t,
+ gf_server_mt_locker,
+ gf_server_mt_lock_table,
+ gf_server_mt_char,
+ gf_server_mt_server_connection_t,
+ gf_server_mt_resolve_comp,
+ gf_server_mt_end
+};
+#endif
+
diff --git a/xlators/protocol/legacy/server/src/server-protocol.c b/xlators/protocol/legacy/server/src/server-protocol.c
new file mode 100644
index 000000000..b462a31f1
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-protocol.c
@@ -0,0 +1,6587 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+#include <time.h>
+#include <sys/uio.h>
+#include <sys/resource.h>
+
+#include <libgen.h>
+
+#include "transport.h"
+#include "fnmatch.h"
+#include "xlator.h"
+#include "protocol.h"
+#include "server-protocol.h"
+#include "server-helpers.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include "list.h"
+#include "dict.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "statedump.h"
+#include "md5.h"
+
+
+static void
+print_caller (char *str, int size, call_frame_t *frame)
+{
+ int filled = 0;
+ server_state_t *state = NULL;
+ transport_t *trans = NULL;
+
+ state = CALL_STATE (frame);
+ trans = state->trans;
+
+ filled += snprintf (str + filled, size - filled,
+ " Callid=%"PRId64", Client=%s",
+ frame->root->unique,
+ trans->peerinfo.identifier);
+
+ return;
+}
+
+
+static void
+server_print_resolve (char *str, int size, server_resolve_t *resolve)
+{
+ int filled = 0;
+
+ if (!resolve) {
+ snprintf (str, size, "<nul>");
+ return;
+ }
+
+ filled += snprintf (str + filled, size - filled,
+ " Resolve={");
+ if (resolve->fd_no != -1)
+ filled += snprintf (str + filled, size - filled,
+ "fd=%"PRId64",", (uint64_t) resolve->fd_no);
+ if (resolve->ino)
+ filled += snprintf (str + filled, size - filled,
+ "ino=%"PRIu64",", (uint64_t) resolve->ino);
+ if (resolve->par)
+ filled += snprintf (str + filled, size - filled,
+ "par=%"PRIu64",", (uint64_t) resolve->par);
+ if (resolve->gen)
+ filled += snprintf (str + filled, size - filled,
+ "gen=%"PRIu64",", (uint64_t) resolve->gen);
+ if (resolve->bname)
+ filled += snprintf (str + filled, size - filled,
+ "bname=%s,", resolve->bname);
+ if (resolve->path)
+ filled += snprintf (str + filled, size - filled,
+ "path=%s", resolve->path);
+
+ filled += snprintf (str + filled, size - filled, "}");
+}
+
+
+static void
+server_print_loc (char *str, int size, loc_t *loc)
+{
+ int filled = 0;
+
+ if (!loc) {
+ snprintf (str, size, "<nul>");
+ return;
+ }
+
+ filled += snprintf (str + filled, size - filled,
+ " Loc={");
+
+ if (loc->path)
+ filled += snprintf (str + filled, size - filled,
+ "path=%s,", loc->path);
+ if (loc->inode)
+ filled += snprintf (str + filled, size - filled,
+ "inode=%p,", loc->inode);
+ if (loc->parent)
+ filled += snprintf (str + filled, size - filled,
+ "parent=%p", loc->parent);
+
+ filled += snprintf (str + filled, size - filled, "}");
+}
+
+
+static void
+server_print_params (char *str, int size, server_state_t *state)
+{
+ int filled = 0;
+
+ filled += snprintf (str + filled, size - filled,
+ " Params={");
+
+ if (state->fd)
+ filled += snprintf (str + filled, size - filled,
+ "fd=%p,", state->fd);
+ if (state->valid)
+ filled += snprintf (str + filled, size - filled,
+ "valid=%d,", state->valid);
+ if (state->flags)
+ filled += snprintf (str + filled, size - filled,
+ "flags=%d,", state->flags);
+ if (state->wbflags)
+ filled += snprintf (str + filled, size - filled,
+ "wbflags=%d,", state->wbflags);
+ if (state->size)
+ filled += snprintf (str + filled, size - filled,
+ "size=%zu,", state->size);
+ if (state->offset)
+ filled += snprintf (str + filled, size - filled,
+ "offset=%"PRId64",", state->offset);
+ if (state->cmd)
+ filled += snprintf (str + filled, size - filled,
+ "cmd=%d,", state->cmd);
+ if (state->type)
+ filled += snprintf (str + filled, size - filled,
+ "type=%d,", state->type);
+ if (state->name)
+ filled += snprintf (str + filled, size - filled,
+ "name=%s,", state->name);
+ if (state->mask)
+ filled += snprintf (str + filled, size - filled,
+ "mask=%d,", state->mask);
+ if (state->volume)
+ filled += snprintf (str + filled, size - filled,
+ "volume=%s,", state->volume);
+
+ filled += snprintf (str + filled, size - filled,
+ "bound_xl=%s}", state->bound_xl->name);
+}
+
+
+static int
+server_resolve_is_empty (server_resolve_t *resolve)
+{
+ if (resolve->fd_no != -1)
+ return 0;
+
+ if (resolve->ino != 0)
+ return 0;
+
+ if (resolve->gen != 0)
+ return 0;
+
+ if (resolve->par != 0)
+ return 0;
+
+ if (resolve->path != 0)
+ return 0;
+
+ if (resolve->bname != 0)
+ return 0;
+
+ return 1;
+}
+
+void
+gf_server_print_request (call_frame_t *frame)
+{
+ server_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ server_state_t *state = NULL;
+ char resolve_vars[256];
+ char resolve2_vars[256];
+ char loc_vars[256];
+ char loc2_vars[256];
+ char other_vars[512];
+ char caller[512];
+ char *op = "UNKNOWN";
+
+ this = frame->this;
+ conf = this->private;
+
+ state = CALL_STATE (frame);
+
+ if (!conf->trace)
+ return;
+
+ memset (resolve_vars, '\0', 256);
+ memset (resolve2_vars, '\0', 256);
+ memset (loc_vars, '\0', 256);
+ memset (loc2_vars, '\0', 256);
+ memset (other_vars, '\0', 256);
+
+ print_caller (caller, 256, frame);
+
+ if (!server_resolve_is_empty (&state->resolve)) {
+ server_print_resolve (resolve_vars, 256, &state->resolve);
+ server_print_loc (loc_vars, 256, &state->loc);
+ }
+
+ if (!server_resolve_is_empty (&state->resolve2)) {
+ server_print_resolve (resolve2_vars, 256, &state->resolve2);
+ server_print_loc (loc2_vars, 256, &state->loc2);
+ }
+
+ server_print_params (other_vars, 512, state);
+
+ switch (frame->root->type) {
+ case GF_OP_TYPE_FOP_REQUEST:
+ case GF_OP_TYPE_FOP_REPLY:
+ op = gf_fop_list[frame->root->op];
+ break;
+ case GF_OP_TYPE_MOP_REQUEST:
+ case GF_OP_TYPE_MOP_REPLY:
+ op = gf_mop_list[frame->root->op];
+ break;
+ case GF_OP_TYPE_CBK_REQUEST:
+ case GF_OP_TYPE_CBK_REPLY:
+ op = gf_cbk_list[frame->root->op];
+ break;
+ }
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%s%s%s%s%s%s%s",
+ gf_fop_list[frame->root->op], caller,
+ resolve_vars, loc_vars, resolve2_vars, loc2_vars, other_vars);
+}
+
+
+static void
+server_print_reply (call_frame_t *frame, int op_ret, int op_errno)
+{
+ server_conf_t *conf = NULL;
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ char caller[512];
+ char fdstr[32];
+ char *op = "UNKNOWN";
+
+ this = frame->this;
+ conf = this->private;
+
+ if (!conf->trace)
+ return;
+
+ state = CALL_STATE (frame);
+
+ print_caller (caller, 256, frame);
+
+ switch (frame->root->type) {
+ case GF_OP_TYPE_FOP_REQUEST:
+ case GF_OP_TYPE_FOP_REPLY:
+ op = gf_fop_list[frame->root->op];
+ break;
+ case GF_OP_TYPE_MOP_REQUEST:
+ case GF_OP_TYPE_MOP_REPLY:
+ op = gf_mop_list[frame->root->op];
+ break;
+ case GF_OP_TYPE_CBK_REQUEST:
+ case GF_OP_TYPE_CBK_REPLY:
+ op = gf_cbk_list[frame->root->op];
+ break;
+ }
+
+ fdstr[0] = '\0';
+ if (state->fd)
+ snprintf (fdstr, 32, " fd=%p", state->fd);
+
+ gf_log (this->name, GF_LOG_INFO,
+ "%s%s => (%d, %d)%s",
+ op, caller, op_ret, op_errno, fdstr);
+}
+
+
+
+static void
+protocol_server_reply (call_frame_t *frame, int type, int op,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iovec *vector, int count,
+ struct iobref *iobref)
+{
+ server_state_t *state = NULL;
+ xlator_t *bound_xl = NULL;
+ transport_t *trans = NULL;
+ int ret = 0;
+
+ xlator_t *this = NULL;
+
+ bound_xl = BOUND_XL (frame);
+ state = CALL_STATE (frame);
+ trans = state->trans;
+ this = frame->this;
+
+ hdr->callid = hton64 (frame->root->unique);
+ hdr->type = hton32 (type);
+ hdr->op = hton32 (op);
+
+ server_print_reply (frame, ntoh32 (hdr->rsp.op_ret),
+ gf_error_to_errno (ntoh32 (hdr->rsp.op_errno)));
+
+ ret = transport_submit (trans, (char *)hdr, hdrlen, vector,
+ count, iobref);
+ if (ret < 0) {
+ gf_log ("protocol/server", GF_LOG_ERROR,
+ "frame %"PRId64": failed to submit. op= %d, type= %d",
+ frame->root->unique, op, type);
+ }
+
+ STACK_DESTROY (frame->root);
+
+ if (state)
+ free_old_server_state (state);
+
+}
+
+
+static int
+gf_add_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc, fd_t *fd, pid_t pid)
+{
+ int32_t ret = -1;
+ struct _locker *new = NULL;
+ uint8_t dir = 0;
+
+ new = GF_CALLOC (1, sizeof (struct _locker),
+ gf_server_mt_locker);
+ if (new == NULL) {
+ gf_log ("server", GF_LOG_ERROR,
+ "failed to allocate memory for \'struct _locker\'");
+ goto out;
+ }
+ INIT_LIST_HEAD (&new->lockers);
+
+ new->volume = gf_strdup (volume);
+
+ if (fd == NULL) {
+ loc_copy (&new->loc, loc);
+ dir = IA_ISDIR (new->loc.inode->ia_type);
+ } else {
+ new->fd = fd_ref (fd);
+ dir = IA_ISDIR (fd->inode->ia_type);
+ }
+
+ new->pid = pid;
+
+ LOCK (&table->lock);
+ {
+ if (dir)
+ list_add_tail (&new->lockers, &table->dir_lockers);
+ else
+ list_add_tail (&new->lockers, &table->file_lockers);
+ }
+ UNLOCK (&table->lock);
+out:
+ return ret;
+}
+
+
+static int
+gf_del_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc, fd_t *fd, pid_t pid)
+{
+ struct _locker *locker = NULL;
+ struct _locker *tmp = NULL;
+ int32_t ret = 0;
+ uint8_t dir = 0;
+ struct list_head *head = NULL;
+ struct list_head del;
+
+ INIT_LIST_HEAD (&del);
+
+ if (fd) {
+ dir = IA_ISDIR (fd->inode->ia_type);
+ } else {
+ dir = IA_ISDIR (loc->inode->ia_type);
+ }
+
+ LOCK (&table->lock);
+ {
+ if (dir) {
+ head = &table->dir_lockers;
+ } else {
+ head = &table->file_lockers;
+ }
+
+ list_for_each_entry_safe (locker, tmp, head, lockers) {
+ if (locker->fd && fd &&
+ (locker->fd == fd) && (locker->pid == pid)
+ && !strcmp (locker->volume, volume)) {
+ list_move_tail (&locker->lockers, &del);
+ } else if (locker->loc.inode &&
+ loc &&
+ (locker->loc.inode == loc->inode) &&
+ (locker->pid == pid)
+ && !strcmp (locker->volume, volume)) {
+ list_move_tail (&locker->lockers, &del);
+ }
+ }
+ }
+ UNLOCK (&table->lock);
+
+ tmp = NULL;
+ locker = NULL;
+
+ list_for_each_entry_safe (locker, tmp, &del, lockers) {
+ list_del_init (&locker->lockers);
+ if (locker->fd)
+ fd_unref (locker->fd);
+ else
+ loc_wipe (&locker->loc);
+
+ GF_FREE (locker->volume);
+ GF_FREE (locker);
+ }
+
+ return ret;
+}
+
+
+/*
+ * server_lk_cbk - lk callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @lock:
+ *
+ * not for external reference
+ */
+static int
+server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_lk_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_flock_from_flock (&rsp->flock, lock);
+ } else if (op_errno != ENOSYS) {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": LK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_inodelk_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ conn = SERVER_CONNECTION(frame);
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ if (state->flock.l_type == F_UNLCK)
+ gf_del_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid);
+ } else if (op_errno != ENOSYS) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_INODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_finodelk_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ conn = SERVER_CONNECTION(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ state = CALL_STATE(frame);
+
+ if (op_ret >= 0) {
+ if (state->flock.l_type == F_UNLCK)
+ gf_del_locker (conn->ltable, state->volume,
+ NULL, state->fd,
+ frame->root->pid);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ NULL, state->fd,
+ frame->root->pid);
+ } else if (op_errno != ENOSYS) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": FINODELK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FINODELK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_entrylk_cbk -
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @lock:
+ *
+ * not for external reference
+ */
+static int
+server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_entrylk_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ conn = SERVER_CONNECTION(frame);
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ if (state->cmd == ENTRYLK_UNLOCK)
+ gf_del_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid);
+ } else if (op_errno != ENOSYS) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_ENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fentrylk_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ conn = SERVER_CONNECTION(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ if (state->cmd == ENTRYLK_UNLOCK)
+ gf_del_locker (conn->ltable, state->volume,
+ NULL, state->fd, frame->root->pid);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ NULL, state->fd, frame->root->pid);
+ } else if (op_errno != ENOSYS) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": FENTRYLK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FENTRYLK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_access_cbk - access callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_access_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_ACCESS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_rmdir_cbk - rmdir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rmdir_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ int32_t gf_errno = 0;
+ size_t hdrlen = 0;
+ inode_t *parent = NULL;
+
+ state = CALL_STATE(frame);
+
+ if (op_ret == 0) {
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": RMDIR %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RMDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_mkdir_cbk - mkdir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_mkdir_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ inode_t *link_inode = NULL;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": MKDIR %s ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_MKDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_mknod_cbk - mknod callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_mknod_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ int32_t gf_errno = 0;
+ size_t hdrlen = 0;
+ inode_t *link_inode = NULL;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": MKNOD %s ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_MKNOD,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_fsyncdir_cbk - fsyncdir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsyncdir_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": FSYNCDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSYNCDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+
+/*
+ * server_readdir_cbk - getdents callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readdir_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ size_t buf_size = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ if (op_ret > 0)
+ buf_size = gf_dirent_serialize (entries, NULL, 0);
+
+ hdrlen = gf_hdr_len (rsp, buf_size);
+ hdr = gf_hdr_new (rsp, buf_size);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret > 0) {
+ rsp->size = hton32 (buf_size);
+ gf_dirent_serialize (entries, rsp->buf, buf_size);
+ } else {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": READDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_releasedir_cbk - releasedir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_cbk_releasedir_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASEDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_opendir_cbk - opendir callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ * @fd: file descriptor structure of opened directory
+ *
+ * not for external reference
+ */
+static int
+server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_opendir_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ uint64_t fd_no = 0;
+
+ conn = SERVER_CONNECTION (frame);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret >= 0) {
+ fd_bind (fd);
+
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd); // on behalf of the client
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": OPENDIR %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ rsp->fd = hton64 (fd_no);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_OPENDIR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_statfs_cbk - statfs callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ * @buf:
+ *
+ * not for external reference
+ */
+static int
+server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_statfs_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ gf_statfs_from_statfs (&rsp->statfs, buf);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_STATFS,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_removexattr_cbk - removexattr callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_removexattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_REMOVEXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_getxattr_cbk - getxattr callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ * @value:
+ *
+ * not for external reference
+ */
+static int
+server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_getxattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t len = 0;
+ int32_t gf_errno = 0;
+ int32_t ret = -1;
+
+ state = CALL_STATE (frame);
+
+ if (op_ret >= 0) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized length of "
+ "reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ }
+ }
+
+ hdrlen = gf_hdr_len (rsp, len + 1);
+ hdr = gf_hdr_new (rsp, len + 1);
+ rsp = gf_param (hdr);
+
+ if (op_ret >= 0) {
+ ret = dict_serialize (dict, rsp->dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = -ret;
+ }
+ }
+ rsp->dict_len = hton32 (len);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_GETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fgetxattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t len = 0;
+ int32_t gf_errno = 0;
+ int32_t ret = -1;
+
+ state = CALL_STATE (frame);
+
+ if (op_ret >= 0) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized length of "
+ "reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ }
+ }
+
+ hdrlen = gf_hdr_len (rsp, len + 1);
+ hdr = gf_hdr_new (rsp, len + 1);
+ rsp = gf_param (hdr);
+
+ if (op_ret >= 0) {
+ ret = dict_serialize (dict, rsp->dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = -ret;
+ }
+ }
+ rsp->dict_len = hton32 (len);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FGETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_setxattr_cbk - setxattr callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_setxattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsetxattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSETXATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_rename_cbk - rename callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
+ struct iatt *preoldparent, struct iatt *postoldparent,
+ struct iatt *prenewparent, struct iatt *postnewparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rename_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ stbuf->ia_ino = state->loc.inode->ino;
+ stbuf->ia_type = state->loc.inode->ia_type;
+
+ gf_log (state->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": RENAME_CBK (%"PRId64") %"PRId64"/%s "
+ "==> %"PRId64"/%s",
+ frame->root->unique, state->loc.inode->ino,
+ state->loc.parent->ino, state->loc.name,
+ state->loc2.parent->ino, state->loc2.name);
+
+ inode_rename (state->itable,
+ state->loc.parent, state->loc.name,
+ state->loc2.parent, state->loc2.name,
+ state->loc.inode, stbuf);
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+
+ gf_stat_from_iatt (&rsp->preoldparent, preoldparent);
+ gf_stat_from_iatt (&rsp->postoldparent, postoldparent);
+
+ gf_stat_from_iatt (&rsp->prenewparent, prenewparent);
+ gf_stat_from_iatt (&rsp->postnewparent, postnewparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RENAME,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_unlink_cbk - unlink callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_unlink_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ inode_t *parent = NULL;
+
+ state = CALL_STATE(frame);
+
+ if (op_ret == 0) {
+ gf_log (state->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": UNLINK_CBK %"PRId64"/%s (%"PRId64")",
+ frame->root->unique, state->loc.parent->ino,
+ state->loc.name, state->loc.inode->ino);
+
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": UNLINK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_UNLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_symlink_cbk - symlink callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret: return value
+ * @op_errno: errno
+ *
+ * not for external reference
+ */
+static int
+server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_symlink_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ inode_t *link_inode = NULL;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": SYMLINK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SYMLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_link_cbk - link callback for server protocol
+ * @frame: call frame
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *stbuf, struct iatt *preparent,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_link_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ int32_t gf_errno = 0;
+ size_t hdrlen = 0;
+ inode_t *link_inode = NULL;
+
+ state = CALL_STATE(frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ stbuf->ia_ino = state->loc.inode->ino;
+
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+
+ gf_log (state->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s",
+ frame->root->unique, inode->ino,
+ state->loc2.parent->ino,
+ state->loc2.name, state->loc.parent->ino,
+ state->loc.name);
+
+ link_inode = inode_link (inode, state->loc2.parent,
+ state->loc2.name, stbuf);
+ inode_unref (link_inode);
+ } else {
+ gf_log (state->bound_xl->name, GF_LOG_DEBUG,
+ "%"PRId64": LINK (%"PRId64") %"PRId64"/%s ==> %"PRId64"/%s "
+ " ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve2.ino,
+ state->resolve2.par,
+ state->resolve2.bname, state->resolve.par,
+ state->resolve.bname,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_truncate_cbk - truncate callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_truncate_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->prestat, prebuf);
+ gf_stat_from_iatt (&rsp->poststat, postbuf);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": TRUNCATE %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_TRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_fstat_cbk - fstat callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fstat_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ } else {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FSTAT %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSTAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_ftruncate_cbk - ftruncate callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_ftruncate_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->prestat, prebuf);
+ gf_stat_from_iatt (&rsp->poststat, postbuf);
+ } else {
+ state = CALL_STATE (frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FTRUNCATE %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FTRUNCATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_flush_cbk - flush callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_flush_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FLUSH %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FLUSH,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_fsync_cbk - fsync callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsync_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ if (op_ret < 0) {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FSYNC %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&(rsp->prestat), prebuf);
+ gf_stat_from_iatt (&(rsp->poststat), postbuf);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSYNC,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_release_cbk - rleease callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_release_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_cbk_release_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_CBK_REPLY, GF_CBK_RELEASE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_writev_cbk - writev callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+
+static int
+server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_write_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->prestat, prebuf);
+ gf_stat_from_iatt (&rsp->poststat, postbuf);
+ } else {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": WRITEV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_WRITE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_readv_cbk - readv callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @vector:
+ * @count:
+ *
+ * not for external reference
+ */
+static int
+server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iovec *vector, int32_t count,
+ struct iatt *stbuf, struct iobref *iobref)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_read_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ } else {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": READV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READ,
+ hdr, hdrlen, vector, count, iobref);
+
+ return 0;
+}
+
+
+/*
+ * server_open_cbk - open callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @fd:
+ *
+ * not for external reference
+ */
+static int
+server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_open_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ uint64_t fd_no = 0;
+
+ conn = SERVER_CONNECTION (frame);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret >= 0) {
+ fd_bind (fd);
+
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": OPEN %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ rsp->fd = hton64 (fd_no);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_OPEN,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_create_cbk - create callback for server
+ * @frame: call frame
+ * @cookie:
+ * @this: translator structure
+ * @op_ret:
+ * @op_errno:
+ * @fd: file descriptor
+ * @inode: inode structure
+ * @stbuf: struct iatt of created file
+ *
+ * not for external reference
+ */
+static int
+server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ fd_t *fd, inode_t *inode, struct iatt *stbuf,
+ struct iatt *preparent, struct iatt *postparent)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_create_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ uint64_t fd_no = 0;
+ inode_t *link_inode = NULL;
+
+ conn = SERVER_CONNECTION (frame);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret >= 0) {
+ gf_log (state->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": CREATE %"PRId64"/%s (%"PRId64")",
+ frame->root->unique, state->loc.parent->ino,
+ state->loc.name, stbuf->ia_ino);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+
+ if (link_inode != inode) {
+
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
+
+ inode_unref (fd->inode);
+ fd->inode = inode_ref (link_inode);
+ }
+
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+ fd_bind (fd);
+
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd);
+
+ if ((fd_no < 0) || (fd == 0)) {
+ op_ret = fd_no;
+ op_errno = errno;
+ }
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": CREATE %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ rsp->fd = hton64 (fd_no);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ gf_stat_from_iatt (&rsp->preparent, preparent);
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_CREATE,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_readlink_cbk - readlink callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @buf:
+ *
+ * not for external reference
+ */
+static int
+server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, const char *buf,
+ struct iatt *sbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readlink_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ size_t linklen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE(frame);
+
+ if (op_ret >= 0) {
+ linklen = strlen (buf) + 1;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": READLINK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ hdrlen = gf_hdr_len (rsp, linklen);
+ hdr = gf_hdr_new (rsp, linklen);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&(rsp->buf), sbuf);
+ strcpy (rsp->path, buf);
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READLINK,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_stat_cbk - stat callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_stat_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": STAT %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_STAT,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_setattr_cbk - setattr callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+
+static int
+server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_setattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->statpre, statpre);
+ gf_stat_from_iatt (&rsp->statpost, statpost);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": SETATTR %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/*
+ * server_setattr_cbk - setattr callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_fsetattr_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ hdrlen = gf_hdr_len (rsp, 0);
+ hdr = gf_hdr_new (rsp, 0);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno_to_error (op_errno));
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp->statpre, statpre);
+ gf_stat_from_iatt (&rsp->statpost, statpost);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FSETATTR %"PRId64" (%"PRId64") ==> "
+ "%"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FSETATTR,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * server_lookup_cbk - lookup callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ * @inode:
+ * @stbuf:
+ *
+ * not for external reference
+ */
+static int
+server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *dict,
+ struct iatt *postparent)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_lookup_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ inode_t *root_inode = NULL;
+ int32_t dict_len = 0;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+ int32_t ret = -1;
+ inode_t *link_inode = NULL;
+ loc_t fresh_loc = {0,};
+
+ state = CALL_STATE(frame);
+
+ if (state->is_revalidate == 1 && op_ret == -1) {
+ state->is_revalidate = 2;
+ loc_copy (&fresh_loc, &state->loc);
+ inode_unref (fresh_loc.inode);
+ fresh_loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_lookup_cbk,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &fresh_loc, state->dict);
+
+ loc_wipe (&fresh_loc);
+ return 0;
+ }
+
+ if (dict) {
+ dict_len = dict_serialized_length (dict);
+ if (dict_len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized "
+ "length of reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ dict_len = 0;
+ }
+ }
+
+ hdrlen = gf_hdr_len (rsp, dict_len);
+ hdr = gf_hdr_new (rsp, dict_len);
+ rsp = gf_param (hdr);
+
+ if ((op_ret >= 0) && dict) {
+ ret = dict_serialize (dict, rsp->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ dict_len = 0;
+ }
+ }
+ rsp->dict_len = hton32 (dict_len);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (postparent)
+ gf_stat_from_iatt (&rsp->postparent, postparent);
+
+ if (op_ret == 0) {
+ root_inode = BOUND_XL(frame)->itable->root;
+ if (inode == root_inode) {
+ /* we just looked up root ("/") */
+ stbuf->ia_ino = 1;
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
+
+ gf_stat_from_iatt (&rsp->stat, stbuf);
+
+ if (inode->ino != 1) {
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ }
+ } else {
+ if (state->is_revalidate && op_errno == ENOENT) {
+ if (state->loc.inode->ino != 1) {
+ inode_unlink (state->loc.inode,
+ state->loc.parent,
+ state->loc.name);
+ }
+ }
+
+ gf_log (this->name,
+ (op_errno == ENOENT ? GF_LOG_TRACE : GF_LOG_DEBUG),
+ "%"PRId64": LOOKUP %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOOKUP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_xattrop_rsp_t *rsp = NULL;
+ server_state_t *state = NULL;
+ size_t hdrlen = 0;
+ int32_t len = 0;
+ int32_t gf_errno = 0;
+ int32_t ret = -1;
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": XATTROP %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
+
+ if ((op_ret >= 0) && dict) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized length"
+ " for reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ }
+ }
+
+ hdrlen = gf_hdr_len (rsp, len + 1);
+ hdr = gf_hdr_new (rsp, len + 1);
+ rsp = gf_param (hdr);
+
+ if ((op_ret >= 0) && dict) {
+ ret = dict_serialize (dict, rsp->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ len = 0;
+ }
+ }
+ rsp->dict_len = hton32 (len);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_XATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_xattrop_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t len = 0;
+ int32_t gf_errno = 0;
+ int32_t ret = -1;
+ server_state_t *state = NULL;
+
+ state = CALL_STATE(frame);
+
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FXATTROP %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ if ((op_ret >= 0) && dict) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to get "
+ "serialized length for reply dict",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ }
+ }
+
+ hdrlen = gf_hdr_len (rsp, len + 1);
+ hdr = gf_hdr_new (rsp, len + 1);
+ rsp = gf_param (hdr);
+
+ if ((op_ret >= 0) && dict) {
+ ret = dict_serialize (dict, rsp->dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to "
+ "serialize reply dict",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ len = 0;
+ }
+ }
+ rsp->dict_len = hton32 (len);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_FXATTROP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ if (!state->loc.inode)
+ state->loc.inode = inode_new (state->itable);
+ else
+ state->is_revalidate = 1;
+
+ STACK_WIND (frame, server_lookup_cbk,
+ bound_xl, bound_xl->fops->lookup,
+ &state->loc, state->dict);
+
+ return 0;
+err:
+ server_lookup_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+static int
+server_lookup (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_lookup_req_t *req = NULL;
+ server_state_t *state = NULL;
+ int32_t ret = -1;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+ size_t dictlen = 0;
+ dict_t *xattr_req = NULL;
+ char *req_dictbuf = NULL;
+
+ req = gf_param (hdr);
+
+ state = CALL_STATE (frame);
+
+ pathlen = STRLEN_0 (req->path);
+ dictlen = ntoh32 (req->dictlen);
+
+ /* NOTE: lookup() uses req->ino only to identify if a lookup()
+ * is requested for 'root' or not
+ */
+ state->resolve.ino = ntoh64 (req->ino);
+ if (state->resolve.ino != 1)
+ state->resolve.ino = 0;
+
+ state->resolve.type = RESOLVE_DONTCARE;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ if (IS_NOT_ROOT (pathlen)) {
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+ baselen = STRLEN_0 (state->resolve.bname);
+ }
+
+ if (dictlen) {
+ /* Unserialize the dictionary */
+ req_dictbuf = memdup (req->dict + pathlen + baselen, dictlen);
+
+ xattr_req = dict_new ();
+
+ ret = dict_unserialize (req_dictbuf, dictlen, &xattr_req);
+ if (ret < 0) {
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ GF_FREE (req_dictbuf);
+ goto err;
+ }
+
+ xattr_req->extra_free = req_dictbuf;
+ state->dict = xattr_req;
+ }
+
+ gf_resolve_and_resume (frame, server_lookup_resume);
+
+ return 0;
+err:
+ if (xattr_req)
+ dict_unref (xattr_req);
+
+ server_lookup_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
+ NULL, NULL);
+ return 0;
+}
+
+
+/*
+ * server_forget - forget function for server protocol
+ *
+ * not for external reference
+ */
+static int
+server_forget (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_log ("forget", GF_LOG_CRITICAL, "function not implemented");
+ return 0;
+}
+
+
+static int
+server_stat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_stat_cbk,
+ bound_xl, bound_xl->fops->stat, &state->loc);
+ return 0;
+err:
+ server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_stat (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_stat_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ {
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ }
+
+ gf_resolve_and_resume (frame, server_stat_resume);
+
+ return 0;
+}
+
+
+static int
+server_setattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setattr_cbk,
+ bound_xl, bound_xl->fops->setattr,
+ &state->loc, &state->stbuf, state->valid);
+ return 0;
+err:
+ server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+static int
+server_setattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_setattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ gf_stat_to_iatt (&req->stbuf, &state->stbuf);
+ state->valid = ntoh32 (req->valid);
+
+ gf_resolve_and_resume (frame, server_setattr_resume);
+
+ return 0;
+}
+
+
+static int
+server_fsetattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsetattr_cbk,
+ bound_xl, bound_xl->fops->fsetattr,
+ state->fd, &state->stbuf, state->valid);
+ return 0;
+err:
+ server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fsetattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fsetattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ gf_stat_to_iatt (&req->stbuf, &state->stbuf);
+ state->valid = ntoh32 (req->valid);
+
+ gf_resolve_and_resume (frame, server_fsetattr_resume);
+
+ return 0;
+}
+
+
+static int
+server_readlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readlink_cbk,
+ bound_xl, bound_xl->fops->readlink,
+ &state->loc, state->size);
+ return 0;
+err:
+ server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_readlink (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_readlink_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ state->size = ntoh32 (req->size);
+
+ gf_resolve_and_resume (frame, server_readlink_resume);
+
+ return 0;
+}
+
+
+static int
+server_create_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_create_cbk,
+ bound_xl, bound_xl->fops->create,
+ &(state->loc), state->flags, state->mode,
+ state->fd, state->params);
+
+ return 0;
+err:
+ server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL,
+ NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_create (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_create_req_t *req = NULL;
+ server_state_t *state = NULL;
+ int pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_NOT;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+ state->mode = ntoh32 (req->mode);
+ state->flags = gf_flags_to_flags (ntoh32 (req->flags));
+
+ gf_resolve_and_resume (frame, server_create_resume);
+
+ return 0;
+}
+
+
+static int
+server_open_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+ state->fd->flags = state->flags;
+
+ STACK_WIND (frame, server_open_cbk,
+ bound_xl, bound_xl->fops->open,
+ &state->loc, state->flags, state->fd, 0);
+
+ return 0;
+err:
+ server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_open (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_open_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ state->flags = gf_flags_to_flags (ntoh32 (req->flags));
+
+ gf_resolve_and_resume (frame, server_open_resume);
+
+ return 0;
+}
+
+
+static int
+server_readv_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readv_cbk,
+ bound_xl, bound_xl->fops->readv,
+ state->fd, state->size, state->offset);
+
+ return 0;
+err:
+ server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, 0, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_readv (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_read_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->size = ntoh32 (req->size);
+ state->offset = ntoh64 (req->offset);
+
+ gf_resolve_and_resume (frame, server_readv_resume);
+
+ return 0;
+}
+
+
+static int
+server_writev_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ struct iovec iov = {0, };
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ iov.iov_len = state->size;
+
+ if (state->iobuf) {
+ iov.iov_base = state->iobuf->ptr;
+ }
+
+ STACK_WIND (frame, server_writev_cbk,
+ bound_xl, bound_xl->fops->writev,
+ state->fd, &iov, 1, state->offset, state->iobref);
+
+ return 0;
+err:
+ server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_writev (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_write_req_t *req = NULL;
+ server_state_t *state = NULL;
+ struct iobref *iobref = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->offset = ntoh64 (req->offset);
+ state->size = ntoh32 (req->size);
+
+ if (iobuf) {
+ iobref = iobref_new ();
+ iobref_add (iobref, iobuf);
+
+ state->iobuf = iobuf;
+ state->iobref = iobref;
+ }
+
+ gf_resolve_and_resume (frame, server_writev_resume);
+
+ return 0;
+}
+
+
+static int
+server_release (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_cbk_release_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION (frame);
+ state = CALL_STATE (frame);
+ req = gf_param (hdr);
+
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ gf_fd_put (conn->fdtable, state->resolve.fd_no);
+
+ server_release_cbk (frame, NULL, frame->this, 0, 0);
+
+ return 0;
+}
+
+
+static int
+server_fsync_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsync_cbk,
+ bound_xl, bound_xl->fops->fsync,
+ state->fd, state->flags);
+ return 0;
+err:
+ server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+static int
+server_fsync (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fsync_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->flags = ntoh32 (req->data);
+
+ gf_resolve_and_resume (frame, server_fsync_resume);
+
+ return 0;
+}
+
+
+
+static int
+server_flush_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_flush_cbk,
+ bound_xl, bound_xl->fops->flush, state->fd);
+ return 0;
+err:
+ server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+
+ return 0;
+}
+
+
+static int
+server_flush (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fsync_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ gf_resolve_and_resume (frame, server_flush_resume);
+
+ return 0;
+}
+
+
+
+static int
+server_ftruncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_ftruncate_cbk,
+ bound_xl, bound_xl->fops->ftruncate,
+ state->fd, state->offset);
+ return 0;
+err:
+ server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+
+ return 0;
+}
+
+
+static int
+server_ftruncate (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_ftruncate_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->offset = ntoh64 (req->offset);
+
+ gf_resolve_and_resume (frame, server_ftruncate_resume);
+
+ return 0;
+}
+
+
+static int
+server_fstat_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fstat_cbk,
+ bound_xl, bound_xl->fops->fstat,
+ state->fd);
+ return 0;
+err:
+ server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_fstat (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fstat_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ gf_resolve_and_resume (frame, server_fstat_resume);
+
+ return 0;
+}
+
+
+static int
+server_truncate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_truncate_cbk,
+ bound_xl, bound_xl->fops->truncate,
+ &state->loc, state->offset);
+ return 0;
+err:
+ server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+
+static int
+server_truncate (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_truncate_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->offset = ntoh64 (req->offset);
+
+ gf_resolve_and_resume (frame, server_truncate_resume);
+
+ return 0;
+}
+
+
+static int
+server_unlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_unlink_cbk,
+ bound_xl, bound_xl->fops->unlink,
+ &state->loc);
+ return 0;
+err:
+ server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_unlink (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_unlink_req_t *req = NULL;
+ server_state_t *state = NULL;
+ int pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+
+ gf_resolve_and_resume (frame, server_unlink_resume);
+
+ return 0;
+}
+
+
+static int
+server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->setxattr,
+ &state->loc, state->dict, state->flags);
+ return 0;
+err:
+ server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+
+ return 0;
+}
+
+
+static int
+server_setxattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_setxattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ size_t dict_len = 0;
+ char *req_dictbuf = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ dict_len = ntoh32 (req->dict_len);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path + dict_len);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->flags = ntoh32 (req->flags);
+
+ if (dict_len) {
+ req_dictbuf = memdup (req->dict, dict_len);
+
+ dict = dict_new ();
+
+ ret = dict_unserialize (req_dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize request buffer to dictionary",
+ frame->root->unique, state->loc.path,
+ state->resolve.ino);
+ GF_FREE (req_dictbuf);
+ goto err;
+ }
+
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ }
+
+ gf_resolve_and_resume (frame, server_setxattr_resume);
+
+ return 0;
+err:
+ if (dict)
+ dict_unref (dict);
+
+ server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL);
+
+ return 0;
+
+}
+
+
+static int
+server_fsetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->fsetxattr,
+ state->fd, state->dict, state->flags);
+ return 0;
+err:
+ server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+
+ return 0;
+}
+
+
+static int
+server_fsetxattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fsetxattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+ dict_t *dict = NULL;
+ int32_t ret = -1;
+ size_t dict_len = 0;
+ char *req_dictbuf = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ dict_len = ntoh32 (req->dict_len);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->flags = ntoh32 (req->flags);
+
+ if (dict_len) {
+ req_dictbuf = memdup (req->dict, dict_len);
+
+ dict = dict_new ();
+
+ ret = dict_unserialize (req_dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize request buffer to dictionary",
+ frame->root->unique, state->loc.path,
+ state->resolve.ino);
+ GF_FREE (req_dictbuf);
+ goto err;
+ }
+
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ }
+
+ gf_resolve_and_resume (frame, server_fsetxattr_resume);
+
+ return 0;
+err:
+ if (dict)
+ dict_unref (dict);
+
+ server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL);
+
+ return 0;
+}
+
+
+static int
+server_fxattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fxattrop_cbk,
+ bound_xl, bound_xl->fops->fxattrop,
+ state->fd, state->flags, state->dict);
+ return 0;
+err:
+ server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_fxattrop (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fxattrop_req_t *req = NULL;
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ size_t dict_len = 0;
+ char *req_dictbuf = NULL;
+ int32_t ret = -1;
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ dict_len = ntoh32 (req->dict_len);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->flags = ntoh32 (req->flags);
+
+ if (dict_len) {
+ /* Unserialize the dictionary */
+ req_dictbuf = memdup (req->dict, dict_len);
+
+ dict = dict_new ();
+
+ ret = dict_unserialize (req_dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to unserialize "
+ "request buffer to dictionary",
+ state->resolve.fd_no, state->fd->inode->ino);
+ GF_FREE (req_dictbuf);
+ goto fail;
+ }
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ dict = NULL;
+ }
+
+ gf_resolve_and_resume (frame, server_fxattrop_resume);
+
+ return 0;
+
+fail:
+ if (dict)
+ dict_unref (dict);
+
+ server_fxattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+static int
+server_xattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_xattrop_cbk,
+ bound_xl, bound_xl->fops->xattrop,
+ &state->loc, state->flags, state->dict);
+ return 0;
+err:
+ server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_xattrop (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_xattrop_req_t *req = NULL;
+ dict_t *dict = NULL;
+ server_state_t *state = NULL;
+ size_t dict_len = 0;
+ char *req_dictbuf = NULL;
+ int32_t ret = -1;
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ dict_len = ntoh32 (req->dict_len);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path + dict_len);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->flags = ntoh32 (req->flags);
+
+ if (dict_len) {
+ /* Unserialize the dictionary */
+ req_dictbuf = memdup (req->dict, dict_len);
+
+ dict = dict_new ();
+
+ ret = dict_unserialize (req_dictbuf, dict_len, &dict);
+ if (ret < 0) {
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to unserialize "
+ "request buffer to dictionary",
+ state->resolve.fd_no, state->fd->inode->ino);
+ GF_FREE (req_dictbuf);
+ goto fail;
+ }
+ dict->extra_free = req_dictbuf;
+ state->dict = dict;
+ dict = NULL;
+ }
+
+ gf_resolve_and_resume (frame, server_xattrop_resume);
+
+ return 0;
+
+fail:
+ if (dict)
+ dict_unref (dict);
+
+ server_xattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
+ return 0;
+}
+
+
+static int
+server_getxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_getxattr_cbk,
+ bound_xl, bound_xl->fops->getxattr,
+ &state->loc, state->name);
+ return 0;
+err:
+ server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_getxattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_getxattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t namelen = 0;
+ size_t pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ namelen = ntoh32 (req->namelen);
+ if (namelen)
+ state->name = gf_strdup (req->name + pathlen);
+
+ gf_resolve_and_resume (frame, server_getxattr_resume);
+
+ return 0;
+}
+
+
+static int
+server_fgetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fgetxattr_cbk,
+ bound_xl, bound_xl->fops->fgetxattr,
+ state->fd, state->name);
+ return 0;
+err:
+ server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_fgetxattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fgetxattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t namelen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+
+ namelen = ntoh32 (req->namelen);
+ if (namelen)
+ state->name = gf_strdup (req->name);
+
+ gf_resolve_and_resume (frame, server_fgetxattr_resume);
+
+ return 0;
+}
+
+
+static int
+server_removexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_removexattr_cbk,
+ bound_xl, bound_xl->fops->removexattr,
+ &state->loc, state->name);
+ return 0;
+err:
+ server_removexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+
+static int
+server_removexattr (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_removexattr_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->name = gf_strdup (req->name + pathlen);
+
+ gf_resolve_and_resume (frame, server_removexattr_resume);
+
+ return 0;
+}
+
+
+static int
+server_statfs_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret !=0)
+ goto err;
+
+ STACK_WIND (frame, server_statfs_cbk,
+ bound_xl, bound_xl->fops->statfs,
+ &state->loc);
+ return 0;
+
+err:
+ server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_statfs (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_statfs_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = ntoh64 (req->ino);
+ if (!state->resolve.ino)
+ state->resolve.ino = 1;
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ gf_resolve_and_resume (frame, server_statfs_resume);
+
+ return 0;
+}
+
+
+static int
+server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->fd = fd_create (state->loc.inode, frame->root->pid);
+
+ STACK_WIND (frame, server_opendir_cbk,
+ bound_xl, bound_xl->fops->opendir,
+ &state->loc, state->fd);
+ return 0;
+err:
+ server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+
+static int
+server_opendir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_opendir_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ gf_resolve_and_resume (frame, server_opendir_resume);
+
+ return 0;
+}
+
+
+static int
+server_releasedir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_cbk_releasedir_req_t *req = NULL;
+ server_connection_t *conn = NULL;
+ uint64_t fd_no = 0;
+
+ conn = SERVER_CONNECTION (frame);
+
+ req = gf_param (hdr);
+
+ fd_no = ntoh64 (req->fd);
+
+ gf_fd_put (conn->fdtable, fd_no);
+
+ server_releasedir_cbk (frame, NULL, frame->this, 0, 0);
+
+ return 0;
+}
+
+/*
+ * server_readdirp_cbk - getdents callback for server protocol
+ * @frame: call frame
+ * @cookie:
+ * @this:
+ * @op_ret:
+ * @op_errno:
+ *
+ * not for external reference
+ */
+static int
+server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_readdirp_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ size_t buf_size = 0;
+ int32_t gf_errno = 0;
+ server_state_t *state = NULL;
+
+ if (op_ret > 0)
+ buf_size = gf_dirent_serialize (entries, NULL, 0);
+
+ hdrlen = gf_hdr_len (rsp, buf_size);
+ hdr = gf_hdr_new (rsp, buf_size);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret > 0) {
+ rsp->size = hton32 (buf_size);
+ gf_dirent_serialize (entries, rsp->buf, buf_size);
+ } else {
+ state = CALL_STATE(frame);
+
+ gf_log (this->name, GF_LOG_TRACE,
+ "%"PRId64": READDIRP %"PRId64" (%"PRId64") ==>"
+ "%"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_READDIRP,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+static int
+server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readdirp_cbk, bound_xl,
+ bound_xl->fops->readdirp, state->fd, state->size,
+ state->offset);
+
+ return 0;
+err:
+ server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+
+/*
+ * server_readdirp - readdirp function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ * not for external reference
+ */
+static int
+server_readdirp (call_frame_t *frame, xlator_t *bound_xl, gf_hdr_common_t *hdr,
+ size_t hdrlen, struct iobuf *iobuf)
+{
+ gf_fop_readdirp_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION(frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->size = ntoh32 (req->size);
+ state->offset = ntoh64 (req->offset);
+
+ gf_resolve_and_resume (frame, server_readdirp_resume);
+
+ return 0;
+}
+
+
+static int
+ server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_readdir_cbk,
+ bound_xl,
+ bound_xl->fops->readdir,
+ state->fd, state->size, state->offset);
+
+ return 0;
+err:
+ server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL);
+ return 0;
+}
+/*
+ * server_readdir - readdir function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ * not for external reference
+ */
+static int
+server_readdir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_readdir_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION(frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->size = ntoh32 (req->size);
+ state->offset = ntoh64 (req->offset);
+
+ gf_resolve_and_resume (frame, server_readdir_resume);
+
+ return 0;
+}
+
+static int
+server_fsyncdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fsyncdir_cbk,
+ bound_xl,
+ bound_xl->fops->fsyncdir,
+ state->fd, state->flags);
+ return 0;
+
+err:
+ server_fsyncdir_cbk (frame, NULL, frame->this,
+ state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+/*
+ * server_fsyncdir - fsyncdir function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ * not for external reference
+ */
+static int
+server_fsyncdir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fsyncdir_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION (frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->flags = ntoh32 (req->data);
+
+ gf_resolve_and_resume (frame, server_fsyncdir_resume);
+
+ return 0;
+}
+
+
+static int
+server_mknod_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mknod_cbk,
+ bound_xl, bound_xl->fops->mknod,
+ &(state->loc), state->mode, state->dev,
+ state->params);
+
+ return 0;
+err:
+ server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+static int
+server_mknod (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_mknod_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_NOT;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+
+ state->mode = ntoh32 (req->mode);
+ state->dev = ntoh64 (req->dev);
+
+ gf_resolve_and_resume (frame, server_mknod_resume);
+
+ return 0;
+}
+
+
+static int
+server_mkdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_mkdir_cbk,
+ bound_xl, bound_xl->fops->mkdir,
+ &(state->loc), state->mode,
+ state->params);
+
+ return 0;
+err:
+ server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_mkdir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_mkdir_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_NOT;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+
+ state->mode = ntoh32 (req->mode);
+
+ gf_resolve_and_resume (frame, server_mkdir_resume);
+
+ return 0;
+}
+
+
+static int
+server_rmdir_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_rmdir_cbk,
+ bound_xl, bound_xl->fops->rmdir, &state->loc);
+ return 0;
+err:
+ server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL);
+ return 0;
+}
+
+static int
+server_rmdir (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_rmdir_req_t *req = NULL;
+ server_state_t *state = NULL;
+ int pathlen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+
+ gf_resolve_and_resume (frame, server_rmdir_resume);
+
+ return 0;
+}
+
+
+static int
+server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_inodelk_cbk,
+ bound_xl, bound_xl->fops->inodelk,
+ state->volume, &state->loc, state->cmd, &state->flock);
+ return 0;
+err:
+ server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+
+static int
+server_inodelk (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_inodelk_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t pathlen = 0;
+ size_t vollen = 0;
+ int cmd = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+ vollen = STRLEN_0 (req->volume + pathlen);
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ cmd = ntoh32 (req->cmd);
+ switch (cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = ntoh32 (req->type);
+ state->volume = gf_strdup (req->volume + pathlen);
+
+ gf_flock_to_flock (&req->flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ gf_resolve_and_resume (frame, server_inodelk_resume);
+
+ return 0;
+}
+
+static int
+server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_finodelk_cbk,
+ BOUND_XL(frame),
+ BOUND_XL(frame)->fops->finodelk,
+ state->volume, state->fd, state->cmd, &state->flock);
+
+ return 0;
+err:
+ server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+
+ return 0;
+}
+
+static int
+server_finodelk (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_finodelk_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION(frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->volume = gf_strdup (req->volume);
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->cmd = ntoh32 (req->cmd);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ state->type = ntoh32 (req->type);
+
+ gf_flock_to_flock (&req->flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ }
+
+ gf_resolve_and_resume (frame, server_finodelk_resume);
+
+ return 0;
+}
+
+
+static int
+server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_entrylk_cbk,
+ bound_xl, bound_xl->fops->entrylk,
+ state->volume, &state->loc, state->name,
+ state->cmd, state->type);
+ return 0;
+err:
+ server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+
+static int
+server_entrylk (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_entrylk_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t pathlen = 0;
+ size_t namelen = 0;
+ size_t vollen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+ namelen = ntoh64 (req->namelen);
+ vollen = STRLEN_0(req->volume + pathlen + namelen);
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.ino = ntoh64 (req->ino);
+ state->resolve.gen = ntoh64 (req->gen);
+
+ if (namelen)
+ state->name = gf_strdup (req->name + pathlen);
+ state->volume = gf_strdup (req->volume + pathlen + namelen);
+
+ state->cmd = ntoh32 (req->cmd);
+ state->type = ntoh32 (req->type);
+
+ gf_resolve_and_resume (frame, server_entrylk_resume);
+
+ return 0;
+}
+
+static int
+server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_fentrylk_cbk,
+ BOUND_XL(frame),
+ BOUND_XL(frame)->fops->fentrylk,
+ state->volume, state->fd, state->name,
+ state->cmd, state->type);
+
+ return 0;
+err:
+ server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+static int
+server_fentrylk (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_fentrylk_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t namelen = 0;
+ size_t vollen = 0;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION (frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE(frame);
+ vollen = STRLEN_0(req->volume + namelen);
+
+ state->resolve.type = RESOLVE_EXACT;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->cmd = ntoh32 (req->cmd);
+ state->type = ntoh32 (req->type);
+ namelen = ntoh64 (req->namelen);
+ if (namelen)
+ state->name = req->name;
+ state->volume = gf_strdup (req->volume + namelen);
+
+
+ gf_resolve_and_resume (frame, server_fentrylk_resume);
+
+ return 0;
+}
+
+
+static int
+server_access_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_access_cbk,
+ bound_xl, bound_xl->fops->access,
+ &state->loc, state->mask);
+ return 0;
+err:
+ server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno);
+ return 0;
+}
+
+
+static int
+server_access (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_access_req_t *req = NULL;
+ server_state_t *state = NULL;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.ino = hton64 (req->ino);
+ state->resolve.gen = hton64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+
+ state->mask = ntoh32 (req->mask);
+
+ gf_resolve_and_resume (frame, server_access_resume);
+
+ return 0;
+}
+
+
+static int
+server_symlink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_symlink_cbk,
+ bound_xl, bound_xl->fops->symlink,
+ state->name, &state->loc, state->params);
+
+ return 0;
+err:
+ server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+
+static int
+server_symlink (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ server_state_t *state = NULL;
+ gf_fop_symlink_req_t *req = NULL;
+ size_t pathlen = 0;
+ size_t baselen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ pathlen = STRLEN_0 (req->path);
+ baselen = STRLEN_0 (req->bname + pathlen);
+
+ state->resolve.type = RESOLVE_NOT;
+ state->resolve.par = ntoh64 (req->par);
+ state->resolve.gen = ntoh64 (req->gen);
+ state->resolve.path = gf_strdup (req->path);
+ state->resolve.bname = gf_strdup (req->bname + pathlen);
+ state->name = gf_strdup (req->linkname + pathlen + baselen);
+
+ gf_resolve_and_resume (frame, server_symlink_resume);
+
+ return 0;
+}
+
+
+static int
+server_link_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ state->loc2.inode = inode_ref (state->loc.inode);
+
+ STACK_WIND (frame, server_link_cbk,
+ bound_xl, bound_xl->fops->link,
+ &state->loc, &state->loc2);
+ return 0;
+err:
+ server_link_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_link (call_frame_t *frame, xlator_t *this,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_link_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t oldpathlen = 0;
+ size_t newpathlen = 0;
+ size_t newbaselen = 0;
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+ oldpathlen = STRLEN_0 (req->oldpath);
+ newpathlen = STRLEN_0 (req->newpath + oldpathlen);
+ newbaselen = STRLEN_0 (req->newbname + oldpathlen + newpathlen);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->oldpath);
+ state->resolve.ino = ntoh64 (req->oldino);
+ state->resolve.gen = ntoh64 (req->oldgen);
+
+ state->resolve2.type = RESOLVE_NOT;
+ state->resolve2.path = gf_strdup (req->newpath + oldpathlen);
+ state->resolve2.bname = gf_strdup (req->newbname + oldpathlen + newpathlen);
+ state->resolve2.par = ntoh64 (req->newpar);
+ state->resolve2.gen = ntoh64 (req->newgen);
+
+ gf_resolve_and_resume (frame, server_link_resume);
+
+ return 0;
+}
+
+
+static int
+server_rename_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ if (state->resolve2.op_ret != 0) {
+ op_ret = state->resolve2.op_ret;
+ op_errno = state->resolve2.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rename_cbk,
+ bound_xl, bound_xl->fops->rename,
+ &state->loc, &state->loc2);
+ return 0;
+err:
+ server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno,
+ NULL, NULL, NULL, NULL, NULL);
+ return 0;
+}
+
+
+static int
+server_rename (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_rename_req_t *req = NULL;
+ server_state_t *state = NULL;
+ size_t oldpathlen = 0;
+ size_t oldbaselen = 0;
+ size_t newpathlen = 0;
+ size_t newbaselen = 0;
+
+ req = gf_param (hdr);
+
+ state = CALL_STATE (frame);
+ oldpathlen = STRLEN_0 (req->oldpath);
+ oldbaselen = STRLEN_0 (req->oldbname + oldpathlen);
+ newpathlen = STRLEN_0 (req->newpath + oldpathlen + oldbaselen);
+ newbaselen = STRLEN_0 (req->newbname + oldpathlen +
+ oldbaselen + newpathlen);
+
+ state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (req->oldpath);
+ state->resolve.bname = gf_strdup (req->oldbname + oldpathlen);
+ state->resolve.par = ntoh64 (req->oldpar);
+ state->resolve.gen = ntoh64 (req->oldgen);
+
+ state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.path = gf_strdup (req->newpath + oldpathlen + oldbaselen);
+ state->resolve2.bname = gf_strdup (req->newbname + oldpathlen + oldbaselen +
+ newpathlen);
+ state->resolve2.par = ntoh64 (req->newpar);
+ state->resolve2.gen = ntoh64 (req->newgen);
+
+ gf_resolve_and_resume (frame, server_rename_resume);
+
+ return 0;
+}
+
+static int
+server_lk_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ STACK_WIND (frame, server_lk_cbk,
+ BOUND_XL(frame),
+ BOUND_XL(frame)->fops->lk,
+ state->fd, state->cmd, &state->flock);
+
+ return 0;
+
+err:
+ server_lk_cbk (frame, NULL, frame->this,
+ state->resolve.op_ret,
+ state->resolve.op_errno,
+ NULL);
+ return 0;
+}
+
+/*
+ * server_lk - lk function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ * not for external reference
+ */
+
+static int
+server_lk (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_lk_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION (frame);
+
+ req = gf_param (hdr);
+ state = CALL_STATE (frame);
+
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->cmd = ntoh32 (req->cmd);
+ state->type = ntoh32 (req->type);
+
+ switch (state->cmd) {
+ case GF_LK_GETLK:
+ state->cmd = F_GETLK;
+ break;
+ case GF_LK_SETLK:
+ state->cmd = F_SETLK;
+ break;
+ case GF_LK_SETLKW:
+ state->cmd = F_SETLKW;
+ break;
+ }
+
+ gf_flock_to_flock (&req->flock, &state->flock);
+
+ switch (state->type) {
+ case GF_LK_F_RDLCK:
+ state->flock.l_type = F_RDLCK;
+ break;
+ case GF_LK_F_WRLCK:
+ state->flock.l_type = F_WRLCK;
+ break;
+ case GF_LK_F_UNLCK:
+ state->flock.l_type = F_UNLCK;
+ break;
+ default:
+ gf_log (bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): Unknown lock type: %"PRId32"!",
+ state->resolve.fd_no, state->fd->inode->ino, state->type);
+ break;
+ }
+
+
+ gf_resolve_and_resume (frame, server_lk_resume);
+
+ return 0;
+}
+
+/* xxx_MOPS */
+static int
+_volfile_update_checksum (xlator_t *this, char *key, uint32_t checksum)
+{
+ server_conf_t *conf = NULL;
+ struct _volfile_ctx *temp_volfile = NULL;
+
+ conf = this->private;
+ temp_volfile = conf->volfile;
+
+ while (temp_volfile) {
+ if ((NULL == key) && (NULL == temp_volfile->key))
+ break;
+ if ((NULL == key) || (NULL == temp_volfile->key)) {
+ temp_volfile = temp_volfile->next;
+ continue;
+ }
+ if (strcmp (temp_volfile->key, key) == 0)
+ break;
+ temp_volfile = temp_volfile->next;
+ }
+
+ if (!temp_volfile) {
+ temp_volfile = GF_CALLOC (1, sizeof (struct _volfile_ctx),
+ gf_server_mt_volfile_ctx);
+ if (!temp_volfile)
+ goto out;
+ temp_volfile->next = conf->volfile;
+ temp_volfile->key = (key)? gf_strdup (key): NULL;
+ temp_volfile->checksum = checksum;
+
+ conf->volfile = temp_volfile;
+ goto out;
+ }
+
+ if (temp_volfile->checksum != checksum) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "the volume file got modified between earlier access "
+ "and now, this may lead to inconsistency between "
+ "clients, advised to remount client");
+ temp_volfile->checksum = checksum;
+ }
+
+ out:
+ return 0;
+}
+
+
+size_t
+build_volfile_path (xlator_t *this, const char *key, char *path,
+ size_t path_len)
+{
+ int ret = -1;
+ int free_filename = 0;
+ int free_conf_dir = 0;
+ char *filename = NULL;
+ char *conf_dir = CONFDIR;
+ struct stat buf = {0,};
+ data_t * conf_dir_data = NULL;
+ char data_key[256] = {0,};
+
+ /* Inform users that this option is changed now */
+ ret = dict_get_str (this->options, "client-volume-filename",
+ &filename);
+ if (ret == 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "option 'client-volume-filename' is changed to "
+ "'volume-filename.<key>' which now takes 'key' as an "
+ "option to choose/fetch different files from server. "
+ "Refer documentation or contact developers for more "
+ "info. Currently defaulting to given file '%s'",
+ filename);
+ }
+
+ if (key && !filename) {
+ sprintf (data_key, "volume-filename.%s", key);
+ ret = dict_get_str (this->options, data_key, &filename);
+
+ if (ret < 0) {
+
+ conf_dir_data = dict_get (this->options, "conf-dir");
+ if (conf_dir_data) {
+ /* Check whether the specified directory exists,
+ or directory specified is non standard */
+ ret = stat (conf_dir_data->data, &buf);
+ if ((ret != 0) || !S_ISDIR (buf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Directory '%s' doesn't"
+ "exist, exiting.",
+ conf_dir_data->data);
+ ret = -1;
+ goto out;
+ }
+ /* Make sure that conf-dir doesn't
+ * contain ".." in path
+ */
+ if ((gf_strstr (conf_dir_data->data,
+ "/", "..")) == -1) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: invalid conf_dir",
+ conf_dir_data->data);
+ goto out;
+ }
+
+ /* Make sure that key doesn't
+ * contain "../" in path
+ */
+
+ if ((gf_strstr (key, "/", "..")) == -1) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: invalid key", key);
+ goto out;
+ }
+
+ conf_dir = gf_strdup (conf_dir_data->data);
+ free_conf_dir = 1;
+ }
+
+ ret = gf_asprintf (&filename, "%s/%s.vol",
+ conf_dir, key);
+ if (-1 == ret)
+ goto out;
+
+ free_filename = 1;
+ }
+ }
+
+ if (!filename) {
+ ret = dict_get_str (this->options,
+ "volume-filename.default", &filename);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "no default volume filename given, "
+ "defaulting to %s", DEFAULT_VOLUME_FILE_PATH);
+ filename = DEFAULT_VOLUME_FILE_PATH;
+ }
+ }
+
+ ret = -1;
+
+ if ((filename) && (path_len > strlen (filename))) {
+ strcpy (path, filename);
+ ret = strlen (filename);
+ }
+
+out:
+ if (free_conf_dir)
+ GF_FREE (conf_dir);
+
+ if (free_filename)
+ GF_FREE (filename);
+
+ return ret;
+}
+
+static int
+_validate_volfile_checksum (xlator_t *this, char *key,
+ uint32_t checksum)
+{
+ char filename[ZR_PATH_MAX] = {0,};
+ server_conf_t *conf = NULL;
+ struct _volfile_ctx *temp_volfile = NULL;
+ int ret = 0;
+ uint32_t local_checksum = 0;
+
+ conf = this->private;
+ temp_volfile = conf->volfile;
+
+ if (!checksum)
+ goto out;
+
+ if (!temp_volfile) {
+ ret = build_volfile_path (this, key, filename,
+ sizeof (filename));
+ if (ret <= 0)
+ goto out;
+ ret = open (filename, O_RDONLY);
+ if (-1 == ret) {
+ ret = 0;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to open volume file (%s) : %s",
+ filename, strerror (errno));
+ goto out;
+ }
+ get_checksum_for_file (ret, &local_checksum);
+ _volfile_update_checksum (this, key, local_checksum);
+ close (ret);
+ }
+
+ temp_volfile = conf->volfile;
+ while (temp_volfile) {
+ if ((NULL == key) && (NULL == temp_volfile->key))
+ break;
+ if ((NULL == key) || (NULL == temp_volfile->key)) {
+ temp_volfile = temp_volfile->next;
+ continue;
+ }
+ if (strcmp (temp_volfile->key, key) == 0)
+ break;
+ temp_volfile = temp_volfile->next;
+ }
+
+ if (!temp_volfile)
+ goto out;
+
+ if ((temp_volfile->checksum) &&
+ (checksum != temp_volfile->checksum))
+ ret = -1;
+
+out:
+ return ret;
+}
+
+/* Management Calls */
+/*
+ * mop_getspec - getspec function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params:
+ *
+ */
+static int
+mop_getspec (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *_hdr = NULL;
+ gf_mop_getspec_rsp_t *rsp = NULL;
+ int32_t ret = -1;
+ int32_t op_errno = ENOENT;
+ int32_t gf_errno = 0;
+ int32_t spec_fd = -1;
+ size_t file_len = 0;
+ size_t _hdrlen = 0;
+ char filename[ZR_PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+ gf_mop_getspec_req_t *req = NULL;
+ uint32_t checksum = 0;
+ uint32_t flags = 0;
+ uint32_t keylen = 0;
+ char *key = NULL;
+ server_conf_t *conf = NULL;
+
+ req = gf_param (hdr);
+ flags = ntoh32 (req->flags);
+ keylen = ntoh32 (req->keylen);
+ if (keylen) {
+ key = req->key;
+ }
+
+ conf = frame->this->private;
+
+ ret = build_volfile_path (frame->this, key, filename,
+ sizeof (filename));
+ if (ret > 0) {
+ /* to allocate the proper buffer to hold the file data */
+ ret = stat (filename, &stbuf);
+ if (ret < 0){
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Unable to stat %s (%s)",
+ filename, strerror (errno));
+ goto fail;
+ }
+
+ spec_fd = open (filename, O_RDONLY);
+ if (spec_fd < 0) {
+ gf_log (frame->this->name, GF_LOG_ERROR,
+ "Unable to open %s (%s)",
+ filename, strerror (errno));
+ goto fail;
+ }
+ ret = 0;
+ file_len = stbuf.st_size;
+ if (conf->verify_volfile_checksum) {
+ get_checksum_for_file (spec_fd, &checksum);
+ _volfile_update_checksum (frame->this, key, checksum);
+ }
+ } else {
+ errno = ENOENT;
+ }
+
+fail:
+ op_errno = errno;
+
+ _hdrlen = gf_hdr_len (rsp, file_len + 1);
+ _hdr = gf_hdr_new (rsp, file_len + 1);
+ rsp = gf_param (_hdr);
+
+ _hdr->rsp.op_ret = hton32 (ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ _hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (file_len) {
+ ret = read (spec_fd, rsp->spec, file_len);
+ close (spec_fd);
+ }
+ protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_GETSPEC,
+ _hdr, _hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+
+static int
+server_checksum (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_CHECKSUM,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ uint32_t weak_checksum, uint8_t *strong_checksum)
+{
+ gf_hdr_common_t *hdr = NULL;
+ gf_fop_rchecksum_rsp_t *rsp = NULL;
+ size_t hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ hdrlen = gf_hdr_len (rsp, MD5_DIGEST_LEN + 1);
+ hdr = gf_hdr_new (rsp, MD5_DIGEST_LEN + 1);
+ rsp = gf_param (hdr);
+
+ hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+
+ if (op_ret >= 0) {
+ rsp->weak_checksum = weak_checksum;
+
+ memcpy (rsp->strong_checksum,
+ strong_checksum, MD5_DIGEST_LEN);
+
+ rsp->strong_checksum[MD5_DIGEST_LEN] = '\0';
+ }
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_RCHECKSUM,
+ hdr, hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+static int
+server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+ int op_ret = 0;
+ int op_errno = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0) {
+ op_ret = state->resolve.op_ret;
+ op_errno = state->resolve.op_errno;
+ goto err;
+ }
+
+ STACK_WIND (frame, server_rchecksum_cbk,
+ bound_xl,
+ bound_xl->fops->rchecksum,
+ state->fd, state->offset, state->size);
+
+ return 0;
+err:
+ server_rchecksum_cbk (frame, NULL, frame->this, -1, EINVAL, 0, NULL);
+
+ return 0;
+
+}
+
+static int
+server_rchecksum (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_fop_rchecksum_req_t *req = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+
+ conn = SERVER_CONNECTION(frame);
+
+ req = gf_param (hdr);
+
+ state = CALL_STATE(frame);
+
+ state->resolve.type = RESOLVE_MAY;
+ state->resolve.fd_no = ntoh64 (req->fd);
+ state->offset = ntoh64 (req->offset);
+ state->size = ntoh32 (req->len);
+
+ gf_resolve_and_resume (frame, server_rchecksum_resume);
+
+ return 0;
+}
+
+
+/*
+ * mop_unlock - unlock management function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ */
+static int
+mop_getvolume (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ return 0;
+}
+
+struct __get_xl_struct {
+ const char *name;
+ xlator_t *reply;
+};
+
+static void __check_and_set (xlator_t *each, void *data)
+{
+ if (!strcmp (each->name,
+ ((struct __get_xl_struct *) data)->name))
+ ((struct __get_xl_struct *) data)->reply = each;
+}
+
+static xlator_t *
+get_xlator_by_name (xlator_t *some_xl, const char *name)
+{
+ struct __get_xl_struct get = {
+ .name = name,
+ .reply = NULL
+ };
+
+ xlator_foreach (some_xl, __check_and_set, &get);
+
+ return get.reply;
+}
+
+
+/*
+ * mop_setvolume - setvolume management function for server protocol
+ * @frame: call frame
+ * @bound_xl:
+ * @params: parameter dictionary
+ *
+ */
+static int
+mop_setvolume (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *req_hdr, size_t req_hdrlen,
+ struct iobuf *iobuf)
+{
+ server_connection_t *conn = NULL;
+ server_conf_t *conf = NULL;
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_setvolume_req_t *req = NULL;
+ gf_mop_setvolume_rsp_t *rsp = NULL;
+ peer_info_t *peerinfo = NULL;
+ int32_t ret = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t gf_errno = 0;
+ dict_t *reply = NULL;
+ dict_t *config_params = NULL;
+ dict_t *params = NULL;
+ char *name = NULL;
+ char *version = NULL;
+ char *process_uuid = NULL;
+ xlator_t *xl = NULL;
+ transport_t *trans = NULL;
+ size_t rsp_hdrlen = -1;
+ size_t dict_len = -1;
+ size_t req_dictlen = -1;
+ char *msg = NULL;
+ char *volfile_key = NULL;
+ uint32_t checksum = 0;
+ int32_t lru_limit = 1024;
+
+ params = dict_new ();
+ reply = dict_new ();
+
+ req = gf_param (req_hdr);
+ req_dictlen = ntoh32 (req->dict_len);
+ ret = dict_unserialize (req->buf, req_dictlen, &params);
+
+ config_params = dict_copy_with_ref (frame->this->options, NULL);
+ trans = TRANSPORT_FROM_FRAME(frame);
+ conf = SERVER_CONF(frame);
+
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "Internal error: failed to unserialize "
+ "request dictionary");
+ if (ret < 0)
+ gf_log (bound_xl->name, GF_LOG_DEBUG,
+ "failed to set error msg \"%s\"",
+ "Internal error: failed to unserialize "
+ "request dictionary");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = dict_get_str (params, "process-uuid", &process_uuid);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "UUID not specified");
+ if (ret < 0)
+ gf_log (bound_xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+
+ conn = gf_server_connection_get (frame->this, process_uuid);
+ if (trans->xl_private != conn)
+ trans->xl_private = conn;
+
+ ret = dict_get_str (params, "protocol-version", &version);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "No version number specified");
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = strcmp (version, GF_PROTOCOL_VERSION);
+ if (ret != 0) {
+ ret = gf_asprintf (&msg, "protocol version mismatch: client(%s) "
+ "- server(%s)", version, GF_PROTOCOL_VERSION);
+ if (-1 == ret) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "gf_asprintf failed while setting up error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr (reply, "ERROR", msg);
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ ret = dict_get_str (params,
+ "remote-subvolume", &name);
+ if (ret < 0) {
+ ret = dict_set_str (reply, "ERROR",
+ "No remote-subvolume option specified");
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto fail;
+ }
+
+ xl = get_xlator_by_name (frame->this, name);
+ if (xl == NULL) {
+ ret = gf_asprintf (&msg, "remote-subvolume \"%s\" is not found",
+ name);
+ if (-1 == ret) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "gf_asprintf failed while setting error msg");
+ goto fail;
+ }
+ ret = dict_set_dynstr (reply, "ERROR", msg);
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto fail;
+ }
+
+ if (conf->verify_volfile_checksum) {
+ ret = dict_get_uint32 (params, "volfile-checksum", &checksum);
+ if (ret == 0) {
+ ret = dict_get_str (params, "volfile-key",
+ &volfile_key);
+
+ ret = _validate_volfile_checksum (trans->xl,
+ volfile_key,
+ checksum);
+ if (-1 == ret) {
+ ret = dict_set_str (reply, "ERROR",
+ "volume-file checksum "
+ "varies from earlier "
+ "access");
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto fail;
+ }
+ }
+ }
+
+
+ peerinfo = &trans->peerinfo;
+ ret = dict_set_static_ptr (params, "peer-info", peerinfo);
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set peer-info");
+ ret = dict_set_str (params, "peer-info-name", peerinfo->identifier);
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set peer-info-name");
+
+ if (conf->auth_modules == NULL) {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "Authentication module not initialized");
+ }
+
+ ret = gf_authenticate (params, config_params,
+ conf->auth_modules);
+ if (ret == AUTH_ACCEPT) {
+ gf_log (trans->xl->name, GF_LOG_INFO,
+ "accepted client from %s",
+ peerinfo->identifier);
+ op_ret = 0;
+ conn->bound_xl = xl;
+ ret = dict_set_str (reply, "ERROR", "Success");
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+ } else {
+ gf_log (trans->xl->name, GF_LOG_ERROR,
+ "Cannot authenticate client from %s",
+ peerinfo->identifier);
+ op_ret = -1;
+ op_errno = EACCES;
+ ret = dict_set_str (reply, "ERROR", "Authentication failed");
+ if (ret < 0)
+ gf_log (bound_xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ goto fail;
+ }
+
+ if (conn->bound_xl == NULL) {
+ ret = dict_set_str (reply, "ERROR",
+ "Check volfile and handshake "
+ "options in protocol/client");
+ if (ret < 0)
+ gf_log (trans->xl->name, GF_LOG_DEBUG,
+ "failed to set error msg");
+
+ op_ret = -1;
+ op_errno = EACCES;
+ goto fail;
+ }
+
+ if ((conn->bound_xl != NULL) &&
+ (ret >= 0) &&
+ (conn->bound_xl->itable == NULL)) {
+ /* create inode table for this bound_xl, if one doesn't
+ already exist */
+ lru_limit = INODE_LRU_LIMIT (frame->this);
+
+ gf_log (trans->xl->name, GF_LOG_TRACE,
+ "creating inode table with lru_limit=%"PRId32", "
+ "xlator=%s", lru_limit, conn->bound_xl->name);
+
+ conn->bound_xl->itable =
+ inode_table_new (lru_limit,
+ conn->bound_xl);
+ }
+
+ ret = dict_set_str (reply, "process-uuid",
+ xl->ctx->process_uuid);
+
+ ret = dict_set_uint64 (reply, "transport-ptr",
+ ((uint64_t) (long) trans));
+
+fail:
+ dict_len = dict_serialized_length (reply);
+ if (dict_len < 0) {
+ gf_log ("server", GF_LOG_DEBUG,
+ "failed to get serialized length of reply dict");
+ op_ret = -1;
+ op_errno = EINVAL;
+ dict_len = 0;
+ }
+
+ rsp_hdr = gf_hdr_new (rsp, dict_len);
+ rsp_hdrlen = gf_hdr_len (rsp, dict_len);
+ rsp = gf_param (rsp_hdr);
+
+ if (dict_len) {
+ ret = dict_serialize (reply, rsp->buf);
+ if (ret < 0) {
+ gf_log ("server", GF_LOG_DEBUG,
+ "failed to serialize reply dict");
+ op_ret = -1;
+ op_errno = -ret;
+ }
+ }
+ rsp->dict_len = hton32 (dict_len);
+
+ rsp_hdr->rsp.op_ret = hton32 (op_ret);
+ gf_errno = gf_errno_to_error (op_errno);
+ rsp_hdr->rsp.op_errno = hton32 (gf_errno);
+
+ protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_SETVOLUME,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ dict_unref (params);
+ dict_unref (reply);
+ dict_unref (config_params);
+
+ return 0;
+}
+
+
+static int
+mop_ping (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL;
+ size_t rsp_hdrlen = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ hdr->rsp.op_ret = 0;
+
+ protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_PING,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+mop_log (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_mop_log_req_t * req = NULL;
+ char * msg = NULL;
+ uint32_t msglen = 0;
+
+ transport_t * trans = NULL;
+
+ trans = TRANSPORT_FROM_FRAME (frame);
+
+ req = gf_param (hdr);
+ msglen = ntoh32 (req->msglen);
+
+ if (msglen)
+ msg = req->msg;
+
+ gf_log_from_client (msg, trans->peerinfo.identifier);
+
+ return 0;
+}
+
+
+/* ENOSYS operations (for backword compatibility) */
+static int
+server_setdents (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_SETDENTS,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/* */
+static int
+server_getdents (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_GETDENTS,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/* */
+static int
+server_lock_notify (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOCK_NOTIFY,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+/* */
+static int
+server_lock_fnotify (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_FOP_REPLY, GF_PROTO_FOP_LOCK_FNOTIFY,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+static int
+mop_stats (call_frame_t *frame, xlator_t *bound_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf)
+{
+ gf_hdr_common_t *rsp_hdr = NULL;
+ gf_mop_ping_rsp_t *rsp = NULL; /* Using for NULL */
+ size_t rsp_hdrlen = 0;
+ int32_t gf_errno = 0;
+
+ rsp_hdrlen = gf_hdr_len (rsp, 0);
+ rsp_hdr = gf_hdr_new (rsp, 0);
+
+ gf_errno = gf_errno_to_error (ENOSYS);
+ hdr->rsp.op_errno = hton32 (gf_errno);
+ hdr->rsp.op_ret = -1;
+
+ protocol_server_reply (frame, GF_OP_TYPE_MOP_REPLY, GF_MOP_STATS,
+ rsp_hdr, rsp_hdrlen, NULL, 0, NULL);
+
+ return 0;
+}
+
+
+/*
+ * get_frame_for_transport - get call frame for specified transport object
+ *
+ * @trans: transport object
+ *
+ */
+static call_frame_t *
+get_frame_for_transport (transport_t *trans)
+{
+ call_frame_t *frame = NULL;
+ call_pool_t *pool = NULL;
+ server_connection_t *conn = NULL;
+ server_state_t *state = NULL;;
+
+ GF_VALIDATE_OR_GOTO("server", trans, out);
+
+ if (trans->xl && trans->xl->ctx)
+ pool = trans->xl->ctx->pool;
+ GF_VALIDATE_OR_GOTO("server", pool, out);
+
+ frame = create_frame (trans->xl, pool);
+ GF_VALIDATE_OR_GOTO("server", frame, out);
+
+ state = GF_CALLOC (1, sizeof (*state),
+ gf_server_mt_server_state_t);
+ GF_VALIDATE_OR_GOTO("server", state, out);
+
+ conn = trans->xl_private;
+ if (conn) {
+ if (conn->bound_xl)
+ state->itable = conn->bound_xl->itable;
+ state->bound_xl = conn->bound_xl;
+ }
+
+ state->trans = transport_ref (trans);
+ state->resolve.fd_no = -1;
+ state->resolve2.fd_no = -1;
+
+ frame->root->trans = conn;
+ frame->root->state = state; /* which socket */
+ frame->root->unique = 0; /* which call */
+
+out:
+ return frame;
+}
+
+
+static int
+server_decode_groups (call_frame_t *frame, gf_hdr_common_t *hdr)
+{
+ int i = 0;
+
+ if ((!frame) || (!hdr))
+ return 0;
+
+ frame->root->ngrps = ntoh32 (hdr->req.ngrps);
+ if (frame->root->ngrps == 0)
+ return 0;
+
+ if (frame->root->ngrps > GF_REQUEST_MAXGROUPS)
+ return -1;
+
+ for (; i < frame->root->ngrps; ++i)
+ frame->root->groups[i] = ntoh32 (hdr->req.groups[i]);
+
+ return 0;
+}
+
+
+/*
+ * get_frame_for_call - create a frame into the capable of
+ * generating and replying the reply packet by itself.
+ * By making a call with this frame, the last UNWIND
+ * function will have all needed state from its
+ * frame_t->root to send reply.
+ * @trans:
+ * @blk:
+ * @params:
+ *
+ * not for external reference
+ */
+static call_frame_t *
+get_frame_for_call (transport_t *trans, gf_hdr_common_t *hdr)
+{
+ call_frame_t *frame = NULL;
+ int32_t ret = -1;
+
+ frame = get_frame_for_transport (trans);
+
+ frame->root->op = ntoh32 (hdr->op);
+ frame->root->type = ntoh32 (hdr->type);
+
+ frame->root->uid = ntoh32 (hdr->req.uid);
+ frame->root->unique = ntoh64 (hdr->callid); /* which call */
+ frame->root->gid = ntoh32 (hdr->req.gid);
+ frame->root->pid = ntoh32 (hdr->req.pid);
+ frame->root->lk_owner = ntoh64 (hdr->req.lk_owner);
+ ret = server_decode_groups (frame, hdr);
+
+ if (ret) {
+ //FRAME_DESTROY (frame);
+ return NULL;
+ }
+
+ return frame;
+}
+
+/*
+ * prototype of operations function for each of mop and
+ * fop at server protocol level
+ *
+ * @frame: call frame pointer
+ * @bound_xl: the xlator that this frame is bound to
+ * @params: parameters dictionary
+ *
+ * to be used by protocol interpret, _not_ for exterenal reference
+ */
+typedef int32_t (*gf_op_t) (call_frame_t *frame, xlator_t *bould_xl,
+ gf_hdr_common_t *hdr, size_t hdrlen,
+ struct iobuf *iobuf);
+
+
+static gf_op_t gf_fops[] = {
+ [GF_PROTO_FOP_STAT] = server_stat,
+ [GF_PROTO_FOP_READLINK] = server_readlink,
+ [GF_PROTO_FOP_MKNOD] = server_mknod,
+ [GF_PROTO_FOP_MKDIR] = server_mkdir,
+ [GF_PROTO_FOP_UNLINK] = server_unlink,
+ [GF_PROTO_FOP_RMDIR] = server_rmdir,
+ [GF_PROTO_FOP_SYMLINK] = server_symlink,
+ [GF_PROTO_FOP_RENAME] = server_rename,
+ [GF_PROTO_FOP_LINK] = server_link,
+ [GF_PROTO_FOP_TRUNCATE] = server_truncate,
+ [GF_PROTO_FOP_OPEN] = server_open,
+ [GF_PROTO_FOP_READ] = server_readv,
+ [GF_PROTO_FOP_WRITE] = server_writev,
+ [GF_PROTO_FOP_STATFS] = server_statfs,
+ [GF_PROTO_FOP_FLUSH] = server_flush,
+ [GF_PROTO_FOP_FSYNC] = server_fsync,
+ [GF_PROTO_FOP_SETXATTR] = server_setxattr,
+ [GF_PROTO_FOP_GETXATTR] = server_getxattr,
+ [GF_PROTO_FOP_FGETXATTR] = server_fgetxattr,
+ [GF_PROTO_FOP_FSETXATTR] = server_fsetxattr,
+ [GF_PROTO_FOP_REMOVEXATTR] = server_removexattr,
+ [GF_PROTO_FOP_OPENDIR] = server_opendir,
+ [GF_PROTO_FOP_FSYNCDIR] = server_fsyncdir,
+ [GF_PROTO_FOP_ACCESS] = server_access,
+ [GF_PROTO_FOP_CREATE] = server_create,
+ [GF_PROTO_FOP_FTRUNCATE] = server_ftruncate,
+ [GF_PROTO_FOP_FSTAT] = server_fstat,
+ [GF_PROTO_FOP_LK] = server_lk,
+ [GF_PROTO_FOP_LOOKUP] = server_lookup,
+ [GF_PROTO_FOP_READDIR] = server_readdir,
+ [GF_PROTO_FOP_READDIRP] = server_readdirp,
+ [GF_PROTO_FOP_INODELK] = server_inodelk,
+ [GF_PROTO_FOP_FINODELK] = server_finodelk,
+ [GF_PROTO_FOP_ENTRYLK] = server_entrylk,
+ [GF_PROTO_FOP_FENTRYLK] = server_fentrylk,
+ [GF_PROTO_FOP_CHECKSUM] = server_checksum,
+ [GF_PROTO_FOP_RCHECKSUM] = server_rchecksum,
+ [GF_PROTO_FOP_XATTROP] = server_xattrop,
+ [GF_PROTO_FOP_FXATTROP] = server_fxattrop,
+ [GF_PROTO_FOP_SETATTR] = server_setattr,
+ [GF_PROTO_FOP_FSETATTR] = server_fsetattr,
+ [GF_PROTO_FOP_SETDENTS] = server_setdents,
+ [GF_PROTO_FOP_GETDENTS] = server_getdents,
+ [GF_PROTO_FOP_LOCK_NOTIFY] = server_lock_notify,
+ [GF_PROTO_FOP_LOCK_FNOTIFY] = server_lock_fnotify,
+};
+
+
+
+static gf_op_t gf_mops[] = {
+ [GF_MOP_SETVOLUME] = mop_setvolume,
+ [GF_MOP_GETVOLUME] = mop_getvolume,
+ [GF_MOP_GETSPEC] = mop_getspec,
+ [GF_MOP_PING] = mop_ping,
+ [GF_MOP_LOG] = mop_log,
+ [GF_MOP_STATS] = mop_stats,
+};
+
+static gf_op_t gf_cbks[] = {
+ [GF_CBK_FORGET] = server_forget,
+ [GF_CBK_RELEASE] = server_release,
+ [GF_CBK_RELEASEDIR] = server_releasedir
+};
+
+static int
+protocol_server_interpret (xlator_t *this, transport_t *trans,
+ char *hdr_p, size_t hdrlen, struct iobuf *iobuf)
+{
+ server_connection_t *conn = NULL;
+ gf_hdr_common_t *hdr = NULL;
+ xlator_t *bound_xl = NULL;
+ call_frame_t *frame = NULL;
+ peer_info_t *peerinfo = NULL;
+ int32_t type = -1;
+ int32_t op = -1;
+ int32_t ret = -1;
+
+ hdr = (gf_hdr_common_t *)hdr_p;
+ type = ntoh32 (hdr->type);
+ op = ntoh32 (hdr->op);
+
+ conn = trans->xl_private;
+ if (conn)
+ bound_xl = conn->bound_xl;
+
+ peerinfo = &trans->peerinfo;
+ switch (type) {
+ case GF_OP_TYPE_FOP_REQUEST:
+ if ((op < 0) || (op >= GF_PROTO_FOP_MAXVALUE)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid fop %"PRId32" from client %s",
+ op, peerinfo->identifier);
+ break;
+ }
+ if (bound_xl == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Received fop %"PRId32" before "
+ "authentication.", op);
+ break;
+ }
+ frame = get_frame_for_call (trans, hdr);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+ frame->op = op;
+ ret = gf_fops[op] (frame, bound_xl, hdr, hdrlen, iobuf);
+ break;
+
+ case GF_OP_TYPE_MOP_REQUEST:
+ if ((op < 0) || (op >= GF_MOP_MAXVALUE)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid mop %"PRId32" from client %s",
+ op, peerinfo->identifier);
+ break;
+ }
+ frame = get_frame_for_call (trans, hdr);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+ frame->op = op;
+ ret = gf_mops[op] (frame, bound_xl, hdr, hdrlen, iobuf);
+ break;
+
+ case GF_OP_TYPE_CBK_REQUEST:
+ if ((op < 0) || (op >= GF_CBK_MAXVALUE)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cbk %"PRId32" from client %s",
+ op, peerinfo->identifier);
+ break;
+ }
+ if (bound_xl == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Received cbk %d before authentication.", op);
+ break;
+ }
+
+ frame = get_frame_for_call (trans, hdr);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+ ret = gf_cbks[op] (frame, bound_xl, hdr, hdrlen, iobuf);
+ break;
+
+ default:
+ break;
+ }
+out:
+ return ret;
+}
+
+
+/*
+ * server_fd - fdtable dump function for server protocol
+ * @this:
+ *
+ */
+static int
+server_fd (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ server_connection_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 1;
+ int ret = -1;
+
+ if (!this)
+ return -1;
+
+ conf = this->private;
+ if (!conf) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
+ }
+
+ gf_proc_dump_add_section("xlator.protocol.server.conn");
+
+ ret = pthread_mutex_trylock (&conf->mutex);
+ if (ret) {
+ gf_log("", GF_LOG_WARNING, "Unable to dump fdtable"
+ " errno: %d", errno);
+ return -1;
+ }
+
+ list_for_each_entry (trav, &conf->conns, list) {
+ if (trav->id) {
+ gf_proc_dump_build_key(key,
+ "xlator.protocol.server.conn",
+ "%d.id", i);
+ gf_proc_dump_write(key, "%s", trav->id);
+ }
+
+ gf_proc_dump_build_key(key,"xlator.protocol.server.conn",
+ "%d.ref",i)
+ gf_proc_dump_write(key, "%d", trav->ref);
+ if (trav->bound_xl) {
+ gf_proc_dump_build_key(key,
+ "xlator.protocol.server.conn",
+ "%d.bound_xl", i);
+ gf_proc_dump_write(key, "%s", trav->bound_xl->name);
+ }
+
+ gf_proc_dump_build_key(key,
+ "xlator.protocol.server.conn",
+ "%d.id", i);
+ fdtable_dump(trav->fdtable,key);
+ i++;
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+
+ return 0;
+ }
+
+static int
+server_priv (xlator_t *this)
+{
+ return 0;
+}
+
+static int
+server_inode (xlator_t *this)
+{
+ server_conf_t *conf = NULL;
+ server_connection_t *trav = NULL;
+ char key[GF_DUMP_MAX_BUF_LEN];
+ int i = 1;
+ int ret = -1;
+
+ if (!this)
+ return -1;
+
+ conf = this->private;
+ if (!conf) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "conf null in xlator");
+ return -1;
+ }
+
+ ret = pthread_mutex_trylock (&conf->mutex);
+ if (ret) {
+ gf_log("", GF_LOG_WARNING, "Unable to dump itable"
+ " errno: %d", errno);
+ return -1;
+ }
+
+ list_for_each_entry (trav, &conf->conns, list) {
+ if (trav->bound_xl && trav->bound_xl->itable) {
+ gf_proc_dump_build_key(key,
+ "xlator.protocol.server.conn",
+ "%d.bound_xl.%s",
+ i, trav->bound_xl->name);
+ inode_table_dump(trav->bound_xl->itable,key);
+ i++;
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+
+
+ return 0;
+}
+
+
+static void
+get_auth_types (dict_t *this, char *key, data_t *value, void *data)
+{
+ dict_t *auth_dict = NULL;
+ char *saveptr = NULL;
+ char *tmp = NULL;
+ char *key_cpy = NULL;
+ int32_t ret = -1;
+
+ auth_dict = data;
+ key_cpy = gf_strdup (key);
+ GF_VALIDATE_OR_GOTO("server", key_cpy, out);
+
+ tmp = strtok_r (key_cpy, ".", &saveptr);
+ ret = strcmp (tmp, "auth");
+ if (ret == 0) {
+ tmp = strtok_r (NULL, ".", &saveptr);
+ if (strcmp (tmp, "ip") == 0) {
+ /* TODO: backward compatibility, remove when
+ newer versions are available */
+ tmp = "addr";
+ gf_log ("server", GF_LOG_WARNING,
+ "assuming 'auth.ip' to be 'auth.addr'");
+ }
+ ret = dict_set_dynptr (auth_dict, tmp, NULL, 0);
+ if (ret < 0) {
+ gf_log ("server", GF_LOG_DEBUG,
+ "failed to dict_set_dynptr");
+ }
+ }
+
+ GF_FREE (key_cpy);
+out:
+ return;
+}
+
+
+static int
+validate_auth_options (xlator_t *this, dict_t *dict)
+{
+ int ret = -1;
+ int error = 0;
+ xlator_list_t *trav = NULL;
+ data_pair_t *pair = NULL;
+ char *saveptr = NULL;
+ char *tmp = NULL;
+ char *key_cpy = NULL;
+
+ trav = this->children;
+ while (trav) {
+ error = -1;
+ for (pair = dict->members_list; pair; pair = pair->next) {
+ key_cpy = gf_strdup (pair->key);
+ tmp = strtok_r (key_cpy, ".", &saveptr);
+ ret = strcmp (tmp, "auth");
+ if (ret == 0) {
+ /* for module type */
+ tmp = strtok_r (NULL, ".", &saveptr);
+ /* for volume name */
+ tmp = strtok_r (NULL, ".", &saveptr);
+ }
+
+ if (strcmp (tmp, trav->xlator->name) == 0) {
+ error = 0;
+ GF_FREE (key_cpy);
+ break;
+ }
+ GF_FREE (key_cpy);
+ }
+ if (-1 == error) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "volume '%s' defined as subvolume, but no "
+ "authentication defined for the same",
+ trav->xlator->name);
+ break;
+ }
+ trav = trav->next;
+ }
+
+ return error;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_server_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ " failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+
+/*
+ * init - called during server protocol initialization
+ *
+ * @this:
+ *
+ */
+int
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ transport_t *trans = NULL;
+ server_conf_t *conf = NULL;
+ data_t *data = NULL;
+ data_t *trace = NULL;
+
+ if (this->children == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "protocol/server should have subvolume");
+ goto out;
+ }
+
+ trans = transport_load (this->options, this);
+ if (trans == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to load transport");
+ goto out;
+ }
+
+ ret = transport_listen (trans);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to bind/listen on socket");
+ goto out;
+ }
+
+ conf = GF_CALLOC (1, sizeof (server_conf_t),
+ gf_server_mt_server_conf_t);
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ INIT_LIST_HEAD (&conf->conns);
+ pthread_mutex_init (&conf->mutex, NULL);
+
+ conf->trans = trans;
+
+ conf->auth_modules = dict_new ();
+ GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out);
+
+ dict_foreach (this->options, get_auth_types,
+ conf->auth_modules);
+ ret = validate_auth_options (this, this->options);
+ if (ret == -1) {
+ /* logging already done in validate_auth_options function. */
+ goto out;
+ }
+
+ ret = gf_auth_init (this, conf->auth_modules);
+ if (ret) {
+ dict_unref (conf->auth_modules);
+ goto out;
+ }
+
+ this->private = conf;
+
+ ret = dict_get_int32 (this->options, "inode-lru-limit",
+ &conf->inode_lru_limit);
+ if (ret < 0) {
+ conf->inode_lru_limit = 1024;
+ }
+
+ ret = dict_get_int32 (this->options, "limits.transaction-size",
+ &conf->max_block_size);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "defaulting limits.transaction-size to %d",
+ DEFAULT_BLOCK_SIZE);
+ conf->max_block_size = DEFAULT_BLOCK_SIZE;
+ }
+
+ conf->verify_volfile_checksum = 1;
+ data = dict_get (this->options, "verify-volfile-checksum");
+ if (data) {
+ ret = gf_string2boolean(data->data,
+ &conf->verify_volfile_checksum);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "wrong value for verify-volfile-checksum");
+ conf->verify_volfile_checksum = 1;
+ }
+ }
+
+ trace = dict_get (this->options, "trace");
+ if (trace) {
+ if (gf_string2boolean (trace->data,
+ &conf->trace) == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'trace' takes on only boolean values.");
+ return -1;
+ }
+ }
+
+#ifndef GF_DARWIN_HOST_OS
+ {
+ struct rlimit lim;
+
+ lim.rlim_cur = 1048576;
+ lim.rlim_max = 1048576;
+
+ if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "WARNING: Failed to set 'ulimit -n 1M': %s",
+ strerror(errno));
+ lim.rlim_cur = 65536;
+ lim.rlim_max = 65536;
+
+ if (setrlimit (RLIMIT_NOFILE, &lim) == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "Failed to set max open fd to 64k: %s",
+ strerror(errno));
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "max open fd set to 64k");
+ }
+ }
+ }
+#endif
+ this->graph->top = this;
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+
+static int
+protocol_server_pollin (xlator_t *this, transport_t *trans)
+{
+ char *hdr = NULL;
+ size_t hdrlen = 0;
+ int ret = -1;
+ struct iobuf *iobuf = NULL;
+
+
+ ret = transport_receive (trans, &hdr, &hdrlen, &iobuf);
+
+ if (ret == 0)
+ ret = protocol_server_interpret (this, trans, hdr,
+ hdrlen, iobuf);
+
+ /* TODO: use mem-pool */
+ GF_FREE (hdr);
+
+ return ret;
+}
+
+
+/*
+ * fini - finish function for server protocol, called before
+ * unloading server protocol.
+ *
+ * @this:
+ *
+ */
+void
+fini (xlator_t *this)
+{
+ server_conf_t *conf = this->private;
+
+ GF_VALIDATE_OR_GOTO(this->name, conf, out);
+
+ if (conf->auth_modules) {
+ dict_unref (conf->auth_modules);
+ }
+
+ GF_FREE (conf);
+ this->private = NULL;
+out:
+ return;
+}
+
+/*
+ * server_protocol_notify - notify function for server protocol
+ * @this:
+ * @trans:
+ * @event:
+ *
+ */
+int
+notify (xlator_t *this, int32_t event, void *data, ...)
+{
+ int ret = 0;
+ transport_t *trans = NULL;
+ peer_info_t *peerinfo = NULL;
+ peer_info_t *myinfo = NULL;
+
+ THIS = this;
+ trans = data;
+ if (!trans) {
+ gf_log (this->name, GF_LOG_ERROR, "!trans");
+ goto out;
+ }
+
+ peerinfo = &(trans->peerinfo);
+ myinfo = &(trans->myinfo);
+
+ switch (event) {
+ case GF_EVENT_POLLIN:
+ ret = protocol_server_pollin (this, trans);
+ break;
+ case GF_EVENT_POLLERR:
+ {
+ gf_log (trans->xl->name, GF_LOG_INFO, "%s disconnected",
+ peerinfo->identifier);
+
+ ret = -1;
+ transport_disconnect (trans);
+ if (trans->xl_private == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "POLLERR received on (%s) even before "
+ "handshake with (%s) is successful",
+ myinfo->identifier, peerinfo->identifier);
+ } else {
+ /*
+ * FIXME: shouldn't we check for return value?
+ * what should be done if cleanup fails?
+ */
+ gf_server_connection_cleanup (this, trans->xl_private);
+ }
+ }
+ break;
+
+ case GF_EVENT_TRANSPORT_CLEANUP:
+ {
+ if (trans->xl_private) {
+ gf_server_connection_put (this, trans->xl_private);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "transport (%s) cleaned up even before "
+ "handshake with (%s) is successful",
+ myinfo->identifier, peerinfo->identifier);
+ }
+ }
+ break;
+
+ default:
+ default_notify (this, event, data);
+ break;
+ }
+out:
+ return ret;
+}
+
+
+struct xlator_fops fops = {
+};
+
+struct xlator_cbks cbks = {
+};
+
+struct xlator_dumpops dumpops = {
+ .inode = server_inode,
+ .priv = server_priv,
+ .fd = server_fd,
+};
+
+
+struct volume_options options[] = {
+ { .key = {"transport-type"},
+ .value = {"tcp", "socket", "ib-verbs", "unix", "ib-sdp",
+ "tcp/server", "ib-verbs/server"},
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"volume-filename.*"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+ { .key = {"inode-lru-limit"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,
+ .max = (1 * GF_UNIT_MB)
+ },
+ { .key = {"client-volume-filename"},
+ .type = GF_OPTION_TYPE_PATH
+ },
+ { .key = {"verify-volfile-checksum"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"trace"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"conf-dir"},
+ .type = GF_OPTION_TYPE_PATH,
+ },
+
+ { .key = {NULL} },
+};
diff --git a/xlators/protocol/legacy/server/src/server-protocol.h b/xlators/protocol/legacy/server/src/server-protocol.h
new file mode 100644
index 000000000..feef60ce7
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-protocol.h
@@ -0,0 +1,191 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SERVER_PROTOCOL_H_
+#define _SERVER_PROTOCOL_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <pthread.h>
+
+#include "glusterfs.h"
+#include "xlator.h"
+#include "logging.h"
+#include "call-stub.h"
+#include "fd.h"
+#include "byte-order.h"
+#include "server-mem-types.h"
+#include "authenticate.h"
+#include "transport.h"
+
+#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
+#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
+
+typedef struct _server_state server_state_t;
+
+struct _locker {
+ struct list_head lockers;
+ char *volume;
+ loc_t loc;
+ fd_t *fd;
+ pid_t pid;
+};
+
+struct _lock_table {
+ struct list_head file_lockers;
+ struct list_head dir_lockers;
+ gf_lock_t lock;
+ size_t count;
+};
+
+
+/* private structure per connection (transport object)
+ * used as transport_t->xl_private
+ */
+struct _server_connection {
+ struct list_head list;
+ char *id;
+ int ref;
+ int active_transports;
+ pthread_mutex_t lock;
+ char disconnected;
+ fdtable_t *fdtable;
+ struct _lock_table *ltable;
+ xlator_t *bound_xl;
+};
+
+typedef struct _server_connection server_connection_t;
+
+
+server_connection_t *
+gf_server_connection_get (xlator_t *this, const char *id);
+
+void
+gf_server_connection_put (xlator_t *this, server_connection_t *conn);
+
+int
+gf_server_connection_cleanup (xlator_t *this, server_connection_t *conn);
+
+struct _volfile_ctx {
+ struct _volfile_ctx *next;
+ char *key;
+ uint32_t checksum;
+};
+
+typedef struct {
+ struct _volfile_ctx *volfile;
+
+ dict_t *auth_modules;
+ transport_t *trans;
+ int32_t max_block_size;
+ int32_t inode_lru_limit;
+ pthread_mutex_t mutex;
+ struct list_head conns;
+ gf_boolean_t verify_volfile_checksum;
+ gf_boolean_t trace;
+} server_conf_t;
+
+
+typedef enum {
+ RESOLVE_MUST = 1,
+ RESOLVE_NOT,
+ RESOLVE_MAY,
+ RESOLVE_DONTCARE,
+ RESOLVE_EXACT
+} server_resolve_type_t;
+
+
+struct resolve_comp {
+ char *basename;
+ ino_t ino;
+ uint64_t gen;
+ inode_t *inode;
+};
+
+typedef struct {
+ server_resolve_type_t type;
+ uint64_t fd_no;
+ ino_t ino;
+ uint64_t gen;
+ ino_t par;
+ char *path;
+ char *bname;
+ char *resolved;
+ int op_ret;
+ int op_errno;
+ loc_t deep_loc;
+ struct resolve_comp *components;
+ int comp_count;
+} server_resolve_t;
+
+
+typedef int (*server_resume_fn_t) (call_frame_t *frame, xlator_t *bound_xl);
+
+int
+gf_resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn);
+
+struct _server_state {
+ transport_t *trans;
+ xlator_t *bound_xl;
+ inode_table_t *itable;
+
+ server_resume_fn_t resume_fn;
+
+ loc_t loc;
+ loc_t loc2;
+ server_resolve_t resolve;
+ server_resolve_t resolve2;
+
+ /* used within resolve_and_resume */
+ loc_t *loc_now;
+ server_resolve_t *resolve_now;
+
+ struct iatt stbuf;
+ int valid;
+
+ fd_t *fd;
+ dict_t *params;
+ int flags;
+ int wbflags;
+ struct iobuf *iobuf;
+ struct iobref *iobref;
+
+ size_t size;
+ off_t offset;
+ mode_t mode;
+ dev_t dev;
+ size_t nr_count;
+ int cmd;
+ int type;
+ char *name;
+ int name_len;
+
+ int mask;
+ char is_revalidate;
+ dict_t *dict;
+ struct gf_flock flock;
+ const char *volume;
+ dir_entry_t *entry;
+};
+
+
+#endif
diff --git a/xlators/protocol/legacy/server/src/server-resolve.c b/xlators/protocol/legacy/server/src/server-resolve.c
new file mode 100644
index 000000000..573e77e1f
--- /dev/null
+++ b/xlators/protocol/legacy/server/src/server-resolve.c
@@ -0,0 +1,658 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "server-protocol.h"
+#include "server-helpers.h"
+
+#include "compat-errno.h"
+
+void
+gf_server_print_request (call_frame_t *frame);
+
+static int
+server_resolve_all (call_frame_t *frame);
+static int
+resolve_entry_simple (call_frame_t *frame);
+static int
+resolve_inode_simple (call_frame_t *frame);
+static int
+resolve_path_simple (call_frame_t *frame);
+
+
+static int
+component_count (const char *path)
+{
+ int count = 0;
+ const char *trav = NULL;
+
+ trav = path;
+
+ for (trav = path; *trav; trav++) {
+ if (*trav == '/')
+ count++;
+ }
+
+ return count + 2;
+}
+
+
+static int
+prepare_components (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ char *resolved = NULL;
+ int count = 0;
+ struct resolve_comp *components = NULL;
+ int i = 0;
+ char *trav = NULL;
+
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ resolved = gf_strdup (resolve->path);
+ resolve->resolved = resolved;
+
+ count = component_count (resolve->path);
+ components = GF_CALLOC (sizeof (*components), count,
+ gf_server_mt_resolve_comp);
+ resolve->components = components;
+
+ components[0].basename = "";
+ components[0].ino = 1;
+ components[0].gen = 0;
+ components[0].inode = state->itable->root;
+
+ i = 1;
+ for (trav = resolved; *trav; trav++) {
+ if (*trav == '/') {
+ components[i].basename = trav + 1;
+ *trav = 0;
+ i++;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+resolve_loc_touchup (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ loc_t *loc = NULL;
+ char *path = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+
+ resolve = state->resolve_now;
+ loc = state->loc_now;
+
+ if (!loc->path) {
+ if (loc->parent && resolve->bname) {
+ ret = inode_path (loc->parent, resolve->bname, &path);
+ } else if (loc->inode) {
+ ret = inode_path (loc->inode, NULL, &path);
+ }
+
+ if (!path)
+ path = gf_strdup (resolve->path);
+
+ loc->path = path;
+ }
+
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+
+ if (!loc->parent && loc->inode) {
+ loc->parent = inode_parent (loc->inode, 0, NULL);
+ }
+
+ return 0;
+}
+
+
+static int
+resolve_deep_continue (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
+
+ if (resolve->par)
+ ret = resolve_entry_simple (frame);
+ else if (resolve->ino)
+ ret = resolve_inode_simple (frame);
+ else if (resolve->path)
+ ret = resolve_path_simple (frame);
+
+ resolve_loc_touchup (frame);
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+static int
+resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
+ dict_t *xattr, struct iatt *postparent)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ struct resolve_comp *components = NULL;
+ int i = 0;
+ inode_t *link_inode = NULL;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+ components = resolve->components;
+
+ i = (long) cookie;
+
+ if (op_ret == -1) {
+ goto get_out_of_here;
+ }
+
+ if (i != 0) {
+ /* no linking for root inode */
+ link_inode = inode_link (inode, resolve->deep_loc.parent,
+ resolve->deep_loc.name, buf);
+ inode_lookup (link_inode);
+ components[i].inode = link_inode;
+ link_inode = NULL;
+ }
+
+ loc_wipe (&resolve->deep_loc);
+
+ i++; /* next component */
+
+ if (!components[i].basename) {
+ /* all components of the path are resolved */
+ goto get_out_of_here;
+ }
+
+ /* join the current component with the path resolved until now */
+ *(components[i].basename - 1) = '/';
+
+ resolve->deep_loc.path = gf_strdup (resolve->resolved);
+ resolve->deep_loc.parent = inode_ref (components[i-1].inode);
+ resolve->deep_loc.inode = inode_new (state->itable);
+ resolve->deep_loc.name = components[i].basename;
+
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_loc, NULL);
+ return 0;
+
+get_out_of_here:
+ resolve_deep_continue (frame);
+ return 0;
+}
+
+
+static int
+resolve_path_deep (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ int i = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ gf_log (BOUND_XL (frame)->name, GF_LOG_DEBUG,
+ "RESOLVE %s() seeking deep resolution of %s",
+ gf_fop_list[frame->root->op], resolve->path);
+
+ prepare_components (frame);
+
+ /* start from the root */
+ resolve->deep_loc.inode = state->itable->root;
+ resolve->deep_loc.path = gf_strdup ("/");
+ resolve->deep_loc.name = "";
+
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_loc, NULL);
+ return 0;
+}
+
+
+static int
+resolve_path_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ struct resolve_comp *components = NULL;
+ int ret = -1;
+ int par_idx = 0;
+ int ino_idx = 0;
+ int i = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ components = resolve->components;
+
+ if (!components) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ for (i = 0; components[i].basename; i++) {
+ par_idx = ino_idx;
+ ino_idx = i;
+ }
+
+ if (!components[par_idx].inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ if (!components[ino_idx].inode &&
+ (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) {
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ goto out;
+ }
+
+ if (components[ino_idx].inode)
+ state->loc_now->inode = inode_ref (components[ino_idx].inode);
+ state->loc_now->parent = inode_ref (components[par_idx].inode);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/*
+ Check if the requirements are fulfilled by entries in the inode cache itself
+ Return value:
+ <= 0 - simple resolution was decisive and complete (either success or failure)
+ > 0 - indecisive, need to perform deep resolution
+*/
+
+static int
+resolve_entry_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *parent = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ parent = inode_get (state->itable, resolve->par, 0);
+ if (!parent) {
+ /* simple resolution is indecisive. need to perform
+ deep resolution */
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+
+ inode = inode_grep (state->itable, parent, resolve->bname);
+ if (inode != NULL) {
+ gf_log (this->name, GF_LOG_DEBUG, "%"PRId64": inode "
+ "(pointer:%p ino: %"PRIu64") present but parent"
+ " is NULL for path (%s)", frame->root->unique,
+ inode, inode->ino, resolve->path);
+ inode_unref (inode);
+ }
+ goto out;
+ }
+
+// if (parent->ino != 1 && parent->generation != resolve->gen) {
+ if (0) {
+ /* simple resolution is decisive - request was for a
+ stale handle */
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = -1;
+ goto out;
+ }
+
+ /* expected @parent was found from the inode cache */
+ state->loc_now->parent = inode_ref (parent);
+
+ inode = inode_grep (state->itable, parent, resolve->bname);
+ if (!inode) {
+ switch (resolve->type) {
+ case RESOLVE_DONTCARE:
+ case RESOLVE_NOT:
+ ret = 0;
+ break;
+ case RESOLVE_MAY:
+ ret = 1;
+ break;
+ default:
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ break;
+ }
+
+ goto out;
+ }
+
+ if (resolve->type == RESOLVE_NOT) {
+ gf_log (this->name, GF_LOG_DEBUG, "inode (pointer: %p ino:%"
+ PRIu64") found for path (%s) while type is RESOLVE_NOT",
+ inode, inode->ino, resolve->path);
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (parent)
+ inode_unref (parent);
+
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+static int
+server_resolve_entry (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ loc = state->loc_now;
+
+ ret = resolve_entry_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_path_deep (frame);
+ return 0;
+ }
+
+ if (ret == 0)
+ resolve_loc_touchup (frame);
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+static int
+resolve_inode_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ if (resolve->type == RESOLVE_EXACT) {
+ inode = inode_get (state->itable, resolve->ino, resolve->gen);
+ } else {
+ inode = inode_get (state->itable, resolve->ino, 0);
+ }
+
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+// if (inode->ino != 1 && inode->generation != resolve->gen) {
+ if (0) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+static int
+server_resolve_inode (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ loc = state->loc_now;
+
+ ret = resolve_inode_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_path_deep (frame);
+ return 0;
+ }
+
+ if (ret == 0)
+ resolve_loc_touchup (frame);
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+static int
+server_resolve_fd (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ server_connection_t *conn = NULL;
+ uint64_t fd_no = -1;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ conn = SERVER_CONNECTION (frame);
+
+ fd_no = resolve->fd_no;
+
+ state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no);
+
+ if (!state->fd) {
+ resolve->op_ret = -1;
+ resolve->op_errno = EBADFD;
+ }
+
+ server_resolve_all (frame);
+
+ return 0;
+}
+
+
+static int
+server_resolve (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+
+ if (resolve->fd_no != -1) {
+
+ server_resolve_fd (frame);
+
+ } else if (resolve->par) {
+
+ server_resolve_entry (frame);
+
+ } else if (resolve->ino) {
+
+ server_resolve_inode (frame);
+
+ } else if (resolve->path) {
+
+ resolve_path_deep (frame);
+
+ } else {
+
+ resolve->op_ret = -1;
+ resolve->op_errno = EINVAL;
+
+ server_resolve_all (frame);
+ }
+
+ return 0;
+}
+
+
+static int
+server_resolve_done (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *bound_xl = NULL;
+
+ state = CALL_STATE (frame);
+ bound_xl = BOUND_XL (frame);
+
+ gf_server_print_request (frame);
+
+ state->resume_fn (frame, bound_xl);
+
+ return 0;
+}
+
+
+/*
+ * This function is called multiple times, once per resolving one location/fd.
+ * state->resolve_now is used to decide which location/fd is to be resolved now
+ */
+static int
+server_resolve_all (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+
+ this = frame->this;
+ state = CALL_STATE (frame);
+
+ if (state->resolve_now == NULL) {
+
+ state->resolve_now = &state->resolve;
+ state->loc_now = &state->loc;
+
+ server_resolve (frame);
+
+ } else if (state->resolve_now == &state->resolve) {
+
+ state->resolve_now = &state->resolve2;
+ state->loc_now = &state->loc2;
+
+ server_resolve (frame);
+
+ } else if (state->resolve_now == &state->resolve2) {
+
+ server_resolve_done (frame);
+
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Invalid pointer for state->resolve_now");
+ }
+
+ return 0;
+}
+
+
+int
+gf_resolve_and_resume (call_frame_t *frame, server_resume_fn_t fn)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+
+ state = CALL_STATE (frame);
+ state->resume_fn = fn;
+
+ this = frame->this;
+
+ server_resolve_all (frame);
+
+ return 0;
+}
diff --git a/xlators/protocol/legacy/transport/Makefile.am b/xlators/protocol/legacy/transport/Makefile.am
new file mode 100644
index 000000000..e2f97437c
--- /dev/null
+++ b/xlators/protocol/legacy/transport/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = socket $(IBVERBS_SUBDIR)
+
+CLEANFILES =
diff --git a/xlators/protocol/legacy/transport/ib-verbs/Makefile.am b/xlators/protocol/legacy/transport/ib-verbs/Makefile.am
new file mode 100644
index 000000000..f963effea
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src \ No newline at end of file
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am b/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am
new file mode 100644
index 000000000..3db7aff98
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/Makefile.am
@@ -0,0 +1,19 @@
+# TODO : need to change transportdir
+
+transport_LTLIBRARIES = ib-verbs.la
+transportdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/transport
+
+ib_verbs_la_LDFLAGS = -module -avoidversion
+
+ib_verbs_la_SOURCES = ib-verbs.c name.c
+ib_verbs_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ -libverbs $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la
+
+noinst_HEADERS = ib-verbs.h name.h ib-verbs-mem-types.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS) \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
+ -I$(top_srcdir)/xlators/protocol/legacy/transport/ib-verbs \
+ -I$(top_srcdir)/xlators/protocol/legacy/lib/src
+
+CLEANFILES = *~
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h
new file mode 100644
index 000000000..36eba63d3
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs-mem-types.h
@@ -0,0 +1,39 @@
+
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __IB_VERBS_MEM_TYPES_H__
+#define __IB_VERBS_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_ib_verbs_mem_types_ {
+ gf_ibv_mt_ib_verbs_private_t = gf_common_mt_end + 1,
+ gf_ibv_mt_ib_verbs_ioq_t,
+ gf_ibv_mt_transport_t,
+ gf_ibv_mt_ib_verbs_local_t,
+ gf_ibv_mt_ib_verbs_post_t,
+ gf_ibv_mt_char,
+ gf_ibv_mt_qpent,
+ gf_ibv_mt_ib_verbs_device_t,
+ gf_ibv_mt_end
+};
+#endif
+
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c
new file mode 100644
index 000000000..92034cd15
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.c
@@ -0,0 +1,2625 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "dict.h"
+#include "glusterfs.h"
+#include "transport.h"
+#include "protocol.h"
+#include "logging.h"
+#include "xlator.h"
+#include "name.h"
+#include "ib-verbs.h"
+#include <signal.h>
+
+int32_t
+gf_resolve_ip6 (const char *hostname,
+ uint16_t port,
+ int family,
+ void **dnscache,
+ struct addrinfo **addr_info);
+
+static uint16_t
+ib_verbs_get_local_lid (struct ibv_context *context,
+ int32_t port)
+{
+ struct ibv_port_attr attr;
+
+ if (ibv_query_port (context, port, &attr))
+ return 0;
+
+ return attr.lid;
+}
+
+static const char *
+get_port_state_str(enum ibv_port_state pstate)
+{
+ switch (pstate) {
+ case IBV_PORT_DOWN: return "PORT_DOWN";
+ case IBV_PORT_INIT: return "PORT_INIT";
+ case IBV_PORT_ARMED: return "PORT_ARMED";
+ case IBV_PORT_ACTIVE: return "PORT_ACTIVE";
+ case IBV_PORT_ACTIVE_DEFER: return "PORT_ACTIVE_DEFER";
+ default: return "invalid state";
+ }
+}
+
+static int32_t
+ib_check_active_port (struct ibv_context *ctx, uint8_t port)
+{
+ struct ibv_port_attr port_attr;
+
+ int32_t ret = 0;
+ const char *state_str = NULL;
+
+ if (!ctx) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "Error in supplied context");
+ return -1;
+ }
+
+ ret = ibv_query_port (ctx, port, &port_attr);
+
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "Failed to query port %u properties", port);
+ return -1;
+ }
+
+ state_str = get_port_state_str (port_attr.state);
+ gf_log ("transport/ib-verbs", GF_LOG_TRACE,
+ "Infiniband PORT: (%u) STATE: (%s)",
+ port, state_str);
+
+ if (port_attr.state == IBV_PORT_ACTIVE)
+ return 0;
+
+ return -1;
+}
+
+static int32_t
+ib_get_active_port (struct ibv_context *ib_ctx)
+{
+ struct ibv_device_attr ib_device_attr;
+
+ int32_t ret = -1;
+ uint8_t ib_port = 0;
+
+ if (!ib_ctx) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "Error in supplied context");
+ return -1;
+ }
+ if (ibv_query_device (ib_ctx, &ib_device_attr)) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "Failed to query device properties");
+ return -1;
+ }
+
+ for (ib_port = 1; ib_port <= ib_device_attr.phys_port_cnt; ++ib_port) {
+ ret = ib_check_active_port (ib_ctx, ib_port);
+ if (ret == 0)
+ return ib_port;
+
+ gf_log ("transport/ib-verbs", GF_LOG_TRACE,
+ "Port:(%u) not active", ib_port);
+ continue;
+ }
+ return ret;
+}
+
+
+
+static void
+ib_verbs_put_post (ib_verbs_queue_t *queue,
+ ib_verbs_post_t *post)
+{
+ pthread_mutex_lock (&queue->lock);
+ if (post->prev) {
+ queue->active_count--;
+ post->prev->next = post->next;
+ }
+ if (post->next)
+ post->next->prev = post->prev;
+ post->prev = &queue->passive_posts;
+ post->next = post->prev->next;
+ post->prev->next = post;
+ post->next->prev = post;
+ queue->passive_count++;
+ pthread_mutex_unlock (&queue->lock);
+}
+
+
+static ib_verbs_post_t *
+ib_verbs_new_post (ib_verbs_device_t *device, int32_t len)
+{
+ ib_verbs_post_t *post;
+
+ post = (ib_verbs_post_t *) GF_CALLOC (1, sizeof (*post),
+ gf_ibv_mt_ib_verbs_post_t);
+ if (!post)
+ return NULL;
+
+ post->buf_size = len;
+
+ post->buf = valloc (len);
+ if (!post->buf) {
+ GF_FREE (post);
+ return NULL;
+ }
+
+ post->mr = ibv_reg_mr (device->pd,
+ post->buf,
+ post->buf_size,
+ IBV_ACCESS_LOCAL_WRITE);
+ if (!post->mr) {
+ free (post->buf);
+ GF_FREE (post);
+ return NULL;
+ }
+
+ return post;
+}
+
+
+static ib_verbs_post_t *
+ib_verbs_get_post (ib_verbs_queue_t *queue)
+{
+ ib_verbs_post_t *post;
+
+ pthread_mutex_lock (&queue->lock);
+ {
+ post = queue->passive_posts.next;
+ if (post == &queue->passive_posts)
+ post = NULL;
+
+ if (post) {
+ if (post->prev)
+ post->prev->next = post->next;
+ if (post->next)
+ post->next->prev = post->prev;
+ post->prev = &queue->active_posts;
+ post->next = post->prev->next;
+ post->prev->next = post;
+ post->next->prev = post;
+ post->reused++;
+ queue->active_count++;
+ }
+ }
+ pthread_mutex_unlock (&queue->lock);
+
+ return post;
+}
+
+void
+ib_verbs_destroy_post (ib_verbs_post_t *post)
+{
+ ibv_dereg_mr (post->mr);
+ free (post->buf);
+ GF_FREE (post);
+}
+
+
+static int32_t
+__ib_verbs_quota_get (ib_verbs_peer_t *peer)
+{
+ int32_t ret = -1;
+ ib_verbs_private_t *priv = peer->trans->private;
+
+ if (priv->connected && peer->quota > 0) {
+ ret = peer->quota--;
+ }
+
+ return ret;
+}
+
+/*
+ static int32_t
+ ib_verbs_quota_get (ib_verbs_peer_t *peer)
+ {
+ int32_t ret = -1;
+ ib_verbs_private_t *priv = peer->trans->private;
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ ret = __ib_verbs_quota_get (peer);
+ }
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ return ret;
+ }
+*/
+
+static void
+__ib_verbs_ioq_entry_free (ib_verbs_ioq_t *entry)
+{
+ list_del_init (&entry->list);
+ if (entry->iobref)
+ iobref_unref (entry->iobref);
+
+ /* TODO: use mem-pool */
+ GF_FREE (entry->buf);
+
+ /* TODO: use mem-pool */
+ GF_FREE (entry);
+}
+
+
+static void
+__ib_verbs_ioq_flush (ib_verbs_peer_t *peer)
+{
+ ib_verbs_ioq_t *entry = NULL, *dummy = NULL;
+
+ list_for_each_entry_safe (entry, dummy, &peer->ioq, list) {
+ __ib_verbs_ioq_entry_free (entry);
+ }
+}
+
+
+static int32_t
+__ib_verbs_disconnect (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ int32_t ret = 0;
+
+ if (priv->connected || priv->tcp_connected) {
+ fcntl (priv->sock, F_SETFL, O_NONBLOCK);
+ if (shutdown (priv->sock, SHUT_RDWR) != 0) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_DEBUG,
+ "shutdown () - error: %s",
+ strerror (errno));
+ ret = -errno;
+ priv->tcp_connected = 0;
+ }
+ }
+
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_post_send (struct ibv_qp *qp,
+ ib_verbs_post_t *post,
+ int32_t len)
+{
+ struct ibv_sge list = {
+ .addr = (unsigned long) post->buf,
+ .length = len,
+ .lkey = post->mr->lkey
+ };
+
+ struct ibv_send_wr wr = {
+ .wr_id = (unsigned long) post,
+ .sg_list = &list,
+ .num_sge = 1,
+ .opcode = IBV_WR_SEND,
+ .send_flags = IBV_SEND_SIGNALED,
+ }, *bad_wr;
+
+ if (!qp)
+ return -1;
+
+ return ibv_post_send (qp, &wr, &bad_wr);
+}
+
+
+static int32_t
+__ib_verbs_ioq_churn_entry (ib_verbs_peer_t *peer, ib_verbs_ioq_t *entry)
+{
+ int32_t ret = 0, quota = 0;
+ ib_verbs_private_t *priv = peer->trans->private;
+ ib_verbs_device_t *device = priv->device;
+ ib_verbs_options_t *options = &priv->options;
+ ib_verbs_post_t *post = NULL;
+ int32_t len = 0;
+
+ quota = __ib_verbs_quota_get (peer);
+ if (quota > 0) {
+ post = ib_verbs_get_post (&device->sendq);
+ if (!post)
+ post = ib_verbs_new_post (device,
+ (options->send_size + 2048));
+
+ len = iov_length ((const struct iovec *)&entry->vector,
+ entry->count);
+ if (len >= (options->send_size + 2048)) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "increase value of option 'transport.ib-verbs."
+ "work-request-send-size' (given=> %"PRId64") "
+ "to send bigger (%d) messages",
+ (options->send_size + 2048), len);
+ return -1;
+ }
+
+ iov_unload (post->buf,
+ (const struct iovec *)&entry->vector,
+ entry->count);
+
+ ret = ib_verbs_post_send (peer->qp, post, len);
+ if (!ret) {
+ __ib_verbs_ioq_entry_free (entry);
+ ret = len;
+ } else {
+ gf_log ("transport/ib-verbs", GF_LOG_DEBUG,
+ "ibv_post_send failed with ret = %d", ret);
+ ib_verbs_put_post (&device->sendq, post);
+ __ib_verbs_disconnect (peer->trans);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+
+static int32_t
+__ib_verbs_ioq_churn (ib_verbs_peer_t *peer)
+{
+ ib_verbs_ioq_t *entry = NULL;
+ int32_t ret = 0;
+
+ while (!list_empty (&peer->ioq))
+ {
+ /* pick next entry */
+ entry = peer->ioq_next;
+
+ ret = __ib_verbs_ioq_churn_entry (peer, entry);
+
+ if (ret <= 0)
+ break;
+ }
+
+ /*
+ list_for_each_entry_safe (entry, dummy, &peer->ioq, list) {
+ ret = __ib_verbs_ioq_churn_entry (peer, entry);
+ if (ret <= 0) {
+ break;
+ }
+ }
+ */
+
+ return ret;
+}
+
+static int32_t
+__ib_verbs_quota_put (ib_verbs_peer_t *peer)
+{
+ int32_t ret;
+
+ peer->quota++;
+ ret = peer->quota;
+
+ if (!list_empty (&peer->ioq)) {
+ ret = __ib_verbs_ioq_churn (peer);
+ }
+
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_quota_put (ib_verbs_peer_t *peer)
+{
+ int32_t ret;
+ ib_verbs_private_t *priv = peer->trans->private;
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ ret = __ib_verbs_quota_put (peer);
+ }
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_post_recv (struct ibv_srq *srq,
+ ib_verbs_post_t *post)
+{
+ struct ibv_sge list = {
+ .addr = (unsigned long) post->buf,
+ .length = post->buf_size,
+ .lkey = post->mr->lkey
+ };
+
+ struct ibv_recv_wr wr = {
+ .wr_id = (unsigned long) post,
+ .sg_list = &list,
+ .num_sge = 1,
+ }, *bad_wr;
+
+ return ibv_post_srq_recv (srq, &wr, &bad_wr);
+}
+
+
+static int32_t
+ib_verbs_writev (transport_t *this,
+ ib_verbs_ioq_t *entry)
+{
+ int32_t ret = 0, need_append = 1;
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_peer_t *peer = NULL;
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ if (!priv->connected) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "ib-verbs is not connected to post a "
+ "send request");
+ ret = -1;
+ goto unlock;
+ }
+
+ peer = &priv->peer;
+ if (list_empty (&peer->ioq)) {
+ ret = __ib_verbs_ioq_churn_entry (peer, entry);
+ if (ret != 0) {
+ need_append = 0;
+ }
+ }
+
+ if (need_append) {
+ list_add_tail (&entry->list, &peer->ioq);
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->write_mutex);
+ return ret;
+}
+
+
+static ib_verbs_ioq_t *
+ib_verbs_ioq_new (char *buf, int len, struct iovec *vector,
+ int count, struct iobref *iobref)
+{
+ ib_verbs_ioq_t *entry = NULL;
+
+ /* TODO: use mem-pool */
+ entry = GF_CALLOC (1, sizeof (*entry), gf_ibv_mt_ib_verbs_ioq_t);
+
+ GF_ASSERT (count <= (MAX_IOVEC-2));
+
+ entry->header.colonO[0] = ':';
+ entry->header.colonO[1] = 'O';
+ entry->header.colonO[2] = '\0';
+ entry->header.version = 42;
+ entry->header.size1 = hton32 (len);
+ entry->header.size2 = hton32 (iov_length (vector, count));
+
+ entry->vector[0].iov_base = &entry->header;
+ entry->vector[0].iov_len = sizeof (entry->header);
+ entry->count++;
+
+ entry->vector[1].iov_base = buf;
+ entry->vector[1].iov_len = len;
+ entry->count++;
+
+ if (vector && count)
+ {
+ memcpy (&entry->vector[2], vector, sizeof (*vector) * count);
+ entry->count += count;
+ }
+
+ if (iobref)
+ entry->iobref = iobref_ref (iobref);
+
+ entry->buf = buf;
+
+ INIT_LIST_HEAD (&entry->list);
+
+ return entry;
+}
+
+
+static int32_t
+ib_verbs_submit (transport_t *this, char *buf, int32_t len,
+ struct iovec *vector, int count, struct iobref *iobref)
+{
+ int32_t ret = 0;
+ ib_verbs_ioq_t *entry = NULL;
+
+ entry = ib_verbs_ioq_new (buf, len, vector, count, iobref);
+ ret = ib_verbs_writev (this, entry);
+
+ if (ret > 0) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+ib_verbs_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p)
+{
+ ib_verbs_private_t *priv = this->private;
+ /* TODO: return error if !priv->connected, check with locks */
+ /* TODO: boundry checks for data_ptr/offset */
+ char *copy_from = NULL;
+ ib_verbs_header_t *header = NULL;
+ uint32_t size1, size2, data_len = 0;
+ char *hdr = NULL;
+ struct iobuf *iobuf = NULL;
+ int32_t ret = 0;
+
+ pthread_mutex_lock (&priv->recv_mutex);
+ {
+/*
+ while (!priv->data_ptr)
+ pthread_cond_wait (&priv->recv_cond, &priv->recv_mutex);
+*/
+
+ copy_from = priv->data_ptr + priv->data_offset;
+
+ priv->data_ptr = NULL;
+ data_len = priv->data_len;
+ pthread_cond_broadcast (&priv->recv_cond);
+ }
+ pthread_mutex_unlock (&priv->recv_mutex);
+
+ header = (ib_verbs_header_t *)copy_from;
+ if (strcmp (header->colonO, ":O")) {
+ gf_log ("transport/ib-verbs", GF_LOG_DEBUG,
+ "%s: corrupt header received", this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ size1 = ntoh32 (header->size1);
+ size2 = ntoh32 (header->size2);
+
+ if (data_len != (size1 + size2 + sizeof (*header))) {
+ gf_log ("transport/ib-verbs", GF_LOG_DEBUG,
+ "%s: sizeof data read from transport is not equal "
+ "to the size specified in the header",
+ this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ copy_from += sizeof (*header);
+
+ if (size1) {
+ hdr = GF_CALLOC (1, size1, gf_ibv_mt_char);
+ if (!hdr) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unable to allocate header for peer %s",
+ this->peerinfo.identifier);
+ ret = -ENOMEM;
+ goto err;
+ }
+ memcpy (hdr, copy_from, size1);
+ copy_from += size1;
+ *hdr_p = hdr;
+ }
+ *hdrlen_p = size1;
+
+ if (size2) {
+ iobuf = iobuf_get (this->xl->ctx->iobuf_pool);
+ if (!iobuf) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unable to allocate IO buffer for peer %s",
+ this->peerinfo.identifier);
+ ret = -ENOMEM;
+ goto err;
+ }
+ memcpy (iobuf->ptr, copy_from, size2);
+ *iobuf_p = iobuf;
+ }
+
+err:
+ return ret;
+}
+
+
+static void
+ib_verbs_destroy_cq (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_device_t *device = priv->device;
+
+ if (device->recv_cq)
+ ibv_destroy_cq (device->recv_cq);
+ device->recv_cq = NULL;
+
+ if (device->send_cq)
+ ibv_destroy_cq (device->send_cq);
+ device->send_cq = NULL;
+
+ return;
+}
+
+
+static int32_t
+ib_verbs_create_cq (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ ib_verbs_device_t *device = priv->device;
+ int32_t ret = 0;
+
+ device->recv_cq = ibv_create_cq (priv->device->context,
+ options->recv_count * 2,
+ device,
+ device->recv_chan,
+ 0);
+ if (!device->recv_cq) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: creation of CQ failed",
+ this->xl->name);
+ ret = -1;
+ } else if (ibv_req_notify_cq (device->recv_cq, 0)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: ibv_req_notify_cq on CQ failed",
+ this->xl->name);
+ ret = -1;
+ }
+
+ do {
+ /* TODO: make send_cq size dynamically adaptive */
+ device->send_cq = ibv_create_cq (priv->device->context,
+ options->send_count * 1024,
+ device,
+ device->send_chan,
+ 0);
+ if (!device->send_cq) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: creation of send_cq failed",
+ this->xl->name);
+ ret = -1;
+ break;
+ }
+
+ if (ibv_req_notify_cq (device->send_cq, 0)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: ibv_req_notify_cq on send_cq failed",
+ this->xl->name);
+ ret = -1;
+ break;
+ }
+ } while (0);
+
+ if (ret != 0)
+ ib_verbs_destroy_cq (this);
+
+ return ret;
+}
+
+
+static void
+ib_verbs_register_peer (ib_verbs_device_t *device,
+ int32_t qp_num,
+ ib_verbs_peer_t *peer)
+{
+ struct _qpent *ent;
+ ib_verbs_qpreg_t *qpreg = &device->qpreg;
+ int32_t hash = qp_num % 42;
+
+ pthread_mutex_lock (&qpreg->lock);
+ ent = qpreg->ents[hash].next;
+ while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num))
+ ent = ent->next;
+ if (ent->qp_num == qp_num) {
+ pthread_mutex_unlock (&qpreg->lock);
+ return;
+ }
+ ent = (struct _qpent *) GF_CALLOC (1, sizeof (*ent), gf_ibv_mt_qpent);
+ if (!ent)
+ return;
+ /* TODO: ref reg->peer */
+ ent->peer = peer;
+ ent->next = &qpreg->ents[hash];
+ ent->prev = ent->next->prev;
+ ent->next->prev = ent;
+ ent->prev->next = ent;
+ ent->qp_num = qp_num;
+ qpreg->count++;
+ pthread_mutex_unlock (&qpreg->lock);
+}
+
+
+static void
+ib_verbs_unregister_peer (ib_verbs_device_t *device,
+ int32_t qp_num)
+{
+ struct _qpent *ent;
+ ib_verbs_qpreg_t *qpreg = &device->qpreg;
+ int32_t hash = qp_num % 42;
+
+ pthread_mutex_lock (&qpreg->lock);
+ ent = qpreg->ents[hash].next;
+ while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num))
+ ent = ent->next;
+ if (ent->qp_num != qp_num) {
+ pthread_mutex_unlock (&qpreg->lock);
+ return;
+ }
+ ent->prev->next = ent->next;
+ ent->next->prev = ent->prev;
+ /* TODO: unref reg->peer */
+ GF_FREE (ent);
+ qpreg->count--;
+ pthread_mutex_unlock (&qpreg->lock);
+}
+
+
+static ib_verbs_peer_t *
+__ib_verbs_lookup_peer (ib_verbs_device_t *device, int32_t qp_num)
+{
+ struct _qpent *ent = NULL;
+ ib_verbs_peer_t *peer = NULL;
+ ib_verbs_qpreg_t *qpreg = NULL;
+ int32_t hash = 0;
+
+ qpreg = &device->qpreg;
+ hash = qp_num % 42;
+ ent = qpreg->ents[hash].next;
+ while ((ent != &qpreg->ents[hash]) && (ent->qp_num != qp_num))
+ ent = ent->next;
+
+ if (ent != &qpreg->ents[hash]) {
+ peer = ent->peer;
+ }
+
+ return peer;
+}
+
+/*
+static ib_verbs_peer_t *
+ib_verbs_lookup_peer (ib_verbs_device_t *device,
+ int32_t qp_num)
+{
+ ib_verbs_qpreg_t *qpreg = NULL;
+ ib_verbs_peer_t *peer = NULL;
+
+ qpreg = &device->qpreg;
+ pthread_mutex_lock (&qpreg->lock);
+ {
+ peer = __ib_verbs_lookup_peer (device, qp_num);
+ }
+ pthread_mutex_unlock (&qpreg->lock);
+
+ return peer;
+}
+*/
+
+
+static void
+__ib_verbs_destroy_qp (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+
+ if (priv->peer.qp) {
+ ib_verbs_unregister_peer (priv->device, priv->peer.qp->qp_num);
+ ibv_destroy_qp (priv->peer.qp);
+ }
+ priv->peer.qp = NULL;
+
+ return;
+}
+
+
+static int32_t
+ib_verbs_create_qp (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ ib_verbs_device_t *device = priv->device;
+ int32_t ret = 0;
+ ib_verbs_peer_t *peer;
+
+ peer = &priv->peer;
+ struct ibv_qp_init_attr init_attr = {
+ .send_cq = device->send_cq,
+ .recv_cq = device->recv_cq,
+ .srq = device->srq,
+ .cap = {
+ .max_send_wr = peer->send_count,
+ .max_recv_wr = peer->recv_count,
+ .max_send_sge = 1,
+ .max_recv_sge = 1
+ },
+ .qp_type = IBV_QPT_RC
+ };
+
+ struct ibv_qp_attr attr = {
+ .qp_state = IBV_QPS_INIT,
+ .pkey_index = 0,
+ .port_num = options->port,
+ .qp_access_flags = 0
+ };
+
+ peer->qp = ibv_create_qp (device->pd, &init_attr);
+ if (!peer->qp) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "%s: could not create QP",
+ this->xl->name);
+ ret = -1;
+ goto out;
+ } else if (ibv_modify_qp (peer->qp, &attr,
+ IBV_QP_STATE |
+ IBV_QP_PKEY_INDEX |
+ IBV_QP_PORT |
+ IBV_QP_ACCESS_FLAGS)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: failed to modify QP to INIT state",
+ this->xl->name);
+ ret = -1;
+ goto out;
+ }
+
+ peer->local_lid = ib_verbs_get_local_lid (device->context,
+ options->port);
+ peer->local_qpn = peer->qp->qp_num;
+ peer->local_psn = lrand48 () & 0xffffff;
+
+ ib_verbs_register_peer (device, peer->qp->qp_num, peer);
+
+out:
+ if (ret == -1)
+ __ib_verbs_destroy_qp (this);
+
+ return ret;
+}
+
+
+static void
+ib_verbs_destroy_posts (transport_t *this)
+{
+
+}
+
+
+static int32_t
+__ib_verbs_create_posts (transport_t *this,
+ int32_t count,
+ int32_t size,
+ ib_verbs_queue_t *q)
+{
+ int32_t i;
+ int32_t ret = 0;
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_device_t *device = priv->device;
+
+ for (i=0 ; i<count ; i++) {
+ ib_verbs_post_t *post;
+
+ post = ib_verbs_new_post (device, size + 2048);
+ if (!post) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: post creation failed",
+ this->xl->name);
+ ret = -1;
+ break;
+ }
+
+ ib_verbs_put_post (q, post);
+ }
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_create_posts (transport_t *this)
+{
+ int32_t i, ret;
+ ib_verbs_post_t *post = NULL;
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ ib_verbs_device_t *device = priv->device;
+
+ ret = __ib_verbs_create_posts (this, options->send_count,
+ options->send_size,
+ &device->sendq);
+ if (!ret)
+ ret = __ib_verbs_create_posts (this, options->recv_count,
+ options->recv_size,
+ &device->recvq);
+
+ if (!ret) {
+ for (i=0 ; i<options->recv_count ; i++) {
+ post = ib_verbs_get_post (&device->recvq);
+ if (ib_verbs_post_recv (device->srq, post) != 0) {
+ ret = -1;
+ break;
+ }
+ }
+ }
+
+ if (ret)
+ ib_verbs_destroy_posts (this);
+
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_connect_qp (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ struct ibv_qp_attr attr = {
+ .qp_state = IBV_QPS_RTR,
+ .path_mtu = options->mtu,
+ .dest_qp_num = priv->peer.remote_qpn,
+ .rq_psn = priv->peer.remote_psn,
+ .max_dest_rd_atomic = 1,
+ .min_rnr_timer = 12,
+ .ah_attr = {
+ .is_global = 0,
+ .dlid = priv->peer.remote_lid,
+ .sl = 0,
+ .src_path_bits = 0,
+ .port_num = options->port
+ }
+ };
+ if (ibv_modify_qp (priv->peer.qp, &attr,
+ IBV_QP_STATE |
+ IBV_QP_AV |
+ IBV_QP_PATH_MTU |
+ IBV_QP_DEST_QPN |
+ IBV_QP_RQ_PSN |
+ IBV_QP_MAX_DEST_RD_ATOMIC |
+ IBV_QP_MIN_RNR_TIMER)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "Failed to modify QP to RTR\n");
+ return -1;
+ }
+
+ /* TODO: make timeout and retry_cnt configurable from options */
+ attr.qp_state = IBV_QPS_RTS;
+ attr.timeout = 14;
+ attr.retry_cnt = 7;
+ attr.rnr_retry = 7;
+ attr.sq_psn = priv->peer.local_psn;
+ attr.max_rd_atomic = 1;
+ if (ibv_modify_qp (priv->peer.qp, &attr,
+ IBV_QP_STATE |
+ IBV_QP_TIMEOUT |
+ IBV_QP_RETRY_CNT |
+ IBV_QP_RNR_RETRY |
+ IBV_QP_SQ_PSN |
+ IBV_QP_MAX_QP_RD_ATOMIC)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "Failed to modify QP to RTS\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int32_t
+__ib_verbs_teardown (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+
+ __ib_verbs_destroy_qp (this);
+
+ if (!list_empty (&priv->peer.ioq)) {
+ __ib_verbs_ioq_flush (&priv->peer);
+ }
+
+ /* TODO: decrement cq size */
+ return 0;
+}
+
+/*
+ * return value:
+ * 0 = success (completed)
+ * -1 = error
+ * > 0 = incomplete
+ */
+
+static int
+__tcp_rwv (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count,
+ int write)
+{
+ ib_verbs_private_t *priv = NULL;
+ int sock = -1;
+ int ret = -1;
+ struct iovec *opvector = vector;
+ int opcount = count;
+ int moved = 0;
+
+ priv = this->private;
+ sock = priv->sock;
+
+ while (opcount)
+ {
+ if (write)
+ {
+ ret = writev (sock, opvector, opcount);
+
+ if (ret == 0 || (ret == -1 && errno == EAGAIN))
+ {
+ /* done for now */
+ break;
+ }
+ }
+ else
+ {
+ ret = readv (sock, opvector, opcount);
+
+ if (ret == -1 && errno == EAGAIN)
+ {
+ /* done for now */
+ break;
+ }
+ }
+
+ if (ret == 0)
+ {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "EOF from peer %s", this->peerinfo.identifier);
+ opcount = -1;
+ errno = ENOTCONN;
+ break;
+ }
+
+ if (ret == -1)
+ {
+ if (errno == EINTR)
+ continue;
+
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "%s failed (%s)", write ? "writev" : "readv",
+ strerror (errno));
+ if (write && !priv->connected &&
+ (errno == ECONNREFUSED))
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "possible mismatch of 'transport-type'"
+ " in protocol server and client. "
+ "check volume file");
+ opcount = -1;
+ break;
+ }
+
+ moved = 0;
+
+ while (moved < ret)
+ {
+ if ((ret - moved) >= opvector[0].iov_len)
+ {
+ moved += opvector[0].iov_len;
+ opvector++;
+ opcount--;
+ }
+ else
+ {
+ opvector[0].iov_len -= (ret - moved);
+ opvector[0].iov_base += (ret - moved);
+ moved += (ret - moved);
+ }
+ while (opcount && !opvector[0].iov_len)
+ {
+ opvector++;
+ opcount--;
+ }
+ }
+ }
+
+ if (pending_vector)
+ *pending_vector = opvector;
+
+ if (pending_count)
+ *pending_count = opcount;
+
+ return opcount;
+}
+
+
+static int
+__tcp_readv (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count)
+{
+ int ret = -1;
+
+ ret = __tcp_rwv (this, vector, count,
+ pending_vector, pending_count, 0);
+
+ return ret;
+}
+
+
+static int
+__tcp_writev (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count)
+{
+ int ret = -1;
+ ib_verbs_private_t *priv = this->private;
+
+ ret = __tcp_rwv (this, vector, count, pending_vector,
+ pending_count, 1);
+
+ if (ret > 0) {
+ /* TODO: Avoid multiple calls when socket is already
+ registered for POLLOUT */
+ priv->idx = event_select_on (this->xl->ctx->event_pool,
+ priv->sock, priv->idx, -1, 1);
+ } else if (ret == 0) {
+ priv->idx = event_select_on (this->xl->ctx->event_pool,
+ priv->sock,
+ priv->idx, -1, 0);
+ }
+
+ return ret;
+}
+
+
+static void *
+ib_verbs_recv_completion_proc (void *data)
+{
+ struct ibv_comp_channel *chan = data;
+ ib_verbs_private_t *priv = NULL;
+ ib_verbs_device_t *device;
+ ib_verbs_post_t *post;
+ ib_verbs_peer_t *peer;
+ struct ibv_cq *event_cq;
+ struct ibv_wc wc;
+ void *event_ctx;
+ int32_t ret = 0;
+
+
+ while (1) {
+ ret = ibv_get_cq_event (chan, &event_cq, &event_ctx);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "ibv_get_cq_event failed, terminating recv "
+ "thread %d (%d)", ret, errno);
+ continue;
+ }
+
+ device = event_ctx;
+
+ ret = ibv_req_notify_cq (event_cq, 0);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "ibv_req_notify_cq on %s failed, terminating "
+ "recv thread: %d (%d)",
+ device->device_name, ret, errno);
+ continue;
+ }
+
+ device = (ib_verbs_device_t *) event_ctx;
+
+ while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) {
+ post = (ib_verbs_post_t *) (long) wc.wr_id;
+
+ pthread_mutex_lock (&device->qpreg.lock);
+ {
+ peer = __ib_verbs_lookup_peer (device,
+ wc.qp_num);
+
+ /*
+ * keep a refcount on transport so that it
+ * doesnot get freed because of some error
+ * indicated by wc.status till we are done
+ * with usage of peer and thereby that of trans.
+ */
+ if (peer != NULL) {
+ transport_ref (peer->trans);
+ }
+ }
+ pthread_mutex_unlock (&device->qpreg.lock);
+
+ if (wc.status != IBV_WC_SUCCESS) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "recv work request on `%s' returned "
+ "error (%d)",
+ device->device_name,
+ wc.status);
+ if (peer) {
+ transport_unref (peer->trans);
+ transport_disconnect (peer->trans);
+ }
+
+ if (post) {
+ ib_verbs_post_recv (device->srq, post);
+ }
+ continue;
+ }
+
+ if (peer) {
+ priv = peer->trans->private;
+
+ pthread_mutex_lock (&priv->recv_mutex);
+ {
+ while (priv->data_ptr)
+ pthread_cond_wait (&priv->recv_cond,
+ &priv->recv_mutex);
+
+ priv->data_ptr = post->buf;
+ priv->data_offset = 0;
+ priv->data_len = wc.byte_len;
+
+ /*pthread_cond_broadcast (&priv->recv_cond);*/
+ }
+ pthread_mutex_unlock (&priv->recv_mutex);
+
+ if ((ret = xlator_notify (peer->trans->xl, GF_EVENT_POLLIN,
+ peer->trans, NULL)) == -1) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_DEBUG,
+ "pollin notification to %s "
+ "failed, disconnecting "
+ "transport",
+ peer->trans->xl->name);
+ transport_disconnect (peer->trans);
+ }
+
+ transport_unref (peer->trans);
+ } else {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_DEBUG,
+ "could not lookup peer for qp_num: %d",
+ wc.qp_num);
+ }
+ ib_verbs_post_recv (device->srq, post);
+ }
+
+ if (ret < 0) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "ibv_poll_cq on `%s' returned error "
+ "(ret = %d, errno = %d)",
+ device->device_name, ret, errno);
+ continue;
+ }
+ ibv_ack_cq_events (event_cq, 1);
+ }
+ return NULL;
+}
+
+
+static void *
+ib_verbs_send_completion_proc (void *data)
+{
+ struct ibv_comp_channel *chan = data;
+ ib_verbs_post_t *post;
+ ib_verbs_peer_t *peer;
+ struct ibv_cq *event_cq;
+ void *event_ctx;
+ ib_verbs_device_t *device;
+ struct ibv_wc wc;
+ int32_t ret;
+
+ while (1) {
+ ret = ibv_get_cq_event (chan, &event_cq, &event_ctx);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "ibv_get_cq_event on failed, terminating "
+ "send thread: %d (%d)", ret, errno);
+ continue;
+ }
+
+ device = event_ctx;
+
+ ret = ibv_req_notify_cq (event_cq, 0);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "ibv_req_notify_cq on %s failed, terminating "
+ "send thread: %d (%d)",
+ device->device_name, ret, errno);
+ continue;
+ }
+
+ while ((ret = ibv_poll_cq (event_cq, 1, &wc)) > 0) {
+ post = (ib_verbs_post_t *) (long) wc.wr_id;
+
+ pthread_mutex_lock (&device->qpreg.lock);
+ {
+ peer = __ib_verbs_lookup_peer (device,
+ wc.qp_num);
+
+ /*
+ * keep a refcount on transport so that it
+ * doesnot get freed because of some error
+ * indicated by wc.status till we are done
+ * with usage of peer and thereby that of trans.
+ */
+ if (peer != NULL) {
+ transport_ref (peer->trans);
+ }
+ }
+ pthread_mutex_unlock (&device->qpreg.lock);
+
+ if (wc.status != IBV_WC_SUCCESS) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "send work request on `%s' returned "
+ "error wc.status = %d, wc.vendor_err "
+ "= %d, post->buf = %p, wc.byte_len = "
+ "%d, post->reused = %d",
+ device->device_name, wc.status,
+ wc.vendor_err,
+ post->buf, wc.byte_len, post->reused);
+ if (wc.status == IBV_WC_RETRY_EXC_ERR)
+ gf_log ("ib-verbs", GF_LOG_ERROR,
+ "connection between client and"
+ " server not working. check by"
+ " running 'ibv_srq_pingpong'. "
+ "also make sure subnet manager"
+ " is running (eg: 'opensm'), "
+ "or check if ib-verbs port is "
+ "valid (or active) by running "
+ " 'ibv_devinfo'. contact "
+ "Gluster Support Team if "
+ "the problem persists.");
+ if (peer)
+ transport_disconnect (peer->trans);
+ }
+
+ if (post) {
+ ib_verbs_put_post (&device->sendq, post);
+ }
+
+ if (peer) {
+ int quota_ret = ib_verbs_quota_put (peer);
+ if (quota_ret < 0) {
+ gf_log ("ib-verbs", GF_LOG_DEBUG,
+ "failed to send message");
+
+ }
+
+ transport_unref (peer->trans);
+ } else {
+ gf_log ("transport/ib-verbs", GF_LOG_DEBUG,
+ "could not lookup peer for qp_num: %d",
+ wc.qp_num);
+ }
+ }
+
+ if (ret < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "ibv_poll_cq on `%s' returned error (ret = %d,"
+ " errno = %d)",
+ device->device_name, ret, errno);
+ continue;
+ }
+ ibv_ack_cq_events (event_cq, 1);
+ }
+
+ return NULL;
+}
+
+static void
+ib_verbs_options_init (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ int32_t mtu;
+ data_t *temp;
+
+ /* TODO: validate arguments from options below */
+
+ options->send_size = this->xl->ctx->page_size * 4; /* 512 KB */
+ options->recv_size = this->xl->ctx->page_size * 4; /* 512 KB */
+ options->send_count = 32;
+ options->recv_count = 32;
+
+ temp = dict_get (this->xl->options,
+ "transport.ib-verbs.work-request-send-count");
+ if (temp)
+ options->send_count = data_to_int32 (temp);
+
+ temp = dict_get (this->xl->options,
+ "transport.ib-verbs.work-request-recv-count");
+ if (temp)
+ options->recv_count = data_to_int32 (temp);
+
+ options->port = 0;
+ temp = dict_get (this->xl->options,
+ "transport.ib-verbs.port");
+ if (temp)
+ options->port = data_to_uint64 (temp);
+
+ options->mtu = mtu = IBV_MTU_2048;
+ temp = dict_get (this->xl->options,
+ "transport.ib-verbs.mtu");
+ if (temp)
+ mtu = data_to_int32 (temp);
+ switch (mtu) {
+ case 256: options->mtu = IBV_MTU_256;
+ break;
+ case 512: options->mtu = IBV_MTU_512;
+ break;
+ case 1024: options->mtu = IBV_MTU_1024;
+ break;
+ case 2048: options->mtu = IBV_MTU_2048;
+ break;
+ case 4096: options->mtu = IBV_MTU_4096;
+ break;
+ default:
+ if (temp)
+ gf_log ("transport/ib-verbs", GF_LOG_WARNING,
+ "%s: unrecognized MTU value '%s', defaulting "
+ "to '2048'", this->xl->name,
+ data_to_str (temp));
+ else
+ gf_log ("transport/ib-verbs", GF_LOG_TRACE,
+ "%s: defaulting MTU to '2048'",
+ this->xl->name);
+ options->mtu = IBV_MTU_2048;
+ break;
+ }
+
+ temp = dict_get (this->xl->options,
+ "transport.ib-verbs.device-name");
+ if (temp)
+ options->device_name = gf_strdup (temp->data);
+
+ return;
+}
+
+static void
+ib_verbs_queue_init (ib_verbs_queue_t *queue)
+{
+ pthread_mutex_init (&queue->lock, NULL);
+
+ queue->active_posts.next = &queue->active_posts;
+ queue->active_posts.prev = &queue->active_posts;
+ queue->passive_posts.next = &queue->passive_posts;
+ queue->passive_posts.prev = &queue->passive_posts;
+}
+
+
+static ib_verbs_device_t *
+ib_verbs_get_device (transport_t *this,
+ struct ibv_context *ibctx)
+{
+ glusterfs_ctx_t *ctx = this->xl->ctx;
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ char *device_name = priv->options.device_name;
+ uint32_t port = priv->options.port;
+
+ uint8_t active_port = 0;
+ int32_t ret = 0;
+ int32_t i = 0;
+
+ ib_verbs_device_t *trav;
+
+ trav = ctx->ib;
+ while (trav) {
+ if ((!strcmp (trav->device_name, device_name)) &&
+ (trav->port == port))
+ break;
+ trav = trav->next;
+ }
+
+ if (!trav) {
+
+ trav = GF_CALLOC (1, sizeof (*trav),
+ gf_ibv_mt_ib_verbs_device_t);
+ if (!trav)
+ return NULL;
+ priv->device = trav;
+
+ trav->context = ibctx;
+
+ ret = ib_get_active_port (trav->context);
+
+ if (ret < 0) {
+ if (!port) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "Failed to find any active ports and "
+ "none specified in volume file,"
+ " exiting");
+ return NULL;
+ }
+ }
+
+ active_port = ret;
+
+ if (port) {
+ ret = ib_check_active_port (trav->context, port);
+ if (ret < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_WARNING,
+ "On device %s: provided port:%u is "
+ "found to be offline, continuing to "
+ "use the same port", device_name, port);
+ }
+ } else {
+ priv->options.port = active_port;
+ port = active_port;
+ gf_log ("transport/ib-verbs", GF_LOG_TRACE,
+ "Port unspecified in volume file using active "
+ "port: %u", port);
+ }
+
+ trav->device_name = gf_strdup (device_name);
+ trav->port = port;
+
+ trav->next = ctx->ib;
+ ctx->ib = trav;
+
+ trav->send_chan = ibv_create_comp_channel (trav->context);
+ if (!trav->send_chan) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not create send completion channel",
+ device_name);
+ /* TODO: cleanup current mess */
+ return NULL;
+ }
+
+ trav->recv_chan = ibv_create_comp_channel (trav->context);
+ if (!trav->recv_chan) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "could not create recv completion channel");
+ /* TODO: cleanup current mess */
+ return NULL;
+ }
+
+ if (ib_verbs_create_cq (this) < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not create CQ",
+ this->xl->name);
+ return NULL;
+ }
+
+ /* protection domain */
+ trav->pd = ibv_alloc_pd (trav->context);
+
+ if (!trav->pd) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not allocate protection domain",
+ this->xl->name);
+ return NULL;
+ }
+
+ struct ibv_srq_init_attr attr = {
+ .attr = {
+ .max_wr = options->recv_count,
+ .max_sge = 1
+ }
+ };
+ trav->srq = ibv_create_srq (trav->pd, &attr);
+
+ if (!trav->srq) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not create SRQ",
+ this->xl->name);
+ return NULL;
+ }
+
+ /* queue init */
+ ib_verbs_queue_init (&trav->sendq);
+ ib_verbs_queue_init (&trav->recvq);
+
+ if (ib_verbs_create_posts (this) < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not allocate posts",
+ this->xl->name);
+ return NULL;
+ }
+
+ /* completion threads */
+ ret = pthread_create (&trav->send_thread,
+ NULL,
+ ib_verbs_send_completion_proc,
+ trav->send_chan);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "could not create send completion thread");
+ return NULL;
+ }
+ ret = pthread_create (&trav->recv_thread,
+ NULL,
+ ib_verbs_recv_completion_proc,
+ trav->recv_chan);
+ if (ret) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "could not create recv completion thread");
+ return NULL;
+ }
+
+ /* qpreg */
+ pthread_mutex_init (&trav->qpreg.lock, NULL);
+ for (i=0; i<42; i++) {
+ trav->qpreg.ents[i].next = &trav->qpreg.ents[i];
+ trav->qpreg.ents[i].prev = &trav->qpreg.ents[i];
+ }
+ }
+ return trav;
+}
+
+static int32_t
+ib_verbs_init (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = &priv->options;
+ struct ibv_device **dev_list;
+ struct ibv_context *ib_ctx = NULL;
+ int32_t ret = 0;
+
+ ib_verbs_options_init (this);
+
+ {
+ dev_list = ibv_get_device_list (NULL);
+
+ if (!dev_list) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "Failed to get IB devices");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (!*dev_list) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "No IB devices found");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (!options->device_name) {
+ if (*dev_list) {
+ options->device_name =
+ gf_strdup (ibv_get_device_name (*dev_list));
+ } else {
+ gf_log ("transport/ib-verbs", GF_LOG_CRITICAL,
+ "IB device list is empty. Check for "
+ "'ib_uverbs' module");
+ return -1;
+ goto cleanup;
+ }
+ }
+
+ while (*dev_list) {
+ if (!strcmp (ibv_get_device_name (*dev_list),
+ options->device_name)) {
+ ib_ctx = ibv_open_device (*dev_list);
+
+ if (!ib_ctx) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "Failed to get infiniband"
+ "device context");
+ ret = -1;
+ goto cleanup;
+ }
+ break;
+ }
+ ++dev_list;
+ }
+
+ priv->device = ib_verbs_get_device (this, ib_ctx);
+
+ if (!priv->device) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "could not create ib_verbs device for %s",
+ options->device_name);
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ priv->peer.trans = this;
+ INIT_LIST_HEAD (&priv->peer.ioq);
+
+ pthread_mutex_init (&priv->read_mutex, NULL);
+ pthread_mutex_init (&priv->write_mutex, NULL);
+ pthread_mutex_init (&priv->recv_mutex, NULL);
+ pthread_cond_init (&priv->recv_cond, NULL);
+
+cleanup:
+ if (-1 == ret) {
+ if (ib_ctx)
+ ibv_close_device (ib_ctx);
+ }
+
+ if (dev_list)
+ ibv_free_device_list (dev_list);
+
+ return ret;
+}
+
+
+static int32_t
+ib_verbs_disconnect (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ int32_t ret = 0;
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ ret = __ib_verbs_disconnect (this);
+ }
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ return ret;
+}
+
+
+static int32_t
+__tcp_connect_finish (int fd)
+{
+ int ret = -1;
+ int optval = 0;
+ socklen_t optlen = sizeof (int);
+
+ ret = getsockopt (fd, SOL_SOCKET, SO_ERROR,
+ (void *)&optval, &optlen);
+
+ if (ret == 0 && optval)
+ {
+ errno = optval;
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static inline void
+ib_verbs_fill_handshake_data (char *buf, struct ib_verbs_nbio *nbio,
+ ib_verbs_private_t *priv)
+{
+ sprintf (buf,
+ "QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n"
+ "QP1:LID=%04x:QPN=%06x:PSN=%06x\n",
+ priv->peer.recv_size,
+ priv->peer.send_size,
+ priv->peer.local_lid,
+ priv->peer.local_qpn,
+ priv->peer.local_psn);
+
+ nbio->vector.iov_base = buf;
+ nbio->vector.iov_len = strlen (buf) + 1;
+ nbio->count = 1;
+ return;
+}
+
+static inline void
+ib_verbs_fill_handshake_ack (char *buf, struct ib_verbs_nbio *nbio)
+{
+ sprintf (buf, "DONE\n");
+ nbio->vector.iov_base = buf;
+ nbio->vector.iov_len = strlen (buf) + 1;
+ nbio->count = 1;
+ return;
+}
+
+static int
+ib_verbs_handshake_pollin (transport_t *this)
+{
+ int ret = 0;
+ ib_verbs_private_t *priv = this->private;
+ char *buf = priv->handshake.incoming.buf;
+ int32_t recv_buf_size, send_buf_size;
+ socklen_t sock_len;
+
+ if (priv->handshake.incoming.state == IB_VERBS_HANDSHAKE_COMPLETE) {
+ return -1;
+ }
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ while (priv->handshake.incoming.state != IB_VERBS_HANDSHAKE_COMPLETE)
+ {
+ switch (priv->handshake.incoming.state)
+ {
+ case IB_VERBS_HANDSHAKE_START:
+ buf = priv->handshake.incoming.buf = GF_CALLOC (1, 256, gf_ibv_mt_char);
+ ib_verbs_fill_handshake_data (buf, &priv->handshake.incoming, priv);
+ buf[0] = 0;
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVING_DATA;
+ break;
+
+ case IB_VERBS_HANDSHAKE_RECEIVING_DATA:
+ ret = __tcp_readv (this,
+ &priv->handshake.incoming.vector,
+ priv->handshake.incoming.count,
+ &priv->handshake.incoming.pending_vector,
+ &priv->handshake.incoming.pending_count);
+ if (ret == -1) {
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial header read on NB socket. continue later");
+ goto unlock;
+ }
+
+ if (!ret) {
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVED_DATA;
+ }
+ break;
+
+ case IB_VERBS_HANDSHAKE_RECEIVED_DATA:
+ ret = sscanf (buf,
+ "QP1:RECV_BLKSIZE=%08x:SEND_BLKSIZE=%08x\n"
+ "QP1:LID=%04x:QPN=%06x:PSN=%06x\n",
+ &recv_buf_size,
+ &send_buf_size,
+ &priv->peer.remote_lid,
+ &priv->peer.remote_qpn,
+ &priv->peer.remote_psn);
+
+ if ((ret != 5) && (strncmp (buf, "QP1:", 4))) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_CRITICAL,
+ "%s: remote-host(%s)'s "
+ "transport type is different",
+ this->xl->name,
+ this->peerinfo.identifier);
+ ret = -1;
+ goto unlock;
+ }
+
+ if (recv_buf_size < priv->peer.recv_size)
+ priv->peer.recv_size = recv_buf_size;
+ if (send_buf_size < priv->peer.send_size)
+ priv->peer.send_size = send_buf_size;
+
+ gf_log ("transport/ib-verbs", GF_LOG_TRACE,
+ "%s: transacted recv_size=%d "
+ "send_size=%d",
+ this->xl->name, priv->peer.recv_size,
+ priv->peer.send_size);
+
+ priv->peer.quota = priv->peer.send_count;
+
+ if (ib_verbs_connect_qp (this)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_ERROR,
+ "%s: failed to connect with "
+ "remote QP", this->xl->name);
+ ret = -1;
+ goto unlock;
+ }
+ ib_verbs_fill_handshake_ack (buf, &priv->handshake.incoming);
+ buf[0] = 0;
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVING_ACK;
+ break;
+
+ case IB_VERBS_HANDSHAKE_RECEIVING_ACK:
+ ret = __tcp_readv (this,
+ &priv->handshake.incoming.vector,
+ priv->handshake.incoming.count,
+ &priv->handshake.incoming.pending_vector,
+ &priv->handshake.incoming.pending_count);
+ if (ret == -1) {
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial header read on NB "
+ "socket. continue later");
+ goto unlock;
+ }
+
+ if (!ret) {
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_RECEIVED_ACK;
+ }
+ break;
+
+ case IB_VERBS_HANDSHAKE_RECEIVED_ACK:
+ if (strncmp (buf, "DONE", 4)) {
+ gf_log ("transport/ib-verbs",
+ GF_LOG_DEBUG,
+ "%s: handshake-3 did not "
+ "return 'DONE' (%s)",
+ this->xl->name, buf);
+ ret = -1;
+ goto unlock;
+ }
+ ret = 0;
+ priv->connected = 1;
+ sock_len = sizeof (struct sockaddr_storage);
+ getpeername (priv->sock,
+ (struct sockaddr *) &this->peerinfo.sockaddr,
+ &sock_len);
+
+ GF_FREE (priv->handshake.incoming.buf);
+ priv->handshake.incoming.buf = NULL;
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_COMPLETE;
+ }
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ if (ret == -1) {
+ transport_disconnect (this);
+ } else {
+ ret = 0;
+ }
+
+ if (!ret && priv->connected) {
+ ret = xlator_notify (this->xl, GF_EVENT_CHILD_UP, this);
+ }
+
+ return ret;
+}
+
+static int
+ib_verbs_handshake_pollout (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ char *buf = priv->handshake.outgoing.buf;
+ int32_t ret = 0;
+
+ if (priv->handshake.outgoing.state == IB_VERBS_HANDSHAKE_COMPLETE) {
+ return 0;
+ }
+
+ pthread_mutex_unlock (&priv->write_mutex);
+ {
+ while (priv->handshake.outgoing.state != IB_VERBS_HANDSHAKE_COMPLETE)
+ {
+ switch (priv->handshake.outgoing.state)
+ {
+ case IB_VERBS_HANDSHAKE_START:
+ buf = priv->handshake.outgoing.buf = GF_CALLOC (1, 256, gf_ibv_mt_char);
+ ib_verbs_fill_handshake_data (buf, &priv->handshake.outgoing, priv);
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENDING_DATA;
+ break;
+
+ case IB_VERBS_HANDSHAKE_SENDING_DATA:
+ ret = __tcp_writev (this,
+ &priv->handshake.outgoing.vector,
+ priv->handshake.outgoing.count,
+ &priv->handshake.outgoing.pending_vector,
+ &priv->handshake.outgoing.pending_count);
+ if (ret == -1) {
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial header read on NB socket. continue later");
+ goto unlock;
+ }
+
+ if (!ret) {
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENT_DATA;
+ }
+ break;
+
+ case IB_VERBS_HANDSHAKE_SENT_DATA:
+ ib_verbs_fill_handshake_ack (buf, &priv->handshake.outgoing);
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_SENDING_ACK;
+ break;
+
+ case IB_VERBS_HANDSHAKE_SENDING_ACK:
+ ret = __tcp_writev (this,
+ &priv->handshake.outgoing.vector,
+ priv->handshake.outgoing.count,
+ &priv->handshake.outgoing.pending_vector,
+ &priv->handshake.outgoing.pending_count);
+
+ if (ret == -1) {
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial header read on NB "
+ "socket. continue later");
+ goto unlock;
+ }
+
+ if (!ret) {
+ GF_FREE (priv->handshake.outgoing.buf);
+ priv->handshake.outgoing.buf = NULL;
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_COMPLETE;
+ }
+ break;
+ }
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ if (ret == -1) {
+ transport_disconnect (this);
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+ib_verbs_handshake_pollerr (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ int32_t ret = 0;
+ char need_unref = 0;
+
+ gf_log ("transport/ib-verbs", GF_LOG_DEBUG,
+ "%s: peer disconnected, cleaning up",
+ this->xl->name);
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ __ib_verbs_teardown (this);
+
+ if (priv->sock != -1) {
+ event_unregister (this->xl->ctx->event_pool,
+ priv->sock, priv->idx);
+ need_unref = 1;
+
+ if (close (priv->sock) != 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "close () - error: %s",
+ strerror (errno));
+ ret = -errno;
+ }
+ priv->tcp_connected = priv->connected = 0;
+ priv->sock = -1;
+ }
+
+ if (priv->handshake.incoming.buf) {
+ GF_FREE (priv->handshake.incoming.buf);
+ priv->handshake.incoming.buf = NULL;
+ }
+
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START;
+
+ if (priv->handshake.outgoing.buf) {
+ GF_FREE (priv->handshake.outgoing.buf);
+ priv->handshake.outgoing.buf = NULL;
+ }
+
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START;
+ }
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ xlator_notify (this->xl, GF_EVENT_POLLERR, this, NULL);
+
+ if (need_unref)
+ transport_unref (this);
+
+ return 0;
+}
+
+
+static int
+tcp_connect_finish (transport_t *this)
+{
+ ib_verbs_private_t *priv = this->private;
+ int error = 0, ret = 0;
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ ret = __tcp_connect_finish (priv->sock);
+
+ if (!ret) {
+ this->myinfo.sockaddr_len =
+ sizeof (this->myinfo.sockaddr);
+ ret = getsockname (priv->sock,
+ (struct sockaddr *)&this->myinfo.sockaddr,
+ &this->myinfo.sockaddr_len);
+ if (ret == -1)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "getsockname on new client-socket %d "
+ "failed (%s)",
+ priv->sock, strerror (errno));
+ close (priv->sock);
+ error = 1;
+ goto unlock;
+ }
+
+ gf_ibverbs_get_transport_identifiers (this);
+ priv->tcp_connected = 1;
+ }
+
+ if (ret == -1 && errno != EINPROGRESS) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "tcp connect to %s failed (%s)",
+ this->peerinfo.identifier, strerror (errno));
+ error = 1;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ if (error) {
+ transport_disconnect (this);
+ }
+
+ return ret;
+}
+
+static int
+ib_verbs_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
+{
+ transport_t *this = data;
+ ib_verbs_private_t *priv = this->private;
+ ib_verbs_options_t *options = NULL;
+ int ret = 0;
+
+ if (!priv->tcp_connected) {
+ ret = tcp_connect_finish (this);
+ if (priv->tcp_connected) {
+ options = &priv->options;
+
+ priv->peer.send_count = options->send_count;
+ priv->peer.recv_count = options->recv_count;
+ priv->peer.send_size = options->send_size;
+ priv->peer.recv_size = options->recv_size;
+
+ if ((ret = ib_verbs_create_qp (this)) < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not create QP",
+ this->xl->name);
+ transport_disconnect (this);
+ }
+ }
+ }
+
+ if (!ret && poll_out && priv->tcp_connected) {
+ ret = ib_verbs_handshake_pollout (this);
+ }
+
+ if (!ret && poll_in && priv->tcp_connected) {
+ if (priv->handshake.incoming.state == IB_VERBS_HANDSHAKE_COMPLETE) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: pollin received on tcp socket (peer: %s) "
+ "after handshake is complete",
+ this->xl->name, this->peerinfo.identifier);
+ ib_verbs_handshake_pollerr (this);
+ return 0;
+ }
+ ret = ib_verbs_handshake_pollin (this);
+ }
+
+ if (ret < 0 || poll_err) {
+ ret = ib_verbs_handshake_pollerr (this);
+ }
+
+ return 0;
+}
+
+static int
+__tcp_nonblock (int fd)
+{
+ int flags = 0;
+ int ret = -1;
+
+ flags = fcntl (fd, F_GETFL);
+
+ if (flags != -1)
+ ret = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+
+ return ret;
+}
+
+static int32_t
+ib_verbs_connect (struct transport *this)
+{
+ dict_t *options = this->xl->options;
+
+ ib_verbs_private_t *priv = this->private;
+
+ int32_t ret = 0;
+ gf_boolean_t non_blocking = 1;
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len = 0;
+
+ if (priv->connected) {
+ return 0;
+ }
+
+ if (dict_get (options, "non-blocking-io")) {
+ char *nb_connect = data_to_str (dict_get (this->xl->options,
+ "non-blocking-io"));
+
+ if (gf_string2boolean (nb_connect, &non_blocking) == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "'non-blocking-io' takes only boolean "
+ "options, not taking any action");
+ non_blocking = 1;
+ }
+ }
+
+ ret = gf_ibverbs_client_get_remote_sockaddr (this,
+ (struct sockaddr *)&sockaddr,
+ &sockaddr_len);
+ if (ret != 0) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "cannot get remote address to connect");
+ return ret;
+ }
+
+ pthread_mutex_lock (&priv->write_mutex);
+ {
+ if (priv->sock != -1) {
+ ret = 0;
+ goto unlock;
+ }
+
+ priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family,
+ SOCK_STREAM, 0);
+
+ if (priv->sock == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "socket () - error: %s", strerror (errno));
+ ret = -errno;
+ goto unlock;
+ }
+
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "socket fd = %d", priv->sock);
+
+ memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len);
+ this->peerinfo.sockaddr_len = sockaddr_len;
+
+ ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family =
+ ((struct sockaddr *)&this->peerinfo.sockaddr)->sa_family;
+
+ if (non_blocking)
+ {
+ ret = __tcp_nonblock (priv->sock);
+
+ if (ret == -1)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "could not set socket %d to non "
+ "blocking mode (%s)",
+ priv->sock, strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+ }
+
+ ret = gf_ibverbs_client_bind (this,
+ (struct sockaddr *)&this->myinfo.sockaddr,
+ &this->myinfo.sockaddr_len, priv->sock);
+ if (ret == -1)
+ {
+ gf_log (this->xl->name, GF_LOG_WARNING,
+ "client bind failed: %s", strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ ret = connect (priv->sock,
+ (struct sockaddr *)&this->peerinfo.sockaddr,
+ this->peerinfo.sockaddr_len);
+ if (ret == -1 && errno != EINPROGRESS)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connection attempt failed (%s)",
+ strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ priv->tcp_connected = priv->connected = 0;
+
+ transport_ref (this);
+
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START;
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START;
+
+ priv->idx = event_register (this->xl->ctx->event_pool,
+ priv->sock, ib_verbs_event_handler,
+ this, 1, 1);
+ }
+unlock:
+ pthread_mutex_unlock (&priv->write_mutex);
+
+ return ret;
+}
+
+static int
+ib_verbs_server_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
+{
+ int32_t main_sock = -1;
+ transport_t *this, *trans = data;
+ ib_verbs_private_t *priv = NULL;
+ ib_verbs_private_t *trans_priv = (ib_verbs_private_t *) trans->private;
+ ib_verbs_options_t *options = NULL;
+
+ if (!poll_in)
+ return 0;
+
+ this = GF_CALLOC (1, sizeof (transport_t),
+ gf_ibv_mt_transport_t);
+ if (!this)
+ return 0;
+
+ priv = GF_CALLOC (1, sizeof (ib_verbs_private_t),
+ gf_ibv_mt_ib_verbs_private_t);
+ if (!priv) {
+ GF_FREE (this);
+ return 0;
+ }
+
+ this->private = priv;
+ /* Copy all the ib_verbs related values in priv, from trans_priv
+ as other than QP, all the values remain same */
+ priv->device = trans_priv->device;
+ priv->options = trans_priv->options;
+ options = &priv->options;
+
+ this->ops = trans->ops;
+ this->xl = trans->xl;
+ this->init = trans->init;
+ this->fini = trans->fini;
+
+ memcpy (&this->myinfo.sockaddr, &trans->myinfo.sockaddr,
+ trans->myinfo.sockaddr_len);
+ this->myinfo.sockaddr_len = trans->myinfo.sockaddr_len;
+
+ main_sock = (trans_priv)->sock;
+ this->peerinfo.sockaddr_len = sizeof (this->peerinfo.sockaddr);
+ priv->sock = accept (main_sock,
+ (struct sockaddr *)&this->peerinfo.sockaddr,
+ &this->peerinfo.sockaddr_len);
+ if (priv->sock == -1) {
+ gf_log ("ib-verbs/server", GF_LOG_ERROR,
+ "accept() failed: %s",
+ strerror (errno));
+ GF_FREE (this->private);
+ GF_FREE (this);
+ return -1;
+ }
+
+ priv->peer.trans = this;
+ transport_ref (this);
+
+ gf_ibverbs_get_transport_identifiers (this);
+
+ priv->tcp_connected = 1;
+ priv->handshake.incoming.state = IB_VERBS_HANDSHAKE_START;
+ priv->handshake.outgoing.state = IB_VERBS_HANDSHAKE_START;
+
+ priv->peer.send_count = options->send_count;
+ priv->peer.recv_count = options->recv_count;
+ priv->peer.send_size = options->send_size;
+ priv->peer.recv_size = options->recv_size;
+ INIT_LIST_HEAD (&priv->peer.ioq);
+
+ if (ib_verbs_create_qp (this) < 0) {
+ gf_log ("transport/ib-verbs", GF_LOG_ERROR,
+ "%s: could not create QP",
+ this->xl->name);
+ transport_disconnect (this);
+ return -1;
+ }
+
+ priv->idx = event_register (this->xl->ctx->event_pool, priv->sock,
+ ib_verbs_event_handler, this, 1, 1);
+
+ pthread_mutex_init (&priv->read_mutex, NULL);
+ pthread_mutex_init (&priv->write_mutex, NULL);
+ pthread_mutex_init (&priv->recv_mutex, NULL);
+ /* pthread_cond_init (&priv->recv_cond, NULL); */
+
+ return 0;
+}
+
+static int32_t
+ib_verbs_listen (transport_t *this)
+{
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ ib_verbs_private_t *priv = this->private;
+ int opt = 1, ret = 0;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
+
+ memset (&sockaddr, 0, sizeof (sockaddr));
+ ret = gf_ibverbs_server_get_local_sockaddr (this,
+ (struct sockaddr *)&sockaddr,
+ &sockaddr_len);
+ if (ret != 0) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "cannot find network address of server to bind to");
+ goto err;
+ }
+
+ priv->sock = socket (((struct sockaddr *)&sockaddr)->sa_family,
+ SOCK_STREAM, 0);
+ if (priv->sock == -1) {
+ gf_log ("ib-verbs/server", GF_LOG_CRITICAL,
+ "init: failed to create socket, error: %s",
+ strerror (errno));
+ GF_FREE (this->private);
+ ret = -1;
+ goto err;
+ }
+
+ memcpy (&this->myinfo.sockaddr, &sockaddr, sockaddr_len);
+ this->myinfo.sockaddr_len = sockaddr_len;
+
+ ret = getnameinfo ((struct sockaddr *)&this->myinfo.sockaddr,
+ this->myinfo.sockaddr_len,
+ host, sizeof (host),
+ service, sizeof (service),
+ NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "getnameinfo failed (%s)", gai_strerror (ret));
+ goto err;
+ }
+ sprintf (this->myinfo.identifier, "%s:%s", host, service);
+
+ setsockopt (priv->sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
+ if (bind (priv->sock,
+ (struct sockaddr *)&sockaddr,
+ sockaddr_len) != 0) {
+ ret = -1;
+ gf_log ("ib-verbs/server", GF_LOG_ERROR,
+ "init: failed to bind to socket for %s (%s)",
+ this->myinfo.identifier, strerror (errno));
+ goto err;
+ }
+
+ if (listen (priv->sock, 10) != 0) {
+ gf_log ("ib-verbs/server", GF_LOG_ERROR,
+ "init: listen () failed on socket for %s (%s)",
+ this->myinfo.identifier, strerror (errno));
+ ret = -1;
+ goto err;
+ }
+
+ /* Register the main socket */
+ priv->idx = event_register (this->xl->ctx->event_pool, priv->sock,
+ ib_verbs_server_event_handler,
+ transport_ref (this), 1, 0);
+
+err:
+ return ret;
+}
+
+struct transport_ops tops = {
+ .receive = ib_verbs_receive,
+ .submit = ib_verbs_submit,
+ .connect = ib_verbs_connect,
+ .disconnect = ib_verbs_disconnect,
+ .listen = ib_verbs_listen,
+};
+
+int32_t
+init (transport_t *this)
+{
+ ib_verbs_private_t *priv = GF_CALLOC (1, sizeof (*priv),
+ gf_ibv_mt_ib_verbs_private_t);
+ this->private = priv;
+ priv->sock = -1;
+
+ if (ib_verbs_init (this)) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "Failed to initialize IB Device");
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+fini (struct transport *this)
+{
+ /* TODO: verify this function does graceful finish */
+ ib_verbs_private_t *priv = this->private;
+ this->private = NULL;
+
+ pthread_mutex_destroy (&priv->recv_mutex);
+ pthread_mutex_destroy (&priv->write_mutex);
+ pthread_mutex_destroy (&priv->read_mutex);
+ /* pthread_cond_destroy (&priv->recv_cond); */
+
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "called fini on transport: %p",
+ this);
+ GF_FREE (priv);
+ return;
+}
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_common_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+/* TODO: expand each option */
+struct volume_options options[] = {
+ { .key = {"transport.ib-verbs.port",
+ "ib-verbs-port"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 4,
+ .description = "check the option by 'ibv_devinfo'"
+ },
+ { .key = {"transport.ib-verbs.mtu",
+ "ib-verbs-mtu"},
+ .type = GF_OPTION_TYPE_INT,
+ },
+ { .key = {"transport.ib-verbs.device-name",
+ "ib-verbs-device-name"},
+ .type = GF_OPTION_TYPE_ANY,
+ .description = "check by 'ibv_devinfo'"
+ },
+ { .key = {"transport.ib-verbs.work-request-send-count",
+ "ib-verbs-work-request-send-count"},
+ .type = GF_OPTION_TYPE_INT,
+ },
+ { .key = {"transport.ib-verbs.work-request-recv-count",
+ "ib-verbs-work-request-recv-count"},
+ .type = GF_OPTION_TYPE_INT,
+ },
+ { .key = {"remote-port",
+ "transport.remote-port",
+ "transport.ib-verbs.remote-port"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.ib-verbs.listen-port", "listen-port"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.ib-verbs.connect-path", "connect-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport.ib-verbs.bind-path", "bind-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport.ib-verbs.listen-path", "listen-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport.address-family",
+ "address-family"},
+ .value = {"inet", "inet6", "inet/inet6", "inet6/inet",
+ "unix", "inet-sdp" },
+ .type = GF_OPTION_TYPE_STR
+ },
+ { .key = {"transport.socket.lowlat"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {NULL} }
+};
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h
new file mode 100644
index 000000000..dae8acec9
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/ib-verbs.h
@@ -0,0 +1,220 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _XPORT_IB_VERBS_H
+#define _XPORT_IB_VERBS_H
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef MAX_IOVEC
+#define MAX_IOVEC 16
+#endif /* MAX_IOVEC */
+
+#include "xlator.h"
+#include "event.h"
+#include "ib-verbs-mem-types.h"
+
+#include <stdio.h>
+#include <list.h>
+#include <arpa/inet.h>
+#include <infiniband/verbs.h>
+
+#define GF_DEFAULT_IBVERBS_LISTEN_PORT 6997
+
+/* options per transport end point */
+struct _ib_verbs_options {
+ int32_t port;
+ char *device_name;
+ enum ibv_mtu mtu;
+ int32_t send_count;
+ int32_t recv_count;
+ uint64_t recv_size;
+ uint64_t send_size;
+};
+typedef struct _ib_verbs_options ib_verbs_options_t;
+
+
+struct _ib_verbs_header {
+ char colonO[3];
+ uint32_t size1;
+ uint32_t size2;
+ char version;
+} __attribute__((packed));
+typedef struct _ib_verbs_header ib_verbs_header_t;
+
+struct _ib_verbs_ioq {
+ union {
+ struct list_head list;
+ struct {
+ struct _ib_verbs_ioq *next;
+ struct _ib_verbs_ioq *prev;
+ };
+ };
+ ib_verbs_header_t header;
+ struct iovec vector[MAX_IOVEC];
+ int count;
+ char *buf;
+ struct iobref *iobref;
+};
+typedef struct _ib_verbs_ioq ib_verbs_ioq_t;
+
+/* represents one communication peer, two per transport_t */
+struct _ib_verbs_peer {
+ transport_t *trans;
+ struct ibv_qp *qp;
+
+ int32_t recv_count;
+ int32_t send_count;
+ int32_t recv_size;
+ int32_t send_size;
+
+ int32_t quota;
+ union {
+ struct list_head ioq;
+ struct {
+ ib_verbs_ioq_t *ioq_next;
+ ib_verbs_ioq_t *ioq_prev;
+ };
+ };
+
+ /* QP attributes, needed to connect with remote QP */
+ int32_t local_lid;
+ int32_t local_psn;
+ int32_t local_qpn;
+ int32_t remote_lid;
+ int32_t remote_psn;
+ int32_t remote_qpn;
+};
+typedef struct _ib_verbs_peer ib_verbs_peer_t;
+
+
+struct _ib_verbs_post {
+ struct _ib_verbs_post *next, *prev;
+ struct ibv_mr *mr;
+ char *buf;
+ int32_t buf_size;
+ char aux;
+ int32_t reused;
+ pthread_barrier_t wait;
+};
+typedef struct _ib_verbs_post ib_verbs_post_t;
+
+
+struct _ib_verbs_queue {
+ ib_verbs_post_t active_posts, passive_posts;
+ int32_t active_count, passive_count;
+ pthread_mutex_t lock;
+};
+typedef struct _ib_verbs_queue ib_verbs_queue_t;
+
+
+struct _ib_verbs_qpreg {
+ pthread_mutex_t lock;
+ int32_t count;
+ struct _qpent {
+ struct _qpent *next, *prev;
+ int32_t qp_num;
+ ib_verbs_peer_t *peer;
+ } ents[42];
+};
+typedef struct _ib_verbs_qpreg ib_verbs_qpreg_t;
+
+/* context per device, stored in global glusterfs_ctx_t->ib */
+struct _ib_verbs_device {
+ struct _ib_verbs_device *next;
+ const char *device_name;
+ struct ibv_context *context;
+ int32_t port;
+ struct ibv_pd *pd;
+ struct ibv_srq *srq;
+ ib_verbs_qpreg_t qpreg;
+ struct ibv_comp_channel *send_chan, *recv_chan;
+ struct ibv_cq *send_cq, *recv_cq;
+ ib_verbs_queue_t sendq, recvq;
+ pthread_t send_thread, recv_thread;
+};
+typedef struct _ib_verbs_device ib_verbs_device_t;
+
+typedef enum {
+ IB_VERBS_HANDSHAKE_START = 0,
+ IB_VERBS_HANDSHAKE_SENDING_DATA,
+ IB_VERBS_HANDSHAKE_RECEIVING_DATA,
+ IB_VERBS_HANDSHAKE_SENT_DATA,
+ IB_VERBS_HANDSHAKE_RECEIVED_DATA,
+ IB_VERBS_HANDSHAKE_SENDING_ACK,
+ IB_VERBS_HANDSHAKE_RECEIVING_ACK,
+ IB_VERBS_HANDSHAKE_RECEIVED_ACK,
+ IB_VERBS_HANDSHAKE_COMPLETE,
+} ib_verbs_handshake_state_t;
+
+struct ib_verbs_nbio {
+ int state;
+ char *buf;
+ int count;
+ struct iovec vector;
+ struct iovec *pending_vector;
+ int pending_count;
+};
+
+
+struct _ib_verbs_private {
+ int32_t sock;
+ int32_t idx;
+ unsigned char connected;
+ unsigned char tcp_connected;
+ unsigned char ib_connected;
+ in_addr_t addr;
+ unsigned short port;
+
+ /* IB Verbs Driver specific variables, pointers */
+ ib_verbs_peer_t peer;
+ ib_verbs_device_t *device;
+ ib_verbs_options_t options;
+
+ /* Used by trans->op->receive */
+ char *data_ptr;
+ int32_t data_offset;
+ int32_t data_len;
+
+ /* Mutex */
+ pthread_mutex_t read_mutex;
+ pthread_mutex_t write_mutex;
+ pthread_barrier_t handshake_barrier;
+ char handshake_ret;
+
+ pthread_mutex_t recv_mutex;
+ pthread_cond_t recv_cond;
+
+ /* used during ib_verbs_handshake */
+ struct {
+ struct ib_verbs_nbio incoming;
+ struct ib_verbs_nbio outgoing;
+ int state;
+ ib_verbs_header_t header;
+ char *buf;
+ size_t size;
+ } handshake;
+};
+typedef struct _ib_verbs_private ib_verbs_private_t;
+
+#endif /* _XPORT_IB_VERBS_H */
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/name.c b/xlators/protocol/legacy/transport/ib-verbs/src/name.c
new file mode 100644
index 000000000..7fdeb13fc
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/name.c
@@ -0,0 +1,712 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+
+#ifdef CLIENT_PORT_CEILING
+#undef CLIENT_PORT_CEILING
+#endif
+
+#define CLIENT_PORT_CEILING 1024
+
+#ifndef AF_INET_SDP
+#define AF_INET_SDP 27
+#endif
+
+#include "transport.h"
+#include "ib-verbs.h"
+
+int32_t
+gf_resolve_ip6 (const char *hostname,
+ uint16_t port,
+ int family,
+ void **dnscache,
+ struct addrinfo **addr_info);
+
+static int32_t
+af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr,
+ socklen_t sockaddr_len, int ceiling)
+{
+ int32_t ret = -1;
+ /* struct sockaddr_in sin = {0, }; */
+ uint16_t port = ceiling - 1;
+
+ while (port)
+ {
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port);
+ break;
+
+ case AF_INET_SDP:
+ case AF_INET:
+ ((struct sockaddr_in *)sockaddr)->sin_port = htons (port);
+ break;
+ }
+
+ ret = bind (fd, sockaddr, sockaddr_len);
+
+ if (ret == 0)
+ break;
+
+ if (ret == -1 && errno == EACCES)
+ break;
+
+ port--;
+ }
+
+ return ret;
+}
+
+static int32_t
+af_unix_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t sockaddr_len,
+ int sock)
+{
+ data_t *path_data = NULL;
+ struct sockaddr_un *addr = NULL;
+ int32_t ret = -1;
+
+ path_data = dict_get (this->xl->options,
+ "transport.ib-verbs.bind-path");
+ if (path_data) {
+ char *path = data_to_str (path_data);
+ if (!path || strlen (path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "transport.ib-verbs.bind-path not specfied "
+ "for unix socket, letting connect to assign "
+ "default value");
+ goto err;
+ }
+
+ addr = (struct sockaddr_un *) sockaddr;
+ strcpy (addr->sun_path, path);
+ ret = bind (sock, (struct sockaddr *)addr, sockaddr_len);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "cannot bind to unix-domain socket %d (%s)",
+ sock, strerror (errno));
+ goto err;
+ }
+ }
+
+err:
+ return ret;
+}
+
+static int32_t
+client_fill_address_family (transport_t *this, struct sockaddr *sockaddr)
+{
+ data_t *address_family_data = NULL;
+
+ address_family_data = dict_get (this->xl->options,
+ "transport.address-family");
+ if (!address_family_data) {
+ data_t *remote_host_data = NULL, *connect_path_data = NULL;
+ remote_host_data = dict_get (this->xl->options, "remote-host");
+ connect_path_data = dict_get (this->xl->options,
+ "transport.ib-verbs.connect-path");
+
+ if (!(remote_host_data || connect_path_data) ||
+ (remote_host_data && connect_path_data)) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "address-family not specified and not able to "
+ "determine the same from other options "
+ "(remote-host:%s and connect-path:%s)",
+ data_to_str (remote_host_data),
+ data_to_str (connect_path_data));
+ return -1;
+ }
+
+ if (remote_host_data) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "address-family not specified, guessing it "
+ "to be inet/inet6");
+ sockaddr->sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "address-family not specified, guessing it "
+ "to be unix");
+ sockaddr->sa_family = AF_UNIX;
+ }
+
+ } else {
+ char *address_family = data_to_str (address_family_data);
+ if (!strcasecmp (address_family, "unix")) {
+ sockaddr->sa_family = AF_UNIX;
+ } else if (!strcasecmp (address_family, "inet")) {
+ sockaddr->sa_family = AF_INET;
+ } else if (!strcasecmp (address_family, "inet6")) {
+ sockaddr->sa_family = AF_INET6;
+ } else if (!strcasecmp (address_family, "inet-sdp")) {
+ sockaddr->sa_family = AF_INET_SDP;
+ } else if (!strcasecmp (address_family, "inet/inet6")
+ || !strcasecmp (address_family, "inet6/inet")) {
+ sockaddr->sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address-family (%s) specified",
+ address_family);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int32_t
+af_inet_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len)
+{
+ dict_t *options = this->xl->options;
+ data_t *remote_host_data = NULL;
+ data_t *remote_port_data = NULL;
+ char *remote_host = NULL;
+ uint16_t remote_port = 0;
+ struct addrinfo *addr_info = NULL;
+ int32_t ret = 0;
+
+ remote_host_data = dict_get (options, "remote-host");
+ if (remote_host_data == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-host missing in volume %s",
+ this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ remote_host = data_to_str (remote_host_data);
+ if (remote_host == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-host has data NULL in volume %s",
+ this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ remote_port_data = dict_get (options, "remote-port");
+ if (remote_port_data == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "option remote-port missing in volume %s. "
+ "Defaulting to %d",
+ this->xl->name, GF_DEFAULT_IBVERBS_LISTEN_PORT);
+
+ remote_port = GF_DEFAULT_IBVERBS_LISTEN_PORT;
+ }
+ else
+ {
+ remote_port = data_to_uint16 (remote_port_data);
+ }
+
+ if (remote_port == (uint16_t)-1)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-port has invalid port in volume %s",
+ this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ /* TODO: gf_resolve is a blocking call. kick in some
+ non blocking dns techniques */
+ ret = gf_resolve_ip6 (remote_host, remote_port,
+ sockaddr->sa_family,
+ &this->dnscache, &addr_info);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "DNS resolution failed on host %s", remote_host);
+ goto err;
+ }
+
+ memcpy (sockaddr, addr_info->ai_addr, addr_info->ai_addrlen);
+ *sockaddr_len = addr_info->ai_addrlen;
+
+err:
+ return ret;
+}
+
+static int32_t
+af_unix_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len)
+{
+ struct sockaddr_un *sockaddr_un = NULL;
+ char *connect_path = NULL;
+ data_t *connect_path_data = NULL;
+ int32_t ret = 0;
+
+ connect_path_data = dict_get (this->xl->options,
+ "transport.ib-verbs.connect-path");
+ if (!connect_path_data) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option transport.ib-verbs.connect-path not "
+ "specified for address-family unix");
+ ret = -1;
+ goto err;
+ }
+
+ connect_path = data_to_str (connect_path_data);
+ if (!connect_path) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connect-path is null-string");
+ ret = -1;
+ goto err;
+ }
+
+ if (strlen (connect_path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connect-path value length %"GF_PRI_SIZET" > "
+ "%d octets", strlen (connect_path), UNIX_PATH_MAX);
+ ret = -1;
+ goto err;
+ }
+
+ gf_log (this->xl->name,
+ GF_LOG_DEBUG,
+ "using connect-path %s", connect_path);
+ sockaddr_un = (struct sockaddr_un *)sockaddr;
+ strcpy (sockaddr_un->sun_path, connect_path);
+ *sockaddr_len = sizeof (struct sockaddr_un);
+
+err:
+ return ret;
+}
+
+static int32_t
+af_unix_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ data_t *listen_path_data = NULL;
+ char *listen_path = NULL;
+ int32_t ret = 0;
+ struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
+
+
+ listen_path_data = dict_get (this->xl->options,
+ "transport.ib-verbs.listen-path");
+ if (!listen_path_data) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "missing option listen-path");
+ ret = -1;
+ goto err;
+ }
+
+ listen_path = data_to_str (listen_path_data);
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+ if (strlen (listen_path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option listen-path has value length %"GF_PRI_SIZET" > %d",
+ strlen (listen_path), UNIX_PATH_MAX);
+ ret = -1;
+ goto err;
+ }
+
+ sunaddr->sun_family = AF_UNIX;
+ strcpy (sunaddr->sun_path, listen_path);
+ *addr_len = sizeof (struct sockaddr_un);
+
+err:
+ return ret;
+}
+
+static int32_t
+af_inet_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ struct addrinfo hints, *res = 0;
+ data_t *listen_port_data = NULL, *listen_host_data = NULL;
+ uint16_t listen_port = -1;
+ char service[NI_MAXSERV], *listen_host = NULL;
+ dict_t *options = NULL;
+ int32_t ret = 0;
+
+ options = this->xl->options;
+
+ listen_port_data = dict_get (options, "transport.ib-verbs.listen-port");
+ listen_host_data = dict_get (options, "transport.ib-verbs.bind-address");
+
+ if (listen_port_data)
+ {
+ listen_port = data_to_uint16 (listen_port_data);
+ } else {
+ if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
+ in->sin6_addr = in6addr_any;
+ in->sin6_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in6);
+ goto out;
+ } else if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *in = (struct sockaddr_in *) addr;
+ in->sin_addr.s_addr = htonl(INADDR_ANY);
+ in->sin_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in);
+ goto out;
+ }
+ }
+
+ if (listen_port == (uint16_t) -1)
+ listen_port = GF_DEFAULT_IBVERBS_LISTEN_PORT;
+
+
+ if (listen_host_data)
+ {
+ listen_host = data_to_str (listen_host_data);
+ }
+
+ memset (service, 0, sizeof (service));
+ sprintf (service, "%d", listen_port);
+
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_family = addr->sa_family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+
+ ret = getaddrinfo(listen_host, service, &hints, &res);
+ if (ret != 0) {
+ gf_log (this->xl->name,
+ GF_LOG_ERROR,
+ "getaddrinfo failed for host %s, service %s (%s)",
+ listen_host, service, gai_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+
+ memcpy (addr, res->ai_addr, res->ai_addrlen);
+ *addr_len = res->ai_addrlen;
+
+ freeaddrinfo (res);
+
+out:
+ return ret;
+}
+
+int32_t
+gf_ibverbs_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ int sock)
+{
+ int ret = 0;
+
+ *sockaddr_len = sizeof (struct sockaddr_in6);
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET_SDP:
+ case AF_INET:
+ *sockaddr_len = sizeof (struct sockaddr_in);
+
+ case AF_INET6:
+ ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
+ *sockaddr_len,
+ CLIENT_PORT_CEILING);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_WARNING,
+ "cannot bind inet socket (%d) to port "
+ "less than %d (%s)",
+ sock, CLIENT_PORT_CEILING, strerror (errno));
+ ret = 0;
+ }
+ break;
+
+ case AF_UNIX:
+ *sockaddr_len = sizeof (struct sockaddr_un);
+ ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr,
+ *sockaddr_len, sock);
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family %d", sockaddr->sa_family);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int32_t
+gf_ibverbs_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len)
+{
+ int32_t ret = 0;
+ char is_inet_sdp = 0;
+
+ ret = client_fill_address_family (this, sockaddr);
+ if (ret) {
+ ret = -1;
+ goto err;
+ }
+
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET_SDP:
+ sockaddr->sa_family = AF_INET;
+ is_inet_sdp = 1;
+
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ ret = af_inet_client_get_remote_sockaddr (this,
+ sockaddr,
+ sockaddr_len);
+
+ if (is_inet_sdp) {
+ sockaddr->sa_family = AF_INET_SDP;
+ }
+
+ break;
+
+ case AF_UNIX:
+ ret = af_unix_client_get_remote_sockaddr (this,
+ sockaddr,
+ sockaddr_len);
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address-family %d", sockaddr->sa_family);
+ ret = -1;
+ }
+
+err:
+ return ret;
+}
+
+int32_t
+gf_ibverbs_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ data_t *address_family_data = NULL;
+ int32_t ret = 0;
+ char is_inet_sdp = 0;
+
+ address_family_data = dict_get (this->xl->options,
+ "transport.address-family");
+ if (address_family_data) {
+ char *address_family = NULL;
+ address_family = data_to_str (address_family_data);
+
+ if (!strcasecmp (address_family, "inet")) {
+ addr->sa_family = AF_INET;
+ } else if (!strcasecmp (address_family, "inet6")) {
+ addr->sa_family = AF_INET6;
+ } else if (!strcasecmp (address_family, "inet-sdp")) {
+ addr->sa_family = AF_INET_SDP;
+ } else if (!strcasecmp (address_family, "unix")) {
+ addr->sa_family = AF_UNIX;
+ } else if (!strcasecmp (address_family, "inet/inet6")
+ || !strcasecmp (address_family, "inet6/inet")) {
+ addr->sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family (%s) specified",
+ address_family);
+ ret = -1;
+ goto err;
+ }
+ } else {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "option address-family not specified, defaulting "
+ "to inet/inet6");
+ addr->sa_family = AF_UNSPEC;
+ }
+
+ switch (addr->sa_family)
+ {
+ case AF_INET_SDP:
+ is_inet_sdp = 1;
+ addr->sa_family = AF_INET;
+
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ ret = af_inet_server_get_local_sockaddr (this, addr, addr_len);
+ if (is_inet_sdp && !ret) {
+ addr->sa_family = AF_INET_SDP;
+ }
+ break;
+
+ case AF_UNIX:
+ ret = af_unix_server_get_local_sockaddr (this, addr, addr_len);
+ break;
+ }
+
+err:
+ return ret;
+}
+
+int32_t
+fill_inet6_inet_identifiers (transport_t *this, struct sockaddr_storage *addr,
+ int32_t addr_len, char *identifier)
+{
+ int32_t ret = 0, tmpaddr_len = 0;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
+ struct sockaddr_storage tmpaddr;
+
+ memset (&tmpaddr, 0, sizeof (tmpaddr));
+ tmpaddr = *addr;
+ tmpaddr_len = addr_len;
+
+ if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) {
+ int32_t one_to_four, four_to_eight, twelve_to_sixteen;
+ int16_t eight_to_ten, ten_to_twelve;
+
+ one_to_four = four_to_eight = twelve_to_sixteen = 0;
+ eight_to_ten = ten_to_twelve = 0;
+
+ one_to_four = ((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr.s6_addr32[0];
+ four_to_eight = ((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr.s6_addr32[1];
+#ifdef GF_SOLARIS_HOST_OS
+ eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr)[4];
+#else
+ eight_to_ten = ((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr.s6_addr16[4];
+#endif
+
+#ifdef GF_SOLARIS_HOST_OS
+ ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr)[5];
+#else
+ ten_to_twelve = ((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr.s6_addr16[5];
+#endif
+ twelve_to_sixteen = ((struct sockaddr_in6 *)
+ &tmpaddr)->sin6_addr.s6_addr32[3];
+
+ /* ipv4 mapped ipv6 address has
+ bits 0-80: 0
+ bits 80-96: 0xffff
+ bits 96-128: ipv4 address
+ */
+
+ if (one_to_four == 0 &&
+ four_to_eight == 0 &&
+ eight_to_ten == 0 &&
+ ten_to_twelve == -1) {
+ struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr;
+ memset (&tmpaddr, 0, sizeof (tmpaddr));
+
+ in_ptr->sin_family = AF_INET;
+ in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port;
+ in_ptr->sin_addr.s_addr = twelve_to_sixteen;
+ tmpaddr_len = sizeof (*in_ptr);
+ }
+ }
+
+ ret = getnameinfo ((struct sockaddr *) &tmpaddr,
+ tmpaddr_len,
+ host, sizeof (host),
+ service, sizeof (service),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ret != 0) {
+ gf_log (this->xl->name,
+ GF_LOG_ERROR,
+ "getnameinfo failed (%s)", gai_strerror (ret));
+ }
+
+ sprintf (identifier, "%s:%s", host, service);
+
+ return ret;
+}
+
+int32_t
+gf_ibverbs_get_transport_identifiers (transport_t *this)
+{
+ int32_t ret = 0;
+ char is_inet_sdp = 0;
+
+ switch (((struct sockaddr *) &this->myinfo.sockaddr)->sa_family)
+ {
+ case AF_INET_SDP:
+ is_inet_sdp = 1;
+ ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET;
+
+ case AF_INET:
+ case AF_INET6:
+ {
+ ret = fill_inet6_inet_identifiers (this,
+ &this->myinfo.sockaddr,
+ this->myinfo.sockaddr_len,
+ this->myinfo.identifier);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "can't fill inet/inet6 identifier for server");
+ goto err;
+ }
+
+ ret = fill_inet6_inet_identifiers (this,
+ &this->peerinfo.sockaddr,
+ this->peerinfo.sockaddr_len,
+ this->peerinfo.identifier);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "can't fill inet/inet6 identifier for client");
+ goto err;
+ }
+
+ if (is_inet_sdp) {
+ ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET_SDP;
+ }
+ }
+ break;
+
+ case AF_UNIX:
+ {
+ struct sockaddr_un *sunaddr = NULL;
+
+ sunaddr = (struct sockaddr_un *) &this->myinfo.sockaddr;
+ strcpy (this->myinfo.identifier, sunaddr->sun_path);
+
+ sunaddr = (struct sockaddr_un *) &this->peerinfo.sockaddr;
+ strcpy (this->peerinfo.identifier, sunaddr->sun_path);
+ }
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family (%d)",
+ ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family);
+ ret = -1;
+ break;
+ }
+
+err:
+ return ret;
+}
diff --git a/xlators/protocol/legacy/transport/ib-verbs/src/name.h b/xlators/protocol/legacy/transport/ib-verbs/src/name.h
new file mode 100644
index 000000000..159efb22f
--- /dev/null
+++ b/xlators/protocol/legacy/transport/ib-verbs/src/name.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _IB_VERBS_NAME_H
+#define _IB_VERBS_NAME_H
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "compat.h"
+
+int32_t
+gf_ibverbs_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ int sock);
+
+int32_t
+gf_ibverbs_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len);
+
+int32_t
+gf_ibverbs_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len);
+
+int32_t
+gf_ibverbs_get_transport_identifiers (transport_t *this);
+
+#endif /* _IB_VERBS_NAME_H */
diff --git a/xlators/protocol/legacy/transport/socket/Makefile.am b/xlators/protocol/legacy/transport/socket/Makefile.am
new file mode 100644
index 000000000..f963effea
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src \ No newline at end of file
diff --git a/xlators/protocol/legacy/transport/socket/src/Makefile.am b/xlators/protocol/legacy/transport/socket/src/Makefile.am
new file mode 100644
index 000000000..5952e18e9
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/Makefile.am
@@ -0,0 +1,19 @@
+# TODO : change to proper transport dir
+
+transport_LTLIBRARIES = socket.la
+transportdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/transport
+
+socket_la_LDFLAGS = -module -avoidversion
+
+socket_la_SOURCES = socket.c name.c
+socket_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
+ $(top_builddir)/xlators/protocol/legacy/lib/src/libgfproto.la
+
+noinst_HEADERS = socket.h name.h socket-mem-types.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS) \
+ -I$(top_srcdir)/xlators/protocol/legacy/transport/socket/src \
+ -I$(top_srcdir)/xlators/protocol/legacy/lib/src
+
+CLEANFILES = *~
diff --git a/xlators/protocol/legacy/transport/socket/src/name.c b/xlators/protocol/legacy/transport/socket/src/name.c
new file mode 100644
index 000000000..537f48005
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/name.c
@@ -0,0 +1,740 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+
+#ifdef CLIENT_PORT_CEILING
+#undef CLIENT_PORT_CEILING
+#endif
+
+#define CLIENT_PORT_CEILING 1024
+
+#ifndef AF_INET_SDP
+#define AF_INET_SDP 27
+#endif
+
+static int gf_name_addr_enotspec_log;
+
+#include "transport.h"
+#include "socket.h"
+
+int32_t
+gf_resolve_ip6 (const char *hostname,
+ uint16_t port,
+ int family,
+ void **dnscache,
+ struct addrinfo **addr_info);
+
+static int32_t
+af_inet_bind_to_port_lt_ceiling (int fd, struct sockaddr *sockaddr,
+ socklen_t sockaddr_len, int ceiling)
+{
+ int32_t ret = -1;
+ /* struct sockaddr_in sin = {0, }; */
+ uint16_t port = ceiling - 1;
+
+ while (port)
+ {
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port);
+ break;
+
+ case AF_INET_SDP:
+ case AF_INET:
+ ((struct sockaddr_in *)sockaddr)->sin_port = htons (port);
+ break;
+ }
+
+ ret = bind (fd, sockaddr, sockaddr_len);
+
+ if (ret == 0)
+ break;
+
+ if (ret == -1 && errno == EACCES)
+ break;
+
+ port--;
+ }
+
+ return ret;
+}
+
+static int32_t
+af_unix_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t sockaddr_len,
+ int sock)
+{
+ data_t *path_data = NULL;
+ struct sockaddr_un *addr = NULL;
+ int32_t ret = 0;
+
+ path_data = dict_get (this->xl->options, "transport.socket.bind-path");
+ if (path_data) {
+ char *path = data_to_str (path_data);
+ if (!path || strlen (path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "bind-path not specfied for unix socket, "
+ "letting connect to assign default value");
+ goto err;
+ }
+
+ addr = (struct sockaddr_un *) sockaddr;
+ strcpy (addr->sun_path, path);
+ ret = bind (sock, (struct sockaddr *)addr, sockaddr_len);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "cannot bind to unix-domain socket %d (%s)",
+ sock, strerror (errno));
+ goto err;
+ }
+ } else {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "bind-path not specfied for unix socket, "
+ "letting connect to assign default value");
+ }
+
+err:
+ return ret;
+}
+
+static int32_t
+client_fill_address_family (transport_t *this, sa_family_t *sa_family)
+{
+ data_t *address_family_data = NULL;
+ int32_t ret = -1;
+
+ if (sa_family == NULL) {
+ goto out;
+ }
+
+ address_family_data = dict_get (this->xl->options,
+ "transport.address-family");
+ if (!address_family_data) {
+ data_t *remote_host_data = NULL, *connect_path_data = NULL;
+ remote_host_data = dict_get (this->xl->options, "remote-host");
+ connect_path_data = dict_get (this->xl->options,
+ "transport.socket.connect-path");
+
+ if (!(remote_host_data || connect_path_data) ||
+ (remote_host_data && connect_path_data)) {
+ GF_LOG_OCCASIONALLY (gf_name_addr_enotspec_log,
+ this->xl->name, GF_LOG_ERROR,
+ "transport.address-family not specified and "
+ "not able to determine the "
+ "same from other options (remote-host:%s and "
+ "transport.unix.connect-path:%s)",
+ data_to_str (remote_host_data),
+ data_to_str (connect_path_data));
+ goto out;
+ }
+
+ if (remote_host_data) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "address-family not specified, guessing it "
+ "to be inet/inet6");
+ *sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "address-family not specified, guessing it "
+ "to be unix");
+ *sa_family = AF_UNIX;
+ }
+
+ } else {
+ char *address_family = data_to_str (address_family_data);
+ if (!strcasecmp (address_family, "unix")) {
+ *sa_family = AF_UNIX;
+ } else if (!strcasecmp (address_family, "inet")) {
+ *sa_family = AF_INET;
+ } else if (!strcasecmp (address_family, "inet6")) {
+ *sa_family = AF_INET6;
+ } else if (!strcasecmp (address_family, "inet-sdp")) {
+ *sa_family = AF_INET_SDP;
+ } else if (!strcasecmp (address_family, "inet/inet6")
+ || !strcasecmp (address_family, "inet6/inet")) {
+ *sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address-family (%s) specified",
+ address_family);
+ goto out;
+ }
+ }
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
+static int32_t
+af_inet_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len)
+{
+ dict_t *options = this->xl->options;
+ data_t *remote_host_data = NULL;
+ data_t *remote_port_data = NULL;
+ char *remote_host = NULL;
+ uint16_t remote_port = 0;
+ struct addrinfo *addr_info = NULL;
+ int32_t ret = 0;
+
+ remote_host_data = dict_get (options, "remote-host");
+ if (remote_host_data == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-host missing in volume %s", this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ remote_host = data_to_str (remote_host_data);
+ if (remote_host == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-host has data NULL in volume %s", this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ remote_port_data = dict_get (options, "remote-port");
+ if (remote_port_data == NULL)
+ {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "option remote-port missing in volume %s. Defaulting to %d",
+ this->xl->name, GF_DEFAULT_SOCKET_LISTEN_PORT);
+
+ remote_port = GF_DEFAULT_SOCKET_LISTEN_PORT;
+ }
+ else
+ {
+ remote_port = data_to_uint16 (remote_port_data);
+ }
+
+ if (remote_port == (uint16_t)-1)
+ {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option remote-port has invalid port in volume %s",
+ this->xl->name);
+ ret = -1;
+ goto err;
+ }
+
+ /* TODO: gf_resolve is a blocking call. kick in some
+ non blocking dns techniques */
+ ret = gf_resolve_ip6 (remote_host, remote_port,
+ sockaddr->sa_family, &this->dnscache, &addr_info);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "DNS resolution failed on host %s", remote_host);
+ goto err;
+ }
+
+ memcpy (sockaddr, addr_info->ai_addr, addr_info->ai_addrlen);
+ *sockaddr_len = addr_info->ai_addrlen;
+
+err:
+ return ret;
+}
+
+static int32_t
+af_unix_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len)
+{
+ struct sockaddr_un *sockaddr_un = NULL;
+ char *connect_path = NULL;
+ data_t *connect_path_data = NULL;
+ int32_t ret = 0;
+
+ connect_path_data = dict_get (this->xl->options,
+ "transport.socket.connect-path");
+ if (!connect_path_data) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option transport.unix.connect-path not specified for "
+ "address-family unix");
+ ret = -1;
+ goto err;
+ }
+
+ connect_path = data_to_str (connect_path_data);
+ if (!connect_path) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "transport.unix.connect-path is null-string");
+ ret = -1;
+ goto err;
+ }
+
+ if (strlen (connect_path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connect-path value length %"GF_PRI_SIZET" > %d octets",
+ strlen (connect_path), UNIX_PATH_MAX);
+ ret = -1;
+ goto err;
+ }
+
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "using connect-path %s", connect_path);
+ sockaddr_un = (struct sockaddr_un *)sockaddr;
+ strcpy (sockaddr_un->sun_path, connect_path);
+ *sockaddr_len = sizeof (struct sockaddr_un);
+
+err:
+ return ret;
+}
+
+static int32_t
+af_unix_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ data_t *listen_path_data = NULL;
+ char *listen_path = NULL;
+ int32_t ret = 0;
+ struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
+
+
+ listen_path_data = dict_get (this->xl->options,
+ "transport.socket.listen-path");
+ if (!listen_path_data) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "missing option transport.socket.listen-path");
+ ret = -1;
+ goto err;
+ }
+
+ listen_path = data_to_str (listen_path_data);
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+ if (strlen (listen_path) > UNIX_PATH_MAX) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "option transport.unix.listen-path has value length "
+ "%"GF_PRI_SIZET" > %d",
+ strlen (listen_path), UNIX_PATH_MAX);
+ ret = -1;
+ goto err;
+ }
+
+ sunaddr->sun_family = AF_UNIX;
+ strcpy (sunaddr->sun_path, listen_path);
+ *addr_len = sizeof (struct sockaddr_un);
+
+err:
+ return ret;
+}
+
+static int32_t
+af_inet_server_get_local_sockaddr (transport_t *this,
+ struct sockaddr *addr,
+ socklen_t *addr_len)
+{
+ struct addrinfo hints, *res = 0;
+ data_t *listen_port_data = NULL, *listen_host_data = NULL;
+ uint16_t listen_port = -1;
+ char service[NI_MAXSERV], *listen_host = NULL;
+ dict_t *options = NULL;
+ int32_t ret = 0;
+
+ options = this->xl->options;
+
+ listen_port_data = dict_get (options, "transport.socket.listen-port");
+ listen_host_data = dict_get (options, "transport.socket.bind-address");
+
+ if (listen_port_data)
+ {
+ listen_port = data_to_uint16 (listen_port_data);
+ }
+
+ if (listen_port == (uint16_t) -1)
+ listen_port = GF_DEFAULT_SOCKET_LISTEN_PORT;
+
+
+ if (listen_host_data)
+ {
+ listen_host = data_to_str (listen_host_data);
+ } else {
+ if (addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *in = (struct sockaddr_in6 *) addr;
+ in->sin6_addr = in6addr_any;
+ in->sin6_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in6);
+ goto out;
+ } else if (addr->sa_family == AF_INET) {
+ struct sockaddr_in *in = (struct sockaddr_in *) addr;
+ in->sin_addr.s_addr = htonl(INADDR_ANY);
+ in->sin_port = htons(listen_port);
+ *addr_len = sizeof(struct sockaddr_in);
+ goto out;
+ }
+ }
+
+ memset (service, 0, sizeof (service));
+ sprintf (service, "%d", listen_port);
+
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_family = addr->sa_family;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
+
+ ret = getaddrinfo(listen_host, service, &hints, &res);
+ if (ret != 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "getaddrinfo failed for host %s, service %s (%s)",
+ listen_host, service, gai_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+
+ memcpy (addr, res->ai_addr, res->ai_addrlen);
+ *addr_len = res->ai_addrlen;
+
+ freeaddrinfo (res);
+
+out:
+ return ret;
+}
+
+int32_t
+gf_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ int sock)
+{
+ int ret = 0;
+
+ *sockaddr_len = sizeof (struct sockaddr_in6);
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET_SDP:
+ case AF_INET:
+ *sockaddr_len = sizeof (struct sockaddr_in);
+
+ case AF_INET6:
+ ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
+ *sockaddr_len, CLIENT_PORT_CEILING);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_WARNING,
+ "cannot bind inet socket (%d) to port less than %d (%s)",
+ sock, CLIENT_PORT_CEILING, strerror (errno));
+ ret = 0;
+ }
+ break;
+
+ case AF_UNIX:
+ *sockaddr_len = sizeof (struct sockaddr_un);
+ ret = af_unix_client_bind (this, (struct sockaddr *)sockaddr,
+ *sockaddr_len, sock);
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family %d", sockaddr->sa_family);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+int32_t
+gf_socket_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ sa_family_t *sa_family)
+{
+ int32_t ret = 0;
+
+ if ((sockaddr == NULL) || (sockaddr_len == NULL)
+ || (sa_family == NULL)) {
+ ret = -1;
+ goto err;
+ }
+
+
+ ret = client_fill_address_family (this, &sockaddr->sa_family);
+ if (ret) {
+ ret = -1;
+ goto err;
+ }
+
+ *sa_family = sockaddr->sa_family;
+
+ switch (sockaddr->sa_family)
+ {
+ case AF_INET_SDP:
+ sockaddr->sa_family = AF_INET;
+
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ ret = af_inet_client_get_remote_sockaddr (this, sockaddr,
+ sockaddr_len);
+ break;
+
+ case AF_UNIX:
+ ret = af_unix_client_get_remote_sockaddr (this, sockaddr,
+ sockaddr_len);
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address-family %d", sockaddr->sa_family);
+ ret = -1;
+ }
+
+ if (*sa_family == AF_UNSPEC) {
+ *sa_family = sockaddr->sa_family;
+ }
+
+err:
+ return ret;
+}
+
+
+static int32_t
+server_fill_address_family (transport_t *this, sa_family_t *sa_family)
+{
+ data_t *address_family_data = NULL;
+ int32_t ret = -1;
+
+ if (sa_family == NULL) {
+ goto out;
+ }
+
+ address_family_data = dict_get (this->xl->options,
+ "transport.address-family");
+ if (address_family_data) {
+ char *address_family = NULL;
+ address_family = data_to_str (address_family_data);
+
+ if (!strcasecmp (address_family, "inet")) {
+ *sa_family = AF_INET;
+ } else if (!strcasecmp (address_family, "inet6")) {
+ *sa_family = AF_INET6;
+ } else if (!strcasecmp (address_family, "inet-sdp")) {
+ *sa_family = AF_INET_SDP;
+ } else if (!strcasecmp (address_family, "unix")) {
+ *sa_family = AF_UNIX;
+ } else if (!strcasecmp (address_family, "inet/inet6")
+ || !strcasecmp (address_family, "inet6/inet")) {
+ *sa_family = AF_UNSPEC;
+ } else {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family (%s) specified", address_family);
+ goto out;
+ }
+ } else {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "option address-family not specified, defaulting to inet/inet6");
+ *sa_family = AF_UNSPEC;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int32_t
+gf_socket_server_get_local_sockaddr (transport_t *this, struct sockaddr *addr,
+ socklen_t *addr_len, sa_family_t *sa_family)
+{
+ int32_t ret = -1;
+
+ if ((addr == NULL) || (addr_len == NULL) || (sa_family == NULL)) {
+ goto err;
+ }
+
+ ret = server_fill_address_family (this, &addr->sa_family);
+ if (ret == -1) {
+ goto err;
+ }
+
+ *sa_family = addr->sa_family;
+
+ switch (addr->sa_family)
+ {
+ case AF_INET_SDP:
+ addr->sa_family = AF_INET;
+
+ case AF_INET:
+ case AF_INET6:
+ case AF_UNSPEC:
+ ret = af_inet_server_get_local_sockaddr (this, addr, addr_len);
+ break;
+
+ case AF_UNIX:
+ ret = af_unix_server_get_local_sockaddr (this, addr, addr_len);
+ break;
+ }
+
+ if (*sa_family == AF_UNSPEC) {
+ *sa_family = addr->sa_family;
+ }
+
+err:
+ return ret;
+}
+
+static int32_t
+fill_inet6_inet_identifiers (transport_t *this, struct sockaddr_storage *addr,
+ int32_t addr_len, char *identifier)
+{
+ int32_t ret = 0, tmpaddr_len = 0;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
+ struct sockaddr_storage tmpaddr;
+
+ memset (&tmpaddr, 0, sizeof (tmpaddr));
+ tmpaddr = *addr;
+ tmpaddr_len = addr_len;
+
+ if (((struct sockaddr *) &tmpaddr)->sa_family == AF_INET6) {
+ int32_t one_to_four, four_to_eight, twelve_to_sixteen;
+ int16_t eight_to_ten, ten_to_twelve;
+
+ one_to_four = four_to_eight = twelve_to_sixteen = 0;
+ eight_to_ten = ten_to_twelve = 0;
+
+ one_to_four = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[0];
+ four_to_eight = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[1];
+#ifdef GF_SOLARIS_HOST_OS
+ eight_to_ten = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[4];
+#else
+ eight_to_ten = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[4];
+#endif
+
+#ifdef GF_SOLARIS_HOST_OS
+ ten_to_twelve = S6_ADDR16(((struct sockaddr_in6 *) &tmpaddr)->sin6_addr)[5];
+#else
+ ten_to_twelve = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr16[5];
+#endif
+
+ twelve_to_sixteen = ((struct sockaddr_in6 *) &tmpaddr)->sin6_addr.s6_addr32[3];
+
+ /* ipv4 mapped ipv6 address has
+ bits 0-80: 0
+ bits 80-96: 0xffff
+ bits 96-128: ipv4 address
+ */
+
+ if (one_to_four == 0 &&
+ four_to_eight == 0 &&
+ eight_to_ten == 0 &&
+ ten_to_twelve == -1) {
+ struct sockaddr_in *in_ptr = (struct sockaddr_in *)&tmpaddr;
+ memset (&tmpaddr, 0, sizeof (tmpaddr));
+
+ in_ptr->sin_family = AF_INET;
+ in_ptr->sin_port = ((struct sockaddr_in6 *)addr)->sin6_port;
+ in_ptr->sin_addr.s_addr = twelve_to_sixteen;
+ tmpaddr_len = sizeof (*in_ptr);
+ }
+ }
+
+ ret = getnameinfo ((struct sockaddr *) &tmpaddr,
+ tmpaddr_len,
+ host, sizeof (host),
+ service, sizeof (service),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ret != 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "getnameinfo failed (%s)", gai_strerror (ret));
+ }
+
+ sprintf (identifier, "%s:%s", host, service);
+
+ return ret;
+}
+
+int32_t
+gf_get_transport_identifiers (transport_t *this)
+{
+ int32_t ret = 0;
+ char is_inet_sdp = 0;
+
+ switch (((struct sockaddr *) &this->myinfo.sockaddr)->sa_family)
+ {
+ case AF_INET_SDP:
+ is_inet_sdp = 1;
+ ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET;
+
+ case AF_INET:
+ case AF_INET6:
+ {
+ ret = fill_inet6_inet_identifiers (this,
+ &this->myinfo.sockaddr,
+ this->myinfo.sockaddr_len,
+ this->myinfo.identifier);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "cannot fill inet/inet6 identifier for server");
+ goto err;
+ }
+
+ ret = fill_inet6_inet_identifiers (this,
+ &this->peerinfo.sockaddr,
+ this->peerinfo.sockaddr_len,
+ this->peerinfo.identifier);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "cannot fill inet/inet6 identifier for client");
+ goto err;
+ }
+
+ if (is_inet_sdp) {
+ ((struct sockaddr *) &this->peerinfo.sockaddr)->sa_family = ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family = AF_INET_SDP;
+ }
+ }
+ break;
+
+ case AF_UNIX:
+ {
+ struct sockaddr_un *sunaddr = NULL;
+
+ sunaddr = (struct sockaddr_un *) &this->myinfo.sockaddr;
+ strcpy (this->myinfo.identifier, sunaddr->sun_path);
+
+ sunaddr = (struct sockaddr_un *) &this->peerinfo.sockaddr;
+ strcpy (this->peerinfo.identifier, sunaddr->sun_path);
+ }
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unknown address family (%d)",
+ ((struct sockaddr *) &this->myinfo.sockaddr)->sa_family);
+ ret = -1;
+ break;
+ }
+
+err:
+ return ret;
+}
diff --git a/xlators/protocol/legacy/transport/socket/src/name.h b/xlators/protocol/legacy/transport/socket/src/name.h
new file mode 100644
index 000000000..2dd8e882b
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/name.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SOCKET_NAME_H
+#define _SOCKET_NAME_H
+
+#include "compat.h"
+
+int32_t
+gf_client_bind (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ int sock);
+
+int32_t
+gf_socket_client_get_remote_sockaddr (transport_t *this,
+ struct sockaddr *sockaddr,
+ socklen_t *sockaddr_len,
+ sa_family_t *sa_family);
+
+int32_t
+gf_socket_server_get_local_sockaddr (transport_t *this, struct sockaddr *addr,
+ socklen_t *addr_len, sa_family_t *sa_family);
+
+int32_t
+gf_get_transport_identifiers (transport_t *this);
+
+#endif /* _SOCKET_NAME_H */
diff --git a/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h b/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h
new file mode 100644
index 000000000..e43bade51
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/socket-mem-types.h
@@ -0,0 +1,36 @@
+
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __SOCKET_MEM_TYPES_H__
+#define __SOCKET_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_socket_mem_types_ {
+ gf_socket_mt_socket_private_t = gf_common_mt_end + 1,
+ gf_socket_mt_ioq,
+ gf_socket_mt_transport_t,
+ gf_socket_mt_socket_local_t,
+ gf_socket_mt_char,
+ gf_socket_mt_end
+};
+#endif
+
diff --git a/xlators/protocol/legacy/transport/socket/src/socket.c b/xlators/protocol/legacy/transport/socket/src/socket.c
new file mode 100644
index 000000000..c101a8715
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/socket.c
@@ -0,0 +1,1625 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "socket.h"
+#include "name.h"
+#include "dict.h"
+#include "transport.h"
+#include "logging.h"
+#include "xlator.h"
+#include "byte-order.h"
+#include "common-utils.h"
+#include "compat-errno.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <netinet/tcp.h>
+
+
+#define GF_LOG_ERRNO(errno) ((errno == ENOTCONN) ? GF_LOG_DEBUG : GF_LOG_ERROR)
+#define SA(ptr) ((struct sockaddr *)ptr)
+
+static int socket_init (transport_t *this);
+
+/*
+ * return value:
+ * 0 = success (completed)
+ * -1 = error
+ * > 0 = incomplete
+ */
+
+static int
+__socket_rwv (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count,
+ int write)
+{
+ socket_private_t *priv = NULL;
+ int sock = -1;
+ int ret = -1;
+ struct iovec *opvector = NULL;
+ int opcount = 0;
+ int moved = 0;
+
+ priv = this->private;
+ sock = priv->sock;
+
+ opvector = vector;
+ opcount = count;
+
+ while (opcount) {
+ if (write) {
+ ret = writev (sock, opvector, opcount);
+
+ if (ret == 0 || (ret == -1 && errno == EAGAIN)) {
+ /* done for now */
+ break;
+ }
+ } else {
+ ret = readv (sock, opvector, opcount);
+
+ if (ret == -1 && errno == EAGAIN) {
+ /* done for now */
+ break;
+ }
+ }
+
+ if (ret == 0) {
+ /* Mostly due to 'umount' in client */
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "EOF from peer %s", this->peerinfo.identifier);
+ opcount = -1;
+ errno = ENOTCONN;
+ break;
+ }
+
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "%s failed (%s)", write ? "writev" : "readv",
+ strerror (errno));
+ opcount = -1;
+ break;
+ }
+
+ moved = 0;
+
+ while (moved < ret) {
+ if ((ret - moved) >= opvector[0].iov_len) {
+ moved += opvector[0].iov_len;
+ opvector++;
+ opcount--;
+ } else {
+ opvector[0].iov_len -= (ret - moved);
+ opvector[0].iov_base += (ret - moved);
+ moved += (ret - moved);
+ }
+ while (opcount && !opvector[0].iov_len) {
+ opvector++;
+ opcount--;
+ }
+ }
+ }
+
+ if (pending_vector)
+ *pending_vector = opvector;
+
+ if (pending_count)
+ *pending_count = opcount;
+
+ return opcount;
+}
+
+
+static int
+__socket_readv (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count)
+{
+ int ret = -1;
+
+ ret = __socket_rwv (this, vector, count,
+ pending_vector, pending_count, 0);
+
+ return ret;
+}
+
+
+static int
+__socket_writev (transport_t *this, struct iovec *vector, int count,
+ struct iovec **pending_vector, int *pending_count)
+{
+ int ret = -1;
+
+ ret = __socket_rwv (this, vector, count,
+ pending_vector, pending_count, 1);
+
+ return ret;
+}
+
+
+static int
+__socket_disconnect (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+
+ priv = this->private;
+
+ if (priv->sock != -1) {
+ ret = shutdown (priv->sock, SHUT_RDWR);
+ priv->connected = -1;
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "shutdown() returned %d. set connection state to -1",
+ ret);
+ }
+
+ return ret;
+}
+
+
+static int
+__socket_server_bind (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+ int opt = 1;
+
+ priv = this->private;
+
+ ret = setsockopt (priv->sock, SOL_SOCKET, SO_REUSEADDR,
+ &opt, sizeof (opt));
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setsockopt() for SO_REUSEADDR failed (%s)",
+ strerror (errno));
+ }
+
+ ret = bind (priv->sock, (struct sockaddr *)&this->myinfo.sockaddr,
+ this->myinfo.sockaddr_len);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "binding to %s failed: %s",
+ this->myinfo.identifier, strerror (errno));
+ if (errno == EADDRINUSE) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "Port is already in use");
+ }
+ }
+
+ return ret;
+}
+
+
+static int
+__socket_nonblock (int fd)
+{
+ int flags = 0;
+ int ret = -1;
+
+ flags = fcntl (fd, F_GETFL);
+
+ if (flags != -1)
+ ret = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
+
+ return ret;
+}
+
+
+static int
+__socket_nodelay (int fd)
+{
+ int on = 1;
+ int ret = -1;
+
+ ret = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY,
+ &on, sizeof (on));
+ if (!ret)
+ gf_log ("", GF_LOG_TRACE,
+ "NODELAY enabled for socket %d", fd);
+
+ return ret;
+}
+
+
+static int
+__socket_keepalive (int fd, int keepalive_intvl)
+{
+ int on = 1;
+ int ret = -1;
+
+ ret = setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on));
+ if (ret == -1)
+ goto err;
+
+ if (keepalive_intvl == GF_USE_DEFAULT_KEEPALIVE)
+ goto done;
+
+#ifndef GF_LINUX_HOST_OS
+ ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPALIVE, &keepalive_intvl,
+ sizeof (keepalive_intvl));
+ if (ret == -1)
+ goto err;
+#else
+ ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalive_intvl,
+ sizeof (keepalive_intvl));
+ if (ret == -1)
+ goto err;
+
+ ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl,
+ sizeof (keepalive_intvl));
+ if (ret == -1)
+ goto err;
+#endif
+
+done:
+ gf_log ("", GF_LOG_TRACE, "Keep-alive enabled for socket %d, interval "
+ "%d", fd, keepalive_intvl);
+
+err:
+ return ret;
+}
+
+
+static int
+__socket_connect_finish (int fd)
+{
+ int ret = -1;
+ int optval = 0;
+ socklen_t optlen = sizeof (int);
+
+ ret = getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen);
+
+ if (ret == 0 && optval) {
+ errno = optval;
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+static void
+__socket_reset (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+
+ priv = this->private;
+
+ /* TODO: use mem-pool on incoming data */
+
+ if (priv->incoming.hdr_p)
+ GF_FREE (priv->incoming.hdr_p);
+
+ if (priv->incoming.iobuf)
+ iobuf_unref (priv->incoming.iobuf);
+
+ memset (&priv->incoming, 0, sizeof (priv->incoming));
+
+ event_unregister (this->xl->ctx->event_pool, priv->sock, priv->idx);
+ close (priv->sock);
+ priv->sock = -1;
+ priv->idx = -1;
+ priv->connected = -1;
+}
+
+
+static struct ioq *
+__socket_ioq_new (transport_t *this, char *buf, int len,
+ struct iovec *vector, int count, struct iobref *iobref)
+{
+ socket_private_t *priv = NULL;
+ struct ioq *entry = NULL;
+
+ priv = this->private;
+
+ /* TODO: use mem-pool */
+ entry = GF_CALLOC (1, sizeof (*entry),
+ gf_common_mt_ioq);
+ if (!entry)
+ return NULL;
+
+ GF_ASSERT (count <= (MAX_IOVEC-2));
+
+ entry->header.colonO[0] = ':';
+ entry->header.colonO[1] = 'O';
+ entry->header.colonO[2] = '\0';
+ entry->header.version = 42;
+ entry->header.size1 = hton32 (len);
+ entry->header.size2 = hton32 (iov_length (vector, count));
+
+ entry->vector[0].iov_base = &entry->header;
+ entry->vector[0].iov_len = sizeof (entry->header);
+ entry->count++;
+
+ entry->vector[1].iov_base = buf;
+ entry->vector[1].iov_len = len;
+ entry->count++;
+
+ if (vector && count) {
+ memcpy (&entry->vector[2], vector, sizeof (*vector) * count);
+ entry->count += count;
+ }
+
+ entry->pending_vector = entry->vector;
+ entry->pending_count = entry->count;
+
+ if (iobref)
+ entry->iobref = iobref_ref (iobref);
+
+ entry->buf = buf;
+
+ INIT_LIST_HEAD (&entry->list);
+
+ return entry;
+}
+
+
+static void
+__socket_ioq_entry_free (struct ioq *entry)
+{
+ list_del_init (&entry->list);
+ if (entry->iobref)
+ iobref_unref (entry->iobref);
+
+ /* TODO: use mem-pool */
+ GF_FREE (entry->buf);
+
+ /* TODO: use mem-pool */
+ GF_FREE (entry);
+}
+
+
+static void
+__socket_ioq_flush (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ struct ioq *entry = NULL;
+
+ priv = this->private;
+
+ while (!list_empty (&priv->ioq)) {
+ entry = priv->ioq_next;
+ __socket_ioq_entry_free (entry);
+ }
+
+ return;
+}
+
+
+static int
+__socket_ioq_churn_entry (transport_t *this, struct ioq *entry)
+{
+ int ret = -1;
+
+ ret = __socket_writev (this, entry->pending_vector,
+ entry->pending_count,
+ &entry->pending_vector,
+ &entry->pending_count);
+
+ if (ret == 0) {
+ /* current entry was completely written */
+ GF_ASSERT (entry->pending_count == 0);
+ __socket_ioq_entry_free (entry);
+ }
+
+ return ret;
+}
+
+
+static int
+__socket_ioq_churn (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = 0;
+ struct ioq *entry = NULL;
+
+ priv = this->private;
+
+ while (!list_empty (&priv->ioq)) {
+ /* pick next entry */
+ entry = priv->ioq_next;
+
+ ret = __socket_ioq_churn_entry (this, entry);
+
+ if (ret != 0)
+ break;
+ }
+
+ if (list_empty (&priv->ioq)) {
+ /* all pending writes done, not interested in POLLOUT */
+ priv->idx = event_select_on (this->xl->ctx->event_pool,
+ priv->sock, priv->idx, -1, 0);
+ }
+
+ return ret;
+}
+
+
+static int
+socket_event_poll_err (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ __socket_ioq_flush (this);
+ __socket_reset (this);
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ xlator_notify (this->xl, GF_EVENT_POLLERR, this);
+
+ return ret;
+}
+
+
+static int
+socket_event_poll_out (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->connected == 1) {
+ ret = __socket_ioq_churn (this);
+
+ if (ret == -1) {
+ __socket_disconnect (this);
+ }
+ }
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ xlator_notify (this->xl, GF_EVENT_POLLOUT, this);
+
+ return ret;
+}
+
+
+static int
+__socket_proto_validate_header (transport_t *this,
+ struct socket_header *header,
+ size_t *size1_p, size_t *size2_p)
+{
+ size_t size1 = 0;
+ size_t size2 = 0;
+
+ if (strcmp (header->colonO, ":O")) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "socket header signature does not match :O (%x.%x.%x)",
+ header->colonO[0], header->colonO[1],
+ header->colonO[2]);
+ return -1;
+ }
+
+ if (header->version != 42) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "socket header version does not match 42 != %d",
+ header->version);
+ return -1;
+ }
+
+ size1 = ntoh32 (header->size1);
+ size2 = ntoh32 (header->size2);
+
+ if (size1 <= 0 || size1 > 1048576) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "socket header has incorrect size1=%"GF_PRI_SIZET,
+ size1);
+ return -1;
+ }
+
+ if (size2 > (131072)) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "socket header has incorrect size2=%"GF_PRI_SIZET,
+ size2);
+ return -1;
+ }
+
+ if (size1_p)
+ *size1_p = size1;
+
+ if (size2_p)
+ *size2_p = size2;
+
+ return 0;
+}
+
+
+
+/* socket protocol state machine */
+
+static int
+__socket_proto_state_machine (transport_t *this)
+{
+ int ret = -1;
+ socket_private_t *priv = NULL;
+ size_t size1 = 0;
+ size_t size2 = 0;
+ int previous_state = -1;
+ struct socket_header *hdr = NULL;
+ struct iobuf *iobuf = NULL;
+
+
+ priv = this->private;
+
+ while (priv->incoming.state != SOCKET_PROTO_STATE_COMPLETE) {
+ /* debug check against infinite loops */
+ if (previous_state == priv->incoming.state) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "state did not change! (%d) breaking",
+ previous_state);
+ ret = -1;
+ goto unlock;
+ }
+ previous_state = priv->incoming.state;
+
+ switch (priv->incoming.state) {
+
+ case SOCKET_PROTO_STATE_NADA:
+ priv->incoming.pending_vector =
+ priv->incoming.vector;
+
+ priv->incoming.pending_vector->iov_base =
+ &priv->incoming.header;
+
+ priv->incoming.pending_vector->iov_len =
+ sizeof (struct socket_header);
+
+ priv->incoming.state =
+ SOCKET_PROTO_STATE_HEADER_COMING;
+ break;
+
+ case SOCKET_PROTO_STATE_HEADER_COMING:
+
+ ret = __socket_readv (this,
+ priv->incoming.pending_vector, 1,
+ &priv->incoming.pending_vector,
+ NULL);
+ if (ret == 0) {
+ priv->incoming.state =
+ SOCKET_PROTO_STATE_HEADER_CAME;
+ break;
+ }
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "read (%s) in state %d (%s)",
+ strerror (errno),
+ SOCKET_PROTO_STATE_HEADER_COMING,
+ this->peerinfo.identifier);
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial header read on NB socket.");
+ goto unlock;
+ }
+ break;
+
+ case SOCKET_PROTO_STATE_HEADER_CAME:
+ hdr = &priv->incoming.header;
+ ret = __socket_proto_validate_header (this, hdr,
+ &size1, &size2);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "socket header validate failed (%s). "
+ "possible mismatch of transport-type "
+ "between server and client volumes, "
+ "or version mismatch",
+ this->peerinfo.identifier);
+ goto unlock;
+ }
+
+ priv->incoming.hdrlen = size1;
+ priv->incoming.buflen = size2;
+
+ /* TODO: use mem-pool */
+ priv->incoming.hdr_p = GF_MALLOC (size1,
+ gf_common_mt_char);
+ if (size2) {
+ /* TODO: sanity check size2 < page size
+ */
+ iobuf = iobuf_get (this->xl->ctx->iobuf_pool);
+ if (!iobuf) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "unable to allocate IO buffer "
+ "for peer %s",
+ this->peerinfo.identifier);
+ ret = -ENOMEM;
+ goto unlock;
+ }
+ priv->incoming.iobuf = iobuf;
+ priv->incoming.buf_p = iobuf->ptr;
+ }
+
+ priv->incoming.vector[0].iov_base =
+ priv->incoming.hdr_p;
+
+ priv->incoming.vector[0].iov_len = size1;
+
+ priv->incoming.vector[1].iov_base =
+ priv->incoming.buf_p;
+
+ priv->incoming.vector[1].iov_len = size2;
+ priv->incoming.count = size2 ? 2 : 1;
+
+ priv->incoming.pending_vector =
+ priv->incoming.vector;
+
+ priv->incoming.pending_count =
+ priv->incoming.count;
+
+ priv->incoming.state =
+ SOCKET_PROTO_STATE_DATA_COMING;
+ break;
+
+ case SOCKET_PROTO_STATE_DATA_COMING:
+
+ ret = __socket_readv (this,
+ priv->incoming.pending_vector,
+ priv->incoming.pending_count,
+ &priv->incoming.pending_vector,
+ &priv->incoming.pending_count);
+ if (ret == 0) {
+ priv->incoming.state =
+ SOCKET_PROTO_STATE_DATA_CAME;
+ break;
+ }
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "read (%s) in state %d (%s)",
+ strerror (errno),
+ SOCKET_PROTO_STATE_DATA_COMING,
+ this->peerinfo.identifier);
+ goto unlock;
+ }
+
+ if (ret > 0) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "partial data read on NB socket");
+ goto unlock;
+ }
+ break;
+
+ case SOCKET_PROTO_STATE_DATA_CAME:
+ memset (&priv->incoming.vector, 0,
+ sizeof (priv->incoming.vector));
+ priv->incoming.pending_vector = NULL;
+ priv->incoming.pending_count = 0;
+ priv->incoming.state = SOCKET_PROTO_STATE_COMPLETE;
+ break;
+
+ case SOCKET_PROTO_STATE_COMPLETE:
+ /* not reached */
+ break;
+
+ default:
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "undefined state reached: %d",
+ priv->incoming.state);
+ goto unlock;
+ }
+ }
+unlock:
+
+ return ret;
+}
+
+
+static int
+socket_proto_state_machine (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = 0;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ ret = __socket_proto_state_machine (this);
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+static int
+socket_event_poll_in (transport_t *this)
+{
+ int ret = -1;
+
+ ret = socket_proto_state_machine (this);
+
+ /* call POLLIN on xlator even if complete block is not received,
+ just to keep the last_received timestamp ticking */
+
+ if (ret == 0)
+ ret = xlator_notify (this->xl, GF_EVENT_POLLIN, this);
+
+ return ret;
+}
+
+
+static int
+socket_connect_finish (transport_t *this)
+{
+ int ret = -1;
+ socket_private_t *priv = NULL;
+ int event = -1;
+ char notify_xlator = 0;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->connected)
+ goto unlock;
+
+ ret = __socket_connect_finish (priv->sock);
+
+ if (ret == -1 && errno == EINPROGRESS)
+ ret = 1;
+
+ if (ret == -1 && errno != EINPROGRESS) {
+ if (!priv->connect_finish_log) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connection to %s failed (%s)",
+ this->peerinfo.identifier,
+ strerror (errno));
+ priv->connect_finish_log = 1;
+ }
+ __socket_disconnect (this);
+ notify_xlator = 1;
+ event = GF_EVENT_POLLERR;
+ goto unlock;
+ }
+
+ if (ret == 0) {
+ notify_xlator = 1;
+
+ this->myinfo.sockaddr_len =
+ sizeof (this->myinfo.sockaddr);
+
+ ret = getsockname (priv->sock,
+ SA (&this->myinfo.sockaddr),
+ &this->myinfo.sockaddr_len);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "getsockname on (%d) failed (%s)",
+ priv->sock, strerror (errno));
+ __socket_disconnect (this);
+ event = GF_EVENT_POLLERR;
+ goto unlock;
+ }
+
+ priv->connected = 1;
+ priv->connect_finish_log = 0;
+ event = GF_EVENT_CHILD_UP;
+ gf_get_transport_identifiers (this);
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+ if (notify_xlator)
+ xlator_notify (this->xl, event, this);
+
+ return 0;
+}
+
+
+static int
+socket_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
+{
+ transport_t *this = NULL;
+ socket_private_t *priv = NULL;
+ int ret = 0;
+
+ this = data;
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ priv->idx = idx;
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ if (!priv->connected) {
+ ret = socket_connect_finish (this);
+ }
+
+ if (!ret && poll_out) {
+ ret = socket_event_poll_out (this);
+ }
+
+ if (!ret && poll_in) {
+ ret = socket_event_poll_in (this);
+ }
+
+ if (ret < 0 || poll_err) {
+ socket_event_poll_err (this);
+ transport_unref (this);
+ }
+
+ return 0;
+}
+
+
+static int
+socket_server_event_handler (int fd, int idx, void *data,
+ int poll_in, int poll_out, int poll_err)
+{
+ transport_t *this = NULL;
+ socket_private_t *priv = NULL;
+ int ret = 0;
+ int new_sock = -1;
+ transport_t *new_trans = NULL;
+ struct sockaddr_storage new_sockaddr = {0, };
+ socklen_t addrlen = sizeof (new_sockaddr);
+ socket_private_t *new_priv = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = data;
+ priv = this->private;
+ ctx = this->xl->ctx;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ priv->idx = idx;
+
+ if (poll_in) {
+ new_sock = accept (priv->sock, SA (&new_sockaddr),
+ &addrlen);
+
+ if (new_sock == -1)
+ goto unlock;
+
+ if (!priv->bio) {
+ ret = __socket_nonblock (new_sock);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "NBIO on %d failed (%s)",
+ new_sock, strerror (errno));
+ close (new_sock);
+ goto unlock;
+ }
+ }
+
+ if (priv->nodelay) {
+ ret = __socket_nodelay (new_sock);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setsockopt() failed for "
+ "NODELAY (%s)",
+ strerror (errno));
+ }
+ }
+
+ if (priv->keepalive) {
+ ret = __socket_keepalive (new_sock,
+ priv->keepaliveintvl);
+ if (ret == -1)
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "Failed to set keep-alive: %s",
+ strerror (errno));
+ }
+
+ new_trans = GF_CALLOC (1, sizeof (*new_trans),
+ gf_common_mt_transport_t);
+ new_trans->xl = this->xl;
+ new_trans->fini = this->fini;
+
+ memcpy (&new_trans->peerinfo.sockaddr, &new_sockaddr,
+ addrlen);
+ new_trans->peerinfo.sockaddr_len = addrlen;
+
+ new_trans->myinfo.sockaddr_len =
+ sizeof (new_trans->myinfo.sockaddr);
+
+ ret = getsockname (new_sock,
+ SA (&new_trans->myinfo.sockaddr),
+ &new_trans->myinfo.sockaddr_len);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "getsockname on %d failed (%s)",
+ new_sock, strerror (errno));
+ close (new_sock);
+ goto unlock;
+ }
+
+ gf_get_transport_identifiers (new_trans);
+ socket_init (new_trans);
+ new_trans->ops = this->ops;
+ new_trans->init = this->init;
+ new_trans->fini = this->fini;
+
+ new_priv = new_trans->private;
+
+ pthread_mutex_lock (&new_priv->lock);
+ {
+ new_priv->sock = new_sock;
+ new_priv->connected = 1;
+
+ transport_ref (new_trans);
+ new_priv->idx =
+ event_register (ctx->event_pool,
+ new_sock,
+ socket_event_handler,
+ new_trans, 1, 0);
+
+ if (new_priv->idx == -1)
+ ret = -1;
+ }
+ pthread_mutex_unlock (&new_priv->lock);
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+static int
+socket_disconnect (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ ret = __socket_disconnect (this);
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+static int
+socket_connect (transport_t *this)
+{
+ int ret = -1;
+ int sock = -1;
+ socket_private_t *priv = NULL;
+ struct sockaddr_storage sockaddr = {0, };
+ socklen_t sockaddr_len = 0;
+ glusterfs_ctx_t *ctx = NULL;
+ sa_family_t sa_family = {0, };
+
+ priv = this->private;
+ ctx = this->xl->ctx;
+
+ if (!priv) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "connect() called on uninitialized transport");
+ goto err;
+ }
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ sock = priv->sock;
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ if (sock != -1) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "connect () called on transport already connected");
+ ret = 0;
+ goto err;
+ }
+
+ ret = gf_socket_client_get_remote_sockaddr (this, SA (&sockaddr),
+ &sockaddr_len, &sa_family);
+ if (ret == -1) {
+ /* logged inside client_get_remote_sockaddr */
+ goto err;
+ }
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->sock != -1) {
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "connect() -- already connected");
+ goto unlock;
+ }
+
+ memcpy (&this->peerinfo.sockaddr, &sockaddr, sockaddr_len);
+ this->peerinfo.sockaddr_len = sockaddr_len;
+
+ priv->sock = socket (sa_family, SOCK_STREAM, 0);
+ if (priv->sock == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "socket creation failed (%s)",
+ strerror (errno));
+ goto unlock;
+ }
+
+ /* Cant help if setting socket options fails. We can continue
+ * working nonetheless.
+ */
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setting receive window size failed: %d: %d: "
+ "%s", priv->sock, priv->windowsize,
+ strerror (errno));
+ }
+
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setting send window size failed: %d: %d: "
+ "%s", priv->sock, priv->windowsize,
+ strerror (errno));
+ }
+
+
+ if (priv->nodelay && priv->lowlat) {
+ ret = __socket_nodelay (priv->sock);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setsockopt() failed for NODELAY (%s)",
+ strerror (errno));
+ }
+ }
+
+ if (!priv->bio) {
+ ret = __socket_nonblock (priv->sock);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "NBIO on %d failed (%s)",
+ priv->sock, strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+ }
+
+ if (priv->keepalive) {
+ ret = __socket_keepalive (priv->sock,
+ priv->keepaliveintvl);
+ if (ret == -1)
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "Failed to set keep-alive: %s",
+ strerror (errno));
+ }
+
+ SA (&this->myinfo.sockaddr)->sa_family =
+ SA (&this->peerinfo.sockaddr)->sa_family;
+
+ ret = gf_client_bind (this, SA (&this->myinfo.sockaddr),
+ &this->myinfo.sockaddr_len, priv->sock);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_WARNING,
+ "client bind failed: %s", strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ ret = connect (priv->sock, SA (&this->peerinfo.sockaddr),
+ this->peerinfo.sockaddr_len);
+
+ if (ret == -1 && errno != EINPROGRESS) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "connection attempt failed (%s)",
+ strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ priv->connected = 0;
+
+ transport_ref (this);
+
+ priv->idx = event_register (ctx->event_pool, priv->sock,
+ socket_event_handler, this, 1, 1);
+ if (priv->idx == -1)
+ ret = -1;
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+err:
+ return ret;
+}
+
+
+static int
+socket_listen (transport_t *this)
+{
+ socket_private_t * priv = NULL;
+ int ret = -1;
+ int sock = -1;
+ struct sockaddr_storage sockaddr;
+ socklen_t sockaddr_len;
+ peer_info_t *myinfo = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ sa_family_t sa_family = {0, };
+
+ priv = this->private;
+ myinfo = &this->myinfo;
+ ctx = this->xl->ctx;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ sock = priv->sock;
+ }
+ pthread_mutex_unlock (&priv->lock);
+
+ if (sock != -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "alreading listening");
+ return ret;
+ }
+
+ ret = gf_socket_server_get_local_sockaddr (this, SA (&sockaddr),
+ &sockaddr_len, &sa_family);
+ if (ret == -1) {
+ return ret;
+ }
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->sock != -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "already listening");
+ goto unlock;
+ }
+
+ memcpy (&myinfo->sockaddr, &sockaddr, sockaddr_len);
+ myinfo->sockaddr_len = sockaddr_len;
+
+ priv->sock = socket (sa_family, SOCK_STREAM, 0);
+
+ if (priv->sock == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "socket creation failed (%s)",
+ strerror (errno));
+ goto unlock;
+ }
+
+ /* Cant help if setting socket options fails. We can continue
+ * working nonetheless.
+ */
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_RCVBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setting receive window size failed: %d: %d: "
+ "%s", priv->sock, priv->windowsize,
+ strerror (errno));
+ }
+
+ if (setsockopt (priv->sock, SOL_SOCKET, SO_SNDBUF,
+ &priv->windowsize,
+ sizeof (priv->windowsize)) < 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setting send window size failed: %d: %d: "
+ "%s", priv->sock, priv->windowsize,
+ strerror (errno));
+ }
+
+ if (priv->nodelay) {
+ ret = __socket_nodelay (priv->sock);
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "setsockopt() failed for NODELAY (%s)",
+ strerror (errno));
+ }
+ }
+
+ if (!priv->bio) {
+ ret = __socket_nonblock (priv->sock);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "NBIO on %d failed (%s)",
+ priv->sock, strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+ }
+
+ ret = __socket_server_bind (this);
+
+ if (ret == -1) {
+ /* logged inside __socket_server_bind() */
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ ret = listen (priv->sock, 10);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "could not set socket %d to listen mode (%s)",
+ priv->sock, strerror (errno));
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+
+ transport_ref (this);
+
+ priv->idx = event_register (ctx->event_pool, priv->sock,
+ socket_server_event_handler,
+ this, 1, 0);
+
+ if (priv->idx == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "could not register socket %d with events",
+ priv->sock);
+ ret = -1;
+ close (priv->sock);
+ priv->sock = -1;
+ goto unlock;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+static int
+socket_receive (transport_t *this, char **hdr_p, size_t *hdrlen_p,
+ struct iobuf **iobuf_p)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->connected != 1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "socket not connected to receive");
+ goto unlock;
+ }
+
+ if (!hdr_p || !hdrlen_p || !iobuf_p) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "bad parameters %p %p %p",
+ hdr_p, hdrlen_p, iobuf_p);
+ goto unlock;
+ }
+
+ if (priv->incoming.state == SOCKET_PROTO_STATE_COMPLETE) {
+ *hdr_p = priv->incoming.hdr_p;
+ *hdrlen_p = priv->incoming.hdrlen;
+ *iobuf_p = priv->incoming.iobuf;
+
+ memset (&priv->incoming, 0, sizeof (priv->incoming));
+ priv->incoming.state = SOCKET_PROTO_STATE_NADA;
+
+ ret = 0;
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+/* TODO: implement per transfer limit */
+static int
+socket_submit (transport_t *this, char *buf, int len,
+ struct iovec *vector, int count,
+ struct iobref *iobref)
+{
+ socket_private_t *priv = NULL;
+ int ret = -1;
+ char need_poll_out = 0;
+ char need_append = 1;
+ struct ioq *entry = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ priv = this->private;
+ ctx = this->xl->ctx;
+
+ pthread_mutex_lock (&priv->lock);
+ {
+ if (priv->connected != 1) {
+ if (!priv->submit_log && !priv->connect_finish_log) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "not connected (priv->connected = %d)",
+ priv->connected);
+ priv->submit_log = 1;
+ }
+ goto unlock;
+ }
+
+ priv->submit_log = 0;
+ entry = __socket_ioq_new (this, buf, len, vector, count, iobref);
+ if (!entry)
+ goto unlock;
+
+ if (list_empty (&priv->ioq)) {
+ ret = __socket_ioq_churn_entry (this, entry);
+
+ if (ret == 0)
+ need_append = 0;
+
+ if (ret > 0)
+ need_poll_out = 1;
+ }
+
+ if (need_append) {
+ list_add_tail (&entry->list, &priv->ioq);
+ ret = 0;
+ }
+
+ if (need_poll_out) {
+ /* first entry to wait. continue writing on POLLOUT */
+ priv->idx = event_select_on (ctx->event_pool,
+ priv->sock,
+ priv->idx, -1, 1);
+ }
+ }
+unlock:
+ pthread_mutex_unlock (&priv->lock);
+
+ return ret;
+}
+
+
+struct transport_ops tops = {
+ .listen = socket_listen,
+ .connect = socket_connect,
+ .disconnect = socket_disconnect,
+ .submit = socket_submit,
+ .receive = socket_receive
+};
+
+
+static int
+socket_init (transport_t *this)
+{
+ socket_private_t *priv = NULL;
+ gf_boolean_t tmp_bool = 0;
+ uint64_t windowsize = GF_DEFAULT_SOCKET_WINDOW_SIZE;
+ char *optstr = NULL;
+ uint32_t keepalive = 0;
+
+ if (this->private) {
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "double init attempted");
+ return -1;
+ }
+
+ priv = GF_CALLOC (1, sizeof (*priv),
+ gf_common_mt_socket_private_t);
+ if (!priv) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "calloc (1, %"GF_PRI_SIZET") returned NULL",
+ sizeof (*priv));
+ return -1;
+ }
+
+ pthread_mutex_init (&priv->lock, NULL);
+
+ priv->sock = -1;
+ priv->idx = -1;
+ priv->connected = -1;
+
+ INIT_LIST_HEAD (&priv->ioq);
+
+ if (dict_get (this->xl->options, "non-blocking-io")) {
+ optstr = data_to_str (dict_get (this->xl->options,
+ "non-blocking-io"));
+
+ if (gf_string2boolean (optstr, &tmp_bool) == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "'non-blocking-io' takes only boolean options,"
+ " not taking any action");
+ tmp_bool = 1;
+ }
+ priv->bio = 0;
+ if (!tmp_bool) {
+ priv->bio = 1;
+ gf_log (this->xl->name, GF_LOG_WARNING,
+ "disabling non-blocking IO");
+ }
+ }
+
+ optstr = NULL;
+
+ // By default, we enable NODELAY
+ priv->nodelay = 1;
+ if (dict_get (this->xl->options, "transport.socket.nodelay")) {
+ optstr = data_to_str (dict_get (this->xl->options,
+ "transport.socket.nodelay"));
+
+ if (gf_string2boolean (optstr, &tmp_bool) == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "'transport.socket.nodelay' takes only "
+ "boolean options, not taking any action");
+ tmp_bool = 1;
+ }
+ if (!tmp_bool) {
+ priv->nodelay = 0;
+ gf_log (this->xl->name, GF_LOG_DEBUG,
+ "disabling nodelay");
+ }
+ }
+
+
+ optstr = NULL;
+ if (dict_get_str (this->xl->options, "transport.window-size",
+ &optstr) == 0) {
+ if (gf_string2bytesize (optstr, &windowsize) != 0) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "invalid number format: %s", optstr);
+ return -1;
+ }
+ }
+
+ optstr = NULL;
+
+ if (dict_get_str (this->xl->options, "transport.socket.lowlat",
+ &optstr) == 0) {
+ priv->lowlat = 1;
+ }
+
+ /* Enable Keep-alive by default. */
+ priv->keepalive = 1;
+ priv->keepaliveintvl = GF_USE_DEFAULT_KEEPALIVE;
+ if (dict_get_str (this->xl->options, "transport.socket.keepalive",
+ &optstr) == 0) {
+ if (gf_string2boolean (optstr, &tmp_bool) == -1) {
+ gf_log (this->xl->name, GF_LOG_ERROR,
+ "'transport.socket.keepalive' takes only "
+ "boolean options, not taking any action");
+ tmp_bool = 1;
+ }
+
+ if (!tmp_bool)
+ priv->keepalive = 0;
+
+ }
+
+ if (dict_get_uint32 (this->xl->options,
+ "transport.socket.keepalive-interval",
+ &keepalive) == 0) {
+ priv->keepaliveintvl = keepalive;
+ }
+
+ priv->windowsize = (int)windowsize;
+ this->private = priv;
+
+ return 0;
+}
+
+
+void
+fini (transport_t *this)
+{
+ socket_private_t *priv = this->private;
+
+ if (!priv)
+ return;
+ this->private = NULL;
+ gf_log (this->xl->name, GF_LOG_TRACE,
+ "transport %p destroyed", this);
+
+ pthread_mutex_destroy (&priv->lock);
+ GF_FREE (priv);
+}
+
+
+int32_t
+init (transport_t *this)
+{
+ int ret = -1;
+
+ ret = socket_init (this);
+
+ if (ret == -1) {
+ gf_log (this->xl->name, GF_LOG_DEBUG, "socket_init() failed");
+ }
+
+ return ret;
+}
+
+struct volume_options options[] = {
+ { .key = {"remote-port",
+ "transport.remote-port",
+ "transport.socket.remote-port"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.socket.listen-port", "listen-port"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {"transport.socket.bind-address", "bind-address" },
+ .type = GF_OPTION_TYPE_INTERNET_ADDRESS
+ },
+ { .key = {"transport.socket.connect-path", "connect-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport.socket.bind-path", "bind-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {"transport.socket.listen-path", "listen-path"},
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = { "transport.address-family",
+ "address-family" },
+ .value = {"inet", "inet6", "inet/inet6", "inet6/inet",
+ "unix", "inet-sdp" },
+ .type = GF_OPTION_TYPE_STR
+ },
+
+ { .key = {"non-blocking-io"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"transport.window-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = GF_MIN_SOCKET_WINDOW_SIZE,
+ .max = GF_MAX_SOCKET_WINDOW_SIZE,
+ },
+ { .key = {"transport.socket.nodelay"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"transport.socket.lowlat"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"transport.socket.keepalive"},
+ .type = GF_OPTION_TYPE_BOOL
+ },
+ { .key = {"transport.socket.keepalive-interval"},
+ .type = GF_OPTION_TYPE_INT
+ },
+ { .key = {NULL} }
+};
+
diff --git a/xlators/protocol/legacy/transport/socket/src/socket.h b/xlators/protocol/legacy/transport/socket/src/socket.h
new file mode 100644
index 000000000..aa25e08b7
--- /dev/null
+++ b/xlators/protocol/legacy/transport/socket/src/socket.h
@@ -0,0 +1,129 @@
+/*
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SOCKET_H
+#define _SOCKET_H
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "event.h"
+#include "transport.h"
+#include "logging.h"
+#include "dict.h"
+#include "mem-pool.h"
+#include "socket-mem-types.h"
+
+#ifndef MAX_IOVEC
+#define MAX_IOVEC 16
+#endif /* MAX_IOVEC */
+
+#define GF_DEFAULT_SOCKET_LISTEN_PORT 6996
+
+/* This is the size set through setsockopt for
+ * both the TCP receive window size and the
+ * send buffer size.
+ * Till the time iobuf size becomes configurable, this size is set to include
+ * two iobufs + the GlusterFS protocol headers.
+ * Linux allows us to over-ride the max values for the system.
+ * Should we over-ride them? Because if we set a value larger than the default
+ * setsockopt will fail. Having larger values might be beneficial for
+ * IB links.
+ */
+#define GF_DEFAULT_SOCKET_WINDOW_SIZE (512 * GF_UNIT_KB)
+#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
+#define GF_MIN_SOCKET_WINDOW_SIZE (128 * GF_UNIT_KB)
+
+#define GF_USE_DEFAULT_KEEPALIVE (-1)
+
+typedef enum {
+ SOCKET_PROTO_STATE_NADA = 0,
+ SOCKET_PROTO_STATE_HEADER_COMING,
+ SOCKET_PROTO_STATE_HEADER_CAME,
+ SOCKET_PROTO_STATE_DATA_COMING,
+ SOCKET_PROTO_STATE_DATA_CAME,
+ SOCKET_PROTO_STATE_COMPLETE,
+} socket_proto_state_t;
+
+struct socket_header {
+ char colonO[3];
+ uint32_t size1;
+ uint32_t size2;
+ char version;
+} __attribute__((packed));
+
+
+struct ioq {
+ union {
+ struct list_head list;
+ struct {
+ struct ioq *next;
+ struct ioq *prev;
+ };
+ };
+ struct socket_header header;
+ struct iovec vector[MAX_IOVEC];
+ int count;
+ struct iovec *pending_vector;
+ int pending_count;
+ char *buf;
+ struct iobref *iobref;
+};
+
+
+typedef struct {
+ int32_t sock;
+ int32_t idx;
+ unsigned char connected; // -1 = not connected. 0 = in progress. 1 = connected
+ char bio;
+ char connect_finish_log;
+ char submit_log;
+ union {
+ struct list_head ioq;
+ struct {
+ struct ioq *ioq_next;
+ struct ioq *ioq_prev;
+ };
+ };
+ struct {
+ int state;
+ struct socket_header header;
+ char *hdr_p;
+ size_t hdrlen;
+ struct iobuf *iobuf;
+ char *buf_p;
+ size_t buflen;
+ struct iovec vector[2];
+ int count;
+ struct iovec *pending_vector;
+ int pending_count;
+ } incoming;
+ pthread_mutex_t lock;
+ int windowsize;
+ char lowlat;
+ char nodelay;
+ int keepalive;
+ int keepaliveintvl;
+} socket_private_t;
+
+
+#endif
diff --git a/xlators/protocol/server/src/Makefile.am b/xlators/protocol/server/src/Makefile.am
index 0b706cf85..72a581ddf 100644
--- a/xlators/protocol/server/src/Makefile.am
+++ b/xlators/protocol/server/src/Makefile.am
@@ -8,7 +8,7 @@ server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la
server_la_SOURCES = server.c server-resolve.c server-helpers.c \
- server-rpc-fops.c server-handshake.c authenticate.c
+ server3_1-fops.c server-handshake.c authenticate.c
noinst_HEADERS = server.h server-helpers.h server-mem-types.h authenticate.h
@@ -18,6 +18,7 @@ AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall \
-DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \
$(GF_CFLAGS) -I$(top_srcdir)/xlators/protocol/lib/src \
-I$(top_srcdir)/rpc/rpc-lib/src/ \
- -I$(top_srcdir)/rpc/xdr/src/
+ -I$(top_srcdir)/rpc/xdr/src/ \
+ -I$(top_srcdir)/contrib/md5/
CLEANFILES = *~
diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c
index d1cdebdee..5a1c2a8c8 100644
--- a/xlators/protocol/server/src/authenticate.c
+++ b/xlators/protocol/server/src/authenticate.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -34,12 +34,12 @@
static void
init (dict_t *this, char *key, data_t *value, void *data)
{
- void *handle = NULL;
- char *auth_file = NULL;
- auth_handle_t *auth_handle = NULL;
- auth_fn_t authenticate = NULL;
- int *error = NULL;
- int ret = 0;
+ void *handle = NULL;
+ char *auth_file = NULL;
+ auth_handle_t *auth_handle = NULL;
+ auth_fn_t authenticate = NULL;
+ int *error = NULL;
+ int ret = 0;
/* It gets over written */
error = data;
@@ -78,7 +78,6 @@ init (dict_t *this, char *key, data_t *value, void *data)
gf_log ("authenticate", GF_LOG_ERROR,
"dlsym(gf_auth) on %s\n", dlerror ());
dict_set (this, key, data_from_dynptr (NULL, 0));
- dlclose (handle);
*error = -1;
return;
}
@@ -88,18 +87,10 @@ init (dict_t *this, char *key, data_t *value, void *data)
if (!auth_handle) {
dict_set (this, key, data_from_dynptr (NULL, 0));
*error = -1;
- dlclose (handle);
return;
}
auth_handle->vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
gf_common_mt_volume_opt_list_t);
- if (!auth_handle->vol_opt) {
- dict_set (this, key, data_from_dynptr (NULL, 0));
- *error = -1;
- GF_FREE (auth_handle);
- dlclose (handle);
- return;
- }
auth_handle->vol_opt->given_opt = dlsym (handle, "options");
if (auth_handle->vol_opt->given_opt == NULL) {
gf_log ("authenticate", GF_LOG_DEBUG,
@@ -143,9 +134,8 @@ gf_auth_init (xlator_t *xl, dict_t *auth_modules)
list_add_tail (&(handle->vol_opt->list),
&(xl->volume_options));
- ret = xlator_options_validate_list (xl, xl->options,
- handle->vol_opt, NULL);
-
+ ret = validate_xlator_volume_options (xl,
+ handle->vol_opt->given_opt);
if (ret)
gf_log ("authenticate", GF_LOG_ERROR,
"volume option validation failed");
diff --git a/xlators/protocol/server/src/authenticate.h b/xlators/protocol/server/src/authenticate.h
index bb9f77e45..7c9dd58d2 100644
--- a/xlators/protocol/server/src/authenticate.h
+++ b/xlators/protocol/server/src/authenticate.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2007-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
index 04662b403..66b9ea78d 100644
--- a/xlators/protocol/server/src/server-handshake.c
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -40,7 +40,7 @@ gf_compare_client_version (rpcsvc_request_t *req, int fop_prognum,
{
int ret = -1;
/* TODO: think.. */
- if (glusterfs3_3_fop_prog.prognum == fop_prognum)
+ if (glusterfs3_1_fop_prog.prognum == fop_prognum)
ret = 0;
return ret;
@@ -190,7 +190,7 @@ int
_validate_volfile_checksum (xlator_t *this, char *key,
uint32_t checksum)
{
- char filename[PATH_MAX] = {0,};
+ char filename[ZR_PATH_MAX] = {0,};
server_conf_t *conf = NULL;
struct _volfile_ctx *temp_volfile = NULL;
int ret = 0;
@@ -253,7 +253,7 @@ server_getspec (rpcsvc_request_t *req)
int32_t op_errno = ENOENT;
int32_t spec_fd = -1;
size_t file_len = 0;
- char filename[PATH_MAX] = {0,};
+ char filename[ZR_PATH_MAX] = {0,};
struct stat stbuf = {0,};
uint32_t checksum = 0;
char *key = NULL;
@@ -261,10 +261,12 @@ server_getspec (rpcsvc_request_t *req)
xlator_t *this = NULL;
gf_getspec_req args = {0,};
gf_getspec_rsp rsp = {0,};
+ server_connection_t *conn = NULL;
+ conn = req->trans->private;
this = req->svc->mydata;
conf = this->private;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_getspec_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_getspec_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
op_errno = EINVAL;
@@ -311,6 +313,8 @@ server_getspec (rpcsvc_request_t *req)
goto fail;
}
ret = read (spec_fd, rsp.spec, file_len);
+
+ close (spec_fd);
}
/* convert to XDR */
@@ -321,11 +325,8 @@ fail:
rsp.op_errno = gf_errno_to_error (op_errno);
rsp.op_ret = ret;
- if (spec_fd != -1)
- close (spec_fd);
-
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_getspec_rsp);
+ (gfs_serialize_t)xdr_serialize_getspec_rsp);
return 0;
}
@@ -344,7 +345,6 @@ server_setvolume (rpcsvc_request_t *req)
dict_t *params = NULL;
char *name = NULL;
char *process_uuid = NULL;
- char *clnt_version = NULL;
xlator_t *xl = NULL;
char *msg = NULL;
char *volfile_key = NULL;
@@ -355,13 +355,11 @@ server_setvolume (rpcsvc_request_t *req)
int32_t op_errno = EINVAL;
int32_t fop_version = 0;
int32_t mgmt_version = 0;
- uint32_t lk_version = 0;
char *buf = NULL;
- gf_boolean_t cancelled = _gf_false;
params = dict_new ();
reply = dict_new ();
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gf_setvolume_req)) {
+ if (xdr_to_glusterfs_req (req, &args, xdr_to_setvolume_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto fail;
@@ -411,37 +409,8 @@ server_setvolume (rpcsvc_request_t *req)
goto fail;
}
- /*lk_verion :: [1..2^31-1]*/
- ret = dict_get_uint32 (params, "clnt-lk-version", &lk_version);
- if (ret < 0) {
- ret = dict_set_str (reply, "ERROR",
- "lock state version not supplied");
- if (ret < 0)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set error msg");
-
- op_ret = -1;
- op_errno = EINVAL;
- goto fail;
- }
conn = server_connection_get (this, process_uuid);
- if (!conn) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto fail;
- }
-
- gf_log (this->name, GF_LOG_DEBUG, "Connected to %s", conn->id);
- cancelled = server_cancel_conn_timer (this, conn);
- if (cancelled)//Do connection_put on behalf of grace-timer-handler.
- server_connection_put (this, conn, NULL);
- if (conn->lk_version != 0 &&
- conn->lk_version != lk_version) {
- (void) server_connection_cleanup (this, conn,
- INTERNAL_LOCKS | POSIX_LOCKS);
- }
-
if (req->trans->xl_private != conn)
req->trans->xl_private = conn;
@@ -556,20 +525,13 @@ server_setvolume (rpcsvc_request_t *req)
"Authentication module not initialized");
}
- ret = dict_get_str (params, "client-version", &clnt_version);
- if (ret)
- gf_log (this->name, GF_LOG_INFO, "client-version not set, "
- "may be of older version");
-
ret = gf_authenticate (params, config_params,
conf->auth_modules);
if (ret == AUTH_ACCEPT) {
-
gf_log (this->name, GF_LOG_INFO,
- "accepted client from %s (version: %s)",
- conn->id,
- (clnt_version) ? clnt_version : "old");
+ "accepted client from %s",
+ (peerinfo)?peerinfo->identifier:"");
op_ret = 0;
conn->bound_xl = xl;
ret = dict_set_str (reply, "ERROR", "Success");
@@ -578,10 +540,8 @@ server_setvolume (rpcsvc_request_t *req)
"failed to set error msg");
} else {
gf_log (this->name, GF_LOG_ERROR,
- "Cannot authenticate client from %s %s",
- conn->id,
- (clnt_version) ? clnt_version : "old");
-
+ "Cannot authenticate client from %s",
+ (peerinfo)? peerinfo->identifier:"<>");
op_ret = -1;
op_errno = EACCES;
ret = dict_set_str (reply, "ERROR", "Authentication failed");
@@ -627,12 +587,6 @@ server_setvolume (rpcsvc_request_t *req)
gf_log (this->name, GF_LOG_DEBUG,
"failed to set 'process-uuid'");
- ret = dict_set_uint32 (reply, "clnt-lk-version",
- conn->lk_version);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING,
- "failed to set 'clnt-lk-version'");
-
ret = dict_set_uint64 (reply, "transport-ptr",
((uint64_t) (long) req->trans));
if (ret)
@@ -666,18 +620,22 @@ fail:
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_setvolume_rsp);
+ (gfs_serialize_t)xdr_serialize_setvolume_rsp);
- free (args.dict.dict_val);
+ if (args.dict.dict_val)
+ free (args.dict.dict_val);
- GF_FREE (rsp.dict.dict_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
dict_unref (params);
dict_unref (reply);
dict_unref (config_params);
- GF_FREE (buf);
+ if (buf) {
+ GF_FREE (buf);
+ }
return 0;
}
@@ -692,58 +650,17 @@ server_ping (rpcsvc_request_t *req)
rsp.op_ret = 0;
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ xdr_serialize_common_rsp);
return 0;
}
-int
-server_set_lk_version (rpcsvc_request_t *req)
-{
- int op_ret = -1;
- int op_errno = EINVAL;
- gf_set_lk_ver_req args = {0, };
- gf_set_lk_ver_rsp rsp = {0,};
- server_connection_t *conn = NULL;
- xlator_t *this = NULL;
-
- this = req->svc->mydata;
- //TODO: Decide on an appropriate errno for the error-path
- //below
- if (!this)
- goto fail;
-
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gf_set_lk_ver_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto fail;
- }
-
- conn = server_connection_get (this, args.uid);
- conn->lk_version = args.lk_ver;
- server_connection_put (this, conn, NULL);
-
- rsp.lk_ver = args.lk_ver;
-
- op_ret = 0;
-fail:
- rsp.op_ret = op_ret;
- rsp.op_errno = op_errno;
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_set_lk_ver_rsp);
-
- free (args.uid);
-
- return 0;
-}
rpcsvc_actor_t gluster_handshake_actors[] = {
- [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, NULL, 0},
- [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, NULL, 0},
- [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, NULL, 0},
- [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, NULL, 0},
- [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, NULL },
+ [GF_HNDSK_NULL] = {"NULL", GF_HNDSK_NULL, server_null, NULL, NULL },
+ [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, NULL },
+ [GF_HNDSK_GETSPEC] = {"GETSPEC", GF_HNDSK_GETSPEC, server_getspec, NULL, NULL },
+ [GF_HNDSK_PING] = {"PING", GF_HNDSK_PING, server_ping, NULL, NULL },
};
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 3a7bb4aea..1abe4d2d8 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -39,7 +39,7 @@ server_decode_groups (call_frame_t *frame, rpcsvc_request_t *req)
if (frame->root->ngrps == 0)
return 0;
- if (frame->root->ngrps > GF_MAX_AUX_GROUPS)
+ if (frame->root->ngrps > GF_REQUEST_MAXGROUPS)
return -1;
for (; i < frame->root->ngrps; ++i)
@@ -61,18 +61,36 @@ server_loc_wipe (loc_t *loc)
loc->inode = NULL;
}
- GF_FREE ((void *)loc->path);
+ if (loc->path)
+ GF_FREE ((void *)loc->path);
}
void
server_resolve_wipe (server_resolve_t *resolve)
{
- GF_FREE ((void *)resolve->path);
+ struct resolve_comp *comp = NULL;
+ int i = 0;
+
+ if (resolve->path)
+ GF_FREE ((void *)resolve->path);
+
+ if (resolve->bname)
+ GF_FREE ((void *)resolve->bname);
+
+ if (resolve->resolved)
+ GF_FREE ((void *)resolve->resolved);
- GF_FREE ((void *)resolve->bname);
+ loc_wipe (&resolve->deep_loc);
- loc_wipe (&resolve->resolve_loc);
+ comp = resolve->components;
+ if (comp) {
+ for (i = 0; comp[i].basename; i++) {
+ if (comp[i].inode)
+ inode_unref (comp[i].inode);
+ }
+ GF_FREE ((void *)resolve->components);
+ }
}
@@ -113,14 +131,11 @@ free_state (server_state_t *state)
state->dict = NULL;
}
- if (state->xdata) {
- dict_unref (state->xdata);
- state->xdata = NULL;
- }
-
- GF_FREE ((void *)state->volume);
+ if (state->volume)
+ GF_FREE ((void *)state->volume);
- GF_FREE ((void *)state->name);
+ if (state->name)
+ GF_FREE ((void *)state->name);
server_loc_wipe (&state->loc);
server_loc_wipe (&state->loc2);
@@ -133,14 +148,14 @@ free_state (server_state_t *state)
int
-gf_add_locker (server_connection_t *conn, const char *volume,
- loc_t *loc, fd_t *fd, pid_t pid, gf_lkowner_t *owner,
+gf_add_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc, fd_t *fd, pid_t pid, uint64_t owner,
glusterfs_fop_t type)
{
int32_t ret = -1;
struct _locker *new = NULL;
- struct _lock_table *table = NULL;
+ GF_VALIDATE_OR_GOTO ("server", table, out);
GF_VALIDATE_OR_GOTO ("server", volume, out);
new = GF_CALLOC (1, sizeof (struct _locker), gf_server_mt_locker_t);
@@ -158,39 +173,38 @@ gf_add_locker (server_connection_t *conn, const char *volume,
}
new->pid = pid;
- new->owner = *owner;
+ new->owner = owner;
- pthread_mutex_lock (&conn->lock);
+ LOCK (&table->lock);
{
- table = conn->ltable;
if (type == GF_FOP_ENTRYLK)
list_add_tail (&new->lockers, &table->entrylk_lockers);
else
list_add_tail (&new->lockers, &table->inodelk_lockers);
}
- pthread_mutex_unlock (&conn->lock);
+ UNLOCK (&table->lock);
out:
return ret;
}
int
-gf_del_locker (server_connection_t *conn, const char *volume,
- loc_t *loc, fd_t *fd, gf_lkowner_t *owner,
- glusterfs_fop_t type)
+gf_del_locker (struct _lock_table *table, const char *volume,
+ loc_t *loc, fd_t *fd, uint64_t owner, glusterfs_fop_t type)
{
struct _locker *locker = NULL;
struct _locker *tmp = NULL;
int32_t ret = -1;
struct list_head *head = NULL;
- struct _lock_table *table = NULL;
- int found = 0;
+ struct list_head del;
+ GF_VALIDATE_OR_GOTO ("server", table, out);
GF_VALIDATE_OR_GOTO ("server", volume, out);
- pthread_mutex_lock (&conn->lock);
+ INIT_LIST_HEAD (&del);
+
+ LOCK (&table->lock);
{
- table = conn->ltable;
if (type == GF_FOP_ENTRYLK) {
head = &table->entrylk_lockers;
} else {
@@ -198,26 +212,26 @@ gf_del_locker (server_connection_t *conn, const char *volume,
}
list_for_each_entry_safe (locker, tmp, head, lockers) {
- if (!is_same_lkowner (&locker->owner, owner) ||
- strcmp (locker->volume, volume))
- continue;
-
- if (locker->fd && fd && (locker->fd == fd))
- found = 1;
- else if (locker->loc.inode && loc &&
- (locker->loc.inode == loc->inode))
- found = 1;
- if (found) {
- list_del_init (&locker->lockers);
- break;
+ if (locker->fd && fd &&
+ (locker->fd == fd) && (locker->owner == owner)
+ && !strcmp (locker->volume, volume)) {
+ list_move_tail (&locker->lockers, &del);
+ } else if (locker->loc.inode &&
+ loc &&
+ (locker->loc.inode == loc->inode) &&
+ (locker->owner == owner)
+ && !strcmp (locker->volume, volume)) {
+ list_move_tail (&locker->lockers, &del);
}
}
- if (!found)
- locker = NULL;
}
- pthread_mutex_unlock (&conn->lock);
+ UNLOCK (&table->lock);
+
+ tmp = NULL;
+ locker = NULL;
- if (locker) {
+ list_for_each_entry_safe (locker, tmp, &del, lockers) {
+ list_del_init (&locker->lockers);
if (locker->fd)
fd_unref (locker->fd);
else
@@ -243,13 +257,14 @@ gf_lock_table_new (void)
}
INIT_LIST_HEAD (&new->entrylk_lockers);
INIT_LIST_HEAD (&new->inodelk_lockers);
+ LOCK_INIT (&new->lock);
out:
return new;
}
static int
server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
int ret = -1;
server_state_t *state = NULL;
@@ -258,8 +273,6 @@ server_nop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
GF_VALIDATE_OR_GOTO ("server", cookie, out);
GF_VALIDATE_OR_GOTO ("server", this, out);
- if (frame->root->trans)
- server_conn_unref (frame->root->trans);
state = CALL_STATE(frame);
if (state)
@@ -292,10 +305,15 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
INIT_LIST_HEAD (&inodelk_lockers);
INIT_LIST_HEAD (&entrylk_lockers);
- list_splice_init (&ltable->inodelk_lockers,
- &inodelk_lockers);
+ LOCK (&ltable->lock);
+ {
+ list_splice_init (&ltable->inodelk_lockers,
+ &inodelk_lockers);
+
+ list_splice_init (&ltable->entrylk_lockers, &entrylk_lockers);
+ }
+ UNLOCK (&ltable->lock);
- list_splice_init (&ltable->entrylk_lockers, &entrylk_lockers);
GF_FREE (ltable);
flock.l_type = F_UNLCK;
@@ -311,9 +329,9 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
lock owner = 0 is a special case that tells posix-locks
to release all locks from this transport
*/
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = server_conn_ref (conn);
- memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t));
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->trans = conn;
if (locker->fd) {
GF_ASSERT (locker->fd->inode);
@@ -327,14 +345,15 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
} else {
gf_log (this->name, GF_LOG_INFO, "finodelk "
- "released on inode with gfid %s",
+ "released on ino %"PRId64" with gfid %s",
+ locker->fd->inode->ino,
uuid_utoa (locker->fd->inode->gfid));
}
STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
bound_xl->fops->finodelk,
locker->volume,
- locker->fd, F_SETLK, &flock, NULL);
+ locker->fd, F_SETLK, &flock);
fd_unref (locker->fd);
} else {
gf_log (this->name, GF_LOG_INFO, "inodelk released "
@@ -343,7 +362,7 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
bound_xl->fops->inodelk,
locker->volume,
- &(locker->loc), F_SETLK, &flock, NULL);
+ &(locker->loc), F_SETLK, &flock);
loc_wipe (&locker->loc);
}
@@ -358,9 +377,9 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
list_for_each_entry_safe (locker, tmp, &entrylk_lockers, lockers) {
tmp_frame = copy_frame (frame);
- tmp_frame->root->pid = 0;
- tmp_frame->root->trans = server_conn_ref (conn);
- memset (&tmp_frame->root->lk_owner, 0, sizeof (gf_lkowner_t));
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->pid = 0;
+ tmp_frame->root->trans = conn;
if (locker->fd) {
GF_ASSERT (locker->fd->inode);
@@ -374,15 +393,14 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
} else {
gf_log (this->name, GF_LOG_INFO, "fentrylk "
- "released on inode with gfid %s",
- uuid_utoa (locker->fd->inode->gfid));
+ "released on ino %lu", locker->fd->inode->ino);
}
STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
bound_xl->fops->fentrylk,
locker->volume,
locker->fd, NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
fd_unref (locker->fd);
} else {
gf_log (this->name, GF_LOG_INFO, "entrylk released "
@@ -392,7 +410,7 @@ do_lock_table_cleanup (xlator_t *this, server_connection_t *conn,
bound_xl->fops->entrylk,
locker->volume,
&(locker->loc), NULL,
- ENTRYLK_UNLOCK, ENTRYLK_WRLCK, NULL);
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
loc_wipe (&locker->loc);
}
@@ -411,7 +429,7 @@ out:
static int
server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie,
xlator_t *this, int32_t op_ret,
- int32_t op_errno, dict_t *xdata)
+ int32_t op_errno)
{
int32_t ret = -1;
fd_t *fd = NULL;
@@ -425,8 +443,6 @@ server_connection_cleanup_flush_cbk (call_frame_t *frame, void *cookie,
fd_unref (fd);
frame->local = NULL;
- if (frame->root->trans)
- server_conn_unref (frame->root->trans);
STACK_DESTROY (frame->root);
ret = 0;
@@ -470,21 +486,20 @@ do_fd_cleanup (xlator_t *this, server_connection_t *conn, call_frame_t *frame,
GF_FREE (path);
} else {
- gf_log (this->name, GF_LOG_INFO, "fd cleanup on"
- " inode with gfid %s",
+ gf_log (this->name, GF_LOG_INFO, "fd cleanup on "
+ "ino %"PRId64" with gfid %s",
+ fd->inode->ino,
uuid_utoa (fd->inode->gfid));
}
tmp_frame->local = fd;
tmp_frame->root->pid = 0;
- tmp_frame->root->trans = server_conn_ref (conn);
- memset (&tmp_frame->root->lk_owner, 0,
- sizeof (gf_lkowner_t));
-
+ tmp_frame->root->trans = conn;
+ tmp_frame->root->lk_owner = 0;
STACK_WIND (tmp_frame,
server_connection_cleanup_flush_cbk,
- bound_xl, bound_xl->fops->flush, fd, NULL);
+ bound_xl, bound_xl->fops->flush, fd);
}
}
@@ -506,24 +521,23 @@ do_connection_cleanup (xlator_t *this, server_connection_t *conn,
GF_VALIDATE_OR_GOTO ("server", this, out);
GF_VALIDATE_OR_GOTO ("server", conn, out);
-
- if (!ltable && !fdentries)
- goto out;
+ GF_VALIDATE_OR_GOTO ("server", fdentries, out);
+ GF_VALIDATE_OR_GOTO ("server", ltable, out);
frame = create_frame (this, this->ctx->pool);
if (frame == NULL) {
goto out;
}
- if (ltable)
- saved_ret = do_lock_table_cleanup (this, conn, frame, ltable);
+ saved_ret = do_lock_table_cleanup (this, conn, frame, ltable);
if (fdentries != NULL) {
ret = do_fd_cleanup (this, conn, frame, fdentries, fd_count);
}
state = CALL_STATE (frame);
- GF_FREE (state);
+ if (state)
+ GF_FREE (state);
STACK_DESTROY (frame->root);
@@ -537,34 +551,37 @@ out:
int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn,
- int32_t flags)
+server_connection_cleanup (xlator_t *this, server_connection_t *conn)
{
+ char do_cleanup = 0;
struct _lock_table *ltable = NULL;
fdentry_t *fdentries = NULL;
uint32_t fd_count = 0;
int ret = 0;
- GF_VALIDATE_OR_GOTO (this->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, conn, out);
- GF_VALIDATE_OR_GOTO (this->name, flags, out);
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", conn, out);
pthread_mutex_lock (&conn->lock);
{
- if (conn->ltable && (flags & INTERNAL_LOCKS)) {
- ltable = conn->ltable;
- conn->ltable = gf_lock_table_new ();
- }
+ conn->active_transports--;
+ if (conn->active_transports == 0) {
+ if (conn->ltable) {
+ ltable = conn->ltable;
+ conn->ltable = gf_lock_table_new ();
+ }
- if (conn->fdtable && (flags & POSIX_LOCKS))
- fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
- &fd_count);
+ if (conn->fdtable) {
+ fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
+ &fd_count);
+ }
+ do_cleanup = 1;
+ }
}
pthread_mutex_unlock (&conn->lock);
- if (conn->bound_xl)
- ret = do_connection_cleanup (this, conn, ltable,
- fdentries, fd_count);
+ if (do_cleanup && conn->bound_xl)
+ ret = do_connection_cleanup (this, conn, ltable, fdentries, fd_count);
out:
return ret;
@@ -574,12 +591,20 @@ out:
int
server_connection_destroy (xlator_t *this, server_connection_t *conn)
{
+ call_frame_t *frame = NULL, *tmp_frame = NULL;
xlator_t *bound_xl = NULL;
int32_t ret = -1;
+ server_state_t *state = NULL;
struct list_head inodelk_lockers;
struct list_head entrylk_lockers;
struct _lock_table *ltable = NULL;
- fdtable_t *fdtable = NULL;
+ struct _locker *locker = NULL, *tmp = NULL;
+ struct gf_flock flock = {0,};
+ fd_t *fd = NULL;
+ int32_t i = 0;
+ fdentry_t *fdentries = NULL;
+ uint32_t fd_count = 0;
+ char *path = NULL;
GF_VALIDATE_OR_GOTO ("server", this, out);
GF_VALIDATE_OR_GOTO ("server", conn, out);
@@ -587,16 +612,17 @@ server_connection_destroy (xlator_t *this, server_connection_t *conn)
bound_xl = (xlator_t *) (conn->bound_xl);
if (bound_xl) {
+ /* trans will have ref_count = 1 after this call, but its
+ ok since this function is called in
+ GF_EVENT_TRANSPORT_CLEANUP */
+ frame = create_frame (this, this->ctx->pool);
+
pthread_mutex_lock (&(conn->lock));
{
if (conn->ltable) {
ltable = conn->ltable;
conn->ltable = NULL;
}
- if (conn->fdtable) {
- fdtable = conn->fdtable;
- conn->fdtable = NULL;
- }
}
pthread_mutex_unlock (&conn->lock);
@@ -604,68 +630,166 @@ server_connection_destroy (xlator_t *this, server_connection_t *conn)
INIT_LIST_HEAD (&entrylk_lockers);
if (ltable) {
- list_splice_init (&ltable->inodelk_lockers,
- &inodelk_lockers);
+ LOCK (&ltable->lock);
+ {
+ list_splice_init (&ltable->inodelk_lockers,
+ &inodelk_lockers);
- list_splice_init (&ltable->entrylk_lockers,
- &entrylk_lockers);
+ list_splice_init (&ltable->entrylk_lockers, &entrylk_lockers);
+ }
+ UNLOCK (&ltable->lock);
GF_FREE (ltable);
}
- GF_ASSERT (list_empty (&inodelk_lockers));
- GF_ASSERT (list_empty (&entrylk_lockers));
+ flock.l_type = F_UNLCK;
+ flock.l_start = 0;
+ flock.l_len = 0;
+ list_for_each_entry_safe (locker,
+ tmp, &inodelk_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
+ /*
+ lock_owner = 0 is a special case that tells posix-locks
+ to release all locks from this transport
+ */
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->trans = conn;
+
+ if (locker->fd) {
+ GF_ASSERT (locker->fd->inode);
+
+ ret = inode_path (locker->fd->inode, NULL, &path);
+
+ if (ret > 0) {
+ gf_log (this->name, GF_LOG_INFO, "finodelk "
+ "released on %s", path);
+ GF_FREE (path);
+ } else {
+
+ gf_log (this->name, GF_LOG_INFO, "finodelk "
+ "released on ino %"PRId64 "with gfid %s",
+ locker->fd->inode->ino,
+ uuid_utoa (locker->fd->inode->gfid));
+ }
+
+ STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
+ bound_xl->fops->finodelk,
+ locker->volume,
+ locker->fd, F_SETLK, &flock);
+ fd_unref (locker->fd);
+ } else {
+ gf_log (this->name, GF_LOG_INFO, "inodelk "
+ "released on %s", locker->loc.path);
+
+ STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
+ bound_xl->fops->inodelk,
+ locker->volume,
+ &(locker->loc), F_SETLK, &flock);
+ loc_wipe (&locker->loc);
+ }
- if (fdtable)
- gf_fd_fdtable_destroy (fdtable);
- }
+ GF_FREE (locker->volume);
- gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
- conn->id);
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
+ }
- pthread_mutex_destroy (&conn->lock);
- GF_FREE (conn->id);
- GF_FREE (conn);
- ret = 0;
-out:
- return ret;
-}
+ tmp = NULL;
+ locker = NULL;
+ list_for_each_entry_safe (locker, tmp, &entrylk_lockers, lockers) {
+ tmp_frame = copy_frame (frame);
-server_connection_t*
-server_conn_unref (server_connection_t *conn)
-{
- server_connection_t *todel = NULL;
- xlator_t *this = NULL;
+ tmp_frame->root->lk_owner = 0;
+ tmp_frame->root->trans = conn;
- pthread_mutex_lock (&conn->lock);
- {
- conn->ref--;
+ if (locker->fd) {
+ GF_ASSERT (locker->fd->inode);
- if (!conn->ref) {
- todel = conn;
+ ret = inode_path (locker->fd->inode, NULL, &path);
+
+ if (ret > 0) {
+ gf_log (this->name, GF_LOG_INFO, "fentrylk "
+ "released on %s", path);
+
+ GF_FREE (path);
+ } else {
+
+ gf_log (this->name, GF_LOG_INFO, "fentrylk "
+ "released on ino %"PRId64" and gfid= %s",
+ locker->fd->inode->ino,
+ uuid_utoa (locker->fd->inode->gfid));
+ }
+
+ STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
+ bound_xl->fops->fentrylk,
+ locker->volume,
+ locker->fd, NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ fd_unref (locker->fd);
+ } else {
+ gf_log (this->name, GF_LOG_INFO, "entrylk "
+ "released on %s", locker->loc.path);
+
+ STACK_WIND (tmp_frame, server_nop_cbk, bound_xl,
+ bound_xl->fops->entrylk,
+ locker->volume,
+ &(locker->loc), NULL,
+ ENTRYLK_UNLOCK, ENTRYLK_WRLCK);
+ loc_wipe (&locker->loc);
+ }
+
+ GF_FREE (locker->volume);
+
+ list_del_init (&locker->lockers);
+ GF_FREE (locker);
}
- }
- pthread_mutex_unlock (&conn->lock);
- if (todel) {
- this = THIS;
- server_connection_destroy (this, todel);
- conn = NULL;
+ pthread_mutex_lock (&(conn->lock));
+ {
+ if (conn->fdtable) {
+ fdentries = gf_fd_fdtable_get_all_fds (conn->fdtable,
+ &fd_count);
+ gf_fd_fdtable_destroy (conn->fdtable);
+ conn->fdtable = NULL;
+ }
+ }
+ pthread_mutex_unlock (&conn->lock);
+
+ if (fdentries != NULL) {
+ for (i = 0; i < fd_count; i++) {
+ fd = fdentries[i].fd;
+ if (fd != NULL) {
+ tmp_frame = copy_frame (frame);
+ tmp_frame->local = fd;
+
+ STACK_WIND (tmp_frame,
+ server_connection_cleanup_flush_cbk,
+ bound_xl,
+ bound_xl->fops->flush,
+ fd);
+ }
+ }
+ GF_FREE (fdentries);
+ }
}
- return conn;
-}
-server_connection_t*
-server_conn_ref (server_connection_t *conn)
-{
- pthread_mutex_lock (&conn->lock);
- {
- conn->ref++;
+ if (frame) {
+ state = CALL_STATE (frame);
+ if (state)
+ GF_FREE (state);
+ STACK_DESTROY (frame->root);
}
- pthread_mutex_unlock (&conn->lock);
- return conn;
+ gf_log (this->name, GF_LOG_INFO, "destroyed connection of %s",
+ conn->id);
+
+ GF_FREE (conn->id);
+ GF_FREE (conn);
+
+out:
+ return ret;
}
+
server_connection_t *
server_connection_get (xlator_t *this, const char *id)
{
@@ -681,29 +805,29 @@ server_connection_get (xlator_t *this, const char *id)
pthread_mutex_lock (&conf->mutex);
{
list_for_each_entry (trav, &conf->conns, list) {
- if (!strcmp (trav->id, id)) {
+ if (!strcmp (id, trav->id)) {
conn = trav;
- conn->bind_ref++;
- goto unlock;
+ break;
}
}
- conn = (void *) GF_CALLOC (1, sizeof (*conn),
- gf_server_mt_conn_t);
- if (!conn)
- goto unlock;
-
- conn->id = gf_strdup (id);
- /*'0' denotes uninitialised lock state*/
- conn->lk_version = 0;
- conn->fdtable = gf_fd_fdtable_alloc ();
- conn->ltable = gf_lock_table_new ();
- conn->this = this;
- conn->bind_ref = 1;
- conn->ref = 1;//when bind_ref becomes 0 it calls conn_unref
- pthread_mutex_init (&conn->lock, NULL);
- list_add (&conn->list, &conf->conns);
+ if (!conn) {
+ conn = (void *) GF_CALLOC (1, sizeof (*conn),
+ gf_server_mt_conn_t);
+ if (!conn)
+ goto unlock;
+
+ conn->id = gf_strdup (id);
+ conn->fdtable = gf_fd_fdtable_alloc ();
+ conn->ltable = gf_lock_table_new ();
+ conn->this = this;
+ pthread_mutex_init (&conn->lock, NULL);
+ list_add (&conn->list, &conf->conns);
+ }
+
+ conn->ref++;
+ conn->active_transports++;
}
unlock:
pthread_mutex_unlock (&conf->mutex);
@@ -711,34 +835,36 @@ out:
return conn;
}
-server_connection_t*
-server_connection_put (xlator_t *this, server_connection_t *conn,
- gf_boolean_t *detached)
+
+void
+server_connection_put (xlator_t *this, server_connection_t *conn)
{
server_conf_t *conf = NULL;
- gf_boolean_t unref = _gf_false;
+ server_connection_t *todel = NULL;
+
+ GF_VALIDATE_OR_GOTO ("server", this, out);
+ GF_VALIDATE_OR_GOTO ("server", conn, out);
- if (detached)
- *detached = _gf_false;
conf = this->private;
+ GF_VALIDATE_OR_GOTO ("server", conf, out);
+
pthread_mutex_lock (&conf->mutex);
{
- conn->bind_ref--;
- if (!conn->bind_ref) {
+ conn->ref--;
+
+ if (!conn->ref) {
list_del_init (&conn->list);
- unref = _gf_true;
+ todel = conn;
}
}
pthread_mutex_unlock (&conf->mutex);
- if (unref) {
- gf_log (this->name, GF_LOG_INFO, "Shutting down connection %s",
- conn->id);
- if (detached)
- *detached = _gf_true;
- server_conn_unref (conn);
- conn = NULL;
+
+ if (todel) {
+ server_connection_destroy (this, todel);
}
- return conn;
+
+out:
+ return;
}
static call_frame_t *
@@ -802,7 +928,7 @@ get_frame_from_request (rpcsvc_request_t *req)
frame->root->uid = req->uid;
frame->root->gid = req->gid;
frame->root->pid = req->pid;
- frame->root->trans = server_conn_ref (req->trans->xl_private);
+ frame->root->trans = req->trans->xl_private;
frame->root->lk_owner = req->lk_owner;
server_decode_groups (frame, req);
@@ -826,7 +952,7 @@ server_build_config (xlator_t *this, server_conf_t *conf)
ret = dict_get_int32 (this->options, "inode-lru-limit",
&conf->inode_lru_limit);
if (ret < 0) {
- conf->inode_lru_limit = 16384;
+ conf->inode_lru_limit = 1024;
}
conf->verify_volfile = 1;
@@ -887,17 +1013,6 @@ out:
return ret;
}
-void
-put_server_conn_state (xlator_t *this, rpc_transport_t *xprt)
-{
- GF_VALIDATE_OR_GOTO ("server", this, out);
- GF_VALIDATE_OR_GOTO ("server", xprt, out);
-
- xprt->xl_private = NULL;
-out:
- return;
-}
-
server_connection_t *
get_server_conn_state (xlator_t *this, rpc_transport_t *xprt)
{
@@ -1003,6 +1118,15 @@ server_print_resolve (char *str, int size, server_resolve_t *resolve)
if (resolve->fd_no != -1)
filled += snprintf (str + filled, size - filled,
"fd=%"PRId64",", (uint64_t) resolve->fd_no);
+ if (resolve->ino)
+ filled += snprintf (str + filled, size - filled,
+ "ino=%"PRIu64",", (uint64_t) resolve->ino);
+ if (resolve->par)
+ filled += snprintf (str + filled, size - filled,
+ "par=%"PRIu64",", (uint64_t) resolve->par);
+ if (resolve->gen)
+ filled += snprintf (str + filled, size - filled,
+ "gen=%"PRIu64",", (uint64_t) resolve->gen);
if (resolve->bname)
filled += snprintf (str + filled, size - filled,
"bname=%s,", resolve->bname);
@@ -1103,6 +1227,15 @@ server_resolve_is_empty (server_resolve_t *resolve)
if (resolve->fd_no != -1)
return 0;
+ if (resolve->ino != 0)
+ return 0;
+
+ if (resolve->gen != 0)
+ return 0;
+
+ if (resolve->par != 0)
+ return 0;
+
if (resolve->path != 0)
return 0;
@@ -1243,53 +1376,21 @@ serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp)
trav->d_off = entry->d_off;
trav->d_len = entry->d_len;
trav->d_type = entry->d_type;
+ //trav->name = memdup (entry->d_name, entry->d_len + 1);
trav->name = entry->d_name;
gf_stat_from_iatt (&trav->stat, &entry->d_stat);
- /* if 'dict' is present, pack it */
- if (entry->dict) {
- trav->dict.dict_len = dict_serialized_length (entry->dict);
- if (trav->dict.dict_len < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to get serialized length "
- "of reply dict");
- errno = EINVAL;
- trav->dict.dict_len = 0;
- goto out;
- }
-
- trav->dict.dict_val = GF_CALLOC (1, trav->dict.dict_len,
- gf_server_mt_rsp_buf_t);
- if (!trav->dict.dict_val) {
- errno = ENOMEM;
- trav->dict.dict_len = 0;
- goto out;
- }
-
- ret = dict_serialize (entry->dict, trav->dict.dict_val);
- if (ret < 0) {
- gf_log (THIS->name, GF_LOG_ERROR,
- "failed to serialize reply dict");
- errno = -ret;
- trav->dict.dict_len = 0;
- goto out;
- }
- }
-
if (prev)
prev->nextentry = trav;
else
rsp->reply = trav;
prev = trav;
- trav = NULL;
}
ret = 0;
out:
- GF_FREE (trav);
-
return ret;
}
@@ -1354,7 +1455,6 @@ readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp)
prev = trav;
while (trav) {
trav = trav->nextentry;
- GF_FREE (prev->dict.dict_val);
GF_FREE (prev);
prev = trav;
}
@@ -1375,14 +1475,10 @@ gf_server_check_getxattr_cmd (call_frame_t *frame, const char *key)
if (fnmatch ("*list*mount*point*", key, 0) == 0) {
/* list all the client protocol connecting to this process */
- pthread_mutex_lock (&conf->mutex);
- {
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- gf_log ("mount-point-list", GF_LOG_INFO,
- "%s", xprt->peerinfo.identifier);
- }
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ gf_log ("mount-point-list", GF_LOG_INFO,
+ "%s", xprt->peerinfo.identifier);
}
- pthread_mutex_unlock (&conf->mutex);
}
/* Add more options/keys here */
@@ -1401,7 +1497,7 @@ gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
uint64_t total_write = 0;
conf = frame->this->private;
- if (!conf || !dict)
+ if (!conf)
return 0;
for (pair = dict->members_list; pair; pair = pair->next) {
@@ -1421,33 +1517,3 @@ gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)
return 0;
}
-
-gf_boolean_t
-server_cancel_conn_timer (xlator_t *this, server_connection_t *conn)
-{
- gf_timer_t *timer = NULL;
- gf_boolean_t cancelled = _gf_false;
-
- if (!this || !conn) {
- gf_log (THIS->name, GF_LOG_ERROR, "Invalid arguments to "
- "cancel connection timer");
- return cancelled;
- }
-
- pthread_mutex_lock (&conn->lock);
- {
- if (!conn->timer)
- goto unlock;
-
- timer = conn->timer;
- conn->timer = NULL;
- }
-unlock:
- pthread_mutex_unlock (&conn->lock);
-
- if (timer) {
- gf_timer_call_cancel (this->ctx, timer);
- cancelled = _gf_true;
- }
- return cancelled;
-}
diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h
index 5ce5e36ac..85929bbba 100644
--- a/xlators/protocol/server/src/server-helpers.h
+++ b/xlators/protocol/server/src/server-helpers.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -48,18 +48,18 @@ void free_state (server_state_t *state);
void server_loc_wipe (loc_t *loc);
int32_t
-gf_add_locker (server_connection_t *conn, const char *volume,
+gf_add_locker (struct _lock_table *table, const char *volume,
loc_t *loc,
fd_t *fd,
pid_t pid,
- gf_lkowner_t *owner,
+ uint64_t owner,
glusterfs_fop_t type);
int32_t
-gf_del_locker (server_connection_t *conn, const char *volume,
+gf_del_locker (struct _lock_table *table, const char *volume,
loc_t *loc,
fd_t *fd,
- gf_lkowner_t *owner,
+ uint64_t owner,
glusterfs_fop_t type);
void
@@ -68,12 +68,6 @@ server_print_request (call_frame_t *frame);
call_frame_t *
get_frame_from_request (rpcsvc_request_t *req);
-gf_boolean_t
-server_cancel_conn_timer (xlator_t *this, server_connection_t *conn);
-
-void
-put_server_conn_state (xlator_t *this, rpc_transport_t *xprt);
-
server_connection_t *
get_server_conn_state (xlator_t *this, rpc_transport_t *xptr);
diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h
index 5438ed6db..bf1a2faa5 100644
--- a/xlators/protocol/server/src/server-mem-types.h
+++ b/xlators/protocol/server/src/server-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -33,7 +33,6 @@ enum gf_server_mem_types_ {
gf_server_mt_dirent_rsp_t,
gf_server_mt_rsp_buf_t,
gf_server_mt_volfile_ctx_t,
- gf_server_mt_timer_data_t,
gf_server_mt_end,
};
#endif /* __SERVER_MEM_TYPES_H__ */
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 11b488187..0b0487a24 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -33,9 +33,74 @@ resolve_entry_simple (call_frame_t *frame);
int
resolve_inode_simple (call_frame_t *frame);
int
-resolve_continue (call_frame_t *frame);
+resolve_path_simple (call_frame_t *frame);
+
int
-resolve_anonfd_simple (call_frame_t *frame);
+component_count (const char *path)
+{
+ int count = 0;
+ const char *trav = NULL;
+
+ for (trav = path; *trav; trav++) {
+ if (*trav == '/')
+ count++;
+ }
+
+ return count + 2;
+}
+
+
+int
+prepare_components (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ char *resolved = NULL;
+ int count = 0;
+ struct resolve_comp *components = NULL;
+ int i = 0;
+ char *trav = NULL;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ resolved = gf_strdup (resolve->path);
+ resolve->resolved = resolved;
+
+ count = component_count (resolve->path);
+ components = GF_CALLOC (sizeof (*components), count,
+ gf_server_mt_resolv_comp_t);
+ if (!components)
+ goto out;
+
+ resolve->components = components;
+
+ components[0].basename = "";
+ components[0].ino = 1;
+ components[0].gen = 0;
+ components[0].inode = state->itable->root;
+
+ i = 1;
+ for (trav = resolved; *trav; trav++) {
+ if (*trav == '/') {
+ *trav = 0;
+
+ if (!(*(trav + 1))) {
+ /* Skip trailing "/" in a path.
+ This is the check which prevents
+ inode_link'age of itable->root
+ */
+ break;
+ }
+
+ components[i].basename = trav + 1;
+ i++;
+ }
+ }
+out:
+ return 0;
+}
+
int
resolve_loc_touchup (call_frame_t *frame)
@@ -60,172 +125,230 @@ resolve_loc_touchup (call_frame_t *frame)
if (ret)
gf_log (frame->this->name, GF_LOG_TRACE,
"return value inode_path %d", ret);
+
+ if (!path)
+ path = gf_strdup (resolve->path);
+
loc->path = path;
}
+ loc->name = strrchr (loc->path, '/');
+ if (loc->name)
+ loc->name++;
+
+ if (!loc->parent && loc->inode) {
+ loc->parent = inode_parent (loc->inode, 0, NULL);
+ }
+
return 0;
}
int
-resolve_gfid_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int op_ret, int op_errno, inode_t *inode,
- struct iatt *buf, dict_t *xdata,
- struct iatt *postparent)
+resolve_deep_continue (call_frame_t *frame)
{
server_state_t *state = NULL;
+ xlator_t *this = NULL;
server_resolve_t *resolve = NULL;
- inode_t *link_inode = NULL;
- loc_t *resolve_loc = NULL;
+ int ret = 0;
state = CALL_STATE (frame);
+ this = frame->this;
resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
-
- if (op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
- GF_LOG_WARNING),
- "%s/%s: failed to resolve (%s)",
- uuid_utoa (resolve_loc->pargfid), resolve_loc->name,
- strerror (op_errno));
- goto out;
- }
-
- link_inode = inode_link (inode, resolve_loc->parent,
- resolve_loc->name, buf);
- if (!link_inode)
- goto out;
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
- inode_lookup (link_inode);
+ if (!uuid_is_null (resolve->pargfid))
+ ret = resolve_entry_simple (frame);
+ else if (!uuid_is_null (resolve->gfid))
+ ret = resolve_inode_simple (frame);
+ else if (resolve->path)
+ ret = resolve_path_simple (frame);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "return value of resolve_*_simple %d", ret);
- inode_unref (link_inode);
+ resolve_loc_touchup (frame);
-out:
- loc_wipe (resolve_loc);
+ server_resolve_all (frame);
- resolve_continue (frame);
return 0;
}
int
-resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
- dict_t *xdata, struct iatt *postparent)
+ dict_t *xattr, struct iatt *postparent)
{
server_state_t *state = NULL;
server_resolve_t *resolve = NULL;
+ struct resolve_comp *components = NULL;
+ int i = 0;
inode_t *link_inode = NULL;
- loc_t *resolve_loc = NULL;
state = CALL_STATE (frame);
resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
+ components = resolve->components;
+
+ i = (long) cookie;
if (op_ret == -1) {
gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
GF_LOG_WARNING),
"%s: failed to resolve (%s)",
- uuid_utoa (resolve_loc->gfid), strerror (op_errno));
- loc_wipe (&resolve->resolve_loc);
- goto out;
+ resolve->resolved, strerror (op_errno));
+ goto get_out_of_here;
}
- loc_wipe (resolve_loc);
-
- link_inode = inode_link (inode, NULL, NULL, buf);
+ if (i != 0) {
+ /* no linking for root inode */
+ link_inode = inode_link (inode, resolve->deep_loc.parent,
+ resolve->deep_loc.name, buf);
+ inode_lookup (link_inode);
+ components[i].inode = link_inode;
+ link_inode = NULL;
+ }
- if (!link_inode)
- goto out;
+ loc_wipe (&resolve->deep_loc);
- inode_lookup (link_inode);
+ i++; /* next component */
- if (uuid_is_null (resolve->pargfid)) {
- inode_unref (link_inode);
- goto out;
+ if (!components[i].basename) {
+ /* all components of the path are resolved */
+ goto get_out_of_here;
}
- resolve_loc->parent = link_inode;
- uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid);
+ /* join the current component with the path resolved until now */
+ *(components[i].basename - 1) = '/';
- resolve_loc->name = resolve->bname;
+ resolve->deep_loc.path = gf_strdup (resolve->resolved);
+ resolve->deep_loc.parent = inode_ref (components[i-1].inode);
+ resolve->deep_loc.inode = inode_new (state->itable);
+ resolve->deep_loc.name = components[i].basename;
- resolve_loc->inode = inode_new (state->itable);
- inode_path (resolve_loc->parent, resolve_loc->name,
- (char **) &resolve_loc->path);
+ if (frame && frame->root->state && BOUND_XL (frame)) {
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_loc, NULL);
+ return 0;
+ }
- STACK_WIND (frame, resolve_gfid_entry_cbk,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
- &resolve->resolve_loc, NULL);
- return 0;
-out:
- resolve_continue (frame);
+get_out_of_here:
+ resolve_deep_continue (frame);
return 0;
}
int
-resolve_gfid (call_frame_t *frame)
+resolve_path_deep (call_frame_t *frame)
{
- server_state_t *state = NULL;
- xlator_t *this = NULL;
- server_resolve_t *resolve = NULL;
- loc_t *resolve_loc = NULL;
- int ret = 0;
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ int i = 0;
state = CALL_STATE (frame);
- this = frame->this;
resolve = state->resolve_now;
- resolve_loc = &resolve->resolve_loc;
- if (!uuid_is_null (resolve->pargfid))
- uuid_copy (resolve_loc->gfid, resolve->pargfid);
- else if (!uuid_is_null (resolve->gfid))
- uuid_copy (resolve_loc->gfid, resolve->gfid);
+ gf_log (BOUND_XL (frame)->name, GF_LOG_DEBUG,
+ "RESOLVE %s() seeking deep resolution of %s",
+ gf_fop_list[frame->root->op], resolve->path);
+
+ prepare_components (frame);
+
+ /* start from the root */
+ resolve->deep_loc.inode = state->itable->root;
+ resolve->deep_loc.path = gf_strdup ("/");
+ resolve->deep_loc.name = "";
- resolve_loc->inode = inode_new (state->itable);
- ret = loc_path (resolve_loc, NULL);
+ if (frame && frame->root->state && BOUND_XL (frame)) {
+ STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->deep_loc, NULL);
+ return 0;
+ }
- STACK_WIND (frame, resolve_gfid_cbk,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
- &resolve->resolve_loc, NULL);
+ resolve_deep_continue (frame);
return 0;
}
+
int
-resolve_continue (call_frame_t *frame)
+resolve_path_simple (call_frame_t *frame)
{
server_state_t *state = NULL;
- xlator_t *this = NULL;
server_resolve_t *resolve = NULL;
- int ret = 0;
+ struct resolve_comp *components = NULL;
+ int ret = -1;
+ int par_idx = -1;
+ int ino_idx = -1;
+ int i = 0;
state = CALL_STATE (frame);
- this = frame->this;
resolve = state->resolve_now;
+ components = resolve->components;
- resolve->op_ret = 0;
- resolve->op_errno = 0;
+ if (!components) {
+ gf_log ("", GF_LOG_INFO,
+ "failed to resolve, component not found");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
- if (resolve->fd_no != -1) {
- ret = resolve_anonfd_simple (frame);
+ for (i = 0; components[i].basename; i++) {
+ par_idx = ino_idx;
+ ino_idx = i;
+ }
+
+ if (ino_idx == -1) {
+ gf_log ("", GF_LOG_INFO,
+ "failed to resolve, inode index not found");
+ resolve->op_ret = -1;
+ resolve->op_errno = EINVAL;
goto out;
- } else if (!uuid_is_null (resolve->pargfid))
- ret = resolve_entry_simple (frame);
- else if (!uuid_is_null (resolve->gfid))
- ret = resolve_inode_simple (frame);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "return value of resolve_*_simple %d", ret);
+ }
- resolve_loc_touchup (frame);
-out:
- server_resolve_all (frame);
+ if (par_idx == -1)
+ /* "/" will not have a parent */
+ goto noparent;
- return 0;
-}
+ if (!components[par_idx].inode) {
+ gf_log ("", GF_LOG_INFO,
+ "failed to resolve, parent inode not found");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+ state->loc_now->parent = inode_ref (components[par_idx].inode);
+noparent:
+
+ if (!components[ino_idx].inode &&
+ (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) {
+ gf_log ("", GF_LOG_INFO,
+ "failed to resolve, inode not found");
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+ if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) {
+ gf_log ("", GF_LOG_INFO,
+ "failed to resolve, inode found");
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ goto out;
+ }
+
+ if (components[ino_idx].inode)
+ state->loc_now->inode = inode_ref (components[ino_idx].inode);
+
+ ret = 0;
+
+out:
+ return ret;
+}
/*
Check if the requirements are fulfilled by entries in the inode cache itself
@@ -255,13 +378,20 @@ resolve_entry_simple (call_frame_t *frame)
resolve->op_ret = -1;
resolve->op_errno = ENOENT;
ret = 1;
+
+ inode = inode_grep (state->itable, parent, resolve->bname);
+ if (inode != NULL) {
+ gf_log (this->name, GF_LOG_DEBUG, "%"PRId64": inode "
+ "(pointer:%p ino: %"PRIu64") present but parent"
+ " is NULL for path (%s)", frame->root->unique,
+ inode, inode->ino, resolve->path);
+ inode_unref (inode);
+ }
goto out;
}
/* expected @parent was found from the inode cache */
- uuid_copy (state->loc_now->pargfid, resolve->pargfid);
state->loc_now->parent = inode_ref (parent);
- state->loc_now->name = resolve->bname;
inode = inode_grep (state->itable, parent, resolve->bname);
if (!inode) {
@@ -284,9 +414,9 @@ resolve_entry_simple (call_frame_t *frame)
}
if (resolve->type == RESOLVE_NOT) {
- gf_log (this->name, GF_LOG_DEBUG, "inode (pointer: %p gfid:%s"
- " found for path (%s) while type is RESOLVE_NOT",
- inode, uuid_utoa (inode->gfid), resolve->path);
+ gf_log (this->name, GF_LOG_INFO, "inode (pointer: %p ino:%"
+ PRIu64") found for path (%s) while type is RESOLVE_NOT",
+ inode, inode->ino, resolve->path);
resolve->op_ret = -1;
resolve->op_errno = EEXIST;
ret = -1;
@@ -322,7 +452,7 @@ server_resolve_entry (call_frame_t *frame)
if (ret > 0) {
loc_wipe (loc);
- resolve_gfid (frame);
+ resolve_path_deep (frame);
return 0;
}
@@ -358,7 +488,6 @@ resolve_inode_simple (call_frame_t *frame)
ret = 0;
state->loc_now->inode = inode_ref (inode);
- uuid_copy (state->loc_now->gfid, resolve->gfid);
out:
if (inode)
@@ -382,7 +511,7 @@ server_resolve_inode (call_frame_t *frame)
if (ret > 0) {
loc_wipe (loc);
- resolve_gfid (frame);
+ resolve_path_deep (frame);
return 0;
}
@@ -396,66 +525,6 @@ server_resolve_inode (call_frame_t *frame)
int
-resolve_anonfd_simple (call_frame_t *frame)
-{
- server_state_t *state = NULL;
- server_resolve_t *resolve = NULL;
- inode_t *inode = NULL;
- int ret = 0;
-
- state = CALL_STATE (frame);
- resolve = state->resolve_now;
-
- inode = inode_find (state->itable, resolve->gfid);
-
- if (!inode) {
- resolve->op_ret = -1;
- resolve->op_errno = ENOENT;
- ret = 1;
- goto out;
- }
-
- ret = 0;
-
- state->fd = fd_anonymous (inode);
-out:
- if (inode)
- inode_unref (inode);
-
- if (ret != 0)
- gf_log ("server", GF_LOG_WARNING, "inode for the gfid (%s) is "
- "not found. anonymous fd creation failed",
- uuid_utoa (resolve->gfid));
- return ret;
-}
-
-
-int
-server_resolve_anonfd (call_frame_t *frame)
-{
- server_state_t *state = NULL;
- int ret = 0;
- loc_t *loc = NULL;
-
- state = CALL_STATE (frame);
- loc = state->loc_now;
-
- ret = resolve_anonfd_simple (frame);
-
- if (ret > 0) {
- loc_wipe (loc);
- resolve_gfid (frame);
- return 0;
- }
-
- server_resolve_all (frame);
-
- return 0;
-
-}
-
-
-int
server_resolve_fd (call_frame_t *frame)
{
server_state_t *state = NULL;
@@ -469,11 +538,6 @@ server_resolve_fd (call_frame_t *frame)
fd_no = resolve->fd_no;
- if (fd_no == -2) {
- server_resolve_anonfd (frame);
- return 0;
- }
-
state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no);
if (!state->fd) {
@@ -509,11 +573,14 @@ server_resolve (call_frame_t *frame)
server_resolve_inode (frame);
- } else {
- if (resolve == &state->resolve)
- gf_log (frame->this->name, GF_LOG_WARNING,
- "no resolution type for %s (%s)",
- resolve->path, gf_fop_list[frame->root->op]);
+ } else if (resolve->path) {
+
+ gf_log (frame->this->name, GF_LOG_INFO,
+ "pure path resolution for %s (%s)",
+ resolve->path, gf_fop_list[frame->root->op]);
+ resolve_path_deep (frame);
+
+ } else {
resolve->op_ret = -1;
resolve->op_errno = EINVAL;
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index 74dbc17e6..967863d09 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -36,76 +36,41 @@
#include "authenticate.h"
#include "rpcsvc.h"
-void
-grace_time_handler (void *data)
-{
- server_connection_t *conn = NULL;
- xlator_t *this = NULL;
- gf_boolean_t cancelled = _gf_false;
- gf_boolean_t detached = _gf_false;
-
- conn = data;
- this = conn->this;
-
- GF_VALIDATE_OR_GOTO (THIS->name, conn, out);
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
-
- gf_log (this->name, GF_LOG_INFO, "grace timer expired for %s", conn->id);
-
- cancelled = server_cancel_conn_timer (this, conn);
- if (cancelled) {
- //conn should not be destroyed in conn_put, so take a ref.
- server_conn_ref (conn);
- server_connection_put (this, conn, &detached);
- if (detached)//reconnection did not happen :-(
- server_connection_cleanup (this, conn,
- INTERNAL_LOCKS | POSIX_LOCKS);
- server_conn_unref (conn);
- }
-out:
- return;
-}
-
struct iobuf *
-gfs_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg,
- xdrproc_t xdrproc)
+gfs_serialize_reply (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc,
+ struct iovec *outmsg)
{
- struct iobuf *iob = NULL;
- ssize_t retlen = 0;
- ssize_t xdr_size = 0;
+ struct iobuf *iob = NULL;
+ ssize_t retlen = -1;
GF_VALIDATE_OR_GOTO ("server", req, ret);
/* First, get the io buffer into which the reply in arg will
* be serialized.
*/
- if (arg && xdrproc) {
- xdr_size = xdr_sizeof (xdrproc, arg);
- iob = iobuf_get2 (req->svc->ctx->iobuf_pool, xdr_size);
- if (!iob) {
- gf_log_callingfn (THIS->name, GF_LOG_ERROR,
- "Failed to get iobuf");
- goto ret;
- };
-
- iobuf_to_iovec (iob, outmsg);
- /* Use the given serializer to translate the give C structure in arg
- * to XDR format which will be written into the buffer in outmsg.
- */
- /* retlen is used to received the error since size_t is unsigned and we
- * need -1 for error notification during encoding.
- */
-
- retlen = xdr_serialize_generic (*outmsg, arg, xdrproc);
- if (retlen == -1) {
- /* Failed to Encode 'GlusterFS' msg in RPC is not exactly
- failure of RPC return values.. client should get
- notified about this, so there are no missing frames */
- gf_log_callingfn ("", GF_LOG_ERROR, "Failed to encode message");
- req->rpc_err = GARBAGE_ARGS;
- retlen = 0;
- }
+ iob = iobuf_get (req->svc->ctx->iobuf_pool);
+ if (!iob) {
+ gf_log_callingfn ("", GF_LOG_ERROR, "Failed to get iobuf");
+ goto ret;
}
+
+ iobuf_to_iovec (iob, outmsg);
+ /* Use the given serializer to translate the give C structure in arg
+ * to XDR format which will be written into the buffer in outmsg.
+ */
+ /* retlen is used to received the error since size_t is unsigned and we
+ * need -1 for error notification during encoding.
+ */
+ retlen = sfunc (*outmsg, arg);
+ if (retlen == -1) {
+ /* Failed to Encode 'GlusterFS' msg in RPC is not exactly
+ failure of RPC return values.. client should get
+ notified about this, so there are no missing frames */
+ gf_log_callingfn ("", GF_LOG_ERROR, "Failed to encode message");
+ req->rpc_err = GARBAGE_ARGS;
+ retlen = 0;
+ }
+
outmsg->iov_len = retlen;
ret:
if (retlen == -1) {
@@ -118,30 +83,25 @@ ret:
+/* Generic reply function for NFSv3 specific replies. */
int
server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc)
+ struct iobref *iobref, gfs_serialize_t sfunc)
{
struct iobuf *iob = NULL;
int ret = -1;
struct iovec rsp = {0,};
server_state_t *state = NULL;
char new_iobref = 0;
- server_connection_t *conn = NULL;
- gf_boolean_t lk_heal = _gf_false;
GF_VALIDATE_OR_GOTO ("server", req, ret);
if (frame) {
state = CALL_STATE (frame);
frame->local = NULL;
- conn = SERVER_CONNECTION(frame);
}
- if (conn)
- lk_heal = ((server_conf_t *) conn->this->private)->lk_heal;
-
if (!iobref) {
iobref = iobref_new ();
if (!iobref) {
@@ -151,7 +111,7 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
new_iobref = 1;
}
- iob = gfs_serialize_reply (req, arg, &rsp, xdrproc);
+ iob = gfs_serialize_reply (req, arg, sfunc, &rsp);
if (!iob) {
gf_log ("", GF_LOG_ERROR, "Failed to serialize reply");
goto ret;
@@ -174,14 +134,6 @@ server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
iobuf_unref (iob);
if (ret == -1) {
gf_log_callingfn ("", GF_LOG_ERROR, "Reply submission failed");
- if (frame && conn && !lk_heal) {
- server_connection_cleanup (frame->this, conn,
- INTERNAL_LOCKS | POSIX_LOCKS);
- } else {
- /* TODO: Failure of open(dir), create, inodelk, entrylk
- or lk fops send failure must be handled specially. */
- ;
- }
goto ret;
}
@@ -192,8 +144,6 @@ ret:
}
if (frame) {
- if (frame->root->trans)
- server_conn_unref (frame->root->trans);
STACK_DESTROY (frame->root);
}
@@ -206,33 +156,16 @@ ret:
/* */
int
-server_fd_to_dict (xlator_t *this, dict_t *dict)
+xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc)
{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[GF_DUMP_MAX_BUF_LEN] = {0,};
- int count = 0;
int ret = -1;
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- conf = this->private;
- if (!conf)
- return -1;
+ GF_VALIDATE_OR_GOTO ("server", req, out);
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret)
- return -1;
+ ret = sfunc (req->msg[0], arg);
- list_for_each_entry (trav, &conf->conns, list) {
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "conn%d", count++);
- fdtable_dump_to_dict (trav->fdtable, key, dict);
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = dict_set_int32 (dict, "conncount", count);
+ if (ret > 0)
+ ret = 0;
out:
return ret;
}
@@ -267,20 +200,24 @@ server_fd (xlator_t *this)
list_for_each_entry (trav, &conf->conns, list) {
if (trav->id) {
gf_proc_dump_build_key(key,
- "conn","%d.id", i);
+ "xlator.protocol.server.conn",
+ "%d.id", i);
gf_proc_dump_write(key, "%s", trav->id);
}
- gf_proc_dump_build_key(key,"conn","%d.ref",i)
+ gf_proc_dump_build_key(key,"xlator.protocol.server.conn",
+ "%d.ref",i)
gf_proc_dump_write(key, "%d", trav->ref);
if (trav->bound_xl) {
gf_proc_dump_build_key(key,
- "conn","%d.bound_xl", i);
+ "xlator.protocol.server.conn",
+ "%d.bound_xl", i);
gf_proc_dump_write(key, "%s", trav->bound_xl->name);
}
gf_proc_dump_build_key(key,
- "conn","%d.id", i);
+ "xlator.protocol.server.conn",
+ "%d.id", i);
fdtable_dump(trav->fdtable,key);
i++;
}
@@ -292,65 +229,6 @@ out:
}
int
-server_priv_to_dict (xlator_t *this, dict_t *dict)
-{
- server_conf_t *conf = NULL;
- rpc_transport_t *xprt = NULL;
- peer_info_t *peerinfo = NULL;
- char key[32] = {0,};
- int count = 0;
- int ret = -1;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (THIS->name, dict, out);
-
- conf = this->private;
- if (!conf)
- return 0;
- //TODO: Dump only specific info to dict
-
- pthread_mutex_lock (&conf->mutex);
- {
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- peerinfo = &xprt->peerinfo;
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.hostname",
- count);
- ret = dict_set_str (dict, key, peerinfo->identifier);
- if (ret)
- goto unlock;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.bytesread",
- count);
- ret = dict_set_uint64 (dict, key,
- xprt->total_bytes_read);
- if (ret)
- goto unlock;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "client%d.byteswrite",
- count);
- ret = dict_set_uint64 (dict, key,
- xprt->total_bytes_write);
- if (ret)
- goto unlock;
-
- count++;
- }
- }
-unlock:
- pthread_mutex_unlock (&conf->mutex);
- if (ret)
- goto out;
-
- ret = dict_set_int32 (dict, "clientcount", count);
-
-out:
- return ret;
-}
-
-int
server_priv (xlator_t *this)
{
server_conf_t *conf = NULL;
@@ -366,14 +244,10 @@ server_priv (xlator_t *this)
if (!conf)
return 0;
- pthread_mutex_lock (&conf->mutex);
- {
- list_for_each_entry (xprt, &conf->xprt_list, list) {
- total_read += xprt->total_bytes_read;
- total_write += xprt->total_bytes_write;
- }
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ total_read += xprt->total_bytes_read;
+ total_write += xprt->total_bytes_write;
}
- pthread_mutex_unlock (&conf->mutex);
gf_proc_dump_build_key(key, "server", "total-bytes-read");
gf_proc_dump_write(key, "%"PRIu64, total_read);
@@ -387,57 +261,6 @@ out:
}
int
-server_inode_to_dict (xlator_t *this, dict_t *dict)
-{
- server_conf_t *conf = NULL;
- server_connection_t *trav = NULL;
- char key[32] = {0,};
- int count = 0;
- int ret = -1;
- xlator_t *prev_bound_xl = NULL;
-
- GF_VALIDATE_OR_GOTO (THIS->name, this, out);
- GF_VALIDATE_OR_GOTO (this->name, dict, out);
-
- conf = this->private;
- if (!conf)
- return -1;
-
- ret = pthread_mutex_trylock (&conf->mutex);
- if (ret)
- return -1;
-
- list_for_each_entry (trav, &conf->conns, list) {
- if (trav->bound_xl && trav->bound_xl->itable) {
- /* Presently every brick contains only one
- * bound_xl for all connections. This will lead
- * to duplicating of the inode lists, if listing
- * is done for every connection. This simple check
- * prevents duplication in the present case. If
- * need arises the check can be improved.
- */
- if (trav->bound_xl == prev_bound_xl)
- continue;
- prev_bound_xl = trav->bound_xl;
-
- memset (key, 0, sizeof (key));
- snprintf (key, sizeof (key), "conn%d", count);
- inode_table_dump_to_dict (trav->bound_xl->itable,
- key, dict);
- count++;
- }
- }
- pthread_mutex_unlock (&conf->mutex);
-
- ret = dict_set_int32 (dict, "conncount", count);
-
-out:
- if (prev_bound_xl)
- prev_bound_xl = NULL;
- return ret;
-}
-
-int
server_inode (xlator_t *this)
{
server_conf_t *conf = NULL;
@@ -445,7 +268,6 @@ server_inode (xlator_t *this)
char key[GF_DUMP_MAX_BUF_LEN];
int i = 1;
int ret = -1;
- xlator_t *prev_bound_xl = NULL;
GF_VALIDATE_OR_GOTO ("server", this, out);
@@ -465,19 +287,9 @@ server_inode (xlator_t *this)
list_for_each_entry (trav, &conf->conns, list) {
if (trav->bound_xl && trav->bound_xl->itable) {
- /* Presently every brick contains only one
- * bound_xl for all connections. This will lead
- * to duplicating of the inode lists, if listing
- * is done for every connection. This simple check
- * prevents duplication in the present case. If
- * need arises the check can be improved.
- */
- if (trav->bound_xl == prev_bound_xl)
- continue;
- prev_bound_xl = trav->bound_xl;
-
gf_proc_dump_build_key(key,
- "conn","%d.bound_xl.%s",
+ "xlator.protocol.server.conn",
+ "%d.bound_xl.%s",
i, trav->bound_xl->name);
inode_table_dump(trav->bound_xl->itable,key);
i++;
@@ -539,9 +351,6 @@ validate_auth_options (xlator_t *this, dict_t *dict)
xlator_list_t *trav = NULL;
data_pair_t *pair = NULL;
char *tail = NULL;
- char *tmp_addr_list = NULL;
- char *addr = NULL;
- char *tmp_str = NULL;
GF_VALIDATE_OR_GOTO ("server", this, out);
GF_VALIDATE_OR_GOTO ("server", dict, out);
@@ -565,49 +374,9 @@ validate_auth_options (xlator_t *this, dict_t *dict)
if (*tail == '.') {
error = 0;
-
- /* when we are here, the key is checked for
- * valid auth.allow.<xlator>
- * Now we verify the ip address
- */
- if (!strcmp (pair->value->data, "*")) {
- error = 0;
- goto out;
- }
-
- tmp_addr_list = gf_strdup (pair->value->data);
- addr = strtok_r (tmp_addr_list, ",",
- &tmp_str);
- if (!addr)
- addr = pair->value->data;
-
- while (addr) {
-
- if (valid_internet_address
- (addr, _gf_true)) {
- error = 0;
- } else {
- error = -1;
- gf_log (this->name, GF_LOG_ERROR,
- "internet address '%s'"
- " does not conform to"
- " standards.", addr);
- goto out;
-
- }
- if (tmp_str)
- addr = strtok_r (NULL, ",",
- &tmp_str);
- else
- addr = NULL;
- }
-
- GF_FREE (tmp_addr_list);
- tmp_addr_list = NULL;
+ break;
}
-
}
-
if (-1 == error) {
gf_log (this->name, GF_LOG_ERROR,
"volume '%s' defined as subvolume, but no "
@@ -617,9 +386,7 @@ validate_auth_options (xlator_t *this, dict_t *dict)
}
trav = trav->next;
}
-
out:
- GF_FREE (tmp_addr_list);
return error;
}
@@ -628,11 +395,11 @@ int
server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
void *data)
{
- gf_boolean_t detached = _gf_false;
- xlator_t *this = NULL;
- rpc_transport_t *xprt = NULL;
- server_connection_t *conn = NULL;
- server_conf_t *conf = NULL;
+ xlator_t *this = NULL;
+ rpc_transport_t *xprt = NULL;
+ server_connection_t *conn = NULL;
+ server_conf_t *conf = NULL;
+
if (!xl || !data) {
gf_log_callingfn ("server", GF_LOG_WARNING,
@@ -657,69 +424,26 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
*/
INIT_LIST_HEAD (&xprt->list);
- pthread_mutex_lock (&conf->mutex);
- {
- list_add_tail (&xprt->list, &conf->xprt_list);
- }
- pthread_mutex_unlock (&conf->mutex);
+ list_add_tail (&xprt->list, &conf->xprt_list);
break;
}
case RPCSVC_EVENT_DISCONNECT:
- /* transport has to be removed from the list upon disconnect
- * irrespective of whether lock self heal is off or on, since
- * new transport will be created upon reconnect.
- */
- pthread_mutex_lock (&conf->mutex);
- {
- list_del_init (&xprt->list);
- }
- pthread_mutex_unlock (&conf->mutex);
-
conn = get_server_conn_state (this, xprt);
- if (!conn)
- break;
+ if (conn)
+ server_connection_cleanup (this, conn);
+
+ gf_log (this->name, GF_LOG_INFO,
+ "disconnected connection from %s",
+ xprt->peerinfo.identifier);
+
+ list_del (&xprt->list);
- gf_log (this->name, GF_LOG_INFO, "disconnecting connection"
- "from %s", conn->id);
-
- /* If lock self heal is off, then destroy the
- conn object, else register a grace timer event */
- if (!conf->lk_heal) {
- server_conn_ref (conn);
- server_connection_put (this, conn, &detached);
- if (detached)
- server_connection_cleanup (this, conn,
- INTERNAL_LOCKS |
- POSIX_LOCKS);
- server_conn_unref (conn);
- } else {
- put_server_conn_state (this, xprt);
- server_connection_cleanup (this, conn, INTERNAL_LOCKS);
-
- pthread_mutex_lock (&conn->lock);
- {
- if (conn->timer)
- goto unlock;
-
- gf_log (this->name, GF_LOG_INFO, "starting a grace "
- "timer for %s", conn->id);
-
- conn->timer = gf_timer_call_after (this->ctx,
- conf->grace_tv,
- grace_time_handler,
- conn);
- }
- unlock:
- pthread_mutex_unlock (&conn->lock);
- }
break;
case RPCSVC_EVENT_TRANSPORT_DESTROY:
- /*- conn obj has been disassociated from xprt on first
- * disconnect.
- * conn cleanup and destruction is handed over to
- * grace_time_handler or the subsequent handler that 'owns'
- * the conn. Nothing left to be done here. */
+ conn = get_server_conn_state (this, xprt);
+ if (conn)
+ server_connection_put (this, conn);
break;
default:
break;
@@ -747,6 +471,34 @@ out:
return ret;
}
+int
+validate_options ( xlator_t *this, char **op_errstr)
+{
+ int ret = 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp;
+
+ if (!this) {
+ gf_log (this->name, GF_LOG_DEBUG, "'this' not a valid ptr");
+ ret =-1;
+ goto out;
+ }
+
+ if (list_empty (&this->volume_options))
+ goto out;
+
+ vol_opt = list_entry (this->volume_options.next,
+ volume_opt_list_t, list);
+ list_for_each_entry_safe (vol_opt, tmp, &this->volume_options, list) {
+ ret = validate_xlator_volume_options_attacherr (this,
+ vol_opt->given_opt,
+ op_errstr);
+ }
+
+out:
+
+ return ret;
+}
static void
_delete_auth_opt (dict_t *this,
@@ -785,43 +537,6 @@ _copy_auth_opt (dict_t *unused,
int
-server_init_grace_timer (xlator_t *this, dict_t *options,
- server_conf_t *conf)
-{
- int32_t ret = -1;
- int32_t grace_timeout = -1;
- char *lk_heal = NULL;
-
- GF_VALIDATE_OR_GOTO ("server", this, out);
- GF_VALIDATE_OR_GOTO (this->name, options, out);
- GF_VALIDATE_OR_GOTO (this->name, conf, out);
-
- conf->lk_heal = _gf_false;
-
- ret = dict_get_str (options, "lk-heal", &lk_heal);
- if (!ret)
- gf_string2boolean (lk_heal, &conf->lk_heal);
-
- gf_log (this->name, GF_LOG_DEBUG, "lk-heal = %s",
- (conf->lk_heal) ? "on" : "off");
-
- ret = dict_get_int32 (options, "grace-timeout", &grace_timeout);
- if (!ret)
- conf->grace_tv.tv_sec = grace_timeout;
- else
- conf->grace_tv.tv_sec = 10;
-
- gf_log (this->name, GF_LOG_DEBUG, "Server grace timeout "
- "value = %"PRIu64, conf->grace_tv.tv_sec);
-
- conf->grace_tv.tv_usec = 0;
-
- ret = 0;
-out:
- return ret;
-}
-
-int
reconfigure (xlator_t *this, dict_t *options)
{
@@ -832,7 +547,7 @@ reconfigure (xlator_t *this, dict_t *options)
gf_boolean_t trace;
data_t *data;
int ret = 0;
- char *statedump_path = NULL;
+
conf = this->private;
if (!conf) {
@@ -860,25 +575,6 @@ reconfigure (xlator_t *this, dict_t *options)
" to %d", conf->trace);
}
-
- /*ret = dict_get_str (options, "statedump-path", &statedump_path);
- if (!ret) {
- gf_path_strip_trailing_slashes (statedump_path);
- GF_FREE (this->ctx->statedump_path);
- this->ctx->statedump_path = gf_strdup (statedump_path);
- }*/
- GF_OPTION_RECONF ("statedump-path", statedump_path,
- options, path, out);
- if (!statedump_path) {
- gf_log (this->name, GF_LOG_ERROR,
- "Error while reconfiguring statedump path");
- ret = -1;
- goto out;
- }
- gf_path_strip_trailing_slashes (statedump_path);
- GF_FREE (this->ctx->statedump_path);
- this->ctx->statedump_path = gf_strdup (statedump_path);
-
if (!conf->auth_modules)
conf->auth_modules = dict_new ();
@@ -913,7 +609,6 @@ reconfigure (xlator_t *this, dict_t *options)
"Reconfigure not found for transport" );
}
}
- ret = server_init_grace_timer (this, options, conf);
out:
gf_log ("", GF_LOG_DEBUG, "returning %d", ret);
@@ -926,7 +621,7 @@ init (xlator_t *this)
int32_t ret = -1;
server_conf_t *conf = NULL;
rpcsvc_listener_t *listener = NULL;
- char *statedump_path = NULL;
+
GF_VALIDATE_OR_GOTO ("init", this, out);
if (this->children == NULL) {
@@ -950,10 +645,6 @@ init (xlator_t *this)
INIT_LIST_HEAD (&conf->xprt_list);
pthread_mutex_init (&conf->mutex, NULL);
- ret = server_init_grace_timer (this, this->options, conf);
- if (ret)
- goto out;
-
ret = server_build_config (this, conf);
if (ret)
goto out;
@@ -962,22 +653,6 @@ init (xlator_t *this)
if (ret)
conf->conf_dir = CONFDIR;
- /*ret = dict_get_str (this->options, "statedump-path", &statedump_path);
- if (!ret) {
- gf_path_strip_trailing_slashes (statedump_path);
- this->ctx->statedump_path = statedump_path;
- }*/
- GF_OPTION_INIT ("statedump-path", statedump_path, path, out);
- if (statedump_path) {
- gf_path_strip_trailing_slashes (statedump_path);
- this->ctx->statedump_path = gf_strdup (statedump_path);
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Error setting statedump path");
- ret = -1;
- goto out;
- }
-
/* Authentication modules */
conf->auth_modules = dict_new ();
GF_VALIDATE_OR_GOTO(this->name, conf->auth_modules, out);
@@ -996,7 +671,8 @@ init (xlator_t *this)
}
/* RPC related */
- conf->rpc = rpcsvc_init (this, this->ctx, this->options, 0);
+ //conf->rpc = rpc_svc_init (&conf->rpc_conf);
+ conf->rpc = rpcsvc_init (this->ctx, this->options);
if (conf->rpc == NULL) {
gf_log (this->name, GF_LOG_WARNING,
"creation of rpcsvc failed");
@@ -1020,14 +696,14 @@ init (xlator_t *this)
goto out;
}
- glusterfs3_3_fop_prog.options = this->options;
- ret = rpcsvc_program_register (conf->rpc, &glusterfs3_3_fop_prog);
+ glusterfs3_1_fop_prog.options = this->options;
+ ret = rpcsvc_program_register (conf->rpc, &glusterfs3_1_fop_prog);
if (ret) {
gf_log (this->name, GF_LOG_WARNING,
"registration of program (name:%s, prognum:%d, "
- "progver:%d) failed", glusterfs3_3_fop_prog.progname,
- glusterfs3_3_fop_prog.prognum,
- glusterfs3_3_fop_prog.progver);
+ "progver:%d) failed", glusterfs3_1_fop_prog.progname,
+ glusterfs3_1_fop_prog.prognum,
+ glusterfs3_1_fop_prog.progver);
goto out;
}
@@ -1039,7 +715,7 @@ init (xlator_t *this)
"progver:%d) failed", gluster_handshake_prog.progname,
gluster_handshake_prog.prognum,
gluster_handshake_prog.progver);
- rpcsvc_program_unregister (conf->rpc, &glusterfs3_3_fop_prog);
+ rpcsvc_program_unregister (conf->rpc, &glusterfs3_1_fop_prog);
goto out;
}
@@ -1138,12 +814,9 @@ struct xlator_cbks cbks = {
};
struct xlator_dumpops dumpops = {
- .priv = server_priv,
- .fd = server_fd,
- .inode = server_inode,
- .priv_to_dict = server_priv_to_dict,
- .fd_to_dict = server_fd_to_dict,
- .inode_to_dict = server_inode_to_dict,
+ .priv = server_priv,
+ .fd = server_fd,
+ .inode = server_inode,
};
@@ -1169,8 +842,7 @@ struct volume_options options[] = {
{ .key = {"inode-lru-limit"},
.type = GF_OPTION_TYPE_INT,
.min = 0,
- .max = (1 * GF_UNIT_MB),
- .default_value = "16384",
+ .max = (1 * GF_UNIT_MB)
},
{ .key = {"verify-volfile-checksum"},
.type = GF_OPTION_TYPE_BOOL
@@ -1185,42 +857,5 @@ struct volume_options options[] = {
{ .key = {"rpc-auth-allow-insecure"},
.type = GF_OPTION_TYPE_BOOL,
},
- { .key = {"statedump-path"},
- .type = GF_OPTION_TYPE_PATH,
- .default_value = "/tmp",
- .description = "Specifies directory in which gluster should save its"
- " statedumps. By default it is the /tmp directory"
- },
- { .key = {"lk-heal"},
- .type = GF_OPTION_TYPE_BOOL,
- .default_value = "off",
- },
- {.key = {"grace-timeout"},
- .type = GF_OPTION_TYPE_INT,
- .min = 10,
- .max = 1800,
- },
- {.key = {"tcp-window-size"},
- .type = GF_OPTION_TYPE_SIZET,
- .min = GF_MIN_SOCKET_WINDOW_SIZE,
- .max = GF_MAX_SOCKET_WINDOW_SIZE
- },
-
- /* The following two options are defined in addr.c, redifined here *
- * for the sake of validation during volume set from cli */
-
- { .key = {"auth.addr.*.allow"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
- .description = "Allow a comma separated list of addresses and/or "
- "hostnames to connect to the server. By default, all"
- " connections are allowed."
- },
- { .key = {"auth.addr.*.reject"},
- .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST,
- .description = "Reject a comma separated list of addresses and/or "
- "hostnames to connect to the server. By default, all"
- " connections are allowed."
- },
-
{ .key = {NULL} },
};
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index f3b97891a..55ca63248 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -28,17 +28,9 @@
#include "protocol-common.h"
#include "server-mem-types.h"
#include "glusterfs3.h"
-#include "timer.h"
#define DEFAULT_BLOCK_SIZE 4194304 /* 4MB */
#define DEFAULT_VOLUME_FILE_PATH CONFDIR "/glusterfs.vol"
-#define GF_MAX_SOCKET_WINDOW_SIZE (1 * GF_UNIT_MB)
-#define GF_MIN_SOCKET_WINDOW_SIZE (0)
-
-typedef enum {
- INTERNAL_LOCKS = 1,
- POSIX_LOCKS = 2,
-} server_lock_flags_t;
typedef struct _server_state server_state_t;
@@ -47,13 +39,14 @@ struct _locker {
char *volume;
loc_t loc;
fd_t *fd;
- gf_lkowner_t owner;
+ uint64_t owner;
pid_t pid;
};
struct _lock_table {
struct list_head inodelk_lockers;
struct list_head entrylk_lockers;
+ gf_lock_t lock;
size_t count;
};
@@ -64,14 +57,13 @@ struct _server_connection {
struct list_head list;
char *id;
int ref;
- int bind_ref;
+ int active_transports;
pthread_mutex_t lock;
+ char disconnected;
fdtable_t *fdtable;
struct _lock_table *ltable;
- gf_timer_t *timer;
xlator_t *bound_xl;
xlator_t *this;
- uint32_t lk_version;
};
typedef struct _server_connection server_connection_t;
@@ -80,19 +72,11 @@ typedef struct _server_connection server_connection_t;
server_connection_t *
server_connection_get (xlator_t *this, const char *id);
-server_connection_t *
-server_connection_put (xlator_t *this, server_connection_t *conn,
- gf_boolean_t *detached);
-
-server_connection_t*
-server_conn_unref (server_connection_t *conn);
-
-server_connection_t*
-server_conn_ref (server_connection_t *conn);
+void
+server_connection_put (xlator_t *this, server_connection_t *conn);
int
-server_connection_cleanup (xlator_t *this, server_connection_t *conn,
- int32_t flags);
+server_connection_cleanup (xlator_t *this, server_connection_t *conn);
int server_null (rpcsvc_request_t *req);
@@ -108,11 +92,9 @@ struct server_conf {
int inode_lru_limit;
gf_boolean_t verify_volfile;
gf_boolean_t trace;
- gf_boolean_t lk_heal; /* If true means lock self
- heal is on else off. */
char *conf_dir;
struct _volfile_ctx *volfile;
- struct timeval grace_tv;
+
dict_t *auth_modules;
pthread_mutex_t mutex;
struct list_head conns;
@@ -132,19 +114,27 @@ typedef enum {
struct resolve_comp {
char *basename;
+ ino_t ino;
+ uint64_t gen;
inode_t *inode;
};
typedef struct {
server_resolve_type_t type;
- int64_t fd_no;
+ uint64_t fd_no;
+ ino_t ino;
+ uint64_t gen;
+ ino_t par;
u_char gfid[16];
u_char pargfid[16];
char *path;
char *bname;
+ char *resolved;
int op_ret;
int op_errno;
- loc_t resolve_loc;
+ loc_t deep_loc;
+ struct resolve_comp *components;
+ int comp_count;
} server_resolve_t;
@@ -174,7 +164,7 @@ struct _server_state {
fd_t *fd;
dict_t *params;
- int32_t flags;
+ int flags;
int wbflags;
struct iovec payload_vector[MAX_IOVEC];
int payload_count;
@@ -197,19 +187,21 @@ struct _server_state {
struct gf_flock flock;
const char *volume;
dir_entry_t *entry;
-
- dict_t *xdata;
- mode_t umask;
};
extern struct rpcsvc_program gluster_handshake_prog;
-extern struct rpcsvc_program glusterfs3_3_fop_prog;
+extern struct rpcsvc_program glusterfs3_1_fop_prog;
extern struct rpcsvc_program gluster_ping_prog;
+typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *args);
+
int
server_submit_reply (call_frame_t *frame, rpcsvc_request_t *req, void *arg,
struct iovec *payload, int payloadcount,
- struct iobref *iobref, xdrproc_t xdrproc);
+ struct iobref *iobref, gfs_serialize_t sfunc);
+
+int xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg,
+ gfs_serialize_t sfunc);
int gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict);
int gf_server_check_getxattr_cmd (call_frame_t *frame, const char *name);
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server3_1-fops.c
index da9028473..569a46742 100644
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ b/xlators/protocol/server/src/server3_1-fops.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -23,49 +23,38 @@
#include "config.h"
#endif
-#include <openssl/md5.h>
-
#include "server.h"
#include "server-helpers.h"
#include "glusterfs3-xdr.h"
#include "glusterfs3.h"
#include "compat-errno.h"
-#include "xdr-nfs3.h"
+#include "md5.h"
/* Callback function section */
int
server_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct statvfs *buf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct statvfs *buf)
{
gfs3_statfs_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
- req = frame->local;
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "%"PRId64": STATFS (%s)",
- frame->root->unique, strerror (op_errno));
- goto out;
- }
-
- gf_statfs_from_statfs (&rsp.statfs, buf);
+ req = frame->local;
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ if (op_ret >= 0) {
+ gf_statfs_from_statfs (&rsp.statfs, buf);
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": STATFS %"PRId32" (%s)",
+ frame->root->unique, op_ret, strerror (op_errno));
+ }
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_statfs_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_statfs_rsp);
return 0;
}
@@ -73,7 +62,7 @@ out:
int
server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- inode_t *inode, struct iatt *stbuf, dict_t *xdata,
+ inode_t *inode, struct iatt *stbuf, dict_t *dict,
struct iatt *postparent)
{
rpcsvc_request_t *req = NULL;
@@ -82,11 +71,13 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_t *link_inode = NULL;
loc_t fresh_loc = {0,};
gfs3_lookup_rsp rsp = {0,};
+ int32_t ret = -1;
uuid_t rootgfid = {0,};
- req = frame->local;
state = CALL_STATE(frame);
+ req = frame->local;
+
if (state->is_revalidate == 1 && op_ret == -1) {
state->is_revalidate = 2;
loc_copy (&fresh_loc, &state->loc);
@@ -95,76 +86,93 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
STACK_WIND (frame, server_lookup_cbk, BOUND_XL (frame),
BOUND_XL (frame)->fops->lookup,
- &fresh_loc, state->xdata);
+ &fresh_loc, state->dict);
loc_wipe (&fresh_loc);
return 0;
}
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if ((op_ret >= 0) && dict) {
+ rsp.dict.dict_len = dict_serialized_length (dict);
+ if (rsp.dict.dict_len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized "
+ "length of reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ rsp.dict.dict_len = 0;
+ goto out;
+ }
- if (op_ret) {
- if (state->is_revalidate && op_errno == ENOENT) {
- if (!__is_root_gfid (state->resolve.gfid)) {
- inode_unlink (state->loc.inode,
- state->loc.parent,
- state->loc.name);
- }
+ rsp.dict.dict_val = GF_CALLOC (1, rsp.dict.dict_len,
+ gf_server_mt_rsp_buf_t);
+ if (!rsp.dict.dict_val) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ rsp.dict.dict_len = 0;
+ goto out;
+ }
+ ret = dict_serialize (dict, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ rsp.dict.dict_len = 0;
+ goto out;
}
- goto out;
}
- root_inode = BOUND_XL(frame)->itable->root;
- if (inode == root_inode) {
- /* we just looked up root ("/") */
- stbuf->ia_ino = 1;
- rootgfid[15] = 1;
- uuid_copy (stbuf->ia_gfid, rootgfid);
- if (inode->ia_type == 0)
- inode->ia_type = stbuf->ia_type;
- }
+ gf_stat_from_iatt (&rsp.postparent, postparent);
- gf_stat_from_iatt (&rsp.stat, stbuf);
+ if (op_ret == 0) {
+ root_inode = BOUND_XL(frame)->itable->root;
+ if (inode == root_inode) {
+ /* we just looked up root ("/") */
+ stbuf->ia_ino = 1;
+ rootgfid[15] = 1;
+ uuid_copy (stbuf->ia_gfid, rootgfid);
+ if (inode->ia_type == 0)
+ inode->ia_type = stbuf->ia_type;
+ }
- if (!__is_root_gfid (inode->gfid)) {
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- if (link_inode) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+ if (inode->ino != 1) {
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
inode_lookup (link_inode);
inode_unref (link_inode);
}
+ } else {
+ if (state->is_revalidate && op_errno == ENOENT) {
+ if (state->loc.inode->ino != 1) {
+ inode_unlink (state->loc.inode,
+ state->loc.parent,
+ state->loc.name);
+ }
+ }
}
-
out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
if (op_ret) {
- if (state->resolve.bname) {
- gf_log (this->name, ((op_errno == ENOENT) ?
- GF_LOG_TRACE : GF_LOG_INFO),
- "%"PRId64": LOOKUP %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname,
- strerror (op_errno));
- } else {
- gf_log (this->name, ((op_errno == ENOENT) ?
- GF_LOG_TRACE : GF_LOG_INFO),
- "%"PRId64": LOOKUP %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
+ gf_log (this->name,
+ ((op_errno == ENOENT) ? GF_LOG_TRACE : GF_LOG_INFO),
+ "%"PRId64": LOOKUP %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lookup_rsp);
+ (gfs_serialize_t)xdr_serialize_lookup_rsp);
- GF_FREE (rsp.xdata.xdata_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return 0;
}
@@ -172,56 +180,47 @@ out:
int
server_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct gf_flock *lock,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct gf_flock *lock)
{
gfs3_lk_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
- if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": LK %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
+ state = CALL_STATE(frame);
+
+ if (op_ret == 0) {
+ switch (lock->l_type) {
+ case F_RDLCK:
+ lock->l_type = GF_LK_F_RDLCK;
+ break;
+ case F_WRLCK:
+ lock->l_type = GF_LK_F_WRLCK;
+ break;
+ case F_UNLCK:
+ lock->l_type = GF_LK_F_UNLCK;
+ break;
+ default:
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unknown lock type: %"PRId32"!", lock->l_type);
+ break;
}
- goto out;
- }
- switch (lock->l_type) {
- case F_RDLCK:
- lock->l_type = GF_LK_F_RDLCK;
- break;
- case F_WRLCK:
- lock->l_type = GF_LK_F_WRLCK;
- break;
- case F_UNLCK:
- lock->l_type = GF_LK_F_UNLCK;
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "Unknown lock type: %"PRId32"!", lock->l_type);
- break;
+ gf_proto_flock_from_flock (&rsp.flock, lock);
+ } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_proto_flock_from_flock (&rsp.flock, lock);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_lk_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_lk_rsp);
return 0;
}
@@ -229,49 +228,39 @@ out:
int
server_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
server_connection_t *conn = NULL;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": INODELK %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
- goto out;
- }
+ req = frame->local;
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn, state->volume,
- &state->loc, NULL, &frame->root->lk_owner,
- GF_FOP_INODELK);
- else
- gf_add_locker (conn, state->volume,
- &state->loc, NULL, frame->root->pid,
- &frame->root->lk_owner,
- GF_FOP_INODELK);
-
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ conn = SERVER_CONNECTION(frame);
+ state = CALL_STATE(frame);
- GF_FREE (rsp.xdata.xdata_val);
+ if (op_ret >= 0) {
+ if (state->flock.l_type == F_UNLCK)
+ gf_del_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->lk_owner, GF_FOP_INODELK);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid,
+ frame->root->lk_owner, GF_FOP_INODELK);
+ } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ xdr_serialize_common_rsp);
return 0;
}
@@ -279,147 +268,119 @@ out:
int
server_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
server_state_t *state = NULL;
server_connection_t *conn = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
+ req = frame->local;
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
conn = SERVER_CONNECTION(frame);
state = CALL_STATE(frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FINODELK %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
- goto out;
+ if (op_ret >= 0) {
+ if (state->flock.l_type == F_UNLCK)
+ gf_del_locker (conn->ltable, state->volume,
+ NULL, state->fd,
+ frame->root->lk_owner, GF_FOP_INODELK);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ NULL, state->fd,
+ frame->root->pid,
+ frame->root->lk_owner, GF_FOP_INODELK);
+ } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FINODELK %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- if (state->flock.l_type == F_UNLCK)
- gf_del_locker (conn, state->volume,
- NULL, state->fd,
- &frame->root->lk_owner, GF_FOP_INODELK);
- else
- gf_add_locker (conn, state->volume,
- NULL, state->fd,
- frame->root->pid,
- &frame->root->lk_owner, GF_FOP_INODELK);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
int
server_entrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
server_connection_t *conn = NULL;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
gf_common_rsp rsp = {0,};
- req = frame->local;
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": ENTRYLK %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
- goto out;
- }
-
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn, state->volume,
- &state->loc, NULL, &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
- else
- gf_add_locker (conn, state->volume,
- &state->loc, NULL, frame->root->pid,
- &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
+ req = frame->local;
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ conn = SERVER_CONNECTION(frame);
+ state = CALL_STATE(frame);
- GF_FREE (rsp.xdata.xdata_val);
+ if (op_ret >= 0) {
+ if (state->cmd == ENTRYLK_UNLOCK)
+ gf_del_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->lk_owner, GF_FOP_ENTRYLK);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ &state->loc, NULL, frame->root->pid,
+ frame->root->lk_owner, GF_FOP_ENTRYLK);
+ } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": INODELK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ xdr_serialize_common_rsp);
return 0;
}
int
server_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
server_connection_t *conn = NULL;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- conn = SERVER_CONNECTION(frame);
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FENTRYLK %"PRId64" (%s) ==>(%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- }
- goto out;
- }
-
- if (state->cmd == ENTRYLK_UNLOCK)
- gf_del_locker (conn, state->volume,
- NULL, state->fd, &frame->root->lk_owner,
- GF_FOP_ENTRYLK);
- else
- gf_add_locker (conn, state->volume,
- NULL, state->fd, frame->root->pid,
- &frame->root->lk_owner, GF_FOP_ENTRYLK);
+ req = frame->local;
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ conn = SERVER_CONNECTION(frame);
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ if (state->cmd == ENTRYLK_UNLOCK)
+ gf_del_locker (conn->ltable, state->volume,
+ NULL, state->fd, frame->root->lk_owner, GF_FOP_ENTRYLK);
+ else
+ gf_add_locker (conn->ltable, state->volume,
+ NULL, state->fd, frame->root->pid,
+ frame->root->lk_owner, GF_FOP_ENTRYLK);
+ } else if ((op_errno != ENOSYS) && (op_errno != EAGAIN)) {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FENTRYLK %"PRId64" (%"PRId64") "
+ " ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
+ }
- GF_FREE (rsp.xdata.xdata_val);
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ xdr_serialize_common_rsp);
return 0;
}
@@ -427,35 +388,27 @@ out:
int
server_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": ACCESS %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
+ state = CALL_STATE(frame);
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ if (op_ret)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": ACCESS %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
@@ -463,51 +416,41 @@ out:
int
server_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_rmdir_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *parent = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
+ req = frame->local;
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
state = CALL_STATE(frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if (op_ret == 0) {
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
- if (op_ret) {
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RMDIR %s (%s/%s) ==> (%s)",
+ "%"PRId64": RMDIR %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
- parent = inode_parent (state->loc.inode, 0, NULL);
- if (parent)
- /* parent should not be found for directories after
- * inode_unlink, since directories cannot have
- * hardlinks.
- */
- inode_unref (parent);
- else
- inode_forget (state->loc.inode, 0);
-
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rmdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_rmdir_rsp);
return 0;
}
@@ -516,45 +459,37 @@ int
server_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_mkdir_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *link_inode = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKDIR %s (%s/%s) ==> (%s)",
+ "%"PRId64": MKDIR %s ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_mkdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_mkdir_rsp);
return 0;
}
@@ -563,213 +498,170 @@ int
server_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
inode_t *inode, struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_mknod_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *link_inode = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": MKNOD %s (%s/%s) ==> (%s)",
+ "%"PRId64": MKNOD %s ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_mknod_rsp);
+ xdr_serialize_mknod_rsp);
- GF_FREE (rsp.xdata.xdata_val);
return 0;
}
int
server_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ state = CALL_STATE(frame);
if (op_ret < 0) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSYNCDIR %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": FSYNCDIR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
+ state->fd ? state->fd->inode->ino : 0, op_ret,
strerror (op_errno));
- goto out;
}
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
int
server_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
gfs3_readdir_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
int ret = 0;
- req = frame->local;
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READDIR %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
+ req = frame->local;
- /* (op_ret == 0) is valid, and means EOF */
- if (op_ret) {
+ state = CALL_STATE(frame);
+ if (op_ret > 0) {
ret = serialize_rsp_dirent (entries, &rsp);
if (ret == -1) {
op_ret = -1;
op_errno = ENOMEM;
- goto out;
+ goto unwind;
}
+ } else {
+ /* (op_ret == 0) is valid, and means EOF, don't log for that */
+ gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE,
+ "%"PRId64": READDIR %"PRId64" (%"PRId64") ==> %"PRId32
+ " (%s)", frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
-
-out:
+unwind:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readdir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_readdir_rsp);
readdir_rsp_cleanup (&rsp);
return 0;
}
+
int
-server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+server_releasedir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
- server_connection_t *conn = NULL;
- server_state_t *state = NULL;
- rpcsvc_request_t *req = NULL;
- gfs3_opendir_rsp rsp = {0,};
- uint64_t fd_no = 0;
-
- req = frame->local;
- conn = SERVER_CONNECTION (frame);
- state = CALL_STATE (frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": OPENDIR %s (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
+ gf_common_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
- fd_bind (fd);
- fd_no = gf_fd_unused_get (conn->fdtable, fd);
- fd_ref (fd); // on behalf of the client
+ req = frame->local;
-out:
- rsp.fd = fd_no;
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_opendir_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
int
-server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+server_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
- gf_common_rsp rsp = {0,};
- rpcsvc_request_t *req = NULL;
- server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
+ server_state_t *state = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfs3_opendir_rsp rsp = {0,};
+ uint64_t fd_no = 0;
- req = frame->local;
- state = CALL_STATE(frame);
+ conn = SERVER_CONNECTION (frame);
+ state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if (op_ret >= 0) {
+ fd_bind (fd);
- if (op_ret == -1) {
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd); // on behalf of the client
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": REMOVEXATTR %s (%s) of key %s ==> (%s)",
+ "%"PRId64": OPENDIR %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- state->name, strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
-out:
+ req = frame->local;
+
+ rsp.fd = fd_no;
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_opendir_rsp);
return 0;
}
int
-server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+server_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
@@ -778,69 +670,81 @@ server_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
req = frame->local;
state = CALL_STATE(frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FREMOVEXATTR %"PRId64" (%s) (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), state->name,
- strerror (op_errno));
- goto out;
- }
-
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": REMOVEXATTR %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
int
server_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
gfs3_getxattr_rsp rsp = {0,};
+ int32_t len = 0;
+ int32_t ret = -1;
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if (op_ret >= 0) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized length of "
+ "reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ goto out;
+ }
- if (op_ret == -1) {
- gf_log (this->name, (((op_errno == ENOTSUP) ||
- (op_errno == ENODATA)) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": GETXATTR %s (%s) (%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- state->name, strerror (op_errno));
- goto out;
+ rsp.dict.dict_val = GF_CALLOC (len, sizeof (char),
+ gf_server_mt_rsp_buf_t);
+ if (!rsp.dict.dict_val) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ len = 0;
+ goto out;
+ }
+ ret = dict_serialize (dict, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ }
}
-
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, (&rsp.dict.dict_val),
- rsp.dict.dict_len, op_errno, out);
-
out:
+ req = frame->local;
+
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp.dict.dict_len = len;
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": GETXATTR %s (%s) ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->name, op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_getxattr_rsp);
-
- GF_FREE (rsp.dict.dict_val);
+ xdr_serialize_getxattr_rsp);
- GF_FREE (rsp.xdata.xdata_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return 0;
}
@@ -848,82 +752,89 @@ out:
int
server_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
gfs3_fgetxattr_rsp rsp = {0,};
+ int32_t len = 0;
+ int32_t ret = -1;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": FGETXATTR %"PRId64" (%s) (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- state->name, strerror (op_errno));
- goto out;
+ if (op_ret >= 0) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized "
+ "length of reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ goto out;
+ }
+ rsp.dict.dict_val = GF_CALLOC (1, len, gf_server_mt_rsp_buf_t);
+ if (!rsp.dict.dict_val) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ len = 0;
+ goto out;
+ }
+ ret = dict_serialize (dict, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->resolve.ino);
+ op_ret = -1;
+ op_errno = -ret;
+ len = 0;
+ }
}
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, (&rsp.dict.dict_val),
- rsp.dict.dict_len, op_errno, out);
-
out:
+ req = frame->local;
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp.dict.dict_len = len;
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FGETXATTR %"PRId64" (%s) ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->name, op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fgetxattr_rsp);
+ xdr_serialize_fgetxattr_rsp);
- GF_FREE (rsp.dict.dict_val);
-
- GF_FREE (rsp.xdata.xdata_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return 0;
}
int
server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ req = frame->local;
- if (op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": SETXATTR %s (%s) ==> %s (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- ((state->dict) ? ((state->dict->members_list) ?
- state->dict->members_list->key :
- "(null)") : ("null")),
- strerror (op_errno));
- goto out;
- }
-
-out:
+ state = CALL_STATE(frame);
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": SETXATTR %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
@@ -931,39 +842,27 @@ out:
int
server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ state = CALL_STATE(frame);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret == -1) {
- gf_log (this->name, ((op_errno == ENOTSUP) ?
- GF_LOG_DEBUG : GF_LOG_INFO),
- "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s (%s)",
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FSETXATTR %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- ((state->dict) ? ((state->dict->members_list) ?
- state->dict->members_list->key :
- "(null)") : "null"),
+ state->fd ? state->fd->inode->ino : 0, op_ret,
strerror (op_errno));
- goto out;
- }
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_common_rsp);
return 0;
}
@@ -972,83 +871,52 @@ int
server_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
struct iatt *preoldparent, struct iatt *postoldparent,
- struct iatt *prenewparent, struct iatt *postnewparent,
- dict_t *xdata)
+ struct iatt *prenewparent, struct iatt *postnewparent)
{
gfs3_rename_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- inode_t *tmp_inode = NULL;
- inode_t *tmp_parent = NULL;
- char oldpar_str[50] = {0,};
- char newpar_str[50] = {0,};
- req = frame->local;
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ req = frame->local;
- if (op_ret == -1) {
- uuid_utoa_r (state->resolve.gfid, oldpar_str);
- uuid_utoa_r (state->resolve2.gfid, newpar_str);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RENAME %s (%s/%s) -> %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- oldpar_str, state->resolve.bname, state->loc2.path,
- newpar_str, state->resolve2.bname, strerror (op_errno));
- goto out;
- }
-
- stbuf->ia_type = state->loc.inode->ia_type;
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- /* TODO: log gfid of the inodes */
- gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": RENAME_CBK %s ==> %s",
- frame->root->unique, state->loc.name, state->loc2.name);
+ state = CALL_STATE(frame);
- /* Before renaming the inode, we have to get the inode for the
- * destination entry (i.e. inode with state->loc2.parent as
- * parent and state->loc2.name as name). If it exists, then
- * unlink that inode, and send forget on that inode if the
- * unlinked entry is the last entry. In case of fuse client
- * the fuse kernel module itself sends the forget on the
- * unlinked inode.
- */
- tmp_inode = inode_grep (state->loc.inode->table,
- state->loc2.parent, state->loc2.name);
- if (tmp_inode) {
- inode_unlink (tmp_inode, state->loc2.parent,
- state->loc2.name);
- tmp_parent = inode_parent (tmp_inode, 0, NULL);
- if (tmp_parent)
- inode_unref (tmp_parent);
- else
- inode_forget (tmp_inode, 0);
+ if (op_ret == 0) {
+ stbuf->ia_ino = state->loc.inode->ino;
+ stbuf->ia_type = state->loc.inode->ia_type;
- inode_unref (tmp_inode);
- }
+ gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": RENAME_CBK (%"PRId64") %"PRId64"/%s "
+ "==> %"PRId64"/%s",
+ frame->root->unique, state->loc.inode->ino,
+ state->loc.parent->ino, state->loc.name,
+ state->loc2.parent->ino, state->loc2.name);
- inode_rename (state->itable,
- state->loc.parent, state->loc.name,
- state->loc2.parent, state->loc2.name,
- state->loc.inode, stbuf);
- gf_stat_from_iatt (&rsp.stat, stbuf);
+ inode_rename (state->itable,
+ state->loc.parent, state->loc.name,
+ state->loc2.parent, state->loc2.name,
+ state->loc.inode, stbuf);
+ gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preoldparent, preoldparent);
- gf_stat_from_iatt (&rsp.postoldparent, postoldparent);
+ gf_stat_from_iatt (&rsp.preoldparent, preoldparent);
+ gf_stat_from_iatt (&rsp.postoldparent, postoldparent);
- gf_stat_from_iatt (&rsp.prenewparent, prenewparent);
- gf_stat_from_iatt (&rsp.postnewparent, postnewparent);
+ gf_stat_from_iatt (&rsp.prenewparent, prenewparent);
+ gf_stat_from_iatt (&rsp.postnewparent, postnewparent);
+ }
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": RENAME %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rename_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_rename_rsp);
return 0;
}
@@ -1056,53 +924,48 @@ out:
int
server_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_unlink_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *parent = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": UNLINK %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
+ state = CALL_STATE(frame);
- /* TODO: log gfid of the inodes */
- gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": UNLINK_CBK %s",
- frame->root->unique, state->loc.name);
+ if (op_ret == 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": UNLINK_CBK %"PRId64"/%s (%"PRId64")",
+ frame->root->unique, state->loc.parent->ino,
+ state->loc.name, state->loc.inode->ino);
- inode_unlink (state->loc.inode, state->loc.parent,
- state->loc.name);
+ inode_unlink (state->loc.inode, state->loc.parent,
+ state->loc.name);
- parent = inode_parent (state->loc.inode, 0, NULL);
- if (parent)
- inode_unref (parent);
- else
- inode_forget (state->loc.inode, 0);
+ parent = inode_parent (state->loc.inode, 0, NULL);
+ if (parent)
+ inode_unref (parent);
+ else
+ inode_forget (state->loc.inode, 0);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": UNLINK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
+ }
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_unlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_unlink_rsp);
return 0;
}
@@ -1111,45 +974,38 @@ int
server_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_symlink_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *link_inode = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SYMLINK %s (%s/%s) ==> (%s)",
+ "%"PRId64": SYMLINK %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
- inode_lookup (link_inode);
- inode_unref (link_inode);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_symlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_symlink_rsp);
return 0;
}
@@ -1159,48 +1015,42 @@ int
server_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, inode_t *inode,
struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ struct iatt *postparent)
{
gfs3_link_rsp rsp = {0,};
server_state_t *state = NULL;
inode_t *link_inode = NULL;
rpcsvc_request_t *req = NULL;
- char gfid_str[50] = {0,};
- char newpar_str[50] = {0,};
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
- uuid_utoa_r (state->resolve.gfid, gfid_str);
- uuid_utoa_r (state->resolve2.pargfid, newpar_str);
+ state = CALL_STATE(frame);
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": LINK %s (%s) -> %s/%s ==> (%s)",
- frame->root->unique, state->loc.path, gfid_str,
- newpar_str, state->resolve2.bname, strerror (op_errno));
- goto out;
- }
+ if (op_ret == 0) {
+ stbuf->ia_ino = state->loc.inode->ino;
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
- link_inode = inode_link (inode, state->loc2.parent,
- state->loc2.name, stbuf);
- inode_unref (link_inode);
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
+ link_inode = inode_link (inode, state->loc2.parent,
+ state->loc2.name, stbuf);
+ inode_unref (link_inode);
+ }
- server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_link_rsp);
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": LINK %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
- GF_FREE (rsp.xdata.xdata_val);
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ xdr_serialize_link_rsp);
return 0;
}
@@ -1208,74 +1058,63 @@ out:
int
server_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
gfs3_truncate_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE (frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
+ state = CALL_STATE (frame);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": TRUNCATE %s (%s) ==> (%s)",
+ "%"PRId64": TRUNCATE %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.prestat, prebuf);
- gf_stat_from_iatt (&rsp.poststat, postbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_truncate_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_truncate_rsp);
return 0;
}
int
server_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
{
gfs3_fstat_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
+ state = CALL_STATE(frame);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSTAT %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": FSTAT %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fstat_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_fstat_rsp);
return 0;
}
@@ -1283,71 +1122,61 @@ out:
int
server_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
gfs3_ftruncate_rsp rsp = {0};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE (frame);
+ req = frame->local;
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ state = CALL_STATE (frame);
- if (op_ret) {
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FTRUNCATE %"PRId64" (%s)==> (%s)",
+ "%"PRId64": FTRUNCATE %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.prestat, prebuf);
- gf_stat_from_iatt (&rsp.poststat, postbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_ftruncate_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_ftruncate_rsp);
return 0;
}
int
server_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno)
{
gf_common_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+ state = CALL_STATE(frame);
if (op_ret < 0) {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FLUSH %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": FLUSH %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ xdr_serialize_common_rsp);
- GF_FREE (rsp.xdata.xdata_val);
return 0;
}
@@ -1355,37 +1184,32 @@ out:
int
server_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
gfs3_fsync_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
+
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ state = CALL_STATE(frame);
- if (op_ret < 0) {
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&(rsp.prestat), prebuf);
+ gf_stat_from_iatt (&(rsp.poststat), postbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSYNC %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": FSYNC %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_stat_from_iatt (&(rsp.prestat), prebuf);
- gf_stat_from_iatt (&(rsp.poststat), postbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsync_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_fsync_rsp);
return 0;
}
@@ -1393,37 +1217,31 @@ out:
int
server_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
- struct iatt *postbuf, dict_t *xdata)
+ struct iatt *postbuf)
{
gfs3_write_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.prestat, prebuf);
+ gf_stat_from_iatt (&rsp.poststat, postbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": WRITEV %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": WRITEV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.prestat, prebuf);
- gf_stat_from_iatt (&rsp.poststat, postbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_write_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_writev_rsp);
return 0;
}
@@ -1433,47 +1251,31 @@ int
server_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
struct iovec *vector, int32_t count,
- struct iatt *stbuf, struct iobref *iobref, dict_t *xdata)
+ struct iatt *stbuf, struct iobref *iobref)
{
gfs3_read_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
-
-#ifdef GF_TESTING_IO_XDATA
- {
- int ret = 0;
- if (!xdata)
- xdata = dict_new ();
+ req = frame->local;
- ret = dict_set_str (xdata, "testing-the-xdata-key",
- "testing-xdata-value");
- }
-#endif
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+ state = CALL_STATE(frame);
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ rsp.size = op_ret;
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READV %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": READV %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
- rsp.size = op_ret;
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, vector, count, iobref,
- (xdrproc_t)xdr_gfs3_read_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_readv_rsp);
return 0;
}
@@ -1481,40 +1283,33 @@ out:
int
server_rchecksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- uint32_t weak_checksum, uint8_t *strong_checksum,
- dict_t *xdata)
+ uint32_t weak_checksum, uint8_t *strong_checksum)
{
gfs3_rchecksum_rsp rsp = {0,};
rpcsvc_request_t *req = NULL;
server_state_t *state = NULL;
- req = frame->local;
+ req = frame->local;
+
state = CALL_STATE(frame);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if (op_ret >= 0) {
+ rsp.weak_checksum = weak_checksum;
- if (op_ret < 0) {
+ rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum;
+ rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LEN;
+ }
+ if (op_ret == -1)
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": RCHECKSUM %"PRId64" (%s)==> (%s)",
+ "%"PRId64": RCHECKSUM %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid), strerror (op_errno));
- goto out;
- }
-
- rsp.weak_checksum = weak_checksum;
-
- rsp.strong_checksum.strong_checksum_val = (char *)strong_checksum;
- rsp.strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_rchecksum_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_rchecksum_rsp);
return 0;
}
@@ -1522,7 +1317,7 @@ out:
int
server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, fd_t *fd)
{
server_connection_t *conn = NULL;
server_state_t *state = NULL;
@@ -1530,44 +1325,38 @@ server_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
uint64_t fd_no = 0;
gfs3_open_rsp rsp = {0,};
- req = frame->local;
conn = SERVER_CONNECTION (frame);
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
+ if (op_ret >= 0) {
+ fd_bind (fd);
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": OPEN %s (%s) ==> (%s)",
+ "%"PRId64": OPEN %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- fd_bind (fd);
- fd_no = gf_fd_unused_get (conn->fdtable, fd);
- fd_ref (fd);
- rsp.fd = fd_no;
+ req = frame->local;
-out:
+ rsp.fd = fd_no;
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_open_rsp);
- GF_FREE (rsp.xdata.xdata_val);
-
+ xdr_serialize_open_rsp);
return 0;
}
int
server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode,
- struct iatt *stbuf, struct iatt *preparent,
- struct iatt *postparent, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno,
+ fd_t *fd, inode_t *inode, struct iatt *stbuf,
+ struct iatt *preparent, struct iatt *postparent)
{
server_connection_t *conn = NULL;
server_state_t *state = NULL;
@@ -1576,73 +1365,67 @@ server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
uint64_t fd_no = 0;
gfs3_create_rsp rsp = {0,};
- req = frame->local;
conn = SERVER_CONNECTION (frame);
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ if (op_ret >= 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
+ "%"PRId64": CREATE %"PRId64"/%s (%"PRId64")",
+ frame->root->unique, state->loc.parent->ino,
+ state->loc.name, stbuf->ia_ino);
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": CREATE %s (%s/%s) ==> (%s)",
- frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.pargfid),
- state->resolve.bname, strerror (op_errno));
- goto out;
- }
+ link_inode = inode_link (inode, state->loc.parent,
+ state->loc.name, stbuf);
- /* TODO: log gfid too */
- gf_log (state->conn->bound_xl->name, GF_LOG_TRACE,
- "%"PRId64": CREATE %s (%s)",
- frame->root->unique, state->loc.name,
- uuid_utoa (stbuf->ia_gfid));
+ if (!link_inode) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ }
- link_inode = inode_link (inode, state->loc.parent,
- state->loc.name, stbuf);
+ if (link_inode != inode) {
+ /*
+ VERY racy code (if used anywhere else)
+ -- don't do this without understanding
+ */
- if (!link_inode) {
- op_ret = -1;
- op_errno = ENOENT;
- goto out;
- }
+ inode_unref (fd->inode);
+ fd->inode = inode_ref (link_inode);
+ }
- if (link_inode != inode) {
- /*
- VERY racy code (if used anywhere else)
- -- don't do this without understanding
- */
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
- inode_unref (fd->inode);
- fd->inode = inode_ref (link_inode);
- }
+ fd_bind (fd);
- inode_lookup (link_inode);
- inode_unref (link_inode);
+ fd_no = gf_fd_unused_get (conn->fdtable, fd);
+ fd_ref (fd);
- fd_bind (fd);
-
- fd_no = gf_fd_unused_get (conn->fdtable, fd);
- fd_ref (fd);
+ if ((fd_no < 0) || (fd == 0)) {
+ op_ret = fd_no;
+ op_errno = errno;
+ }
- if ((fd_no < 0) || (fd == 0)) {
- op_ret = fd_no;
- op_errno = errno;
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ gf_stat_from_iatt (&rsp.preparent, preparent);
+ gf_stat_from_iatt (&rsp.postparent, postparent);
+ } else {
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": CREATE %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
- gf_stat_from_iatt (&rsp.preparent, preparent);
- gf_stat_from_iatt (&rsp.postparent, postparent);
-
out:
+ req = frame->local;
+
rsp.fd = fd_no;
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_create_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_create_rsp);
return 0;
}
@@ -1650,79 +1433,67 @@ out:
int
server_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, const char *buf,
- struct iatt *stbuf, dict_t *xdata)
+ struct iatt *stbuf)
{
gfs3_readlink_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE(frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret < 0) {
+
+ state = CALL_STATE(frame);
+
+ if (op_ret >= 0) {
+ gf_stat_from_iatt (&rsp.buf, stbuf);
+ rsp.path = (char *)buf;
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READLINK %s (%s) ==> (%s)",
+ "%"PRId64": READLINK %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.buf, stbuf);
- rsp.path = (char *)buf;
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
if (!rsp.path)
rsp.path = "";
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readlink_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_readlink_rsp);
return 0;
}
int
server_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *stbuf,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, struct iatt *stbuf)
{
gfs3_stat_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE (frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
+ state = CALL_STATE (frame);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": STAT %s (%s) ==> (%s)",
+ "%"PRId64": STAT %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.stat, stbuf);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_stat_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_stat_rsp);
return 0;
}
@@ -1731,38 +1502,32 @@ out:
int
server_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpre, struct iatt *statpost)
{
gfs3_setattr_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
- state = CALL_STATE (frame);
+ req = frame->local;
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
- if (op_ret) {
+ state = CALL_STATE (frame);
+
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": SETATTR %s (%s) ==> (%s)",
+ "%"PRId64": SETATTR %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.statpre, statpre);
- gf_stat_from_iatt (&rsp.statpost, statpost);
-
-out:
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
-
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_setattr_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_setattr_rsp);
return 0;
}
@@ -1770,38 +1535,33 @@ out:
int
server_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno,
- struct iatt *statpre, struct iatt *statpost, dict_t *xdata)
+ struct iatt *statpre, struct iatt *statpost)
{
gfs3_fsetattr_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret) {
+ if (op_ret == 0) {
+ gf_stat_from_iatt (&rsp.statpre, statpre);
+ gf_stat_from_iatt (&rsp.statpost, statpost);
+ } else {
gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FSETATTR %"PRId64" (%s) ==> (%s)",
+ "%"PRId64": FSETATTR %"PRId64" (%"PRId64") ==> "
+ "%"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
+ state->fd ? state->fd->inode->ino : 0,
+ op_ret, strerror (op_errno));
}
- gf_stat_from_iatt (&rsp.statpre, statpre);
- gf_stat_from_iatt (&rsp.statpost, statpost);
+ req = frame->local;
-out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fsetattr_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_fsetattr_rsp);
return 0;
}
@@ -1809,41 +1569,72 @@ out:
int
server_xattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
gfs3_xattrop_rsp rsp = {0,};
+ int32_t len = 0;
+ int32_t ret = -1;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
state = CALL_STATE (frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": XATTROP %s (%s) ==> (%s)",
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": XATTROP %s (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->loc.path,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
goto out;
}
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, (&rsp.dict.dict_val),
- rsp.dict.dict_len, op_errno, out);
-
+ if ((op_ret >= 0) && dict) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to get serialized length"
+ " for reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ goto out;
+ }
+ rsp.dict.dict_val = GF_CALLOC (1, len, gf_server_mt_rsp_buf_t);
+ if (!rsp.dict.dict_val) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ len = 0;
+ goto out;
+ }
+ ret = dict_serialize (dict, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s (%"PRId64"): failed to serialize reply dict",
+ state->loc.path, state->loc.inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ len = 0;
+ }
+ }
out:
+ req = frame->local;
+
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp.dict.dict_len = len;
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": XATTROP %s (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->loc.path,
+ state->loc.inode ? state->loc.inode->ino : 0,
+ op_ret, strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_xattrop_rsp);
-
- GF_FREE (rsp.dict.dict_val);
+ xdr_serialize_xattrop_rsp);
- GF_FREE (rsp.xdata.xdata_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return 0;
}
@@ -1851,41 +1642,73 @@ out:
int
server_fxattrop_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, dict_t *dict,
- dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
{
gfs3_xattrop_rsp rsp = {0,};
+ int32_t len = 0;
+ int32_t ret = -1;
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
- req = frame->local;
state = CALL_STATE(frame);
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": FXATTROP %"PRId64" (%s) ==> (%s)",
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%"PRId64": FXATTROP %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
+ state->fd ? state->fd->inode->ino : 0, op_ret,
strerror (op_errno));
goto out;
}
- GF_PROTOCOL_DICT_SERIALIZE (this, dict, (&rsp.dict.dict_val),
- rsp.dict.dict_len, op_errno, out);
-
+ if ((op_ret >= 0) && dict) {
+ len = dict_serialized_length (dict);
+ if (len < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to get "
+ "serialized length for reply dict",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = EINVAL;
+ len = 0;
+ goto out;
+ }
+ rsp.dict.dict_val = GF_CALLOC (1, len, gf_server_mt_rsp_buf_t);
+ if (!rsp.dict.dict_val) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ len = 0;
+ goto out;
+ }
+ ret = dict_serialize (dict, rsp.dict.dict_val);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to "
+ "serialize reply dict",
+ state->resolve.fd_no, state->fd->inode->ino);
+ op_ret = -1;
+ op_errno = -ret;
+ len = 0;
+ }
+ }
out:
+ req = frame->local;
+
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp.dict.dict_len = len;
+ if (op_ret == -1)
+ gf_log (this->name, GF_LOG_INFO,
+ "%"PRId64": FXATTROP %"PRId64" (%"PRId64") ==> %"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_fxattrop_rsp);
-
- GF_FREE (rsp.dict.dict_val);
+ xdr_serialize_fxattrop_rsp);
- GF_FREE (rsp.xdata.xdata_val);
+ if (rsp.dict.dict_val)
+ GF_FREE (rsp.dict.dict_val);
return 0;
}
@@ -1893,49 +1716,39 @@ out:
int
server_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, dict_t *xdata)
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)
{
gfs3_readdirp_rsp rsp = {0,};
server_state_t *state = NULL;
rpcsvc_request_t *req = NULL;
int ret = 0;
- req = frame->local;
- state = CALL_STATE(frame);
-
- GF_PROTOCOL_DICT_SERIALIZE (this, xdata, (&rsp.xdata.xdata_val),
- rsp.xdata.xdata_len, op_errno, out);
-
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_INFO,
- "%"PRId64": READDIRP %"PRId64" (%s) ==> (%s)",
- frame->root->unique, state->resolve.fd_no,
- uuid_utoa (state->resolve.gfid),
- strerror (op_errno));
- goto out;
- }
+ req = frame->local;
- /* (op_ret == 0) is valid, and means EOF */
- if (op_ret) {
+ state = CALL_STATE(frame);
+ if (op_ret > 0) {
ret = serialize_rsp_direntp (entries, &rsp);
if (ret == -1) {
op_ret = -1;
op_errno = ENOMEM;
goto out;
}
+ } else {
+ /* (op_ret == 0) is valid, and means EOF, don't log for that */
+ gf_log (this->name, (op_ret) ? GF_LOG_INFO : GF_LOG_TRACE,
+ "%"PRId64": READDIRP %"PRId64" (%"PRId64") ==>"
+ "%"PRId32" (%s)",
+ frame->root->unique, state->resolve.fd_no,
+ state->fd ? state->fd->inode->ino : 0, op_ret,
+ strerror (op_errno));
}
- /* TODO: need more clear thoughts before calling this function. */
- /* gf_link_inodes_from_dirent (this, state->fd->inode, entries); */
-
out:
rsp.op_ret = op_ret;
rsp.op_errno = gf_errno_to_error (op_errno);
server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gfs3_readdirp_rsp);
-
- GF_FREE (rsp.xdata.xdata_val);
+ xdr_serialize_readdirp_rsp);
readdirp_rsp_cleanup (&rsp);
@@ -1961,12 +1774,11 @@ server_rchecksum_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_rchecksum_cbk, bound_xl,
bound_xl->fops->rchecksum, state->fd,
- state->offset, state->size, state->xdata);
+ state->offset, state->size);
return 0;
err:
- server_rchecksum_cbk (frame, NULL, frame->this, op_ret, op_errno, 0,
- NULL, NULL);
+ server_rchecksum_cbk (frame, NULL, frame->this, op_ret, op_errno, 0, NULL);
return 0;
@@ -1983,13 +1795,13 @@ server_lk_resume (call_frame_t *frame, xlator_t *bound_xl)
goto err;
STACK_WIND (frame, server_lk_cbk, bound_xl, bound_xl->fops->lk,
- state->fd, state->cmd, &state->flock, state->xdata);
+ state->fd, state->cmd, &state->flock);
return 0;
err:
server_lk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2016,11 +1828,11 @@ server_rename_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_rename_cbk,
bound_xl, bound_xl->fops->rename,
- &state->loc, &state->loc2, state->xdata);
+ &state->loc, &state->loc2);
return 0;
err:
server_rename_cbk (frame, NULL, frame->this, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
return 0;
}
@@ -2049,12 +1861,12 @@ server_link_resume (call_frame_t *frame, xlator_t *bound_xl)
state->loc2.inode = inode_ref (state->loc.inode);
STACK_WIND (frame, server_link_cbk, bound_xl, bound_xl->fops->link,
- &state->loc, &state->loc2, state->xdata);
+ &state->loc, &state->loc2);
return 0;
err:
server_link_cbk (frame, NULL, frame->this, op_ret, op_errno,
- NULL, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL);
return 0;
}
@@ -2072,12 +1884,12 @@ server_symlink_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_symlink_cbk,
bound_xl, bound_xl->fops->symlink,
- state->name, &state->loc, state->umask, state->xdata);
+ state->name, &state->loc, state->params);
return 0;
err:
server_symlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -2094,11 +1906,11 @@ server_access_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_access_cbk,
bound_xl, bound_xl->fops->access,
- &state->loc, state->mask, state->xdata);
+ &state->loc, state->mask);
return 0;
err:
server_access_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2115,12 +1927,12 @@ server_fentrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fentrylk_cbk, bound_xl,
bound_xl->fops->fentrylk,
state->volume, state->fd, state->name,
- state->cmd, state->type, state->xdata);
+ state->cmd, state->type);
return 0;
err:
server_fentrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2138,11 +1950,11 @@ server_entrylk_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_entrylk_cbk,
bound_xl, bound_xl->fops->entrylk,
state->volume, &state->loc, state->name,
- state->cmd, state->type, state->xdata);
+ state->cmd, state->type);
return 0;
err:
server_entrylk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2158,13 +1970,13 @@ server_finodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
goto err;
STACK_WIND (frame, server_finodelk_cbk, bound_xl,
- bound_xl->fops->finodelk, state->volume, state->fd,
- state->cmd, &state->flock, state->xdata);
+ bound_xl->fops->finodelk,
+ state->volume, state->fd, state->cmd, &state->flock);
return 0;
err:
server_finodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2179,13 +1991,13 @@ server_inodelk_resume (call_frame_t *frame, xlator_t *bound_xl)
if (state->resolve.op_ret != 0)
goto err;
- STACK_WIND (frame, server_inodelk_cbk, bound_xl,
- bound_xl->fops->inodelk, state->volume, &state->loc,
- state->cmd, &state->flock, state->xdata);
+ STACK_WIND (frame, server_inodelk_cbk,
+ bound_xl, bound_xl->fops->inodelk,
+ state->volume, &state->loc, state->cmd, &state->flock);
return 0;
err:
server_inodelk_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2199,12 +2011,12 @@ server_rmdir_resume (call_frame_t *frame, xlator_t *bound_xl)
if (state->resolve.op_ret != 0)
goto err;
- STACK_WIND (frame, server_rmdir_cbk, bound_xl, bound_xl->fops->rmdir,
- &state->loc, state->flags, state->xdata);
+ STACK_WIND (frame, server_rmdir_cbk,
+ bound_xl, bound_xl->fops->rmdir, &state->loc, state->flags);
return 0;
err:
server_rmdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2223,12 +2035,12 @@ server_mkdir_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_mkdir_cbk,
bound_xl, bound_xl->fops->mkdir,
- &(state->loc), state->mode, state->umask, state->xdata);
+ &(state->loc), state->mode, state->params);
return 0;
err:
server_mkdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -2248,12 +2060,12 @@ server_mknod_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_mknod_cbk,
bound_xl, bound_xl->fops->mknod,
&(state->loc), state->mode, state->dev,
- state->umask, state->xdata);
+ state->params);
return 0;
err:
server_mknod_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL, NULL, NULL);
return 0;
}
@@ -2271,13 +2083,13 @@ server_fsyncdir_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fsyncdir_cbk,
bound_xl,
bound_xl->fops->fsyncdir,
- state->fd, state->flags, state->xdata);
+ state->fd, state->flags);
return 0;
err:
server_fsyncdir_cbk (frame, NULL, frame->this,
state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2292,17 +2104,15 @@ server_readdir_resume (call_frame_t *frame, xlator_t *bound_xl)
if (state->resolve.op_ret != 0)
goto err;
- GF_ASSERT (state->fd);
-
STACK_WIND (frame, server_readdir_cbk,
bound_xl,
bound_xl->fops->readdir,
- state->fd, state->size, state->offset, state->xdata);
+ state->fd, state->size, state->offset);
return 0;
err:
server_readdir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2318,12 +2128,12 @@ server_readdirp_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_readdirp_cbk, bound_xl,
bound_xl->fops->readdirp, state->fd, state->size,
- state->offset, state->dict);
+ state->offset);
return 0;
err:
server_readdirp_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2339,18 +2149,14 @@ server_opendir_resume (call_frame_t *frame, xlator_t *bound_xl)
goto err;
state->fd = fd_create (state->loc.inode, frame->root->pid);
- if (!state->fd) {
- gf_log ("server", GF_LOG_ERROR, "could not create the fd");
- goto err;
- }
STACK_WIND (frame, server_opendir_cbk,
bound_xl, bound_xl->fops->opendir,
- &state->loc, state->fd, state->xdata);
+ &state->loc, state->fd);
return 0;
err:
server_opendir_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2367,12 +2173,12 @@ server_statfs_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_statfs_cbk,
bound_xl, bound_xl->fops->statfs,
- &state->loc, state->xdata);
+ &state->loc);
return 0;
err:
server_statfs_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2389,31 +2195,11 @@ server_removexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_removexattr_cbk,
bound_xl, bound_xl->fops->removexattr,
- &state->loc, state->name, state->xdata);
+ &state->loc, state->name);
return 0;
err:
server_removexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
- return 0;
-}
-
-int
-server_fremovexattr_resume (call_frame_t *frame, xlator_t *bound_xl)
-{
- server_state_t *state = NULL;
-
- state = CALL_STATE (frame);
-
- if (state->resolve.op_ret != 0)
- goto err;
-
- STACK_WIND (frame, server_fremovexattr_cbk,
- bound_xl, bound_xl->fops->fremovexattr,
- state->fd, state->name, state->xdata);
- return 0;
-err:
- server_fremovexattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2429,11 +2215,11 @@ server_fgetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fgetxattr_cbk,
bound_xl, bound_xl->fops->fgetxattr,
- state->fd, state->name, state->xdata);
+ state->fd, state->name);
return 0;
err:
server_fgetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2450,11 +2236,11 @@ server_xattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_xattrop_cbk,
bound_xl, bound_xl->fops->xattrop,
- &state->loc, state->flags, state->dict, state->xdata);
+ &state->loc, state->flags, state->dict);
return 0;
err:
server_xattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2470,11 +2256,11 @@ server_fxattrop_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fxattrop_cbk,
bound_xl, bound_xl->fops->fxattrop,
- state->fd, state->flags, state->dict, state->xdata);
+ state->fd, state->flags, state->dict);
return 0;
err:
server_fxattrop_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2490,11 +2276,11 @@ server_fsetxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_setxattr_cbk,
bound_xl, bound_xl->fops->fsetxattr,
- state->fd, state->dict, state->flags, state->xdata);
+ state->fd, state->dict, state->flags);
return 0;
err:
server_fsetxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2511,11 +2297,11 @@ server_unlink_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_unlink_cbk,
bound_xl, bound_xl->fops->unlink,
- &state->loc, state->flags, state->xdata);
+ &state->loc);
return 0;
err:
server_unlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2531,11 +2317,11 @@ server_truncate_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_truncate_cbk,
bound_xl, bound_xl->fops->truncate,
- &state->loc, state->offset, state->xdata);
+ &state->loc, state->offset);
return 0;
err:
server_truncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2553,11 +2339,11 @@ server_fstat_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fstat_cbk,
bound_xl, bound_xl->fops->fstat,
- state->fd, state->xdata);
+ state->fd);
return 0;
err:
server_fstat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2574,11 +2360,11 @@ server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_setxattr_cbk,
bound_xl, bound_xl->fops->setxattr,
- &state->loc, state->dict, state->flags, state->xdata);
+ &state->loc, state->dict, state->flags);
return 0;
err:
server_setxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2596,11 +2382,11 @@ server_getxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_getxattr_cbk,
bound_xl, bound_xl->fops->getxattr,
- &state->loc, state->name, state->xdata);
+ &state->loc, state->name);
return 0;
err:
server_getxattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2617,11 +2403,11 @@ server_ftruncate_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_ftruncate_cbk,
bound_xl, bound_xl->fops->ftruncate,
- state->fd, state->offset, state->xdata);
+ state->fd, state->offset);
return 0;
err:
server_ftruncate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2638,11 +2424,11 @@ server_flush_resume (call_frame_t *frame, xlator_t *bound_xl)
goto err;
STACK_WIND (frame, server_flush_cbk,
- bound_xl, bound_xl->fops->flush, state->fd, state->xdata);
+ bound_xl, bound_xl->fops->flush, state->fd);
return 0;
err:
server_flush_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL);
+ state->resolve.op_errno);
return 0;
}
@@ -2660,11 +2446,11 @@ server_fsync_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fsync_cbk,
bound_xl, bound_xl->fops->fsync,
- state->fd, state->flags, state->xdata);
+ state->fd, state->flags);
return 0;
err:
server_fsync_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2682,12 +2468,12 @@ server_writev_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_writev_cbk,
bound_xl, bound_xl->fops->writev,
state->fd, state->payload_vector, state->payload_count,
- state->offset, state->flags, state->iobref, state->xdata);
+ state->offset, state->iobref);
return 0;
err:
server_writev_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2704,12 +2490,12 @@ server_readv_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_readv_cbk,
bound_xl, bound_xl->fops->readv,
- state->fd, state->size, state->offset, state->flags, state->xdata);
+ state->fd, state->size, state->offset);
return 0;
err:
server_readv_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, 0, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, 0, NULL, NULL);
return 0;
}
@@ -2727,26 +2513,18 @@ server_create_resume (call_frame_t *frame, xlator_t *bound_xl)
state->loc.inode = inode_new (state->itable);
state->fd = fd_create (state->loc.inode, frame->root->pid);
- if (!state->fd) {
- gf_log ("server", GF_LOG_ERROR, "fd creation for the inode %s "
- "failed", state->loc.inode?
- uuid_utoa (state->loc.inode->gfid):NULL);
- state->resolve.op_ret = -1;
- state->resolve.op_errno = ENOMEM;
- goto err;
- }
state->fd->flags = state->flags;
STACK_WIND (frame, server_create_cbk,
bound_xl, bound_xl->fops->create,
&(state->loc), state->flags, state->mode,
- state->umask, state->fd, state->xdata);
+ state->fd, state->params);
return 0;
err:
server_create_cbk (frame, NULL, frame->this, state->resolve.op_ret,
state->resolve.op_errno, NULL, NULL, NULL,
- NULL, NULL, NULL);
+ NULL, NULL);
return 0;
}
@@ -2766,12 +2544,12 @@ server_open_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_open_cbk,
bound_xl, bound_xl->fops->open,
- &state->loc, state->flags, state->fd, state->xdata);
+ &state->loc, state->flags, state->fd, 0);
return 0;
err:
server_open_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2788,11 +2566,11 @@ server_readlink_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_readlink_cbk,
bound_xl, bound_xl->fops->readlink,
- &state->loc, state->size, state->xdata);
+ &state->loc, state->size);
return 0;
err:
server_readlink_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2809,11 +2587,11 @@ server_fsetattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_fsetattr_cbk,
bound_xl, bound_xl->fops->fsetattr,
- state->fd, &state->stbuf, state->valid, state->xdata);
+ state->fd, &state->stbuf, state->valid);
return 0;
err:
server_fsetattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2831,11 +2609,11 @@ server_setattr_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_setattr_cbk,
bound_xl, bound_xl->fops->setattr,
- &state->loc, &state->stbuf, state->valid, state->xdata);
+ &state->loc, &state->stbuf, state->valid);
return 0;
err:
server_setattr_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL, NULL);
+ state->resolve.op_errno, NULL, NULL);
return 0;
}
@@ -2852,11 +2630,11 @@ server_stat_resume (call_frame_t *frame, xlator_t *bound_xl)
goto err;
STACK_WIND (frame, server_stat_cbk,
- bound_xl, bound_xl->fops->stat, &state->loc, state->xdata);
+ bound_xl, bound_xl->fops->stat, &state->loc);
return 0;
err:
server_stat_cbk (frame, NULL, frame->this, state->resolve.op_ret,
- state->resolve.op_errno, NULL, NULL);
+ state->resolve.op_errno, NULL);
return 0;
}
@@ -2877,7 +2655,7 @@ server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl)
STACK_WIND (frame, server_lookup_cbk,
bound_xl, bound_xl->fops->lookup,
- &state->loc, state->xdata);
+ &state->loc, state->dict);
return 0;
err:
@@ -2893,20 +2671,20 @@ err:
/* Fop section */
int
-server3_3_stat (rpcsvc_request_t *req)
+server_stat (rpcsvc_request_t *req)
{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_stat_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs3_stat_req args = {{0,},};
+ int ret = -1;
if (!req)
return 0;
/* Initialize args first, then decode */
+ args.path = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req)) {
+ if (!xdr_to_stat_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -2929,39 +2707,29 @@ server3_3_stat (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
+ state->resolve.path = gf_strdup (args.path);
ret = 0;
resolve_and_resume (frame, server_stat_resume);
-
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_setattr (rpcsvc_request_t *req)
+server_setattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_setattr_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return 0;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setattr_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+
+ if (!xdr_to_setattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -2984,41 +2752,30 @@ server3_3_setattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
+ state->resolve.path = gf_strdup (args.path);
gf_stat_to_iatt (&args.stbuf, &state->stbuf);
state->valid = args.valid;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_setattr_resume);
-
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
- free (args.xdata.xdata_val);
-
return ret;
}
int
-server3_3_fsetattr (rpcsvc_request_t *req)
+server_fsetattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_fsetattr_req args = {0,};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsetattr_req)) {
+ if (!xdr_to_fsetattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3045,37 +2802,27 @@ server3_3_fsetattr (rpcsvc_request_t *req)
gf_stat_to_iatt (&args.stbuf, &state->stbuf);
state->valid = args.valid;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_fsetattr_resume);
-
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_readlink (rpcsvc_request_t *req)
+server_readlink (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_readlink_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readlink_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+
+ if (!xdr_to_readlink_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3098,42 +2845,34 @@ server3_3_readlink (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->size = args.size;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_readlink_resume);
-
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_create (rpcsvc_request_t *req)
+server_create (rpcsvc_request_t *req)
{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_create_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ dict_t *params = NULL;
+ char *buf = NULL;
+ gfs3_create_req args = {{0,},};
+ int ret = -1;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_create_req)) {
+ if (!xdr_to_create_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3153,53 +2892,80 @@ server3_3_create (rpcsvc_request_t *req)
req->rpc_err = GARBAGE_ARGS;
goto out;
}
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ params = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ goto out;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len,
+ &params);
+ if (ret < 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ goto out;
+ }
+
+ state->params = params;
+ params->extra_free = buf;
+ buf = NULL;
+ }
+
+ state->resolve.type = RESOLVE_NOT;
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->mode = args.mode;
- state->umask = args.umask;
state->flags = gf_flags_to_flags (args.flags);
memcpy (state->resolve.pargfid, args.pargfid, 16);
- if (state->flags & O_EXCL) {
- state->resolve.type = RESOLVE_NOT;
- } else {
- state->resolve.type = RESOLVE_DONTCARE;
- }
-
- /* TODO: can do alloca for xdata field instead of stdalloc */
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_create_resume);
-out:
/* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
+ return ret;
+out:
+ if (params)
+ dict_unref (params);
+
+ if (buf) {
+ GF_FREE (buf);
+ }
+
+ /* memory allocated by libc, don't use GF_FREE */
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
return ret;
}
int
-server3_3_open (rpcsvc_request_t *req)
+server_open (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_open_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+
+ if (!xdr_to_open_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3222,39 +2988,29 @@ server3_3_open (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->flags = gf_flags_to_flags (args.flags);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_open_resume);
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
- free (args.xdata.xdata_val);
-
return ret;
}
int
-server3_3_readv (rpcsvc_request_t *req)
+server_readv (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_read_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
goto out;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_read_req)) {
+ if (!xdr_to_readv_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3279,30 +3035,16 @@ server3_3_readv (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->size = args.size;
state->offset = args.offset;
- state->flags = args.flag;
-
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_readv_resume);
out:
- /* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_writev (rpcsvc_request_t *req)
+server_writev (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
@@ -3310,12 +3052,11 @@ server3_3_writev (rpcsvc_request_t *req)
ssize_t len = 0;
int i = 0;
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- len = xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_write_req);
+ len = xdr_to_writev_req (req->msg[0], &args);
if (len == 0) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -3340,9 +3081,7 @@ server3_3_writev (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
- state->flags = args.flag;
state->iobref = iobref_ref (req->iobref);
- memcpy (state->resolve.gfid, args.gfid, 16);
if (len < req->msg[0].iov_len) {
state->payload_vector[0].iov_base
@@ -3361,146 +3100,64 @@ server3_3_writev (rpcsvc_request_t *req)
state->size += state->payload_vector[i].iov_len;
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
-#ifdef GF_TESTING_IO_XDATA
- dict_dump (state->xdata);
-#endif
-
ret = 0;
resolve_and_resume (frame, server_writev_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_writev_vec (rpcsvc_request_t *req, struct iovec *payload,
+server_writev_vec (rpcsvc_request_t *req, struct iovec *payload,
int payload_count, struct iobref *iobref)
{
- return server3_3_writev (req);
-}
-
-#define SERVER3_3_VECWRITE_START 0
-#define SERVER3_3_VECWRITE_READING_HDR 1
-#define SERVER3_3_VECWRITE_READING_OPAQUE 2
-
-int
-server3_3_writev_vecsizer (int state, ssize_t *readsize, char *base_addr,
- char *curr_addr)
-{
- ssize_t size = 0;
- int nextstate = 0;
- gfs3_write_req write_req = {{0,},};
- XDR xdr;
-
- switch (state) {
- case SERVER3_3_VECWRITE_START:
- size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
- &write_req);
- *readsize = size;
- nextstate = SERVER3_3_VECWRITE_READING_HDR;
- break;
- case SERVER3_3_VECWRITE_READING_HDR:
- size = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req,
- &write_req);
-
- xdrmem_create (&xdr, base_addr, size, XDR_DECODE);
-
- /* This will fail if there is xdata sent from client, if not,
- well and good */
- xdr_gfs3_write_req (&xdr, &write_req);
-
- /* need to round off to proper roof (%4), as XDR packing pads
- the end of opaque object with '0' */
- size = roof (write_req.xdata.xdata_len, 4);
-
- *readsize = size;
-
- if (!size)
- nextstate = SERVER3_3_VECWRITE_START;
- else
- nextstate = SERVER3_3_VECWRITE_READING_OPAQUE;
-
- free (write_req.xdata.xdata_val);
-
- break;
-
- case SERVER3_3_VECWRITE_READING_OPAQUE:
- *readsize = 0;
- nextstate = SERVER3_3_VECWRITE_START;
- break;
- default:
- gf_log ("server", GF_LOG_ERROR, "wrong state: %d", state);
- }
-
- return nextstate;
+ return server_writev (req);
}
int
-server3_3_release (rpcsvc_request_t *req)
+server_release (rpcsvc_request_t *req)
{
server_connection_t *conn = NULL;
gfs3_release_req args = {{0,},};
gf_common_rsp rsp = {0,};
int ret = -1;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_release_req)) {
+ if (!xdr_to_release_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
conn = req->trans->xl_private;
- if (!conn) {
- /* Handshake is not complete yet. */
- req->rpc_err = SYSTEM_ERR;
- goto out;
- }
gf_fd_put (conn->fdtable, args.fd);
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
+ xdr_serialize_common_rsp);
ret = 0;
out:
return ret;
}
int
-server3_3_releasedir (rpcsvc_request_t *req)
+server_releasedir (rpcsvc_request_t *req)
{
server_connection_t *conn = NULL;
gfs3_releasedir_req args = {{0,},};
gf_common_rsp rsp = {0,};
int ret = -1;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_release_req)) {
+ if (!xdr_to_release_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
}
conn = req->trans->xl_private;
- if (!conn) {
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
gf_fd_put (conn->fdtable, args.fd);
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
-
+ xdr_serialize_common_rsp);
ret = 0;
out:
return ret;
@@ -3508,18 +3165,17 @@ out:
int
-server3_3_fsync (rpcsvc_request_t *req)
+server_fsync (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_fsync_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsync_req)) {
+ if (!xdr_to_fsync_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3543,39 +3199,27 @@ server3_3_fsync (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.data;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_fsync_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_flush (rpcsvc_request_t *req)
+server_flush (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_flush_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_flush_req)) {
+ if (!xdr_to_flush_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3598,39 +3242,27 @@ server3_3_flush (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_flush_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_ftruncate (rpcsvc_request_t *req)
+server_ftruncate (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_ftruncate_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_ftruncate_req)) {
+ if (!xdr_to_ftruncate_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3654,38 +3286,26 @@ server3_3_ftruncate (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_ftruncate_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_fstat (rpcsvc_request_t *req)
+server_fstat (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
- gfs3_fstat_req args = {{0,},};
+ gfs3_write_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fstat_req)) {
+ if (!xdr_to_fstat_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3708,38 +3328,27 @@ server3_3_fstat (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_fstat_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_truncate (rpcsvc_request_t *req)
+server_truncate (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_truncate_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_truncate_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+ if (!xdr_to_truncate_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3761,42 +3370,33 @@ server3_3_truncate (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
state->offset = args.offset;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_truncate_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_unlink (rpcsvc_request_t *req)
+server_unlink (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_unlink_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_unlink_req)) {
+ if (!xdr_to_unlink_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3818,44 +3418,37 @@ server3_3_unlink (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->flags = args.xflags;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_unlink_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_setxattr (rpcsvc_request_t *req)
+server_setxattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
dict_t *dict = NULL;
call_frame_t *frame = NULL;
+ server_connection_t *conn = NULL;
+ char *buf = NULL;
gfs3_setxattr_req args = {{0,},};
int32_t ret = -1;
- int32_t op_errno = 0;
if (!req)
return ret;
+ conn = req->trans->xl_private;
+
+ args.path = alloca (req->msg[0].iov_len);
args.dict.dict_val = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setxattr_req)) {
+ if (!xdr_to_setxattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3877,57 +3470,71 @@ server3_3_setxattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
state->flags = args.flags;
memcpy (state->resolve.gfid, args.gfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
+ if (args.dict.dict_len) {
+ dict = dict_new ();
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (conn->bound_xl->name, buf, out);
- state->dict = dict;
+ ret = dict_unserialize (buf, args.dict.dict_len, &dict);
+ if (ret < 0) {
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize request buffer to dictionary",
+ frame->root->unique, state->loc.path,
+ state->resolve.ino);
+ goto err;
+ }
+
+ dict->extra_free = buf;
+ buf = NULL;
+
+ state->dict = dict;
+ }
/* There can be some commands hidden in key, check and proceed */
gf_server_check_setxattr_cmd (frame, dict);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_setxattr_resume);
return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
+err:
if (dict)
dict_unref (dict);
+ server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL);
+ ret = 0;
+out:
+ if (buf)
+ GF_FREE (buf);
return ret;
+
}
int
-server3_3_fsetxattr (rpcsvc_request_t *req)
+server_fsetxattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
dict_t *dict = NULL;
+ server_connection_t *conn = NULL;
call_frame_t *frame = NULL;
+ char *buf = NULL;
gfs3_fsetxattr_req args = {{0,},};
int32_t ret = -1;
- int32_t op_errno = 0;
if (!req)
return ret;
+ conn = req->trans->xl_private;
+
args.dict.dict_val = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsetxattr_req)) {
+ if (!xdr_to_fsetxattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -3951,53 +3558,62 @@ server3_3_fsetxattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.flags;
- memcpy (state->resolve.gfid, args.gfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
+ if (args.dict.dict_len) {
+ dict = dict_new ();
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (conn->bound_xl->name, buf, out);
- state->dict = dict;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ ret = dict_unserialize (buf, args.dict.dict_len, &dict);
+ if (ret < 0) {
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize request buffer to dictionary",
+ frame->root->unique, state->loc.path,
+ state->resolve.ino);
+ goto err;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+ state->dict = dict;
+ }
ret = 0;
resolve_and_resume (frame, server_fsetxattr_resume);
return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
+err:
if (dict)
dict_unref (dict);
+ server_setxattr_cbk (frame, NULL, frame->this, -1, EINVAL);
+ ret = 0;
+out:
+ if (buf)
+ GF_FREE (buf);
return ret;
}
int
-server3_3_fxattrop (rpcsvc_request_t *req)
+server_fxattrop (rpcsvc_request_t *req)
{
dict_t *dict = NULL;
server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
call_frame_t *frame = NULL;
+ char *buf = NULL;
gfs3_fxattrop_req args = {{0,},};
int32_t ret = -1;
- int32_t op_errno = 0;
if (!req)
return ret;
+ conn = req->trans->xl_private;
+
args.dict.dict_val = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fxattrop_req)) {
+ if (!xdr_to_fxattrop_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4023,53 +3639,64 @@ server3_3_fxattrop (rpcsvc_request_t *req)
state->flags = args.flags;
memcpy (state->resolve.gfid, args.gfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
- state->dict = dict;
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (conn->bound_xl->name, buf, out);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ ret = dict_unserialize (buf, args.dict.dict_len, &dict);
+ if (ret < 0) {
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to unserialize "
+ "request buffer to dictionary",
+ state->resolve.fd_no, state->fd->inode->ino);
+ goto fail;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
+
+ state->dict = dict;
+ }
ret = 0;
resolve_and_resume (frame, server_fxattrop_resume);
return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
+fail:
if (dict)
dict_unref (dict);
+ server_fxattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
+ ret = 0;
+out:
return ret;
}
int
-server3_3_xattrop (rpcsvc_request_t *req)
+server_xattrop (rpcsvc_request_t *req)
{
dict_t *dict = NULL;
server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
call_frame_t *frame = NULL;
+ char *buf = NULL;
gfs3_xattrop_req args = {{0,},};
int32_t ret = -1;
- int32_t op_errno = 0;
if (!req)
return ret;
+ conn = req->trans->xl_private;
+
args.dict.dict_val = alloca (req->msg[0].iov_len);
+ args.path = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_xattrop_req)) {
+ if (!xdr_to_xattrop_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4091,53 +3718,61 @@ server3_3_xattrop (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
state->flags = args.flags;
memcpy (state->resolve.gfid, args.gfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ GF_VALIDATE_OR_GOTO (conn->bound_xl->name, buf, out);
- state->dict = dict;
+ ret = dict_unserialize (buf, args.dict.dict_len, &dict);
+ if (ret < 0) {
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): failed to unserialize "
+ "request buffer to dictionary",
+ state->resolve.fd_no, state->fd->inode->ino);
+ goto fail;
+ }
+ dict->extra_free = buf;
+ buf = NULL;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ state->dict = dict;
+ }
ret = 0;
resolve_and_resume (frame, server_xattrop_resume);
return ret;
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
+fail:
if (dict)
dict_unref (dict);
+ server_xattrop_cbk (frame, NULL, frame->this, -1, EINVAL, NULL);
+ ret = 0;
+out:
return ret;
}
int
-server3_3_getxattr (rpcsvc_request_t *req)
+server_getxattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_getxattr_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.name = alloca (256);
+ args.path = alloca (req->msg[0].iov_len);
+ args.name = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_getxattr_req)) {
+ if (!xdr_to_getxattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4159,6 +3794,7 @@ server3_3_getxattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen) {
@@ -4167,37 +3803,26 @@ server3_3_getxattr (rpcsvc_request_t *req)
gf_server_check_getxattr_cmd (frame, state->name);
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_getxattr_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_fgetxattr (rpcsvc_request_t *req)
+server_fgetxattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_fgetxattr_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.name = alloca (256);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fgetxattr_req)) {
+ args.name = alloca (4096);
+ if (!xdr_to_fgetxattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4220,44 +3845,33 @@ server3_3_fgetxattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
state->name = gf_strdup (args.name);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_fgetxattr_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_removexattr (rpcsvc_request_t *req)
+server_removexattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_removexattr_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.name = alloca (256);
+ args.path = alloca (req->msg[0].iov_len);
+ args.name = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_removexattr_req)) {
+ if (!xdr_to_removexattr_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4279,79 +3893,13 @@ server3_3_removexattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
state->name = gf_strdup (args.name);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_removexattr_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
- return ret;
-}
-
-int
-server3_3_fremovexattr (rpcsvc_request_t *req)
-{
- server_state_t *state = NULL;
- call_frame_t *frame = NULL;
- gfs3_fremovexattr_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
-
- if (!req)
- return ret;
-
- args.name = alloca (4096);
-
- if (!xdr_to_generic (req->msg[0], &args,
- (xdrproc_t)xdr_gfs3_fremovexattr_req)) {
- //failed to decode msg;
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- frame = get_frame_from_request (req);
- if (!frame) {
- // something wrong, mostly insufficient memory
- req->rpc_err = GARBAGE_ARGS; /* TODO */
- goto out;
- }
- frame->root->op = GF_FOP_FREMOVEXATTR;
-
- state = CALL_STATE (frame);
- if (!state->conn->bound_xl) {
- /* auth failure, request on subvolume without setvolume */
- req->rpc_err = GARBAGE_ARGS;
- goto out;
- }
-
- state->resolve.type = RESOLVE_MUST;
- state->resolve.fd_no = args.fd;
- memcpy (state->resolve.gfid, args.gfid, 16);
- state->name = gf_strdup (args.name);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
- ret = 0;
- resolve_and_resume (frame, server_fremovexattr_resume);
-out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
@@ -4359,18 +3907,19 @@ out:
int
-server3_3_opendir (rpcsvc_request_t *req)
+server_opendir (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_opendir_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_opendir_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+
+ if (!xdr_to_opendir_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4392,39 +3941,29 @@ server3_3_opendir (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_opendir_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_readdirp (rpcsvc_request_t *req)
+server_readdirp (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_readdirp_req args = {{0,},};
size_t headers_size = 0;
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readdirp_req)) {
+ if (!xdr_to_readdirp_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4459,40 +3998,26 @@ server3_3_readdirp (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- /* here, dict itself works as xdata */
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->dict,
- (args.dict.dict_val),
- (args.dict.dict_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_readdirp_resume);
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
- free (args.dict.dict_val);
-
return ret;
}
int
-server3_3_readdir (rpcsvc_request_t *req)
+server_readdir (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_readdir_req args = {{0,},};
size_t headers_size = 0;
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readdir_req)) {
+ if (!xdr_to_readdir_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4527,37 +4052,25 @@ server3_3_readdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_readdir_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_fsyncdir (rpcsvc_request_t *req)
+server_fsyncdir (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_fsyncdir_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fsyncdir_req)) {
+ if (!xdr_to_fsyncdir_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4581,41 +4094,32 @@ server3_3_fsyncdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.data;
- memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_fsyncdir_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_mknod (rpcsvc_request_t *req)
+server_mknod (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
+ dict_t *params = NULL;
+ char *buf = NULL;
gfs3_mknod_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mknod_req)) {
+ if (!xdr_to_mknod_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4636,28 +4140,62 @@ server3_3_mknod (rpcsvc_request_t *req)
goto out;
}
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ params = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ goto out;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len,
+ &params);
+ if (ret < 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ goto out;
+ }
+
+ state->params = params;
+
+ params->extra_free = buf;
+
+ buf = NULL;
+ }
+
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
- state->mode = args.mode;
- state->dev = args.dev;
- state->umask = args.umask;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ state->mode = args.mode;
+ state->dev = args.dev;
ret = 0;
resolve_and_resume (frame, server_mknod_resume);
+ /* memory allocated by libc, don't use GF_FREE */
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
+
+ return ret;
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
+ if (params)
+ dict_unref (params);
+
+ if (buf) {
+ GF_FREE (buf);
+ }
/* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
return ret;
@@ -4665,20 +4203,22 @@ out:
int
-server3_3_mkdir (rpcsvc_request_t *req)
+server_mkdir (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
+ dict_t *params = NULL;
+ char *buf = NULL;
gfs3_mkdir_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mkdir_req)) {
+ if (!xdr_to_mkdir_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4698,48 +4238,81 @@ server3_3_mkdir (rpcsvc_request_t *req)
req->rpc_err = GARBAGE_ARGS;
goto out;
}
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ params = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ goto out;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len,
+ &params);
+ if (ret < 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ goto out;
+ }
+
+ state->params = params;
+
+ params->extra_free = buf;
+
+ buf = NULL;
+ }
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
- state->mode = args.mode;
- state->umask = args.umask;
-
- /* TODO: can do alloca for xdata field instead of stdalloc */
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ state->mode = args.mode;
ret = 0;
resolve_and_resume (frame, server_mkdir_resume);
+ if (args.dict.dict_val != NULL) {
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.dict.dict_val);
+ }
+
+ return ret;
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
+ if (params)
+ dict_unref (params);
- free (args.xdata.xdata_val);
+ if (buf) {
+ GF_FREE (buf);
+ }
+
+ if (args.dict.dict_val != NULL) {
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.dict.dict_val);
+ }
return ret;
}
int
-server3_3_rmdir (rpcsvc_request_t *req)
+server_rmdir (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_rmdir_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rmdir_req)) {
+ if (!xdr_to_rmdir_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4762,44 +4335,35 @@ server3_3_rmdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
- state->flags = args.xflags;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ state->flags = args.flags;
ret = 0;
resolve_and_resume (frame, server_rmdir_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_inodelk (rpcsvc_request_t *req)
+server_inodelk (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_inodelk_req args = {{0,},};
int cmd = 0;
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.volume = alloca (256);
+ args.path = alloca (req->msg[0].iov_len);
+ args.volume = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_inodelk_req)) {
+ if (!xdr_to_inodelk_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4822,6 +4386,7 @@ server3_3_inodelk (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_EXACT;
memcpy (state->resolve.gfid, args.gfid, 16);
+ state->resolve.path = gf_strdup (args.path);
cmd = args.cmd;
switch (cmd) {
@@ -4853,38 +4418,25 @@ server3_3_inodelk (rpcsvc_request_t *req)
break;
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_inodelk_resume);
out:
- free (args.xdata.xdata_val);
-
- free (args.flock.lk_owner.lk_owner_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_finodelk (rpcsvc_request_t *req)
+server_finodelk (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_finodelk_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.volume = alloca (256);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_finodelk_req)) {
+ args.volume = alloca (4096);
+ if (!xdr_to_finodelk_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4909,7 +4461,6 @@ server3_3_finodelk (rpcsvc_request_t *req)
state->volume = gf_strdup (args.volume);
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
- memcpy (state->resolve.gfid, args.gfid, 16);
switch (state->cmd) {
case GF_LK_GETLK:
@@ -4939,41 +4490,29 @@ server3_3_finodelk (rpcsvc_request_t *req)
break;
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_finodelk_resume);
out:
- free (args.xdata.xdata_val);
-
- free (args.flock.lk_owner.lk_owner_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_entrylk (rpcsvc_request_t *req)
+server_entrylk (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_entrylk_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.volume = alloca (256);
- args.name = alloca (256);
+ args.path = alloca (req->msg[0].iov_len);
+ args.volume = alloca (4096);
+ args.name = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_entrylk_req)) {
+ if (!xdr_to_entrylk_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -4995,6 +4534,7 @@ server3_3_entrylk (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_EXACT;
+ state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
@@ -5004,38 +4544,27 @@ server3_3_entrylk (rpcsvc_request_t *req)
state->cmd = args.cmd;
state->type = args.type;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_entrylk_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_fentrylk (rpcsvc_request_t *req)
+server_fentrylk (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_fentrylk_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- args.name = alloca (256);
- args.volume = alloca (256);
+ args.name = alloca (4096);
+ args.volume = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fentrylk_req)) {
+ if (!xdr_to_fentrylk_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5060,41 +4589,30 @@ server3_3_fentrylk (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
state->type = args.type;
- memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
state->name = gf_strdup (args.name);
state->volume = gf_strdup (args.volume);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_fentrylk_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_access (rpcsvc_request_t *req)
+server_access (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_access_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_access_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+ if (!xdr_to_access_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5117,42 +4635,35 @@ server3_3_access (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->mask = args.mask;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_access_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_symlink (rpcsvc_request_t *req)
+server_symlink (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
+ dict_t *params = NULL;
+ char *buf = NULL;
gfs3_symlink_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
args.linkname = alloca (4096);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_symlink_req)) {
+ if (!xdr_to_symlink_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5173,26 +4684,59 @@ server3_3_symlink (rpcsvc_request_t *req)
goto out;
}
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ params = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ goto out;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len,
+ &params);
+ if (ret < 0) {
+ gf_log (state->conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ goto out;
+ }
+
+ state->params = params;
+
+ params->extra_free = buf;
+
+ buf = NULL;
+ }
+
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->name = gf_strdup (args.linkname);
- state->umask = args.umask;
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
ret = 0;
resolve_and_resume (frame, server_symlink_resume);
+ /* memory allocated by libc, don't use GF_FREE */
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
+ return ret;
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
+ if (params)
+ dict_unref (params);
+
+ if (buf) {
+ GF_FREE (buf);
+ }
/* memory allocated by libc, don't use GF_FREE */
- free (args.xdata.xdata_val);
+ if (args.dict.dict_val != NULL) {
+ free (args.dict.dict_val);
+ }
return ret;
}
@@ -5200,20 +4744,21 @@ out:
int
-server3_3_link (rpcsvc_request_t *req)
+server_link (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_link_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.oldpath = alloca (req->msg[0].iov_len);
+ args.newpath = alloca (req->msg[0].iov_len);
args.newbname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_link_req)) {
+ if (!xdr_to_link_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5235,45 +4780,38 @@ server3_3_link (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.oldpath);
memcpy (state->resolve.gfid, args.oldgfid, 16);
state->resolve2.type = RESOLVE_NOT;
+ state->resolve2.path = gf_strdup (args.newpath);
state->resolve2.bname = gf_strdup (args.newbname);
memcpy (state->resolve2.pargfid, args.newgfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_link_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_rename (rpcsvc_request_t *req)
+server_rename (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_rename_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
+ args.oldpath = alloca (req->msg[0].iov_len);
args.oldbname = alloca (req->msg[0].iov_len);
+ args.newpath = alloca (req->msg[0].iov_len);
args.newbname = alloca (req->msg[0].iov_len);
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rename_req)) {
+ if (!xdr_to_rename_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5295,42 +4833,36 @@ server3_3_rename (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
+ state->resolve.path = gf_strdup (args.oldpath);
state->resolve.bname = gf_strdup (args.oldbname);
memcpy (state->resolve.pargfid, args.oldgfid, 16);
state->resolve2.type = RESOLVE_MAY;
+ state->resolve2.path = gf_strdup (args.newpath);
state->resolve2.bname = gf_strdup (args.newbname);
memcpy (state->resolve2.pargfid, args.newgfid, 16);
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_rename_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_lk (rpcsvc_request_t *req)
+server_lk (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
call_frame_t *frame = NULL;
gfs3_lk_req args = {{0,},};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lk_req)) {
+ conn = req->trans->xl_private;
+
+ if (!xdr_to_lk_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5354,7 +4886,6 @@ server3_3_lk (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
state->type = args.type;
- memcpy (state->resolve.gfid, args.gfid, 16);
switch (state->cmd) {
case GF_LK_GETLK:
@@ -5395,46 +4926,32 @@ server3_3_lk (rpcsvc_request_t *req)
state->flock.l_type = F_UNLCK;
break;
default:
- gf_log (state->conn->bound_xl->name, GF_LOG_ERROR,
- "fd - %"PRId64" (%s): Unknown lock type: %"PRId32"!",
- state->resolve.fd_no,
- uuid_utoa (state->fd->inode->gfid), state->type);
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "fd - %"PRId64" (%"PRId64"): Unknown lock type: %"PRId32"!",
+ state->resolve.fd_no, state->fd->inode->ino, state->type);
break;
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_lk_resume);
out:
- free (args.xdata.xdata_val);
-
- free (args.flock.lk_owner.lk_owner_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
int
-server3_3_rchecksum (rpcsvc_request_t *req)
+server_rchecksum (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_rchecksum_req args = {0,};
int ret = -1;
- int op_errno = 0;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rchecksum_req)) {
+ if (!xdr_to_rchecksum_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5460,19 +4977,9 @@ server3_3_rchecksum (rpcsvc_request_t *req)
state->offset = args.offset;
state->size = args.len;
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
-
ret = 0;
resolve_and_resume (frame, server_rchecksum_resume);
out:
- free (args.xdata.xdata_val);
-
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
@@ -5485,26 +4992,31 @@ server_null (rpcsvc_request_t *req)
rsp.op_ret = 0;
server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_common_rsp);
+ (gfs_serialize_t)xdr_serialize_common_rsp);
return 0;
}
int
-server3_3_lookup (rpcsvc_request_t *req)
+server_lookup (rpcsvc_request_t *req)
{
- call_frame_t *frame = NULL;
- server_state_t *state = NULL;
- gfs3_lookup_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
+ call_frame_t *frame = NULL;
+ server_connection_t *conn = NULL;
+ server_state_t *state = NULL;
+ dict_t *xattr_req = NULL;
+ char *buf = NULL;
+ gfs3_lookup_req args = {{0,},};
+ int ret = -1;
GF_VALIDATE_OR_GOTO ("server", req, err);
- args.bname = alloca (req->msg[0].iov_len);
- args.xdata.xdata_val = alloca (req->msg[0].iov_len);
+ conn = req->trans->xl_private;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_lookup_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+ args.bname = alloca (req->msg[0].iov_len);
+ args.dict.dict_val = alloca (req->msg[0].iov_len);
+
+ if (!xdr_to_lookup_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto err;
@@ -5528,26 +5040,54 @@ server3_3_lookup (rpcsvc_request_t *req)
req->rpc_err = GARBAGE_ARGS;
goto out;
}
+ memcpy (state->resolve.gfid, args.gfid, 16);
state->resolve.type = RESOLVE_DONTCARE;
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
+ state->resolve.path = gf_strdup (args.path);
- if (args.bname && strcmp (args.bname, "")) {
- memcpy (state->resolve.pargfid, args.pargfid, 16);
+ if (IS_NOT_ROOT (STRLEN_0 (args.path))) {
state->resolve.bname = gf_strdup (args.bname);
- } else {
- memcpy (state->resolve.gfid, args.gfid, 16);
}
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ if (args.dict.dict_len) {
+ /* Unserialize the dictionary */
+ xattr_req = dict_new ();
+
+ buf = memdup (args.dict.dict_val, args.dict.dict_len);
+ if (buf == NULL) {
+ goto out;
+ }
+
+ ret = dict_unserialize (buf, args.dict.dict_len,
+ &xattr_req);
+ if (ret < 0) {
+ gf_log (conn->bound_xl->name, GF_LOG_ERROR,
+ "%"PRId64": %s (%"PRId64"): failed to "
+ "unserialize req-buffer to dictionary",
+ frame->root->unique, state->resolve.path,
+ state->resolve.ino);
+ goto out;
+ }
+
+ state->dict = xattr_req;
+
+ xattr_req->extra_free = buf;
+
+ buf = NULL;
+ }
ret = 0;
resolve_and_resume (frame, server_lookup_resume);
return ret;
out:
+ if (xattr_req)
+ dict_unref (xattr_req);
+
+ if (buf) {
+ GF_FREE (buf);
+ }
server_lookup_cbk (frame, NULL, frame->this, -1, EINVAL, NULL, NULL,
NULL, NULL);
@@ -5557,18 +5097,18 @@ err:
}
int
-server3_3_statfs (rpcsvc_request_t *req)
+server_statfs (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
call_frame_t *frame = NULL;
gfs3_statfs_req args = {{0,},};
- int ret = -1;
- int op_errno = 0;
+ int ret = -1;
if (!req)
return ret;
- if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_statfs_req)) {
+ args.path = alloca (req->msg[0].iov_len);
+ if (!xdr_to_statfs_req (req->msg[0], &args)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
goto out;
@@ -5591,74 +5131,66 @@ server3_3_statfs (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
-
- GF_PROTOCOL_DICT_UNSERIALIZE (state->conn->bound_xl, state->xdata,
- (args.xdata.xdata_val),
- (args.xdata.xdata_len), ret,
- op_errno, out);
+ state->resolve.path = gf_strdup (args.path);
ret = 0;
resolve_and_resume (frame, server_statfs_resume);
out:
- if (op_errno)
- req->rpc_err = GARBAGE_ARGS;
-
return ret;
}
-rpcsvc_actor_t glusterfs3_3_fop_actors[] = {
- [GFS3_OP_NULL] = { "NULL", GFS3_OP_NULL, server_null, NULL, NULL, 0},
- [GFS3_OP_STAT] = { "STAT", GFS3_OP_STAT, server3_3_stat, NULL, NULL, 0},
- [GFS3_OP_READLINK] = { "READLINK", GFS3_OP_READLINK, server3_3_readlink, NULL, NULL, 0},
- [GFS3_OP_MKNOD] = { "MKNOD", GFS3_OP_MKNOD, server3_3_mknod, NULL, NULL, 0},
- [GFS3_OP_MKDIR] = { "MKDIR", GFS3_OP_MKDIR, server3_3_mkdir, NULL, NULL, 0},
- [GFS3_OP_UNLINK] = { "UNLINK", GFS3_OP_UNLINK, server3_3_unlink, NULL, NULL, 0},
- [GFS3_OP_RMDIR] = { "RMDIR", GFS3_OP_RMDIR, server3_3_rmdir, NULL, NULL, 0},
- [GFS3_OP_SYMLINK] = { "SYMLINK", GFS3_OP_SYMLINK, server3_3_symlink, NULL, NULL, 0},
- [GFS3_OP_RENAME] = { "RENAME", GFS3_OP_RENAME, server3_3_rename, NULL, NULL, 0},
- [GFS3_OP_LINK] = { "LINK", GFS3_OP_LINK, server3_3_link, NULL, NULL, 0},
- [GFS3_OP_TRUNCATE] = { "TRUNCATE", GFS3_OP_TRUNCATE, server3_3_truncate, NULL, NULL, 0},
- [GFS3_OP_OPEN] = { "OPEN", GFS3_OP_OPEN, server3_3_open, NULL, NULL, 0},
- [GFS3_OP_READ] = { "READ", GFS3_OP_READ, server3_3_readv, NULL, NULL, 0},
- [GFS3_OP_WRITE] = { "WRITE", GFS3_OP_WRITE, server3_3_writev, server3_3_writev_vec, server3_3_writev_vecsizer, 0},
- [GFS3_OP_STATFS] = { "STATFS", GFS3_OP_STATFS, server3_3_statfs, NULL, NULL, 0},
- [GFS3_OP_FLUSH] = { "FLUSH", GFS3_OP_FLUSH, server3_3_flush, NULL, NULL, 0},
- [GFS3_OP_FSYNC] = { "FSYNC", GFS3_OP_FSYNC, server3_3_fsync, NULL, NULL, 0},
- [GFS3_OP_SETXATTR] = { "SETXATTR", GFS3_OP_SETXATTR, server3_3_setxattr, NULL, NULL, 0},
- [GFS3_OP_GETXATTR] = { "GETXATTR", GFS3_OP_GETXATTR, server3_3_getxattr, NULL, NULL, 0},
- [GFS3_OP_REMOVEXATTR] = { "REMOVEXATTR", GFS3_OP_REMOVEXATTR, server3_3_removexattr, NULL, NULL, 0},
- [GFS3_OP_OPENDIR] = { "OPENDIR", GFS3_OP_OPENDIR, server3_3_opendir, NULL, NULL, 0},
- [GFS3_OP_FSYNCDIR] = { "FSYNCDIR", GFS3_OP_FSYNCDIR, server3_3_fsyncdir, NULL, NULL, 0},
- [GFS3_OP_ACCESS] = { "ACCESS", GFS3_OP_ACCESS, server3_3_access, NULL, NULL, 0},
- [GFS3_OP_CREATE] = { "CREATE", GFS3_OP_CREATE, server3_3_create, NULL, NULL, 0},
- [GFS3_OP_FTRUNCATE] = { "FTRUNCATE", GFS3_OP_FTRUNCATE, server3_3_ftruncate, NULL, NULL, 0},
- [GFS3_OP_FSTAT] = { "FSTAT", GFS3_OP_FSTAT, server3_3_fstat, NULL, NULL, 0},
- [GFS3_OP_LK] = { "LK", GFS3_OP_LK, server3_3_lk, NULL, NULL, 0},
- [GFS3_OP_LOOKUP] = { "LOOKUP", GFS3_OP_LOOKUP, server3_3_lookup, NULL, NULL, 0},
- [GFS3_OP_READDIR] = { "READDIR", GFS3_OP_READDIR, server3_3_readdir, NULL, NULL, 0},
- [GFS3_OP_INODELK] = { "INODELK", GFS3_OP_INODELK, server3_3_inodelk, NULL, NULL, 0},
- [GFS3_OP_FINODELK] = { "FINODELK", GFS3_OP_FINODELK, server3_3_finodelk, NULL, NULL, 0},
- [GFS3_OP_ENTRYLK] = { "ENTRYLK", GFS3_OP_ENTRYLK, server3_3_entrylk, NULL, NULL, 0},
- [GFS3_OP_FENTRYLK] = { "FENTRYLK", GFS3_OP_FENTRYLK, server3_3_fentrylk, NULL, NULL, 0},
- [GFS3_OP_XATTROP] = { "XATTROP", GFS3_OP_XATTROP, server3_3_xattrop, NULL, NULL, 0},
- [GFS3_OP_FXATTROP] = { "FXATTROP", GFS3_OP_FXATTROP, server3_3_fxattrop, NULL, NULL, 0},
- [GFS3_OP_FGETXATTR] = { "FGETXATTR", GFS3_OP_FGETXATTR, server3_3_fgetxattr, NULL, NULL, 0},
- [GFS3_OP_FSETXATTR] = { "FSETXATTR", GFS3_OP_FSETXATTR, server3_3_fsetxattr, NULL, NULL, 0},
- [GFS3_OP_RCHECKSUM] = { "RCHECKSUM", GFS3_OP_RCHECKSUM, server3_3_rchecksum, NULL, NULL, 0},
- [GFS3_OP_SETATTR] = { "SETATTR", GFS3_OP_SETATTR, server3_3_setattr, NULL, NULL, 0},
- [GFS3_OP_FSETATTR] = { "FSETATTR", GFS3_OP_FSETATTR, server3_3_fsetattr, NULL, NULL, 0},
- [GFS3_OP_READDIRP] = { "READDIRP", GFS3_OP_READDIRP, server3_3_readdirp, NULL, NULL, 0},
- [GFS3_OP_RELEASE] = { "RELEASE", GFS3_OP_RELEASE, server3_3_release, NULL, NULL, 0},
- [GFS3_OP_RELEASEDIR] = { "RELEASEDIR", GFS3_OP_RELEASEDIR, server3_3_releasedir, NULL, NULL, 0},
- [GFS3_OP_FREMOVEXATTR] = { "FREMOVEXATTR", GFS3_OP_FREMOVEXATTR, server3_3_fremovexattr, NULL, NULL, 0},
+rpcsvc_actor_t glusterfs3_1_fop_actors[] = {
+ [GFS3_OP_NULL] = { "NULL", GFS3_OP_NULL, server_null, NULL, NULL},
+ [GFS3_OP_STAT] = { "STAT", GFS3_OP_STAT, server_stat, NULL, NULL },
+ [GFS3_OP_READLINK] = { "READLINK", GFS3_OP_READLINK, server_readlink, NULL, NULL },
+ [GFS3_OP_MKNOD] = { "MKNOD", GFS3_OP_MKNOD, server_mknod, NULL, NULL },
+ [GFS3_OP_MKDIR] = { "MKDIR", GFS3_OP_MKDIR, server_mkdir, NULL, NULL },
+ [GFS3_OP_UNLINK] = { "UNLINK", GFS3_OP_UNLINK, server_unlink, NULL, NULL },
+ [GFS3_OP_RMDIR] = { "RMDIR", GFS3_OP_RMDIR, server_rmdir, NULL, NULL },
+ [GFS3_OP_SYMLINK] = { "SYMLINK", GFS3_OP_SYMLINK, server_symlink, NULL, NULL },
+ [GFS3_OP_RENAME] = { "RENAME", GFS3_OP_RENAME, server_rename, NULL, NULL },
+ [GFS3_OP_LINK] = { "LINK", GFS3_OP_LINK, server_link, NULL, NULL },
+ [GFS3_OP_TRUNCATE] = { "TRUNCATE", GFS3_OP_TRUNCATE, server_truncate, NULL, NULL },
+ [GFS3_OP_OPEN] = { "OPEN", GFS3_OP_OPEN, server_open, NULL, NULL },
+ [GFS3_OP_READ] = { "READ", GFS3_OP_READ, server_readv, NULL, NULL },
+ [GFS3_OP_WRITE] = { "WRITE", GFS3_OP_WRITE, server_writev, server_writev_vec, NULL },
+ [GFS3_OP_STATFS] = { "STATFS", GFS3_OP_STATFS, server_statfs, NULL, NULL },
+ [GFS3_OP_FLUSH] = { "FLUSH", GFS3_OP_FLUSH, server_flush, NULL, NULL },
+ [GFS3_OP_FSYNC] = { "FSYNC", GFS3_OP_FSYNC, server_fsync, NULL, NULL },
+ [GFS3_OP_SETXATTR] = { "SETXATTR", GFS3_OP_SETXATTR, server_setxattr, NULL, NULL },
+ [GFS3_OP_GETXATTR] = { "GETXATTR", GFS3_OP_GETXATTR, server_getxattr, NULL, NULL },
+ [GFS3_OP_REMOVEXATTR] = { "REMOVEXATTR", GFS3_OP_REMOVEXATTR, server_removexattr, NULL, NULL },
+ [GFS3_OP_OPENDIR] = { "OPENDIR", GFS3_OP_OPENDIR, server_opendir, NULL, NULL },
+ [GFS3_OP_FSYNCDIR] = { "FSYNCDIR", GFS3_OP_FSYNCDIR, server_fsyncdir, NULL, NULL },
+ [GFS3_OP_ACCESS] = { "ACCESS", GFS3_OP_ACCESS, server_access, NULL, NULL },
+ [GFS3_OP_CREATE] = { "CREATE", GFS3_OP_CREATE, server_create, NULL, NULL },
+ [GFS3_OP_FTRUNCATE] = { "FTRUNCATE", GFS3_OP_FTRUNCATE, server_ftruncate, NULL, NULL },
+ [GFS3_OP_FSTAT] = { "FSTAT", GFS3_OP_FSTAT, server_fstat, NULL, NULL },
+ [GFS3_OP_LK] = { "LK", GFS3_OP_LK, server_lk, NULL, NULL },
+ [GFS3_OP_LOOKUP] = { "LOOKUP", GFS3_OP_LOOKUP, server_lookup, NULL, NULL },
+ [GFS3_OP_READDIR] = { "READDIR", GFS3_OP_READDIR, server_readdir, NULL, NULL },
+ [GFS3_OP_INODELK] = { "INODELK", GFS3_OP_INODELK, server_inodelk, NULL, NULL },
+ [GFS3_OP_FINODELK] = { "FINODELK", GFS3_OP_FINODELK, server_finodelk, NULL, NULL },
+ [GFS3_OP_ENTRYLK] = { "ENTRYLK", GFS3_OP_ENTRYLK, server_entrylk, NULL, NULL },
+ [GFS3_OP_FENTRYLK] = { "FENTRYLK", GFS3_OP_FENTRYLK, server_fentrylk, NULL, NULL },
+ [GFS3_OP_XATTROP] = { "XATTROP", GFS3_OP_XATTROP, server_xattrop, NULL, NULL },
+ [GFS3_OP_FXATTROP] = { "FXATTROP", GFS3_OP_FXATTROP, server_fxattrop, NULL, NULL },
+ [GFS3_OP_FGETXATTR] = { "FGETXATTR", GFS3_OP_FGETXATTR, server_fgetxattr, NULL, NULL },
+ [GFS3_OP_FSETXATTR] = { "FSETXATTR", GFS3_OP_FSETXATTR, server_fsetxattr, NULL, NULL },
+ [GFS3_OP_RCHECKSUM] = { "RCHECKSUM", GFS3_OP_RCHECKSUM, server_rchecksum, NULL, NULL },
+ [GFS3_OP_SETATTR] = { "SETATTR", GFS3_OP_SETATTR, server_setattr, NULL, NULL },
+ [GFS3_OP_FSETATTR] = { "FSETATTR", GFS3_OP_FSETATTR, server_fsetattr, NULL, NULL },
+ [GFS3_OP_READDIRP] = { "READDIRP", GFS3_OP_READDIRP, server_readdirp, NULL, NULL },
+ [GFS3_OP_RELEASE] = { "RELEASE", GFS3_OP_RELEASE, server_release, NULL, NULL },
+ [GFS3_OP_RELEASEDIR] = { "RELEASEDIR", GFS3_OP_RELEASEDIR, server_releasedir, NULL, NULL },
};
-struct rpcsvc_program glusterfs3_3_fop_prog = {
- .progname = "GlusterFS 3.3",
- .prognum = GLUSTER_FOP_PROGRAM,
- .progver = GLUSTER_FOP_VERSION,
- .numactors = GLUSTER_FOP_PROCCNT,
- .actors = glusterfs3_3_fop_actors,
+struct rpcsvc_program glusterfs3_1_fop_prog = {
+ .progname = "GlusterFS-3.1.0",
+ .prognum = GLUSTER3_1_FOP_PROGRAM,
+ .progver = GLUSTER3_1_FOP_VERSION,
+ .numactors = GLUSTER3_1_FOP_PROCCNT,
+ .actors = glusterfs3_1_fop_actors,
};
diff --git a/xlators/storage/bdb/Makefile.am b/xlators/storage/bdb/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/storage/bdb/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/storage/bdb/src/Makefile.am b/xlators/storage/bdb/src/Makefile.am
new file mode 100644
index 000000000..7e2376979
--- /dev/null
+++ b/xlators/storage/bdb/src/Makefile.am
@@ -0,0 +1,18 @@
+
+xlator_LTLIBRARIES = bdb.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/testing/storage
+
+bdb_la_LDFLAGS = -module -avoidversion
+
+bdb_la_SOURCES = bctx.c bdb-ll.c bdb.c
+bdb_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = bdb.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE -D$(GF_HOST_OS) -Wall \
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+
+AM_LDFLAGS = -ldb
+
+CLEANFILES =
+
diff --git a/xlators/storage/bdb/src/bctx.c b/xlators/storage/bdb/src/bctx.c
new file mode 100644
index 000000000..e87b2e7a9
--- /dev/null
+++ b/xlators/storage/bdb/src/bctx.c
@@ -0,0 +1,341 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <list.h>
+#include <bdb.h>
+#include <libgen.h> /* for dirname */
+
+static void
+__destroy_bctx (bctx_t *bctx)
+{
+ if (bctx->directory)
+ GF_FREE (bctx->directory);
+
+ if (bctx->db_path)
+ GF_FREE (bctx->db_path);
+
+ GF_FREE (bctx);
+}
+
+static void
+__unhash_bctx (bctx_t *bctx)
+{
+ list_del_init (&bctx->b_hash);
+}
+
+static int32_t
+bctx_table_prune (bctx_table_t *table)
+{
+ int32_t ret = 0;
+ struct list_head purge = {0,};
+ struct list_head *next = NULL;
+ bctx_t *entry = NULL;
+ bctx_t *del = NULL, *tmp = NULL;
+
+ if (!table)
+ return 0;
+
+ INIT_LIST_HEAD (&purge);
+
+ LOCK (&table->lock);
+ {
+ if ((table->lru_limit) &&
+ (table->lru_size > table->lru_limit)) {
+ while (table->lru_size > table->lru_limit) {
+ next = table->b_lru.next;
+ entry = list_entry (next, bctx_t, list);
+
+ list_move_tail (next, &table->purge);
+ __unhash_bctx (entry);
+
+ table->lru_size--;
+ ret++;
+ }
+ }
+ list_move_tail (&purge, &table->purge);
+ list_del_init (&table->purge);
+ }
+ UNLOCK (&table->lock);
+
+ list_for_each_entry_safe (del, tmp, &purge, list) {
+ list_del_init (&del->list);
+ if (del->primary) {
+ ret = del->primary->close (del->primary, 0);
+ if (ret != 0) {
+ gf_log (table->this->name, GF_LOG_DEBUG,
+ "_BCTX_TABLE_PRUNE %s: %s "
+ "(failed to close primary database)",
+ del->directory, db_strerror (ret));
+ } else {
+ gf_log (table->this->name, GF_LOG_DEBUG,
+ "_BCTX_TABLE_PRUNE %s (lru=%d)"
+ "(closed primary database)",
+ del->directory, table->lru_size);
+ }
+ }
+ if (del->secondary) {
+ ret = del->secondary->close (del->secondary, 0);
+ if (ret != 0) {
+ gf_log (table->this->name, GF_LOG_DEBUG,
+ "_BCTX_TABLE_PRUNE %s: %s "
+ "(failed to close secondary database)",
+ del->directory, db_strerror (ret));
+ } else {
+ gf_log (table->this->name, GF_LOG_DEBUG,
+ "_BCTX_TABLE_PRUNE %s (lru=%d)"
+ "(closed secondary database)",
+ del->directory, table->lru_size);
+ }
+ }
+ __destroy_bctx (del);
+ }
+
+ return ret;
+}
+
+
+/* struct bdb_ctx related */
+static inline uint32_t
+bdb_key_hash (char *key, uint32_t hash_size)
+{
+ uint32_t hash = 0;
+
+ hash = *key;
+
+ if (hash) {
+ for (key += 1; *key != '\0'; key++) {
+ hash = (hash << 5) - hash + *key;
+ }
+ }
+
+ return (hash + *key) % hash_size;
+}
+
+static void
+__hash_bctx (bctx_t *bctx)
+{
+ bctx_table_t *table = NULL;
+ char *key = NULL;
+
+ table = bctx->table;
+
+ MAKE_KEY_FROM_PATH (key, bctx->directory);
+ bctx->key_hash = bdb_key_hash (key, table->hash_size);
+
+ list_del_init (&bctx->b_hash);
+ list_add (&bctx->b_hash, &table->b_hash[bctx->key_hash]);
+}
+
+static inline bctx_t *
+__bctx_passivate (bctx_t *bctx)
+{
+ if (bctx->primary) {
+ list_move_tail (&bctx->list, &(bctx->table->b_lru));
+ bctx->table->lru_size++;
+ } else {
+ list_move_tail (&bctx->list, &bctx->table->purge);
+ __unhash_bctx (bctx);
+ }
+ return bctx;
+}
+
+static inline bctx_t *
+__bctx_activate (bctx_t *bctx)
+{
+ list_move (&bctx->list, &bctx->table->active);
+ bctx->table->lru_size--;
+
+ return bctx;
+}
+
+static bctx_t *
+__bdb_ctx_unref (bctx_t *bctx)
+{
+ GF_ASSERT (bctx->ref);
+
+ --bctx->ref;
+
+ if (!bctx->ref)
+ bctx = __bctx_passivate (bctx);
+
+ return bctx;
+}
+
+
+bctx_t *
+bctx_unref (bctx_t *bctx)
+{
+ bctx_table_t *table = NULL;
+
+ if (!bctx && !bctx->table)
+ return NULL;
+
+ table = bctx->table;
+
+ LOCK (&table->lock);
+ {
+ bctx = __bdb_ctx_unref (bctx);
+ }
+ UNLOCK (&table->lock);
+
+ bctx_table_prune (table);
+
+ return bctx;
+}
+
+/*
+ * NOTE: __bdb_ctx_ref() is called only after holding table->lock and
+ * bctx->lock, in that order
+ */
+static inline bctx_t *
+__bctx_ref (bctx_t *bctx)
+{
+ if (!bctx->ref)
+ __bctx_activate (bctx);
+
+ bctx->ref++;
+
+ return bctx;
+}
+
+bctx_t *
+bctx_ref (bctx_t *bctx)
+{
+ LOCK (&(bctx->table->lock));
+ {
+ __bctx_ref (bctx);
+ }
+ UNLOCK (&(bctx->table->lock));
+
+ return bctx;
+}
+
+
+#define BDB_THIS(table) (table->this)
+
+static inline bctx_t *
+__create_bctx (bctx_table_t *table,
+ const char *path)
+{
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
+
+ bctx = GF_CALLOC (1, sizeof (*bctx), gf_bdb_mt_bctx_t);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
+
+ bctx->table = table;
+ bctx->directory = gf_strdup (path);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, BDB_THIS (table), path);
+
+ bctx->db_path = gf_strdup (db_path);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx->directory, out);
+
+ INIT_LIST_HEAD (&bctx->c_list);
+ INIT_LIST_HEAD (&bctx->list);
+ INIT_LIST_HEAD (&bctx->b_hash);
+
+ LOCK_INIT (&bctx->lock);
+
+ __hash_bctx (bctx);
+
+ list_add (&bctx->list, &table->b_lru);
+ table->lru_size++;
+
+out:
+ return bctx;
+}
+
+/* bctx_lookup - lookup bctx_t for the directory @directory.
+ * (see description of bctx_t in bdb.h)
+ *
+ * @table: bctx_table_t for this instance of bdb.
+ * @directory: directory for which bctx_t is being looked up.
+ */
+bctx_t *
+bctx_lookup (bctx_table_t *table,
+ const char *directory)
+{
+ char *key = NULL;
+ uint32_t key_hash = 0;
+ bctx_t *trav = NULL, *bctx = NULL, *tmp = NULL;
+ int32_t need_break = 0;
+
+ GF_VALIDATE_OR_GOTO ("bctx", table, out);
+ GF_VALIDATE_OR_GOTO ("bctx", directory, out);
+
+ MAKE_KEY_FROM_PATH (key, directory);
+ key_hash = bdb_key_hash (key, table->hash_size);
+
+ LOCK (&table->lock);
+ {
+ if (list_empty (&table->b_hash[key_hash])) {
+ goto creat_bctx;
+ }
+
+ list_for_each_entry_safe (trav, tmp, &table->b_hash[key_hash],
+ b_hash) {
+ LOCK(&trav->lock);
+ {
+ if (!strcmp(trav->directory, directory)) {
+ bctx = __bctx_ref (trav);
+ need_break = 1;
+ }
+ }
+ UNLOCK(&trav->lock);
+
+ if (need_break)
+ break;
+ }
+
+ creat_bctx:
+ if (!bctx) {
+ bctx = __create_bctx (table, directory);
+ bctx = __bctx_ref (bctx);
+ }
+ }
+ UNLOCK (&table->lock);
+out:
+ return bctx;
+}
+
+
+bctx_t *
+bctx_parent (bctx_table_t *table,
+ const char *path)
+{
+ char *pathname = NULL, *directory = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bctx", table, out);
+ GF_VALIDATE_OR_GOTO ("bctx", path, out);
+
+ pathname = gf_strdup (path);
+ GF_VALIDATE_OR_GOTO ("bctx", pathname, out);
+ directory = dirname (pathname);
+
+ bctx = bctx_lookup (table, directory);
+ GF_VALIDATE_OR_GOTO ("bctx", bctx, out);
+
+out:
+ if (pathname)
+ free (pathname);
+ return bctx;
+}
diff --git a/xlators/storage/bdb/src/bdb-ll.c b/xlators/storage/bdb/src/bdb-ll.c
new file mode 100644
index 000000000..a9bb08655
--- /dev/null
+++ b/xlators/storage/bdb/src/bdb-ll.c
@@ -0,0 +1,1464 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include <libgen.h>
+#include "bdb.h"
+#include <list.h>
+#include "hashfn.h"
+/*
+ * implement the procedures to interact with bdb */
+
+/****************************************************************
+ *
+ * General wrappers and utility procedures for bdb xlator
+ *
+ ****************************************************************/
+
+ino_t
+bdb_inode_transform (ino_t parent,
+ const char *name,
+ size_t namelen)
+{
+ ino_t ino = -1;
+ uint64_t hash = 0;
+
+ hash = gf_dm_hashfn (name, namelen);
+
+ ino = (((parent << 32) | 0x00000000ffffffffULL)
+ & (hash | 0xffffffff00000000ULL));
+
+ return ino;
+}
+
+static int
+bdb_generate_secondary_hash (DB *secondary,
+ const DBT *pkey,
+ const DBT *data,
+ DBT *skey)
+{
+ char *primary = NULL;
+ uint32_t *hash = NULL;
+
+ primary = pkey->data;
+
+ hash = GF_CALLOC (1, sizeof (uint32_t), gf_bdb_mt_uint32_t);
+
+ *hash = gf_dm_hashfn (primary, pkey->size);
+
+ skey->data = hash;
+ skey->size = sizeof (hash);
+ skey->flags = DB_DBT_APPMALLOC;
+
+ return 0;
+}
+
+/***********************************************************
+ *
+ * bdb storage database utilities
+ *
+ **********************************************************/
+
+/*
+ * bdb_db_open - opens a storage db.
+ *
+ * @ctx: context specific to the directory for which we are supposed to open db
+ *
+ * see, if we have empty slots to open a db.
+ * if (no-empty-slots), then prune open dbs and close as many as possible
+ * if (empty-slot-available), tika muchkonDu db open maaDu
+ *
+ */
+static int
+bdb_db_open (bctx_t *bctx)
+{
+ DB *primary = NULL;
+ DB *secondary = NULL;
+ int32_t ret = -1;
+ bctx_table_t *table = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+
+ table = bctx->table;
+ GF_VALIDATE_OR_GOTO ("bdb-ll", table, out);
+
+ /* we have to do the following, we can't deny someone of db_open ;) */
+ ret = db_create (&primary, table->dbenv, 0);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_OPEN %s: %s (failed to create database object"
+ " for primary database)",
+ bctx->directory, db_strerror (ret));
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (table->page_size) {
+ ret = primary->set_pagesize (primary,
+ table->page_size);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_OPEN %s: %s (failed to set page-size "
+ "to %"PRIu64")",
+ bctx->directory, db_strerror (ret),
+ table->page_size);
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_OPEN %s: page-size set to %"PRIu64,
+ bctx->directory, table->page_size);
+ }
+ }
+
+ ret = primary->open (primary, NULL, bctx->db_path, "primary",
+ table->access_mode, table->dbflags, 0);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "_BDB_DB_OPEN %s: %s "
+ "(failed to open primary database)",
+ bctx->directory, db_strerror (ret));
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = db_create (&secondary, table->dbenv, 0);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_OPEN %s: %s (failed to create database object"
+ " for secondary database)",
+ bctx->directory, db_strerror (ret));
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ ret = secondary->open (secondary, NULL, bctx->db_path, "secondary",
+ table->access_mode, table->dbflags, 0);
+ if (ret != 0 ) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "_BDB_DB_OPEN %s: %s "
+ "(failed to open secondary database)",
+ bctx->directory, db_strerror (ret));
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = primary->associate (primary, NULL, secondary,
+ bdb_generate_secondary_hash,
+#ifdef DB_IMMUTABLE_KEY
+ DB_IMMUTABLE_KEY);
+#else
+ 0);
+#endif
+ if (ret != 0 ) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "_BDB_DB_OPEN %s: %s "
+ "(failed to associate primary database with "
+ "secondary database)",
+ bctx->directory, db_strerror (ret));
+ ret = -1;
+ goto cleanup;
+ }
+
+out:
+ bctx->primary = primary;
+ bctx->secondary = secondary;
+
+ return ret;
+cleanup:
+ if (primary)
+ primary->close (primary, 0);
+ if (secondary)
+ secondary->close (secondary, 0);
+
+ return ret;
+}
+
+int32_t
+bdb_cursor_close (bctx_t *bctx,
+ DBC *cursorp)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
+
+ LOCK (&bctx->lock);
+ {
+#ifdef HAVE_BDB_CURSOR_GET
+ ret = cursorp->close (cursorp);
+#else
+ ret = cursorp->c_close (cursorp);
+#endif
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CURSOR_CLOSE %s: %s "
+ "(failed to close database cursor)",
+ bctx->directory, db_strerror (ret));
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+out:
+ return ret;
+}
+
+
+int32_t
+bdb_cursor_open (bctx_t *bctx,
+ DBC **cursorpp)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorpp, out);
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->secondary) {
+ /* do nothing, just continue */
+ ret = 0;
+ } else {
+ ret = bdb_db_open (bctx);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CURSOR_OPEN %s: ENOMEM "
+ "(failed to open secondary database)",
+ bctx->directory);
+ ret = -ENOMEM;
+ } else {
+ ret = 0;
+ }
+ }
+
+ if (ret == 0) {
+ /* all set, open cursor */
+ ret = bctx->secondary->cursor (bctx->secondary,
+ NULL, cursorpp, 0);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CURSOR_OPEN %s: %s "
+ "(failed to open a cursor to database)",
+ bctx->directory, db_strerror (ret));
+ }
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+out:
+ return ret;
+}
+
+
+/* cache related */
+static bdb_cache_t *
+bdb_cache_lookup (bctx_t *bctx,
+ char *path)
+{
+ bdb_cache_t *bcache = NULL;
+ bdb_cache_t *trav = NULL;
+ char *key = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
+
+ MAKE_KEY_FROM_PATH (key, path);
+
+ LOCK (&bctx->lock);
+ {
+ list_for_each_entry (trav, &bctx->c_list, c_list) {
+ if (!strcmp (trav->key, key)){
+ bcache = trav;
+ break;
+ }
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+out:
+ return bcache;
+}
+
+static int32_t
+bdb_cache_insert (bctx_t *bctx,
+ DBT *key,
+ DBT *data)
+{
+ bdb_cache_t *bcache = NULL;
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", data, out);
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->c_count > 5) {
+ /* most of the times, we enter here */
+ /* FIXME: ugly, not supposed to disect any of the
+ * 'struct list_head' directly */
+ if (!list_empty (&bctx->c_list)) {
+ bcache = list_entry (bctx->c_list.prev,
+ bdb_cache_t, c_list);
+ list_del_init (&bcache->c_list);
+ }
+ if (bcache->key) {
+ GF_FREE (bcache->key);
+ bcache->key = GF_CALLOC (key->size + 1,
+ sizeof (char),
+ gf_bdb_mt_char);
+ GF_VALIDATE_OR_GOTO ("bdb-ll",
+ bcache->key, unlock);
+ memcpy (bcache->key, (char *)key->data,
+ key->size);
+ } else {
+ /* should never come here */
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CACHE_INSERT %s (%s) "
+ "(found a cache entry with empty key)",
+ bctx->directory, (char *)key->data);
+ } /* if(bcache->key)...else */
+ if (bcache->data) {
+ GF_FREE (bcache->data);
+ bcache->data = memdup (data->data, data->size);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data,
+ unlock);
+ bcache->size = data->size;
+ } else {
+ /* should never come here */
+ gf_log ("bdb-ll", GF_LOG_CRITICAL,
+ "_BDB_CACHE_INSERT %s (%s) "
+ "(found a cache entry with no data)",
+ bctx->directory, (char *)key->data);
+ } /* if(bcache->data)...else */
+ list_add (&bcache->c_list, &bctx->c_list);
+ ret = 0;
+ } else {
+ /* we will be entering here very rarely */
+ bcache = GF_CALLOC (1, sizeof (*bcache),
+ gf_bdb_mt_bdb_cache_t);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache, unlock);
+
+ bcache->key = GF_CALLOC (key->size + 1, sizeof (char),
+ gf_bdb_mt_char);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->key, unlock);
+ memcpy (bcache->key, key->data, key->size);
+
+ bcache->data = memdup (data->data, data->size);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bcache->data, unlock);
+
+ bcache->size = data->size;
+ list_add (&bcache->c_list, &bctx->c_list);
+ bctx->c_count++;
+ ret = 0;
+ } /* if(private->c_count < 5)...else */
+ }
+unlock:
+ UNLOCK (&bctx->lock);
+out:
+ return ret;
+}
+
+static int32_t
+bdb_cache_delete (bctx_t *bctx,
+ const char *key)
+{
+ bdb_cache_t *bcache = NULL;
+ bdb_cache_t *trav = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", key, out);
+
+ LOCK (&bctx->lock);
+ {
+ list_for_each_entry (trav, &bctx->c_list, c_list) {
+ if (!strcmp (trav->key, key)){
+ bctx->c_count--;
+ bcache = trav;
+ break;
+ }
+ }
+
+ if (bcache) {
+ list_del_init (&bcache->c_list);
+ GF_FREE (bcache->key);
+ GF_FREE (bcache->data);
+ GF_FREE (bcache);
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+out:
+ return 0;
+}
+
+void *
+bdb_db_stat (bctx_t *bctx,
+ DB_TXN *txnid,
+ uint32_t flags)
+{
+ DB *storage = NULL;
+ void *stat = NULL;
+ int32_t ret = -1;
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->primary == NULL) {
+ ret = bdb_db_open (bctx);
+ storage = bctx->primary;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->primary;
+ } /* if(bctx->dbp==NULL)...else */
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ ret = storage->stat (storage, txnid, &stat, flags);
+
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_STAT %s: %s "
+ "(failed to do stat database)",
+ bctx->directory, db_strerror (ret));
+ }
+out:
+ return stat;
+
+}
+
+/* bdb_storage_get - retrieve a key/value pair corresponding to @path from the
+ * corresponding db file.
+ *
+ * @bctx: bctx_t * corresponding to the parent directory of @path. (should
+ * always be a valid bctx). bdb_storage_get should never be called if
+ * @bctx = NULL.
+ * @txnid: NULL if bdb_storage_get is not embedded in an explicit transaction
+ * or a valid DB_TXN *, when embedded in an explicit transaction.
+ * @path: path of the file to read from (translated to a database key using
+ * MAKE_KEY_FROM_PATH)
+ * @buf: char ** - pointer to a pointer to char. a read buffer is created in
+ * this procedure and pointer to the buffer is passed through @buf to the
+ * caller.
+ * @size: size of the file content to be read.
+ * @offset: offset from which the file content to be read.
+ *
+ * NOTE: bdb_storage_get tries to open DB, if @bctx->dbp == NULL
+ * (@bctx->dbp == NULL, nobody has opened DB till now or DB was closed by
+ * bdb_table_prune()).
+ *
+ * NOTE: if private->cache is set (bdb xlator's internal caching enabled), then
+ * bdb_storage_get first looks up the cache for key/value pair. if
+ * bdb_lookup_cache fails, then only DB->get() is called. also, inserts a
+ * newly read key/value pair to cache through bdb_insert_to_cache.
+ *
+ * return: 'number of bytes read' on success or -1 on error.
+ *
+ * also see: bdb_lookup_cache, bdb_insert_to_cache for details about bdb
+ * xlator's internal cache.
+ */
+static int32_t
+bdb_db_get (bctx_t *bctx,
+ DB_TXN *txnid,
+ const char *path,
+ char *buf,
+ size_t size,
+ off_t offset)
+{
+ DB *storage = NULL;
+ DBT key = {0,};
+ DBT value = {0,};
+ int32_t ret = -1;
+ size_t copy_size = 0;
+ char *key_string = NULL;
+ bdb_cache_t *bcache = NULL;
+ int32_t db_flags = 0;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", bctx, out);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", path, out);
+
+ MAKE_KEY_FROM_PATH (key_string, path);
+
+ if (bctx->cache &&
+ ((bcache = bdb_cache_lookup (bctx, key_string)) != NULL)) {
+ if (buf) {
+ copy_size = ((bcache->size - offset) < size)?
+ (bcache->size - offset) : size;
+
+ memcpy (buf, (bcache->data + offset), copy_size);
+ ret = copy_size;
+ } else {
+ ret = bcache->size;
+ }
+
+ goto out;
+ }
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->primary == NULL) {
+ ret = bdb_db_open (bctx);
+ storage = bctx->primary;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->primary;
+ } /* if(bctx->dbp==NULL)...else */
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ key.data = (char *)key_string;
+ key.size = strlen (key_string);
+ key.flags = DB_DBT_USERMEM;
+
+ if (bctx->cache){
+ value.flags = DB_DBT_MALLOC;
+ } else {
+ if (size) {
+ value.data = buf;
+ value.ulen = size;
+ value.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+ } else {
+ value.flags = DB_DBT_MALLOC;
+ }
+ value.dlen = size;
+ value.doff = offset;
+ }
+
+ do {
+ /* TODO: we prefer to give our own buffer to value.data
+ * and ask bdb to fill in it */
+ ret = storage->get (storage, txnid, &key, &value,
+ db_flags);
+
+ if (ret == DB_NOTFOUND) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s: ENOENT"
+ "(specified key not found in database)",
+ bctx->directory, key_string);
+ ret = -1;
+ need_break = 1;
+ } else if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s"
+ "(deadlock detected, retrying for %d "
+ "time)",
+ bctx->directory, key_string, retries);
+ } else if (ret == 0) {
+ /* successfully read data, lets set everything
+ * in place and return */
+ if (bctx->cache) {
+ if (buf) {
+ copy_size = ((value.size - offset) < size) ?
+ (value.size - offset) : size;
+
+ memcpy (buf, (value.data + offset),
+ copy_size);
+ ret = copy_size;
+ }
+
+ bdb_cache_insert (bctx, &key, &value);
+ } else {
+ ret = value.size;
+ }
+
+ if (size == 0)
+ GF_FREE (value.data);
+
+ need_break = 1;
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_GET %s - %s: %s"
+ "(failed to retrieve specified key from"
+ " database)",
+ bctx->directory, key_string,
+ db_strerror (ret));
+ ret = -1;
+ need_break = 1;
+ }
+ } while (!need_break);
+
+out:
+ return ret;
+}/* bdb_db_get */
+
+/* TODO: handle errors here and log. propogate only the errno to caller */
+int32_t
+bdb_db_fread (struct bdb_fd *bfd, char *buf, size_t size, off_t offset)
+{
+ return bdb_db_get (bfd->ctx, NULL, bfd->key, buf, size, offset);
+}
+
+int32_t
+bdb_db_iread (struct bdb_ctx *bctx, const char *key, char **bufp)
+{
+ char *buf = NULL;
+ size_t size = 0;
+ int64_t ret = 0;
+
+ ret = bdb_db_get (bctx, NULL, key, NULL, 0, 0);
+ size = ret;
+
+ if (bufp) {
+ buf = GF_CALLOC (size, sizeof (char), gf_bdb_mt_char);
+ *bufp = buf;
+ ret = bdb_db_get (bctx, NULL, key, buf, size, 0);
+ }
+
+ return ret;
+}
+
+/* bdb_storage_put - insert a key/value specified to the corresponding DB.
+ *
+ * @bctx: bctx_t * corresponding to the parent directory of @path.
+ * (should always be a valid bctx). bdb_storage_put should never be
+ * called if @bctx = NULL.
+ * @txnid: NULL if bdb_storage_put is not embedded in an explicit transaction
+ * or a valid DB_TXN *, when embedded in an explicit transaction.
+ * @key_string: key of the database entry.
+ * @buf: pointer to the buffer data to be written as data for @key_string.
+ * @size: size of @buf.
+ * @offset: offset in the key's data to be modified with provided data.
+ * @flags: valid flags are BDB_TRUNCATE_RECORD (to reduce the data of
+ * @key_string to 0 size).
+ *
+ * NOTE: bdb_storage_put tries to open DB, if @bctx->dbp == NULL
+ * (@bctx->dbp == NULL, nobody has opened DB till now or DB was closed by
+ * bdb_table_prune()).
+ *
+ * NOTE: bdb_storage_put deletes the key/value from bdb xlator's internal cache.
+ *
+ * return: 0 on success or -1 on error.
+ *
+ * also see: bdb_cache_delete for details on how a cached key/value pair is
+ * removed.
+ */
+static int32_t
+bdb_db_put (bctx_t *bctx,
+ DB_TXN *txnid,
+ const char *key_string,
+ const char *buf,
+ size_t size,
+ off_t offset,
+ int32_t flags)
+{
+ DB *storage = NULL;
+ DBT key = {0,}, value = {0,};
+ int32_t ret = -1;
+ int32_t db_flags = DB_AUTO_COMMIT;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->primary == NULL) {
+ ret = bdb_db_open (bctx);
+ storage = bctx->primary;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->primary;
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ if (bctx->cache) {
+ ret = bdb_cache_delete (bctx, (char *)key_string);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
+ }
+
+ key.data = (void *)key_string;
+ key.size = strlen (key_string);
+
+ /* NOTE: bdb lets us expand the file, suppose value.size > value.len,
+ * then value.len bytes from value.doff offset and value.size bytes
+ * will be written from value.doff and data from
+ * value.doff + value.dlen will be pushed value.doff + value.size
+ */
+ value.data = (void *)buf;
+
+ if (flags & BDB_TRUNCATE_RECORD) {
+ value.size = size;
+ value.doff = 0;
+ value.dlen = offset;
+ } else {
+ value.size = size;
+ value.dlen = size;
+ value.doff = offset;
+ }
+ value.flags = DB_DBT_PARTIAL;
+ if (buf == NULL && size == 0)
+ /* truncate called us */
+ value.flags = 0;
+
+ do {
+ ret = storage->put (storage, txnid, &key, &value, db_flags);
+ if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_PUT %s - %s"
+ "(deadlock detected, retying for %d time)",
+ bctx->directory, key_string, retries);
+ } else if (ret) {
+ /* write failed */
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_PUT %s - %s: %s"
+ "(failed to put specified entry into database)",
+ bctx->directory, key_string, db_strerror (ret));
+ need_break = 1;
+ } else {
+ /* successfully wrote */
+ ret = 0;
+ need_break = 1;
+ }
+ } while (!need_break);
+out:
+ return ret;
+}/* bdb_db_put */
+
+int32_t
+bdb_db_icreate (struct bdb_ctx *bctx, const char *key)
+{
+ return bdb_db_put (bctx, NULL, key, NULL, 0, 0, 0);
+}
+
+/* TODO: handle errors here and log. propogate only the errno to caller */
+int32_t
+bdb_db_fwrite (struct bdb_fd *bfd, char *buf, size_t size, off_t offset)
+{
+ return bdb_db_put (bfd->ctx, NULL, bfd->key, buf, size, offset, 0);
+}
+
+/* TODO: handle errors here and log. propogate only the errno to caller */
+int32_t
+bdb_db_iwrite (struct bdb_ctx *bctx, const char *key, char *buf, size_t size)
+{
+ return bdb_db_put (bctx, NULL, key, buf, size, 0, 0);
+}
+
+int32_t
+bdb_db_itruncate (struct bdb_ctx *bctx, const char *key)
+{
+ return bdb_db_put (bctx, NULL, key, NULL, 0, 1, 0);
+}
+
+/* bdb_storage_del - delete a key/value pair corresponding to @path from
+ * corresponding db file.
+ *
+ * @bctx: bctx_t * corresponding to the parent directory of @path.
+ * (should always be a valid bctx). bdb_storage_del should never be called
+ * if @bctx = NULL.
+ * @txnid: NULL if bdb_storage_del is not embedded in an explicit transaction
+ * or a valid DB_TXN *, when embedded in an explicit transaction.
+ * @path: path to the file, whose key/value pair has to be deleted.
+ *
+ * NOTE: bdb_storage_del tries to open DB, if @bctx->dbp == NULL
+ * (@bctx->dbp == NULL, nobody has opened DB till now or DB was closed by
+ * bdb_table_prune()).
+ *
+ * return: 0 on success or -1 on error.
+ */
+static int32_t
+bdb_db_del (bctx_t *bctx,
+ DB_TXN *txnid,
+ const char *key_string)
+{
+ DB *storage = NULL;
+ DBT key = {0,};
+ int32_t ret = -1;
+ int32_t db_flags = 0;
+ uint8_t need_break = 0;
+ int32_t retries = 1;
+
+ LOCK (&bctx->lock);
+ {
+ if (bctx->primary == NULL) {
+ ret = bdb_db_open (bctx);
+ storage = bctx->primary;
+ } else {
+ /* we are just fine, lets continue */
+ storage = bctx->primary;
+ }
+ }
+ UNLOCK (&bctx->lock);
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", storage, out);
+
+ ret = bdb_cache_delete (bctx, key_string);
+ GF_VALIDATE_OR_GOTO ("bdb-ll", (ret == 0), out);
+
+ key.data = (char *)key_string;
+ key.size = strlen (key_string);
+ key.flags = DB_DBT_USERMEM;
+
+ do {
+ ret = storage->del (storage, txnid, &key, db_flags);
+
+ if (ret == DB_NOTFOUND) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_DEL %s - %s: ENOENT"
+ "(failed to delete entry, could not be "
+ "found in the database)",
+ bctx->directory, key_string);
+ need_break = 1;
+ } else if (ret == DB_LOCK_DEADLOCK) {
+ retries++;
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_DEL %s - %s"
+ "(deadlock detected, retying for %d time)",
+ bctx->directory, key_string, retries);
+ } else if (ret == 0) {
+ /* successfully deleted the entry */
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_DEL %s - %s"
+ "(successfully deleted entry from database)",
+ bctx->directory, key_string);
+ ret = 0;
+ need_break = 1;
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_DB_DEL %s - %s: %s"
+ "(failed to delete entry from database)",
+ bctx->directory, key_string, db_strerror (ret));
+ ret = -1;
+ need_break = 1;
+ }
+ } while (!need_break);
+out:
+ return ret;
+}
+
+int32_t
+bdb_db_iremove (bctx_t *bctx,
+ const char *key)
+{
+ return bdb_db_del (bctx, NULL, key);
+}
+
+/* NOTE: bdb version compatibility wrapper */
+int32_t
+bdb_cursor_get (DBC *cursorp,
+ DBT *sec, DBT *pri,
+ DBT *val,
+ int32_t flags)
+{
+ int32_t ret = -1;
+
+ GF_VALIDATE_OR_GOTO ("bdb-ll", cursorp, out);
+
+#ifdef HAVE_BDB_CURSOR_GET
+ ret = cursorp->pget (cursorp, sec, pri, val, flags);
+#else
+ ret = cursorp->c_pget (cursorp, sec, pri, val, flags);
+#endif
+ if ((ret != 0) && (ret != DB_NOTFOUND)) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CURSOR_GET: %s"
+ "(failed to retrieve entry from database cursor)",
+ db_strerror (ret));
+ }
+
+out:
+ return ret;
+}/* bdb_cursor_get */
+
+int32_t
+bdb_dirent_size (DBT *key)
+{
+ return GF_DIR_ALIGN (24 /* FIX MEEEE!!! */ + key->size);
+}
+
+
+
+/* bdb_dbenv_init - initialize DB_ENV
+ *
+ * initialization includes:
+ * 1. opening DB_ENV (db_env_create(), DB_ENV->open()).
+ * NOTE: see private->envflags for flags used.
+ * 2. DB_ENV->set_lg_dir - set log directory to be used for storing log files
+ * (log files are the files in which transaction logs are written by db).
+ * 3. DB_ENV->set_flags (DB_LOG_AUTOREMOVE) - set DB_ENV to automatically
+ * clear the unwanted log files (flushed at each checkpoint).
+ * 4. DB_ENV->set_errfile - set errfile to be used by db to report detailed
+ * error logs. used only for debbuging purpose.
+ *
+ * return: returns a valid DB_ENV * on success or NULL on error.
+ *
+ */
+static DB_ENV *
+bdb_dbenv_init (xlator_t *this,
+ char *directory)
+{
+ /* Create a DB environment */
+ DB_ENV *dbenv = NULL;
+ int32_t ret = 0;
+ bdb_private_t *private = NULL;
+ int32_t fatal_flags = 0;
+
+ VALIDATE_OR_GOTO (this, err);
+ VALIDATE_OR_GOTO (directory, err);
+
+ private = this->private;
+ VALIDATE_OR_GOTO (private, err);
+
+ ret = db_env_create (&dbenv, 0);
+ VALIDATE_OR_GOTO ((ret == 0), err);
+
+ /* NOTE: set_errpfx returns 'void' */
+ dbenv->set_errpfx(dbenv, this->name);
+
+ ret = dbenv->set_lk_detect (dbenv, DB_LOCK_DEFAULT);
+ VALIDATE_OR_GOTO ((ret == 0), err);
+
+ ret = dbenv->open(dbenv, directory,
+ private->envflags,
+ S_IRUSR | S_IWUSR);
+ if ((ret != 0) && (ret != DB_RUNRECOVERY)) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to join Berkeley DB environment at %s: %s."
+ "please run manual recovery and retry running "
+ "glusterfs",
+ directory, db_strerror (ret));
+ dbenv = NULL;
+ goto err;
+ } else if (ret == DB_RUNRECOVERY) {
+ fatal_flags = ((private->envflags & (~DB_RECOVER))
+ | DB_RECOVER_FATAL);
+ ret = dbenv->open(dbenv, directory, fatal_flags,
+ S_IRUSR | S_IWUSR);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "failed to join Berkeley DB environment in "
+ "recovery mode at %s: %s. please run manual "
+ "recovery and retry running glusterfs",
+ directory, db_strerror (ret));
+ dbenv = NULL;
+ goto err;
+ }
+ }
+
+ ret = 0;
+#if (DB_VERSION_MAJOR == 4 && \
+ DB_VERSION_MINOR == 7)
+ if (private->log_auto_remove) {
+ ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 1);
+ } else {
+ ret = dbenv->log_set_config (dbenv, DB_LOG_AUTO_REMOVE, 0);
+ }
+#else
+ if (private->log_auto_remove) {
+ ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 1);
+ } else {
+ ret = dbenv->set_flags (dbenv, DB_LOG_AUTOREMOVE, 0);
+ }
+#endif
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "autoremoval of transactional log files could not be "
+ "configured (%s). you may have to do a manual "
+ "monitoring of transactional log files and remove "
+ "periodically.",
+ db_strerror (ret));
+ goto err;
+ }
+
+ if (private->transaction) {
+ ret = dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1);
+
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "configuration of auto-commit failed for "
+ "database environment at %s. none of the "
+ "operations will be embedded in transaction "
+ "unless explicitly done so.",
+ db_strerror (ret));
+ goto err;
+ }
+
+ if (private->txn_timeout) {
+ ret = dbenv->set_timeout (dbenv, private->txn_timeout,
+ DB_SET_TXN_TIMEOUT);
+ if (ret != 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "could not configure Berkeley DB "
+ "transaction timeout to %d (%s). please"
+ " review 'option transaction-timeout %d"
+ "' option.",
+ private->txn_timeout,
+ db_strerror (ret),
+ private->txn_timeout);
+ goto err;
+ }
+ }
+
+ if (private->lock_timeout) {
+ ret = dbenv->set_timeout(dbenv,
+ private->txn_timeout,
+ DB_SET_LOCK_TIMEOUT);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "could not configure Berkeley DB "
+ "lock timeout to %d (%s). please"
+ " review 'option lock-timeout %d"
+ "' option.",
+ private->lock_timeout,
+ db_strerror (ret),
+ private->lock_timeout);
+ goto err;
+ }
+ }
+
+ ret = dbenv->set_lg_dir (dbenv, private->logdir);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to configure libdb transaction log "
+ "directory at %s. please review the "
+ "'option logdir %s' option.",
+ db_strerror (ret), private->logdir);
+ goto err;
+ }
+ }
+
+ if (private->errfile) {
+ private->errfp = fopen (private->errfile, "a+");
+ if (private->errfp) {
+ dbenv->set_errfile (dbenv, private->errfp);
+ } else {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "failed to open error logging file for "
+ "libdb (Berkeley DB) internal logging (%s)."
+ "please review the 'option errfile %s' option.",
+ strerror (errno), private->errfile);
+ goto err;
+ }
+ }
+
+ return dbenv;
+err:
+ if (dbenv) {
+ dbenv->close (dbenv, 0);
+ }
+
+ return NULL;
+}
+
+#define BDB_ENV(this) ((((struct bdb_private *)this->private)->b_table)->dbenv)
+
+/* bdb_checkpoint - during transactional usage, db does not directly write the
+ * data to db files, instead db writes a 'log' (similar to a journal entry)
+ * into a log file. db normally clears the log files during opening of an
+ * environment. since we expect a filesystem server to run for a pretty long
+ * duration and flushing 'log's during dbenv->open would prove very costly, if
+ * we accumulate the log entries for one complete run of glusterfs server. to
+ * flush the logs frequently, db provides a mechanism called 'checkpointing'.
+ * when we do a checkpoint, db flushes the logs to disk (writes changes to db
+ * files) and we can also clear the accumulated log files after checkpointing.
+ * NOTE: removing unwanted log files is not part of dbenv->txn_checkpoint()
+ * call.
+ *
+ * @data: xlator_t of the current instance of bdb xlator.
+ *
+ * bdb_checkpoint is called in a different thread from the main glusterfs
+ * thread. bdb xlator creates the checkpoint thread after successfully opening
+ * the db environment.
+ * NOTE: bdb_checkpoint thread shares the DB_ENV handle with the filesystem
+ * thread.
+ *
+ * db environment checkpointing frequency is controlled by
+ * 'option checkpoint-timeout <time-in-seconds>' in volfile.
+ *
+ * NOTE: checkpointing thread is started only if 'option transaction on'
+ * specified in volfile. checkpointing is not valid for non-transactional
+ * environments.
+ *
+ */
+static void *
+bdb_checkpoint (void *data)
+{
+ xlator_t *this = NULL;
+ struct bdb_private *private = NULL;
+ DB_ENV *dbenv = NULL;
+ int32_t ret = 0;
+ uint32_t active = 0;
+
+ this = (xlator_t *) data;
+ dbenv = BDB_ENV(this);
+ private = this->private;
+
+ for (;;sleep (private->checkpoint_interval)) {
+ LOCK (&private->active_lock);
+ active = private->active;
+ UNLOCK (&private->active_lock);
+
+ if (active) {
+ ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
+ if (ret) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CHECKPOINT: %s"
+ "(failed to checkpoint environment)",
+ db_strerror (ret));
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CHECKPOINT: successfully "
+ "checkpointed");
+ }
+ } else {
+ ret = dbenv->txn_checkpoint (dbenv, 1024, 0, 0);
+ if (ret) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "_BDB_CHECKPOINT: %s"
+ "(final checkpointing failed. might "
+ "need to run recovery tool manually on "
+ "next usage of this database "
+ "environment)",
+ db_strerror (ret));
+ } else {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "_BDB_CHECKPOINT: final successfully "
+ "checkpointed");
+ }
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* bdb_db_init - initialize bdb xlator
+ *
+ * reads the options from @options dictionary and sets appropriate values in
+ * @this->private. also initializes DB_ENV.
+ *
+ * return: 0 on success or -1 on error
+ * (with logging the error through gf_log()).
+ */
+int
+bdb_db_init (xlator_t *this,
+ dict_t *options)
+{
+ /* create a db entry for root */
+ int32_t op_ret = 0;
+ bdb_private_t *private = NULL;
+ bctx_table_t *table = NULL;
+
+ char *checkpoint_interval_str = NULL;
+ char *page_size_str = NULL;
+ char *lru_limit_str = NULL;
+ char *timeout_str = NULL;
+ char *access_mode = NULL;
+ char *endptr = NULL;
+ char *errfile = NULL;
+ char *directory = NULL;
+ char *logdir = NULL;
+ char *mode = NULL;
+ char *mode_str = NULL;
+ int ret = -1;
+ int idx = 0;
+ struct stat stbuf = {0,};
+
+ private = this->private;
+
+ /* cache is always on */
+ private->cache = ON;
+
+ ret = dict_get_str (options, "access-mode", &access_mode);
+ if ((ret == 0)
+ && (!strcmp (access_mode, "btree"))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using BTREE access mode to access libdb "
+ "(Berkeley DB)");
+ private->access_mode = DB_BTREE;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using HASH access mode to access libdb (Berkeley DB)");
+ private->access_mode = DB_HASH;
+ }
+
+ ret = dict_get_str (options, "mode", &mode);
+ if ((ret == 0)
+ && (!strcmp (mode, "cache"))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "cache data mode selected for 'storage/bdb'. filesystem"
+ " operations are not transactionally protected and "
+ "system crash does not guarantee recoverability of "
+ "data");
+ private->envflags = DB_CREATE | DB_INIT_LOG |
+ DB_INIT_MPOOL | DB_THREAD;
+ private->dbflags = DB_CREATE | DB_THREAD;
+ private->transaction = OFF;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "persistent data mode selected for 'storage/bdb'. each"
+ "filesystem operation is guaranteed to be Berkeley DB "
+ "transaction protected.");
+ private->transaction = ON;
+ private->envflags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
+ DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD;
+ private->dbflags = DB_CREATE | DB_THREAD;
+
+
+ ret = dict_get_str (options, "lock-timeout", &timeout_str);
+
+ if (ret == 0) {
+ ret = gf_string2time (timeout_str,
+ &private->lock_timeout);
+
+ if (private->lock_timeout > 4260000) {
+ /* db allows us to DB_SET_LOCK_TIMEOUT to be
+ * set to a maximum of 71 mins
+ * (4260000 milliseconds) */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Berkeley DB lock-timeout parameter "
+ "(%d) is out of range. please specify"
+ " a valid timeout value for "
+ "lock-timeout and retry.",
+ private->lock_timeout);
+ goto err;
+ }
+ }
+ ret = dict_get_str (options, "transaction-timeout",
+ &timeout_str);
+ if (ret == 0) {
+ ret = gf_string2time (timeout_str,
+ &private->txn_timeout);
+
+ if (private->txn_timeout > 4260000) {
+ /* db allows us to DB_SET_TXN_TIMEOUT to be set
+ * to a maximum of 71 mins
+ * (4260000 milliseconds) */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Berkeley DB lock-timeout parameter "
+ "(%d) is out of range. please specify"
+ " a valid timeout value for "
+ "lock-timeout and retry.",
+ private->lock_timeout);
+ goto err;
+ }
+ }
+
+ private->checkpoint_interval = BDB_DEFAULT_CHECKPOINT_INTERVAL;
+ ret = dict_get_str (options, "checkpoint-interval",
+ &checkpoint_interval_str);
+ if (ret == 0) {
+ ret = gf_string2time (checkpoint_interval_str,
+ &private->checkpoint_interval);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "'%"PRIu32"' is not a valid parameter "
+ "for checkpoint-interval option. "
+ "please specify a valid "
+ "checkpoint-interval and retry",
+ private->checkpoint_interval);
+ goto err;
+ }
+ }
+ }
+
+ ret = dict_get_str (options, "file-mode", &mode_str);
+ if (ret == 0) {
+ private->file_mode = strtol (mode_str, &endptr, 8);
+
+ if ((*endptr) ||
+ (!IS_VALID_FILE_MODE(private->file_mode))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "'%o' is not a valid parameter for file-mode "
+ "option. please specify a valid parameter for "
+ "file-mode and retry.",
+ private->file_mode);
+ goto err;
+ }
+ } else {
+ private->file_mode = DEFAULT_FILE_MODE;
+ }
+ private->symlink_mode = private->file_mode | S_IFLNK;
+ private->file_mode = private->file_mode | S_IFREG;
+
+ ret = dict_get_str (options, "dir-mode", &mode_str);
+ if (ret == 0) {
+ private->dir_mode = strtol (mode_str, &endptr, 8);
+ if ((*endptr) ||
+ (!IS_VALID_FILE_MODE(private->dir_mode))) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "'%o' is not a valid parameter for dir-mode "
+ "option. please specify a valid parameter for "
+ "dir-mode and retry.",
+ private->dir_mode);
+ goto err;
+ }
+ } else {
+ private->dir_mode = DEFAULT_DIR_MODE;
+ }
+
+ private->dir_mode = private->dir_mode | S_IFDIR;
+
+ table = GF_CALLOC (1, sizeof (*table), gf_bdb_mt_bctx_table_t);
+ if (table == NULL) {
+ gf_log ("bdb-ll", GF_LOG_CRITICAL,
+ "memory allocation for 'storage/bdb' internal "
+ "context table failed.");
+ goto err;
+ }
+
+ INIT_LIST_HEAD(&(table->b_lru));
+ INIT_LIST_HEAD(&(table->active));
+ INIT_LIST_HEAD(&(table->purge));
+
+ LOCK_INIT (&table->lock);
+ LOCK_INIT (&table->checkpoint_lock);
+
+ table->transaction = private->transaction;
+ table->access_mode = private->access_mode;
+ table->dbflags = private->dbflags;
+ table->this = this;
+
+ ret = dict_get_str (options, "lru-limit",
+ &lru_limit_str);
+
+ /* TODO: set max lockers and max txns to accomodate
+ * for more than lru_limit */
+ if (ret == 0) {
+ ret = gf_string2uint32 (lru_limit_str,
+ &table->lru_limit);
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "setting lru limit of 'storage/bdb' internal context"
+ "table to %d. maximum of %d unused databases can be "
+ "open at any given point of time.",
+ table->lru_limit, table->lru_limit);
+ } else {
+ table->lru_limit = BDB_DEFAULT_LRU_LIMIT;
+ }
+
+ ret = dict_get_str (options, "page-size",
+ &page_size_str);
+
+ if (ret == 0) {
+ ret = gf_string2bytesize (page_size_str,
+ &table->page_size);
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "\"%s\" is an invalid parameter to "
+ "\"option page-size\". please specify a valid "
+ "size and retry.",
+ page_size_str);
+ goto err;
+ }
+
+ if (!PAGE_SIZE_IN_RANGE(table->page_size)) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "\"%s\" is out of range for Berkeley DB "
+ "page-size. allowed page-size range is %d to "
+ "%d. please specify a page-size value in the "
+ "range and retry.",
+ page_size_str, BDB_LL_PAGE_SIZE_MIN,
+ BDB_LL_PAGE_SIZE_MAX);
+ goto err;
+ }
+ } else {
+ table->page_size = BDB_LL_PAGE_SIZE_DEFAULT;
+ }
+
+ table->hash_size = BDB_DEFAULT_HASH_SIZE;
+ table->b_hash = GF_CALLOC (BDB_DEFAULT_HASH_SIZE,
+ sizeof (struct list_head),
+ gf_bdb_mt_list_head);
+
+ for (idx = 0; idx < table->hash_size; idx++)
+ INIT_LIST_HEAD(&(table->b_hash[idx]));
+
+ private->b_table = table;
+
+ ret = dict_get_str (options, "errfile", &errfile);
+ if (ret == 0) {
+ private->errfile = gf_strdup (errfile);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "using %s as error logging file for libdb (Berkeley DB "
+ "library) internal logging.", private->errfile);
+ }
+
+ ret = dict_get_str (options, "directory", &directory);
+
+ if (ret == 0) {
+ ret = dict_get_str (options, "logdir", &logdir);
+
+ if (ret < 0) {
+ gf_log ("bdb-ll", GF_LOG_DEBUG,
+ "using the database environment home "
+ "directory (%s) itself as transaction log "
+ "directory", directory);
+ private->logdir = gf_strdup (directory);
+
+ } else {
+ private->logdir = gf_strdup (logdir);
+
+ op_ret = stat (private->logdir, &stbuf);
+ if ((op_ret != 0)
+ || (!S_ISDIR (stbuf.st_mode))) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "specified logdir %s does not exist. "
+ "please provide a valid existing "
+ "directory as parameter to 'option "
+ "logdir'",
+ private->logdir);
+ goto err;
+ }
+ }
+
+ private->b_table->dbenv = bdb_dbenv_init (this, directory);
+ if (private->b_table->dbenv == NULL) {
+ gf_log ("bdb-ll", GF_LOG_ERROR,
+ "initialization of database environment "
+ "failed");
+ goto err;
+ } else {
+ if (private->transaction) {
+ /* all well, start the checkpointing thread */
+ LOCK_INIT (&private->active_lock);
+
+ LOCK (&private->active_lock);
+ {
+ private->active = 1;
+ }
+ UNLOCK (&private->active_lock);
+ pthread_create (&private->checkpoint_thread,
+ NULL, bdb_checkpoint, this);
+ }
+ }
+ }
+
+ return op_ret;
+err:
+ if (table) {
+ GF_FREE (table->b_hash);
+ GF_FREE (table);
+ }
+ if (private) {
+ if (private->errfile)
+ GF_FREE (private->errfile);
+
+ if (private->logdir)
+ GF_FREE (private->logdir);
+ }
+
+ return -1;
+}
diff --git a/xlators/storage/bdb/src/bdb-mem-types.h b/xlators/storage/bdb/src/bdb-mem-types.h
new file mode 100644
index 000000000..92b82b224
--- /dev/null
+++ b/xlators/storage/bdb/src/bdb-mem-types.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __POSIX_MEM_TYPES_H__
+#define __POSIX_MEM_TYPES_H__
+
+#include "mem-types.h"
+
+enum gf_bdb_mem_types_ {
+ gf_bdb_mt_bctx_t = gf_common_mt_end + 1,
+ gf_bdb_mt_bdb_fd,
+ gf_bdb_mt_dir_entry_t,
+ gf_bdb_mt_char,
+ gf_bdb_mt_dir_entry_t,
+ gf_bdb_mt_char,
+ gf_bdb_mt_bdb_private,
+ gf_bdb_mt_uint32_t,
+ gf_bdb_mt_char,
+ gf_bdb_mt_bdb_cache_t,
+ gf_bdb_mt_char,
+ gf_bdb_mt_bctx_table_t,
+ gf_bdb_mt_list_head,
+ gf_bdb_mt_end,
+};
+#endif
diff --git a/xlators/storage/bdb/src/bdb.c b/xlators/storage/bdb/src/bdb.c
new file mode 100644
index 000000000..f8c5ee270
--- /dev/null
+++ b/xlators/storage/bdb/src/bdb.c
@@ -0,0 +1,3603 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+/* bdb based storage translator - named as 'bdb' translator
+ *
+ *
+ * There can be only two modes for files existing on bdb translator:
+ * 1. DIRECTORY - directories are stored by bdb as regular directories on
+ * back-end file-system. directories also have an entry in the ns_db.db of
+ * their parent directory.
+ * 2. REGULAR FILE - regular files are stored as records in the storage_db.db
+ * present in the directory. regular files also have an entry in ns_db.db
+ *
+ * Internally bdb has a maximum of three different types of logical files
+ * associated with each directory:
+ * 1. storage_db.db - storage database, used to store the data corresponding to
+ * regular files in the form of key/value pair. file-name is the 'key' and
+ * data is 'value'.
+ * 2. directory (all subdirectories) - any subdirectory will have a regular
+ * directory entry.
+ */
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#define __XOPEN_SOURCE 500
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <ftw.h>
+#include <libgen.h>
+
+#include "glusterfs.h"
+#include "dict.h"
+#include "logging.h"
+#include "bdb.h"
+#include "xlator.h"
+#include "defaults.h"
+#include "common-utils.h"
+
+/* to be used only by fops, nobody else */
+#define BDB_ENV(this) ((((struct bdb_private *)this->private)->b_table)->dbenv)
+#define B_TABLE(this) (((struct bdb_private *)this->private)->b_table)
+
+
+int32_t
+bdb_mknod (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode,
+ dev_t dev)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *key_string = NULL; /* after translating path to DB key */
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+ struct stat stbuf = {0,};
+
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ if (!S_ISREG(mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): EPERM"
+ "(mknod supported only for regular files. "
+ "file mode '%o' not supported)",
+ loc->parent->ino, loc->name, loc->path, mode);
+ op_ret = -1;
+ op_errno = EPERM;
+ goto out;
+ } /* if(!S_ISREG(mode)) */
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): EINVAL"
+ "(failed to lookup database handle)",
+ loc->parent->ino, loc->name, loc->path);
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = bdb_db_icreate (bctx, key_string);
+ if (op_ret > 0) {
+ /* create successful */
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ stbuf.st_mode = mode;
+ stbuf.st_size = 0;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, \
+ stbuf.st_blksize);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKNOD %"PRId64"/%s (%s): ENOMEM"
+ "(failed to create database entry)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = EINVAL; /* TODO: errno sari illa */
+ goto out;
+ }/* if (!op_ret)...else */
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ return 0;
+}
+
+static inline int32_t
+is_dir_empty (xlator_t *this,
+ loc_t *loc)
+{
+ int32_t ret = 1;
+ bctx_t *bctx = NULL;
+ DIR *dir = NULL;
+ char *real_path = NULL;
+ void *dbstat = NULL;
+ struct dirent *entry = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dbstat = bdb_db_stat (bctx, NULL, 0);
+ if (dbstat) {
+ switch (bctx->table->access_mode)
+ {
+ case DB_HASH:
+ ret = (((DB_HASH_STAT *)dbstat)->hash_nkeys == 0);
+ break;
+ case DB_BTREE:
+ case DB_RECNO:
+ ret = (((DB_BTREE_STAT *)dbstat)->bt_nkeys == 0);
+ break;
+ case DB_QUEUE:
+ ret = (((DB_QUEUE_STAT *)dbstat)->qs_nkeys == 0);
+ break;
+ case DB_UNKNOWN:
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "unknown access-mode set for database");
+ ret = 0;
+ }
+ } else {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ dir = opendir (real_path);
+ if (dir == NULL) {
+ ret = -errno;
+ goto out;
+ }
+
+ while ((entry = readdir (dir))) {
+ if ((!IS_BDB_PRIVATE_FILE(entry->d_name)) &&
+ (!IS_DOT_DOTDOT(entry->d_name))) {
+ ret = 0;
+ break;
+ }/* if(!IS_BDB_PRIVATE_FILE()) */
+ } /* while(true) */
+ closedir (dir);
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ return ret;
+}
+
+int32_t
+bdb_rename (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ STACK_UNWIND (frame, -1, EXDEV, NULL);
+ return 0;
+}
+
+int32_t
+bdb_link (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *oldloc,
+ loc_t *newloc)
+{
+ STACK_UNWIND (frame, -1, EXDEV, NULL, NULL);
+ return 0;
+}
+
+int32_t
+is_space_left (xlator_t *this,
+ size_t size)
+{
+ struct bdb_private *private = this->private;
+ struct statvfs stbuf = {0,};
+ int32_t ret = -1;
+ fsblkcnt_t req_blocks = 0;
+ fsblkcnt_t usable_blocks = 0;
+
+ ret = statvfs (private->export_path, &stbuf);
+ if (ret != 0) {
+ ret = 0;
+ } else {
+ req_blocks = (size / stbuf.f_frsize) + 1;
+
+ usable_blocks = (stbuf.f_bfree - BDB_ENOSPC_THRESHOLD);
+
+ if (req_blocks < usable_blocks)
+ ret = 1;
+ else
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int32_t
+bdb_create (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ mode_t mode,
+ fd_t *fd)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ char *db_path = NULL;
+ struct stat stbuf = {0,};
+ bctx_t *bctx = NULL;
+ struct bdb_private *private = NULL;
+ char *key_string = NULL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ private = this->private;
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = EINVAL;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): EINVAL"
+ "(database file missing)",
+ loc->parent->ino, loc->name, loc->path);
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = bdb_db_icreate (bctx, key_string);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): ENOMEM"
+ "(failed to create database entry)",
+ loc->parent->ino, loc->name, loc->path);
+ op_errno = EINVAL; /* TODO: errno sari illa */
+ goto out;
+ }
+
+ /* create successful */
+ bfd = GF_CALLOC (1, sizeof (*bfd), gf_bdb_mt_bdb_fd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64"/%s (%s): ENOMEM"
+ "(failed to allocate memory for internal fd context)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ /* NOTE: bdb_get_bctx_from () returns bctx with a ref */
+ bfd->ctx = bctx;
+ bfd->key = gf_strdup (key_string);
+ if (bfd->key == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CREATE %"PRId64" (%s): ENOMEM"
+ "(failed to allocate memory for internal fd->key)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ BDB_FCTX_SET (fd, this, bfd);
+
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ stbuf.st_mode = private->file_mode;
+ stbuf.st_size = 0;
+ stbuf.st_nlink = 1;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_ret = 0;
+ op_errno = 0;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd, loc->inode, &stbuf);
+
+ return 0;
+}
+
+
+/* bdb_open
+ *
+ * as input parameters bdb_open gets the file name, i.e key. bdb_open should
+ * effectively
+ * do: store key, open storage db, store storage-db pointer.
+ *
+ */
+int32_t
+bdb_open (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flags,
+ fd_t *fd,
+ int32_t wbflags)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPEN %"PRId64" (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ bfd = GF_CALLOC (1, sizeof (*bfd), gf_bdb_mt_bdb_fd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPEN %"PRId64" (%s): ENOMEM"
+ "(failed to allocate memory for internal fd context)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ /* NOTE: bctx_parent () returns bctx with a ref */
+ bfd->ctx = bctx;
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ bfd->key = gf_strdup (key_string);
+ if (bfd->key == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPEN %"PRId64" (%s): ENOMEM"
+ "(failed to allocate memory for internal fd->key)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ BDB_FCTX_SET (fd, this, bfd);
+ op_ret = 0;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+
+ return 0;
+}
+
+int32_t
+bdb_readv (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t offset)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct iovec vec = {0,};
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ char *db_path = NULL;
+ int32_t read_size = 0;
+ struct iobref *iobref = NULL;
+ struct iobuf *iobuf = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READV %"PRId64" - %"GF_PRI_SIZET",%"PRId64": EBADFD"
+ "(internal fd not found through fd)",
+ fd->inode->ino, size, offset);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READV %"PRId64" - %"GF_PRI_SIZET",%"PRId64": EINVAL"
+ "(database file missing)",
+ fd->inode->ino, size, offset);
+ goto out;
+ }
+
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (!iobuf) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory :(");
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ /* we are ready to go */
+ op_ret = bdb_db_fread (bfd, iobuf->ptr, size, offset);
+ read_size = op_ret;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READV %"PRId64" - %"GF_PRI_SIZET",%"PRId64": EBADFD"
+ "(failed to find entry in database)",
+ fd->inode->ino, size, offset);
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ } else if (op_ret == 0) {
+ goto out;
+ }
+
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory :(");
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ if (size < read_size) {
+ op_ret = size;
+ read_size = size;
+ }
+
+ iobref_add (iobref, iobuf);
+
+ vec.iov_base = iobuf->ptr;
+ vec.iov_len = read_size;
+
+ stbuf.st_ino = fd->inode->ino;
+ stbuf.st_size = bdb_db_fread (bfd, NULL, 0, 0);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_ret = size;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &vec, 1, &stbuf, iobuf);
+
+ if (iobref)
+ iobref_unref (iobref);
+
+ if (iobuf)
+ iobuf_unref (iobuf);
+
+ return 0;
+}
+
+
+int32_t
+bdb_writev (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ struct iovec *vector,
+ int32_t count,
+ off_t offset,
+ struct iobref *iobref)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ int32_t idx = 0;
+ off_t c_off = offset;
+ int32_t c_ret = -1;
+ char *db_path = NULL;
+ size_t total_size = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, vector, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "WRITEV %"PRId64" - %"PRId32",%"PRId64": EBADFD"
+ "(internal fd not found through fd)",
+ fd->inode->ino, count, offset);
+ op_ret = -1;
+ op_errno = EBADFD;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bfd->ctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "WRITEV %"PRId64" - %"PRId32",%"PRId64": EINVAL"
+ "(database file missing)",
+ fd->inode->ino, count, offset);
+ goto out;
+ }
+
+ for (idx = 0; idx < count; idx++)
+ total_size += vector[idx].iov_len;
+
+ if (!is_space_left (this, total_size)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "WRITEV %"PRId64" - %"PRId32" (%"GF_PRI_SIZET"),%"
+ PRId64": ENOSPC "
+ "(not enough space after internal measurement)",
+ fd->inode->ino, count, total_size, offset);
+ op_ret = -1;
+ op_errno = ENOSPC;
+ goto out;
+ }
+
+ /* we are ready to go */
+ for (idx = 0; idx < count; idx++) {
+ c_ret = bdb_db_fwrite (bfd, vector[idx].iov_base,
+ vector[idx].iov_len, c_off);
+ if (c_ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "WRITEV %"PRId64" - %"PRId32",%"PRId64": EINVAL"
+ "(database write at %"PRId64" failed)",
+ fd->inode->ino, count, offset, c_off);
+ break;
+ } else {
+ c_off += vector[idx].iov_len;
+ }
+ op_ret += vector[idx].iov_len;
+ } /* for(idx=0;...)... */
+
+ if (c_ret) {
+ /* write failed after a point, not an error */
+ stbuf.st_size = bdb_db_fread (bfd, NULL, 0, 0);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size,
+ stbuf.st_blksize);
+ goto out;
+ }
+
+ /* NOTE: we want to increment stbuf->st_size, as stored in db */
+ stbuf.st_size = op_ret;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ op_errno = 0;
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ return 0;
+}
+
+int32_t
+bdb_flush (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "FLUSH %"PRId64": EBADFD"
+ "(internal fd not found through fd)",
+ fd->inode->ino);
+ op_ret = -1;
+ op_errno = EBADFD;
+ goto out;
+ }
+
+ /* do nothing */
+ op_ret = 0;
+ op_errno = 0;
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+bdb_release (xlator_t *this,
+ fd_t *fd)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EBADFD;
+ struct bdb_fd *bfd = NULL;
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RELEASE %"PRId64": EBADFD"
+ "(internal fd not found through fd)",
+ fd->inode->ino);
+ op_ret = -1;
+ op_errno = EBADFD;
+ goto out;
+ }
+
+ bctx_unref (bfd->ctx);
+ bfd->ctx = NULL;
+
+ if (bfd->key)
+ GF_FREE (bfd->key); /* we did strdup() in bdb_open() */
+ GF_FREE (bfd);
+ op_ret = 0;
+ op_errno = 0;
+
+out:
+ return 0;
+}/* bdb_release */
+
+
+int32_t
+bdb_fsync (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t datasync)
+{
+ STACK_UNWIND (frame, 0, 0);
+ return 0;
+}/* bdb_fsync */
+
+static int gf_bdb_lk_log;
+
+int32_t
+bdb_lk (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t cmd,
+ struct gf_flock *lock)
+{
+ struct gf_flock nullock = {0, };
+
+ if (BDB_TIMED_LOG (ENOTSUP, gf_bdb_lk_log)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LK %"PRId64": ENOTSUP "
+ "(load \"features/locks\" translator to enable "
+ "lock support)",
+ fd->inode->ino);
+ }
+
+ STACK_UNWIND (frame, -1, ENOTSUP, &nullock);
+ return 0;
+}/* bdb_lk */
+
+/* bdb_lookup
+ *
+ * there are four possibilities for a file being looked up:
+ * 1. file exists and is a directory.
+ * 2. file exists and is a symlink.
+ * 3. file exists and is a regular file.
+ * 4. file does not exist.
+ * case 1 and 2 are handled by doing lstat() on the @loc. if the file is a
+ * directory or symlink, lstat() succeeds. lookup continues to check if the
+ * @loc belongs to case-3 only if lstat() fails.
+ * to check for case 3, bdb_lookup does a bdb_db_iread() for the given @loc.
+ * (see description of bdb_db_iread() for more details on how @loc is transformed
+ * into db handle and key). if check for case 1, 2 and 3 fail, we proceed to
+ * conclude that file doesn't exist (case 4).
+ *
+ * @frame: call frame.
+ * @this: xlator_t of this instance of bdb xlator.
+ * @loc: loc_t specifying the file to operate upon.
+ * @need_xattr: if need_xattr != 0, we are asked to return all the extended
+ * attributed of @loc, if any exist, in a dictionary. if @loc is a regular
+ * file and need_xattr is set, then we look for value of need_xattr. if
+ * need_xattr > sizo-of-the-file @loc, then the file content of @loc is
+ * returned in dictionary of xattr with 'glusterfs.content' as dictionary key.
+ *
+ * NOTE: bdb currently supports only directories, symlinks and regular files.
+ *
+ * NOTE: bdb_lookup returns the 'struct stat' of underlying file itself, in
+ * case of directory and symlink (st_ino is modified as bdb allocates its own
+ * set of inodes of all files). for regular files, bdb uses 'struct stat' of
+ * the database file in which the @loc is stored as templete and modifies
+ * st_ino (see bdb_inode_transform for more details), st_mode (can be set in
+ * volfile 'option file-mode <mode>'), st_size (exact size of the @loc
+ * contents), st_blocks (block count on the underlying filesystem to
+ * accomodate st_size, see BDB_COUNT_BLOCKS in bdb.h for more details).
+ */
+int32_t
+bdb_lookup (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *xattr_req)
+{
+ struct stat stbuf = {0, };
+ int32_t op_ret = -1;
+ int32_t op_errno = ENOENT;
+ dict_t *xattr = NULL;
+ char *pathname = NULL;
+ char *directory = NULL;
+ char *real_path = NULL;
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
+ struct bdb_private *private = NULL;
+ char *key_string = NULL;
+ int32_t entry_size = 0;
+ char *file_content = NULL;
+ uint64_t need_xattr = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ private = this->private;
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ pathname = gf_strdup (loc->path);
+ GF_VALIDATE_OR_GOTO (this->name, pathname, out);
+
+ directory = dirname (pathname);
+ GF_VALIDATE_OR_GOTO (this->name, directory, out);
+
+ if (!strcmp (directory, loc->path)) {
+ /* SPECIAL CASE: looking up root */
+ op_ret = lstat (real_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64" (%s): %s",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+
+ /* bctx_lookup() returns NULL only when its time to wind up,
+ * we should shutdown functioning */
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64" (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ stbuf.st_ino = 1;
+ stbuf.st_mode = private->dir_mode;
+
+ op_ret = 0;
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == 0) && (S_ISDIR (stbuf.st_mode))){
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ if (loc->ino) {
+ /* revalidating directory inode */
+ stbuf.st_ino = loc->ino;
+ } else {
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ }
+ stbuf.st_mode = private->dir_mode;
+
+ op_ret = 0;
+ goto out;
+
+ } else if (op_ret == 0) {
+ /* a symlink */
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ if (loc->ino) {
+ stbuf.st_ino = loc->ino;
+ } else {
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ }
+
+ stbuf.st_mode = private->symlink_mode;
+
+ op_ret = 0;
+ goto out;
+
+ }
+
+ /* for regular files */
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): ENOMEM"
+ "(failed to lookup database handle for parent)",
+ loc->parent->ino, loc->name, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ if (GF_FILE_CONTENT_REQUESTED(xattr_req, &need_xattr)) {
+ entry_size = bdb_db_iread (bctx, key_string, &file_content);
+ } else {
+ entry_size = bdb_db_iread (bctx, key_string, NULL);
+ }
+
+ op_ret = entry_size;
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): ENOENT"
+ "(database entry not found)",
+ loc->parent->ino, loc->name, loc->path);
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "LOOKUP %"PRId64"/%s (%s): %s",
+ loc->parent->ino, loc->name, loc->path,
+ strerror (op_errno));
+ goto out;
+ }
+
+ if (entry_size
+ && (need_xattr >= entry_size)
+ && (file_content)) {
+ xattr = dict_new ();
+ op_ret = dict_set_dynptr (xattr, "glusterfs.content",
+ file_content, entry_size);
+ if (op_ret < 0) {
+ /* continue without giving file contents */
+ GF_FREE (file_content);
+ }
+ } else {
+ if (file_content)
+ GF_FREE (file_content);
+ }
+
+ if (loc->ino) {
+ /* revalidate */
+ stbuf.st_ino = loc->ino;
+ stbuf.st_size = entry_size;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size,
+ stbuf.st_blksize);
+ } else {
+ /* fresh lookup, create an inode number */
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ stbuf.st_size = entry_size;
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size,
+ stbuf.st_blksize);
+ }/* if(inode->ino)...else */
+ stbuf.st_nlink = 1;
+ stbuf.st_mode = private->file_mode;
+
+ op_ret = 0;
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ if (pathname)
+ GF_FREE (pathname);
+
+ if (xattr)
+ dict_ref (xattr);
+
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf, xattr);
+
+ if (xattr)
+ dict_unref (xattr);
+
+ return 0;
+
+}/* bdb_lookup */
+
+int32_t
+bdb_stat (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+
+ struct stat stbuf = {0,};
+ char *real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct bdb_private *private = NULL;
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ private = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, private, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = lstat (real_path, &stbuf);
+ op_errno = errno;
+ if (op_ret == 0) {
+ /* directory or symlink */
+ stbuf.st_ino = loc->inode->ino;
+ if (S_ISDIR(stbuf.st_mode))
+ stbuf.st_mode = private->dir_mode;
+ else
+ stbuf.st_mode = private->symlink_mode;
+ /* we are done, lets unwind the stack */
+ goto out;
+ }
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "STAT %"PRId64" (%s): ENOMEM"
+ "(no database handle for parent)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "STAT %"PRId64" (%s): %s"
+ "(failed to stat on database file)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+
+ stbuf.st_size = bdb_db_iread (bctx, loc->path, NULL);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+ stbuf.st_ino = loc->inode->ino;
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
+}/* bdb_stat */
+
+
+
+/* bdb_opendir - in the world of bdb, open/opendir is all about opening
+ * correspondind databases. opendir in particular, opens the database for the
+ * directory which is to be opened. after opening the database, a cursor to
+ * the database is also created. cursor helps us get the dentries one after
+ * the other, and cursor maintains the state about current positions in
+ * directory. pack 'pointer to db', 'pointer to the cursor' into
+ * struct bdb_dir and store it in fd->ctx, we get from our parent xlator.
+ *
+ * @frame: call frame
+ * @this: our information, as we filled during init()
+ * @loc: location information
+ * @fd: file descriptor structure (glusterfs internal)
+ *
+ * return value - immaterial, async call.
+ *
+ */
+int32_t
+bdb_opendir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ fd_t *fd)
+{
+ char *real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ struct bdb_dir *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPENDIR %"PRId64" (%s): ENOMEM"
+ "(no database handle for directory)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ bfd = GF_CALLOC (1, sizeof (*bfd), gf_bdb_mt_bdb_fd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPENDIR %"PRId64" (%s): ENOMEM"
+ "(failed to allocate memory for internal fd)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ bfd->dir = opendir (real_path);
+ if (bfd->dir == NULL) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPENDIR %"PRId64" (%s): %s",
+ loc->ino, loc->path, strerror (op_errno));
+ goto err;
+ }
+
+ /* NOTE: bctx_lookup() return bctx with ref */
+ bfd->ctx = bctx;
+
+ bfd->path = gf_strdup (real_path);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "OPENDIR %"PRId64" (%s): ENOMEM"
+ "(failed to allocate memory for internal fd->path)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ BDB_FCTX_SET (fd, this, bfd);
+ op_ret = 0;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+ return 0;
+err:
+ if (bctx)
+ bctx_unref (bctx);
+ if (bfd) {
+ if (bfd->dir)
+ closedir (bfd->dir);
+
+ GF_FREE (bfd);
+ }
+
+ return 0;
+}/* bdb_opendir */
+
+int32_t
+bdb_getdents (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t off,
+ int32_t flag)
+{
+ struct bdb_dir *bfd = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ size_t filled = 0;
+ dir_entry_t entries = {0, };
+ dir_entry_t *this_entry = NULL;
+ char *entry_path = NULL;
+ struct dirent *dirent = NULL;
+ off_t in_case = 0;
+ int32_t this_size = 0;
+ DBC *cursorp = NULL;
+ int32_t ret = -1;
+ int32_t real_path_len = 0;
+ int32_t entry_path_len = 0;
+ int32_t count = 0;
+ off_t offset = 0;
+ size_t tmp_name_len = 0;
+ struct stat db_stbuf = {0,};
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " %o: EBADFD "
+ "(failed to find internal context in fd)",
+ fd->inode->ino, size, off, flag);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ ": EBADFD "
+ "(failed to open cursor to database handle)",
+ fd->inode->ino, size, off);
+ op_errno = EBADFD;
+ goto out;
+ }
+
+ if (off) {
+ DBT sec = {0,}, pri = {0,}, val = {0,};
+ sec.data = &(off);
+ sec.size = sizeof (off);
+ sec.flags = DB_DBT_USERMEM;
+ val.dlen = 0;
+ val.doff = 0;
+ val.flags = DB_DBT_PARTIAL;
+
+ op_ret = bdb_cursor_get (cursorp, &sec, &pri, &val, DB_SET);
+ if (op_ret == DB_NOTFOUND) {
+ offset = off;
+ goto dir_read;
+ }
+ }
+
+ while (filled <= size) {
+ DBT sec = {0,}, pri = {0,}, val = {0,};
+
+ this_entry = NULL;
+
+ sec.flags = DB_DBT_MALLOC;
+ pri.flags = DB_DBT_MALLOC;
+ val.dlen = 0;
+ val.doff = 0;
+ val.flags = DB_DBT_PARTIAL;
+ op_ret = bdb_cursor_get (cursorp, &sec, &pri, &val, DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ /* we reached end of the directory */
+ op_ret = 0;
+ op_errno = 0;
+ break;
+ } else if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET
+ ",%"PRId64":"
+ "(failed to read the next entry from database)",
+ fd->inode->ino, size, off);
+ op_errno = ENOENT;
+ break;
+ } /* if (op_ret == DB_NOTFOUND)...else if...else */
+
+ if (pri.data == NULL) {
+ /* NOTE: currently ignore when we get key.data == NULL.
+ * FIXME: we should not get key.data = NULL */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET
+ ",%"PRId64":"
+ "(null key read for entry from database)",
+ fd->inode->ino, size, off);
+ continue;
+ }/* if(key.data)...else */
+
+ this_entry = GF_CALLOC (1, sizeof (*this_entry),
+ gf_bdb_mt_dir_entry_t);
+ if (this_entry == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " - %s:"
+ "(failed to allocate memory for an entry)",
+ fd->inode->ino, size, off, strerror (errno));
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
+
+ this_entry->name = GF_CALLOC (pri.size + 1, sizeof (char),
+ gf_bdb_mt_char);
+ if (this_entry->name == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " - %s:"
+ "(failed to allocate memory for an "
+ "entry->name)",
+ fd->inode->ino, size, off, strerror (errno));
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
+
+ memcpy (this_entry->name, pri.data, pri.size);
+ this_entry->buf = db_stbuf;
+ this_entry->buf.st_size = bdb_db_iread (bfd->ctx,
+ this_entry->name, NULL);
+ this_entry->buf.st_blocks = BDB_COUNT_BLOCKS (
+ this_entry->buf.st_size,
+ this_entry->buf.st_blksize);
+
+ this_entry->buf.st_ino = bdb_inode_transform (fd->inode->ino,
+ pri.data,
+ pri.size);
+ count++;
+
+ this_entry->next = entries.next;
+ this_entry->link = "";
+ entries.next = this_entry;
+ /* if size is 0, count can never be = size,
+ * so entire dir is read */
+ if (sec.data)
+ GF_FREE (sec.data);
+
+ if (pri.data)
+ GF_FREE (pri.data);
+
+ if (count == size)
+ break;
+ }/* while */
+ bdb_cursor_close (bfd->ctx, cursorp);
+ op_ret = count;
+ op_errno = 0;
+ if (count >= size)
+ goto out;
+dir_read:
+ /* hungry kyaa? */
+ if (!offset) {
+ rewinddir (bfd->dir);
+ } else {
+ seekdir (bfd->dir, offset);
+ }
+
+ while (filled <= size) {
+ this_entry = NULL;
+ this_size = 0;
+
+ in_case = telldir (bfd->dir);
+ dirent = readdir (bfd->dir);
+ if (!dirent)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(dirent->d_name))
+ continue;
+
+ tmp_name_len = strlen (dirent->d_name);
+ if (entry_path_len < (real_path_len + 1 + (tmp_name_len) + 1)) {
+ entry_path_len = real_path_len + tmp_name_len + 1024;
+ entry_path = realloc (entry_path, entry_path_len);
+ if (entry_path == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET","
+ "%"PRId64" - %s: (failed to allocate "
+ "memory for an entry_path)",
+ fd->inode->ino, size, off,
+ strerror (errno));
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
+ }
+
+ strncpy (&entry_path[real_path_len+1], dirent->d_name,
+ tmp_name_len);
+ op_ret = stat (entry_path, &buf);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " - %s:"
+ " (failed to stat on an entry '%s')",
+ fd->inode->ino, size, off,
+ strerror (errno), entry_path);
+ goto out; /* FIXME: shouldn't we continue here */
+ }
+
+ if ((flag == GF_GET_DIR_ONLY) &&
+ ((ret != -1) && (!S_ISDIR(buf.st_mode)))) {
+ continue;
+ }
+
+ this_entry = GF_CALLOC (1, sizeof (*this_entry),
+ gf_bdb_mt_dir_entry_t);
+ if (this_entry == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " - %s:"
+ "(failed to allocate memory for an entry)",
+ fd->inode->ino, size, off, strerror (errno));
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
+
+ this_entry->name = gf_strdup (dirent->d_name);
+ if (this_entry->name == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET",%"PRId64
+ " - %s:"
+ "(failed to allocate memory for an "
+ "entry->name)",
+ fd->inode->ino, size, off, strerror (errno));
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
+
+ this_entry->buf = buf;
+
+ this_entry->buf.st_ino = -1;
+ if (S_ISLNK(this_entry->buf.st_mode)) {
+ char linkpath[ZR_PATH_MAX] = {0,};
+ ret = readlink (entry_path, linkpath, ZR_PATH_MAX);
+ if (ret != -1) {
+ linkpath[ret] = '\0';
+ this_entry->link = gf_strdup (linkpath);
+ }
+ } else {
+ this_entry->link = "";
+ }
+
+ count++;
+
+ this_entry->next = entries.next;
+ entries.next = this_entry;
+
+ /* if size is 0, count can never be = size,
+ * so entire dir is read */
+ if (count == size)
+ break;
+ }
+ op_ret = filled;
+ op_errno = 0;
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETDENTS %"PRId64" - %"GF_PRI_SIZET" (%"PRId32")"
+ "/%"GF_PRI_SIZET",%"PRId64":"
+ "(failed to read the next entry from database)",
+ fd->inode->ino, filled, count, size, off);
+
+ STACK_UNWIND (frame, count, op_errno, &entries);
+
+ while (entries.next) {
+ this_entry = entries.next;
+ entries.next = entries.next->next;
+ GF_FREE (this_entry->name);
+ GF_FREE (this_entry);
+ }
+
+ return 0;
+}/* bdb_getdents */
+
+
+int32_t
+bdb_releasedir (xlator_t *this,
+ fd_t *fd)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ struct bdb_dir *bfd = NULL;
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RELEASEDIR %"PRId64": EBADFD",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ if (bfd->path) {
+ GF_FREE (bfd->path);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RELEASEDIR %"PRId64": (bfd->path is NULL)",
+ fd->inode->ino);
+ }
+
+ if (bfd->dir) {
+ closedir (bfd->dir);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RELEASEDIR %"PRId64": (bfd->dir is NULL)",
+ fd->inode->ino);
+ }
+
+ if (bfd->ctx) {
+ bctx_unref (bfd->ctx);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RELEASEDIR %"PRId64": (bfd->ctx is NULL)",
+ fd->inode->ino);
+ }
+
+ GF_FREE (bfd);
+
+out:
+ return 0;
+}/* bdb_releasedir */
+
+
+int32_t
+bdb_readlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ size_t size)
+{
+ char *dest = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ dest = alloca (size + 1);
+ GF_VALIDATE_OR_GOTO (this->name, dest, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = readlink (real_path, dest, size);
+
+ if (op_ret > 0)
+ dest[op_ret] = 0;
+
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READLINK %"PRId64" (%s): %s",
+ loc->ino, loc->path, strerror (op_errno));
+ }
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, dest);
+
+ return 0;
+}/* bdb_readlink */
+
+
+int32_t
+bdb_mkdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ mode_t mode)
+{
+ int32_t op_ret = -1;
+ int32_t ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0, };
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = mkdir (real_path, mode);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64" (%s): %s",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+
+ op_ret = chown (real_path, frame->root->uid, frame->root->gid);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64" (%s): %s "
+ "(failed to do chmod)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto err;
+ }
+
+ op_ret = lstat (real_path, &stbuf);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64" (%s): %s "
+ "(failed to do lstat)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto err;
+ }
+
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64" (%s): ENOMEM"
+ "(no database handle for parent)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino, key_string,
+ strlen (key_string));
+
+ goto out;
+
+err:
+ ret = rmdir (real_path);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "MKDIR %"PRId64" (%s): %s"
+ "(failed to do rmdir)",
+ loc->ino, loc->path, strerror (errno));
+ }
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+
+ return 0;
+}/* bdb_mkdir */
+
+
+int32_t
+bdb_unlink (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+ char *key_string = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "UNLINK %"PRId64" (%s): ENOMEM"
+ "(no database handle for parent)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+ op_ret = bdb_db_iremove (bctx, key_string);
+ if (op_ret == DB_NOTFOUND) {
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = unlink (real_path);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "UNLINK %"PRId64" (%s): %s"
+ "(symlink unlink failed)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+ } else if (op_ret == 0) {
+ op_errno = 0;
+ }
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}/* bdb_unlink */
+
+
+
+static int32_t
+bdb_do_rmdir (xlator_t *this,
+ loc_t *loc)
+{
+ char *real_path = NULL;
+ int32_t ret = -1;
+ bctx_t *bctx = NULL;
+ DB_ENV *dbenv = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ dbenv = BDB_ENV(this);
+ GF_VALIDATE_OR_GOTO (this->name, dbenv, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ LOCK(&bctx->lock);
+ {
+ if ((bctx->primary == NULL)
+ || (bctx->secondary == NULL)) {
+ goto unlock;
+ }
+
+ ret = bctx->primary->close (bctx->primary, 0);
+ if (ret < 0) {
+ ret = -EINVAL;
+ }
+
+ ret = bctx->secondary->close (bctx->secondary, 0);
+ if (ret < 0) {
+ ret = -EINVAL;
+ }
+
+ ret = dbenv->dbremove (dbenv, NULL, bctx->db_path,
+ "primary", 0);
+ if (ret < 0) {
+ ret = -EBUSY;
+ }
+
+ ret = dbenv->dbremove (dbenv, NULL, bctx->db_path,
+ "secondary", 0);
+ if (ret != 0) {
+ ret = -EBUSY;
+ }
+ }
+unlock:
+ UNLOCK(&bctx->lock);
+
+ if (ret) {
+ goto out;
+ }
+ ret = rmdir (real_path);
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ return ret;
+}
+
+int32_t
+bdb_rmdir (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+
+ op_ret = is_dir_empty (this, loc);
+ if (op_ret < 0) {
+ op_errno = -op_ret;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RMDIR %"PRId64" (%s): %s"
+ "(internal rmdir routine returned error)",
+ loc->ino, loc->path, strerror (op_errno));
+ } else if (op_ret == 0) {
+ op_ret = -1;
+ op_errno = ENOTEMPTY;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RMDIR %"PRId64" (%s): ENOTEMPTY",
+ loc->ino, loc->path);
+ goto out;
+ }
+
+ op_ret = bdb_do_rmdir (this, loc);
+ if (op_ret < 0) {
+ op_errno = -op_ret;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "RMDIR %"PRId64" (%s): %s"
+ "(internal rmdir routine returned error)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+} /* bdb_rmdir */
+
+int32_t
+bdb_symlink (call_frame_t *frame,
+ xlator_t *this,
+ const char *linkname,
+ loc_t *loc)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+ struct bdb_private *private = NULL;
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, linkname, out);
+
+ private = this->private;
+ GF_VALIDATE_OR_GOTO (this->name, private, out);
+
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = symlink (linkname, real_path);
+ op_errno = errno;
+ if (op_ret == 0) {
+ op_ret = lstat (real_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SYMLINK %"PRId64" (%s): %s",
+ loc->ino, loc->path, strerror (op_errno));
+ goto err;
+ }
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SYMLINK %"PRId64" (%s): ENOMEM"
+ "(no database handle for parent)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ stbuf.st_mode = private->symlink_mode;
+
+ goto out;
+ }
+err:
+ op_ret = unlink (real_path);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SYMLINK %"PRId64" (%s): %s"
+ "(failed to unlink the created symlink)",
+ loc->ino, loc->path, strerror (op_errno));
+ }
+ op_ret = -1;
+ op_errno = ENOENT;
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+
+ return 0;
+} /* bdb_symlink */
+
+static int
+bdb_do_chmod (xlator_t *this,
+ const char *path,
+ struct stat *stbuf)
+{
+ int32_t ret = -1;
+
+ ret = lchmod (path, stbuf->st_mode);
+ if ((ret == -1) && (errno == ENOSYS)) {
+ ret = chmod (path, stbuf->st_mode);
+ }
+
+ return ret;
+}
+
+static int
+bdb_do_chown (xlator_t *this,
+ const char *path,
+ struct stat *stbuf,
+ int32_t valid)
+{
+ int32_t ret = -1;
+ uid_t uid = -1;
+ gid_t gid = -1;
+
+ if (valid & GF_SET_ATTR_UID)
+ uid = stbuf->st_uid;
+
+ if (valid & GF_SET_ATTR_GID)
+ gid = stbuf->st_gid;
+
+ ret = lchown (path, uid, gid);
+
+ return ret;
+}
+
+static int
+bdb_do_utimes (xlator_t *this,
+ const char *path,
+ struct stat *stbuf)
+{
+ int32_t ret = -1;
+ struct timeval tv[2] = {{0,},{0,}};
+
+ tv[0].tv_sec = stbuf->st_atime;
+ tv[0].tv_usec = ST_ATIM_NSEC (stbuf) / 1000;
+ tv[1].tv_sec = stbuf->st_mtime;
+ tv[1].tv_usec = ST_ATIM_NSEC (stbuf) / 1000;
+
+ ret = lutimes (path, tv);
+
+ return ret;
+}
+
+int32_t
+bdb_setattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ struct stat *stbuf,
+ int32_t valid)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat preop = {0,};
+ struct stat postop = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = lstat (real_path, &preop);
+ op_errno = errno;
+ if (op_ret != 0) {
+ if (op_errno == ENOENT) {
+ op_errno = EPERM;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHMOD %"PRId64" (%s): %s"
+ "(pre-op lstat failed)",
+ loc->ino, loc->path, strerror (op_errno));
+ }
+ goto out;
+ }
+
+ /* directory or symlink */
+ if (valid & GF_SET_ATTR_MODE) {
+ op_ret = bdb_do_chmod (this, real_path, stbuf);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "setattr (chmod) on %s failed: %s", loc->path,
+ strerror (op_errno));
+ goto out;
+ }
+ }
+
+ if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)){
+ op_ret = bdb_do_chown (this, real_path, stbuf, valid);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "setattr (chown) on %s failed: %s", loc->path,
+ strerror (op_errno));
+ goto out;
+ }
+ }
+
+ if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) {
+ op_ret = bdb_do_utimes (this, real_path, stbuf);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR,
+ "setattr (utimes) on %s failed: %s", loc->path,
+ strerror (op_errno));
+ goto out;
+ }
+ }
+
+ op_ret = lstat (real_path, &postop);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHMOD %"PRId64" (%s): %s"
+ "(post-op lstat failed)",
+ loc->ino, loc->path, strerror (op_errno));
+ }
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &preop, &postop);
+
+ return 0;
+}/* bdb_setattr */
+
+int32_t
+bdb_fsetattr (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ struct stat *stbuf,
+ int32_t valid)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct stat preop = {0,};
+ struct stat postop = {0,};
+
+ STACK_UNWIND (frame, op_ret, op_errno, &preop, &postop);
+
+ return 0;
+}/* bdb_fsetattr */
+
+
+int32_t
+bdb_truncate (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ off_t offset)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct stat stbuf = {0,};
+ char *db_path = NULL;
+ bctx_t *bctx = NULL;
+ char *key_string = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ bctx = bctx_parent (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "TRUNCATE %"PRId64" (%s): ENOMEM"
+ "(no database handle for parent)",
+ loc->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_KEY_FROM_PATH (key_string, loc->path);
+
+ /* now truncate */
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "TRUNCATE %"PRId64" (%s): %s"
+ "(lstat on database file failed)",
+ loc->ino, loc->path, strerror (op_errno));
+ goto out;
+ }
+
+ if (loc->inode->ino) {
+ stbuf.st_ino = loc->inode->ino;
+ }else {
+ stbuf.st_ino = bdb_inode_transform (loc->parent->ino,
+ key_string,
+ strlen (key_string));
+ }
+
+ op_ret = bdb_db_itruncate (bctx, key_string);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "TRUNCATE %"PRId64" (%s): EINVAL"
+ "(truncating entry in database failed - %s)",
+ loc->ino, loc->path, db_strerror (op_ret));
+ op_errno = EINVAL; /* TODO: better errno */
+ }
+
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+
+ return 0;
+}/* bdb_truncate */
+
+
+int32_t
+bdb_statfs (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc)
+
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+ struct statvfs buf = {0, };
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = statvfs (real_path, &buf);
+ op_errno = errno;
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+ return 0;
+}/* bdb_statfs */
+
+static int gf_bdb_xattr_log;
+
+/* bdb_setxattr - set extended attributes.
+ *
+ * bdb allows setxattr operation only on directories.
+ * bdb reservers 'glusterfs.file.<attribute-name>' to operate on the content
+ * of the files under the specified directory.
+ * 'glusterfs.file.<attribute-name>' transforms to contents of file of name
+ * '<attribute-name>' under specified directory.
+ *
+ * @frame: call frame.
+ * @this: xlator_t of this instance of bdb xlator.
+ * @loc: loc_t specifying the file to operate upon.
+ * @dict: list of extended attributes to set on @loc.
+ * @flags: can be XATTR_REPLACE (replace an existing extended attribute only if
+ * it exists) or XATTR_CREATE (create an extended attribute only if it
+ * doesn't already exist).
+ *
+ *
+ */
+int32_t
+bdb_setxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ dict_t *dict,
+ int flags)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ data_pair_t *trav = dict->members_list;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+ char *key = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ if (!S_ISDIR (loc->inode->st_mode)) {
+ op_ret = -1;
+ op_errno = ENOATTR;
+ goto out;
+ }
+
+ while (trav) {
+ if (GF_FILE_CONTENT_REQUEST(trav->key) ) {
+ key = BDB_KEY_FROM_FREQUEST_KEY(trav->key);
+
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETXATTR %"PRId64" (%s) - %s: ENOMEM"
+ "(no database handle for directory)",
+ loc->ino, loc->path, key);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ if (flags & XATTR_REPLACE) {
+ op_ret = bdb_db_itruncate (bctx, key);
+ if (op_ret == -1) {
+ /* key doesn't exist in database */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETXATTR %"PRId64" (%s) - %s:"
+ " (entry not present in "
+ "database)",
+ loc->ino, loc->path, key);
+ op_ret = -1;
+ op_errno = ENOATTR;
+ break;
+ }
+ op_ret = bdb_db_iwrite (bctx, key,
+ trav->value->data,
+ trav->value->len);
+ if (op_ret != 0) {
+ op_ret = -1;
+ op_errno = ENOATTR;
+ break;
+ }
+ } else {
+ /* fresh create */
+ op_ret = bdb_db_iwrite (bctx, key,
+ trav->value->data,
+ trav->value->len);
+ if (op_ret != 0) {
+ op_ret = -1;
+ op_errno = EEXIST;
+ break;
+ } else {
+ op_ret = 0;
+ op_errno = 0;
+ } /* if(op_ret!=0)...else */
+ } /* if(flags&XATTR_REPLACE)...else */
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success, see
+ * description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+ } else {
+ /* do plain setxattr */
+ op_ret = lsetxattr (real_path,
+ trav->key, trav->value->data,
+ trav->value->len,
+ flags);
+ op_errno = errno;
+
+ if ((op_errno == ENOATTR) || (op_errno == EEXIST)) {
+ /* don't log, normal behaviour */
+ ;
+ } else if (BDB_TIMED_LOG (op_errno, gf_bdb_xattr_log)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, trav->key,
+ strerror (op_errno));
+ /* do not continue, break out */
+ break;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, trav->key,
+ strerror (op_errno));
+ }
+ } /* if(ZR_FILE_CONTENT_REQUEST())...else */
+ trav = trav->next;
+ }/* while(trav) */
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}/* bdb_setxattr */
+
+
+/* bdb_gettxattr - get extended attributes.
+ *
+ * bdb allows getxattr operation only on directories.
+ * bdb_getxattr retrieves the whole content of the file, when
+ * glusterfs.file.<attribute-name> is specified.
+ *
+ * @frame: call frame.
+ * @this: xlator_t of this instance of bdb xlator.
+ * @loc: loc_t specifying the file to operate upon.
+ * @name: name of extended attributes to get for @loc.
+ *
+ * NOTE: see description of bdb_setxattr for details on how
+ * 'glusterfs.file.<attribute-name>' is handles by bdb.
+ */
+int32_t
+bdb_getxattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+ dict_t *dict = NULL;
+ bctx_t *bctx = NULL;
+ char *buf = NULL;
+ char *key_string = NULL;
+ int32_t list_offset = 0;
+ size_t size = 0;
+ size_t remaining_size = 0;
+ char *real_path = NULL;
+ char key[1024] = {0,};
+ char *value = NULL;
+ char *list = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ dict = dict_new ();
+ GF_VALIDATE_OR_GOTO (this->name, dict, out);
+
+ if (!S_ISDIR (loc->inode->st_mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: ENOATTR "
+ "(not a directory)",
+ loc->ino, loc->path, name);
+ op_ret = -1;
+ op_errno = ENOATTR;
+ goto out;
+ }
+
+ if (name && GF_FILE_CONTENT_REQUEST(name)) {
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: ENOMEM"
+ "(no database handle for directory)",
+ loc->ino, loc->path, name);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ key_string = BDB_KEY_FROM_FREQUEST_KEY(name);
+
+ op_ret = bdb_db_iread (bctx, key_string, &buf);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: ENOATTR"
+ "(attribute not present in database)",
+ loc->ino, loc->path, name);
+ op_errno = ENOATTR;
+ goto out;
+ }
+
+ op_ret = dict_set_dynptr (dict, (char *)name, buf, op_ret);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: ENOATTR"
+ "(attribute present in database, "
+ "dict set failed)",
+ loc->ino, loc->path, name);
+ op_errno = ENODATA;
+ }
+
+ goto out;
+ }
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ size = sys_llistxattr (real_path, NULL, 0);
+ op_errno = errno;
+ if (size < 0) {
+ if (BDB_TIMED_LOG (op_errno, gf_bdb_xattr_log)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ }
+ op_ret = -1;
+ op_errno = ENOATTR;
+
+ goto out;
+ }
+
+ if (size == 0)
+ goto done;
+
+ list = alloca (size + 1);
+ if (list == NULL) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ }
+
+ size = sys_llistxattr (real_path, list, size);
+ op_ret = size;
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ goto out;
+ }
+
+ remaining_size = size;
+ list_offset = 0;
+ while (remaining_size > 0) {
+ if(*(list+list_offset) == '\0')
+ break;
+
+ strcpy (key, list + list_offset);
+
+ op_ret = sys_lgetxattr (real_path, key, NULL, 0);
+ if (op_ret == -1)
+ break;
+
+ value = GF_CALLOC (op_ret + 1, sizeof(char), gf_bdb_mt_char);
+ GF_VALIDATE_OR_GOTO (this->name, value, out);
+
+ op_ret = sys_lgetxattr (real_path, key, value,
+ op_ret);
+ if (op_ret == -1)
+ break;
+ value [op_ret] = '\0';
+ op_ret = dict_set_dynptr (dict, key,
+ value, op_ret);
+ if (op_ret < 0) {
+ GF_FREE (value);
+ gf_log (this->name, GF_LOG_DEBUG,
+ "GETXATTR %"PRId64" (%s) - %s: "
+ "(skipping key %s)",
+ loc->ino, loc->path, name, key);
+ continue;
+ }
+ remaining_size -= strlen (key) + 1;
+ list_offset += strlen (key) + 1;
+ } /* while(remaining_size>0) */
+done:
+out:
+ if(bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+
+ if (dict)
+ dict_unref (dict);
+
+ return 0;
+}/* bdb_getxattr */
+
+
+int32_t
+bdb_removexattr (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ const char *name)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ bctx_t *bctx = NULL;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+ GF_VALIDATE_OR_GOTO (this->name, name, out);
+
+ if (!S_ISDIR(loc->inode->st_mode)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s) - %s: ENOATTR "
+ "(not a directory)",
+ loc->ino, loc->path, name);
+ op_ret = -1;
+ op_errno = ENOATTR;
+ goto out;
+ }
+
+ if (GF_FILE_CONTENT_REQUEST(name)) {
+ bctx = bctx_lookup (B_TABLE(this), loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s) - %s: ENOATTR"
+ "(no database handle for directory)",
+ loc->ino, loc->path, name);
+ op_ret = -1;
+ op_errno = ENOATTR;
+ goto out;
+ }
+
+ op_ret = bdb_db_iremove (bctx, name);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s) - %s: ENOATTR"
+ "(no such attribute in database)",
+ loc->ino, loc->path, name);
+ op_errno = ENOATTR;
+ }
+ goto out;
+ }
+
+ MAKE_REAL_PATH(real_path, this, loc->path);
+ op_ret = lremovexattr (real_path, name);
+ op_errno = errno;
+ if (op_ret == -1) {
+ if (BDB_TIMED_LOG (op_errno, gf_bdb_xattr_log)) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "REMOVEXATTR %"PRId64" (%s) - %s: %s",
+ loc->ino, loc->path, name, strerror (op_errno));
+ }
+ } /* if(op_ret == -1) */
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}/* bdb_removexattr */
+
+
+int32_t
+bdb_fsyncdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int datasync)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct bdb_fd *bfd = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "FSYNCDIR %"PRId64": EBADFD"
+ "(failed to find internal context from fd)",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ op_ret = -1;
+ }
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ return 0;
+}/* bdb_fsycndir */
+
+
+int32_t
+bdb_access (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t mask)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ char *real_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = access (real_path, mask);
+ op_errno = errno;
+ /* TODO: implement for db entries */
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}/* bdb_access */
+
+
+int32_t
+bdb_ftruncate (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ off_t offset)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EPERM;
+ struct stat buf = {0,};
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ /* TODO: impelement */
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &buf);
+
+ return 0;
+}
+
+
+
+int32_t
+bdb_setdents (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t flags,
+ dir_entry_t *entries,
+ int32_t count)
+{
+ int32_t op_ret = -1, op_errno = EINVAL;
+ char *entry_path = NULL;
+ int32_t real_path_len = 0;
+ int32_t entry_path_len = 0;
+ int32_t ret = 0;
+ struct bdb_dir *bfd = NULL;
+ dir_entry_t *trav = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+ GF_VALIDATE_OR_GOTO (this->name, entries, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64": EBADFD",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ real_path_len = strlen (bfd->path);
+ entry_path_len = real_path_len + 256;
+ entry_path = GF_CALLOC (1, entry_path_len, gf_bdb_mt_char);
+ GF_VALIDATE_OR_GOTO (this->name, entry_path, out);
+
+ strcpy (entry_path, bfd->path);
+ entry_path[real_path_len] = '/';
+
+ trav = entries->next;
+ while (trav) {
+ char pathname[ZR_PATH_MAX] = {0,};
+ strcpy (pathname, entry_path);
+ strcat (pathname, trav->name);
+
+ if (S_ISDIR(trav->buf.st_mode)) {
+ /* If the entry is directory, create it by calling
+ * 'mkdir'. If directory is not present, it will be
+ * created, if its present, no worries even if it fails.
+ */
+ ret = mkdir (pathname, trav->buf.st_mode);
+ if ((ret == -1) && (errno != EEXIST)) {
+ op_errno = errno;
+ op_ret = ret;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64" - %s: %s "
+ "(mkdir failed)",
+ fd->inode->ino, pathname,
+ strerror (op_errno));
+ goto loop;
+ }
+
+ /* Change the mode
+ * NOTE: setdents tries its best to restore the state
+ * of storage. if chmod and chown fail, they can
+ * be ignored now */
+ ret = chmod (pathname, trav->buf.st_mode);
+ if (ret < 0) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64" - %s: %s "
+ "(chmod failed)",
+ fd->inode->ino, pathname,
+ strerror (op_errno));
+ goto loop;
+ }
+ /* change the ownership */
+ ret = chown (pathname, trav->buf.st_uid,
+ trav->buf.st_gid);
+ if (ret != 0) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64" - %s: %s "
+ "(chown failed)",
+ fd->inode->ino, pathname,
+ strerror (op_errno));
+ goto loop;
+ }
+ } else if ((flags == GF_SET_IF_NOT_PRESENT) ||
+ (flags != GF_SET_DIR_ONLY)) {
+ /* Create a 0 byte file here */
+ if (S_ISREG (trav->buf.st_mode)) {
+ op_ret = bdb_db_icreate (bfd->ctx,
+ trav->name);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64" (%s) - %s: "
+ "%s (database entry creation"
+ " failed)",
+ fd->inode->ino,
+ bfd->ctx->directory, trav->name,
+ strerror (op_errno));
+ }
+ } else if (S_ISLNK (trav->buf.st_mode)) {
+ /* TODO: impelement */;
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "SETDENTS %"PRId64" (%s) - %s mode=%o: "
+ "(unsupported file type)",
+ fd->inode->ino,
+ bfd->ctx->directory, trav->name,
+ trav->buf.st_mode);
+ } /* if(S_ISREG())...else */
+ } /* if(S_ISDIR())...else if */
+ loop:
+ /* consider the next entry */
+ trav = trav->next;
+ } /* while(trav) */
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno);
+
+ GF_FREE (entry_path);
+ return 0;
+}
+
+int32_t
+bdb_fstat (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ struct stat stbuf = {0,};
+ struct bdb_fd *bfd = NULL;
+ bctx_t *bctx = NULL;
+ char *db_path = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "FSTAT %"PRId64": EBADFD "
+ "(failed to find internal context in fd)",
+ fd->inode->ino);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ bctx = bfd->ctx;
+
+ MAKE_REAL_PATH_TO_STORAGE_DB (db_path, this, bctx->directory);
+ op_ret = lstat (db_path, &stbuf);
+ op_errno = errno;
+ if (op_ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "FSTAT %"PRId64": %s"
+ "(failed to stat database file %s)",
+ fd->inode->ino, strerror (op_errno), db_path);
+ goto out;
+ }
+
+ stbuf.st_ino = fd->inode->ino;
+ stbuf.st_size = bdb_db_fread (bfd, NULL, 0, 0);
+ stbuf.st_blocks = BDB_COUNT_BLOCKS (stbuf.st_size, stbuf.st_blksize);
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ return 0;
+}
+
+gf_dirent_t *
+gf_dirent_for_namen (const char *name,
+ size_t len)
+{
+ char *tmp_name = NULL;
+
+ tmp_name = alloca (len + 1);
+
+ memcpy (tmp_name, name, len);
+
+ tmp_name[len] = 0;
+
+ return gf_dirent_for_name (tmp_name);
+}
+
+int32_t
+bdb_readdir (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ size_t size,
+ off_t off)
+{
+ struct bdb_dir *bfd = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ size_t filled = 0;
+ gf_dirent_t *this_entry = NULL;
+ gf_dirent_t entries;
+ struct dirent *entry = NULL;
+ off_t in_case = 0;
+ int32_t this_size = 0;
+ DBC *cursorp = NULL;
+ int32_t count = 0;
+ off_t offset = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, fd, out);
+
+ INIT_LIST_HEAD (&entries.list);
+
+ BDB_FCTX_GET (fd, this, &bfd);
+ if (bfd == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READDIR %"PRId64" - %"GF_PRI_SIZET",%"PRId64": EBADFD "
+ "(failed to find internal context in fd)",
+ fd->inode->ino, size, off);
+ op_errno = EBADFD;
+ op_ret = -1;
+ goto out;
+ }
+
+ op_ret = bdb_cursor_open (bfd->ctx, &cursorp);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READDIR %"PRId64" - %"GF_PRI_SIZET",%"PRId64": EBADFD "
+ "(failed to open cursor to database handle)",
+ fd->inode->ino, size, off);
+ op_errno = EBADFD;
+ goto out;
+ }
+
+ if (off) {
+ DBT sec = {0,}, pri = {0,}, val = {0,};
+ sec.data = &(off);
+ sec.size = sizeof (off);
+ sec.flags = DB_DBT_USERMEM;
+ val.dlen = 0;
+ val.doff = 0;
+ val.flags = DB_DBT_PARTIAL;
+
+ op_ret = bdb_cursor_get (cursorp, &sec, &pri, &val, DB_SET);
+ if (op_ret == DB_NOTFOUND) {
+ offset = off;
+ goto dir_read;
+ }
+ }
+
+ while (filled <= size) {
+ DBT sec = {0,}, pri = {0,}, val = {0,};
+
+ this_entry = NULL;
+
+ sec.flags = DB_DBT_MALLOC;
+ pri.flags = DB_DBT_MALLOC;
+ val.dlen = 0;
+ val.doff = 0;
+ val.flags = DB_DBT_PARTIAL;
+ op_ret = bdb_cursor_get (cursorp, &sec, &pri, &val, DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ /* we reached end of the directory */
+ op_ret = 0;
+ op_errno = 0;
+ break;
+ } else if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READDIR %"PRId64" - %"GF_PRI_SIZET",%"PRId64":"
+ "(failed to read the next entry from database)",
+ fd->inode->ino, size, off);
+ op_errno = ENOENT;
+ break;
+ } /* if (op_ret == DB_NOTFOUND)...else if...else */
+
+ if (pri.data == NULL) {
+ /* NOTE: currently ignore when we get key.data == NULL.
+ * TODO: we should not get key.data = NULL */
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READDIR %"PRId64" - %"GF_PRI_SIZET",%"PRId64":"
+ "(null key read for entry from database)",
+ fd->inode->ino, size, off);
+ continue;
+ }/* if(key.data)...else */
+ count++;
+ this_size = bdb_dirent_size (&pri);
+ if (this_size + filled > size)
+ break;
+ /* TODO - consider endianness here */
+ this_entry = gf_dirent_for_namen ((const char *)pri.data,
+ pri.size);
+
+ this_entry->d_ino = bdb_inode_transform (fd->inode->ino,
+ pri.data,
+ pri.size);
+ this_entry->d_off = *(uint32_t *)sec.data;
+ this_entry->d_type = 0;
+ this_entry->d_len = pri.size + 1;
+
+ if (sec.data) {
+ GF_FREE (sec.data);
+ }
+
+ if (pri.data)
+ GF_FREE (pri.data);
+
+ list_add_tail (&this_entry->list, &entries.list);
+
+ filled += this_size;
+ }/* while */
+ bdb_cursor_close (bfd->ctx, cursorp);
+ op_ret = filled;
+ op_errno = 0;
+ if (filled >= size) {
+ goto out;
+ }
+dir_read:
+ /* hungry kyaa? */
+ if (!offset) {
+ rewinddir (bfd->dir);
+ } else {
+ seekdir (bfd->dir, offset);
+ }
+
+ while (filled <= size) {
+ this_entry = NULL;
+ entry = NULL;
+ this_size = 0;
+
+ in_case = telldir (bfd->dir);
+ entry = readdir (bfd->dir);
+ if (!entry)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(entry->d_name))
+ continue;
+
+ this_size = dirent_size (entry);
+
+ if (this_size + filled > size) {
+ seekdir (bfd->dir, in_case);
+ break;
+ }
+
+ count++;
+
+ this_entry = gf_dirent_for_name (entry->d_name);
+ this_entry->d_ino = entry->d_ino;
+
+ this_entry->d_off = entry->d_off;
+
+ this_entry->d_type = entry->d_type;
+ this_entry->d_len = entry->d_reclen;
+
+
+ list_add_tail (&this_entry->list, &entries.list);
+
+ filled += this_size;
+ }
+ op_ret = filled;
+ op_errno = 0;
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG,
+ "READDIR %"PRId64" - %"GF_PRI_SIZET" (%"PRId32")"
+ "/%"GF_PRI_SIZET",%"PRId64":"
+ "(failed to read the next entry from database)",
+ fd->inode->ino, filled, count, size, off);
+
+ STACK_UNWIND (frame, count, op_errno, &entries);
+
+ gf_dirent_free (&entries);
+
+ return 0;
+}
+
+
+int32_t
+bdb_stats (call_frame_t *frame,
+ xlator_t *this,
+ int32_t flags)
+
+{
+ int32_t op_ret = 0;
+ int32_t op_errno = 0;
+
+ struct xlator_stats xlstats = {0, }, *stats = NULL;
+ struct statvfs buf = {0,};
+ struct timeval tv;
+ struct bdb_private *private = NULL;
+ int64_t avg_read = 0;
+ int64_t avg_write = 0;
+ int64_t _time_ms = 0;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+
+ private = (struct bdb_private *)(this->private);
+ stats = &xlstats;
+
+ op_ret = statvfs (private->export_path, &buf);
+ if (op_ret != 0) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "STATS %s: %s",
+ private->export_path, strerror (op_errno));
+ goto out;
+ }
+
+ stats->nr_files = private->stats.nr_files;
+
+ /* client info is maintained at FSd */
+ stats->nr_clients = private->stats.nr_clients;
+
+ /* Number of Free block in the filesystem. */
+ stats->free_disk = buf.f_bfree * buf.f_bsize;
+ stats->total_disk_size = buf.f_blocks * buf.f_bsize; /* */
+ stats->disk_usage = (buf.f_blocks - buf.f_bavail) * buf.f_bsize;
+
+ /* Calculate read and write usage */
+ gettimeofday (&tv, NULL);
+
+ /* Read */
+ _time_ms = (tv.tv_sec - private->init_time.tv_sec) * 1000 +
+ ((tv.tv_usec - private->init_time.tv_usec) / 1000);
+
+ avg_read = (_time_ms) ? (private->read_value / _time_ms) : 0;/* KBps */
+ avg_write = (_time_ms) ? (private->write_value / _time_ms) : 0;
+
+ _time_ms = (tv.tv_sec - private->prev_fetch_time.tv_sec) * 1000 +
+ ((tv.tv_usec - private->prev_fetch_time.tv_usec) / 1000);
+ if (_time_ms
+ && ((private->interval_read / _time_ms) > private->max_read)) {
+ private->max_read = (private->interval_read / _time_ms);
+ }
+ if (_time_ms
+ && ((private->interval_write / _time_ms) > private->max_write)) {
+ private->max_write = private->interval_write / _time_ms;
+ }
+
+ stats->read_usage = avg_read / private->max_read;
+ stats->write_usage = avg_write / private->max_write;
+
+ gettimeofday (&(private->prev_fetch_time), NULL);
+ private->interval_read = 0;
+ private->interval_write = 0;
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, stats);
+ return 0;
+}
+
+
+int32_t
+bdb_inodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, int32_t cmd, struct gf_flock *lock)
+{
+ gf_log (this->name, GF_LOG_ERROR,
+ "glusterfs internal locking request. please load "
+ "'features/locks' translator to enable glusterfs "
+ "support");
+
+ STACK_UNWIND (frame, -1, ENOSYS);
+ return 0;
+}
+
+
+int32_t
+bdb_finodelk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, int32_t cmd, struct gf_flock *lock)
+{
+ gf_log (this->name, GF_LOG_ERROR,
+ "glusterfs internal locking request. please load "
+ "'features/locks' translator to enable glusterfs "
+ "support");
+
+ STACK_UNWIND (frame, -1, ENOSYS);
+ return 0;
+}
+
+
+int32_t
+bdb_entrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, loc_t *loc, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+{
+ gf_log (this->name, GF_LOG_ERROR,
+ "glusterfs internal locking request. please load "
+ "'features/locks' translator to enable glusterfs "
+ "support");
+
+ STACK_UNWIND (frame, -1, ENOSYS);
+ return 0;
+}
+
+
+int32_t
+bdb_fentrylk (call_frame_t *frame, xlator_t *this,
+ const char *volume, fd_t *fd, const char *basename,
+ entrylk_cmd cmd, entrylk_type type)
+{
+ gf_log (this->name, GF_LOG_ERROR,
+ "glusterfs internal locking request. please load "
+ "'features/locks' translator to enable glusterfs "
+ "support");
+
+ STACK_UNWIND (frame, -1, ENOSYS);
+ return 0;
+}
+
+int32_t
+bdb_checksum (call_frame_t *frame,
+ xlator_t *this,
+ loc_t *loc,
+ int32_t flag)
+{
+ char *real_path = NULL;
+ DIR *dir = NULL;
+ struct dirent *dirent = NULL;
+ uint8_t file_checksum[NAME_MAX] = {0,};
+ uint8_t dir_checksum[NAME_MAX] = {0,};
+ int32_t op_ret = -1;
+ int32_t op_errno = EINVAL;
+ int32_t idx = 0, length = 0;
+ bctx_t *bctx = NULL;
+ DBC *cursorp = NULL;
+ char *data = NULL;
+ uint8_t no_break = 1;
+
+ GF_VALIDATE_OR_GOTO ("bdb", frame, out);
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, loc, out);
+
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ {
+ dir = opendir (real_path);
+ op_errno = errno;
+ GF_VALIDATE_OR_GOTO (this->name, dir, out);
+ while ((dirent = readdir (dir))) {
+ if (!dirent)
+ break;
+
+ if (IS_BDB_PRIVATE_FILE(dirent->d_name))
+ continue;
+
+ length = strlen (dirent->d_name);
+ for (idx = 0; idx < length; idx++)
+ dir_checksum[idx] ^= dirent->d_name[idx];
+ } /* while((dirent...)) */
+ closedir (dir);
+ }
+
+ {
+ bctx = bctx_lookup (B_TABLE(this), (char *)loc->path);
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHECKSUM %"PRId64" (%s): ENOMEM"
+ "(failed to lookup database handle)",
+ loc->inode->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ op_ret = bdb_cursor_open (bctx, &cursorp);
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHECKSUM %"PRId64" (%s): EBADFD"
+ "(failed to open cursor to database handle)",
+ loc->inode->ino, loc->path);
+ op_ret = -1;
+ op_errno = EBADFD;
+ goto out;
+ }
+
+
+ do {
+ DBT key = {0,}, value = {0,}, sec = {0,};
+
+ key.flags = DB_DBT_MALLOC;
+ value.doff = 0;
+ value.dlen = 0;
+ op_ret = bdb_cursor_get (cursorp, &sec, &key,
+ &value, DB_NEXT);
+
+ if (op_ret == DB_NOTFOUND) {
+ op_ret = 0;
+ op_errno = 0;
+ no_break = 0;
+ } else if (op_ret == 0){
+ /* successfully read */
+ data = key.data;
+ length = key.size;
+ for (idx = 0; idx < length; idx++)
+ file_checksum[idx] ^= data[idx];
+
+ GF_FREE (key.data);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "CHECKSUM %"PRId64" (%s)",
+ loc->inode->ino, loc->path);
+ op_ret = -1;
+ op_errno = ENOENT; /* TODO: watch errno */
+ no_break = 0;
+ }/* if(op_ret == DB_NOTFOUND)...else if...else */
+ } while (no_break);
+ bdb_cursor_close (bctx, cursorp);
+ }
+out:
+ if (bctx) {
+ /* NOTE: bctx_unref always returns success,
+ * see description of bctx_unref for more details */
+ bctx_unref (bctx);
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, file_checksum, dir_checksum);
+
+ return 0;
+}
+
+/**
+ * notify - when parent sends PARENT_UP, send CHILD_UP event from here
+ */
+int32_t
+notify (xlator_t *this,
+ int32_t event,
+ void *data,
+ ...)
+{
+ switch (event)
+ {
+ case GF_EVENT_PARENT_UP:
+ {
+ /* Tell the parent that bdb xlator is up */
+ GF_ASSERT ((this->private != NULL) &&
+ (BDB_ENV(this) != NULL));
+ default_notify (this, GF_EVENT_CHILD_UP, data);
+ }
+ break;
+ default:
+ /* */
+ break;
+ }
+ return 0;
+}
+
+
+int32_t
+mem_acct_init (xlator_t *this)
+{
+ int ret = -1;
+
+ if (!this)
+ return ret;
+
+ ret = xlator_mem_acct_init (this, gf_bdb_mt_end + 1);
+
+ if (ret != 0) {
+ gf_log(this->name, GF_LOG_ERROR, "Memory accounting init"
+ "failed");
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * init -
+ */
+int32_t
+init (xlator_t *this)
+{
+ int32_t ret = -1;
+ struct stat buf = {0,};
+ struct bdb_private *_private = NULL;
+ char *directory = NULL;
+ bctx_t *bctx = NULL;
+
+ GF_VALIDATE_OR_GOTO ("bdb", this, out);
+
+ if (this->children) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'storage/bdb' translator should be used as leaf node "
+ "in translator tree. please remove the subvolumes"
+ " specified and retry.");
+ goto err;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'storage/bdb' translator needs at least one among "
+ "'protocol/server' or 'mount/fuse' translator as "
+ "parent. please add 'protocol/server' or 'mount/fuse' "
+ "as parent of 'storage/bdb' and retry. or you can also"
+ " try specifying mount-point on command-line.");
+ goto err;
+ }
+
+ _private = GF_CALLOC (1, sizeof (*_private), gf_bdb_mt_bdb_private);
+ if (_private == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not allocate memory for 'storage/bdb' "
+ "configuration data-structure. cannot continue from "
+ "here");
+ goto err;
+ }
+
+
+ ret = dict_get_str (this->options, "directory", &directory);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "'storage/bdb' needs at least "
+ "'option directory <path-to-export-directory>' as "
+ "minimal configuration option. please specify an "
+ "export directory using "
+ "'option directory <path-to-export-directory>' and "
+ "retry.");
+ goto err;
+ }
+
+ umask (000); /* umask `masking' is done at the client side */
+
+ /* Check whether the specified directory exists, if not create it. */
+ ret = stat (directory, &buf);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "specified export path '%s' does not exist. "
+ "please create the export path '%s' and retry.",
+ directory, directory);
+ goto err;
+ } else if (!S_ISDIR (buf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "specified export path '%s' is not a directory. "
+ "please specify a valid and existing directory as "
+ "export directory and retry.",
+ directory);
+ goto err;
+ } else {
+ ret = 0;
+ }
+
+
+ _private->export_path = gf_strdup (directory);
+ if (_private->export_path == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not allocate memory for 'storage/bdb' "
+ "configuration data-structure. cannot continue from "
+ "here");
+ goto err;
+ }
+
+ _private->export_path_length = strlen (_private->export_path);
+
+ {
+ /* Stats related variables */
+ gettimeofday (&_private->init_time, NULL);
+ gettimeofday (&_private->prev_fetch_time, NULL);
+ _private->max_read = 1;
+ _private->max_write = 1;
+ }
+
+ this->private = (void *)_private;
+
+ {
+ ret = bdb_db_init (this, this->options);
+
+ if (ret < 0){
+ gf_log (this->name, GF_LOG_ERROR,
+ "database environment initialisation failed. "
+ "manually run database recovery tool and "
+ "retry to run glusterfs");
+ goto err;
+ } else {
+ bctx = bctx_lookup (_private->b_table, "/");
+ /* NOTE: we are not doing bctx_unref() for root bctx,
+ * let it remain in active list forever */
+ if (bctx == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "could not allocate memory for "
+ "'storage/bdb' configuration data-"
+ "structure. cannot continue from "
+ "here");
+ goto err;
+ } else {
+ ret = 0;
+ goto out;
+ }
+ }
+ }
+err:
+ if (_private) {
+ if (_private->export_path)
+ GF_FREE (_private->export_path);
+
+ GF_FREE (_private);
+ }
+out:
+ return ret;
+}
+
+void
+bctx_cleanup (struct list_head *head)
+{
+ bctx_t *trav = NULL;
+ bctx_t *tmp = NULL;
+ DB *storage = NULL;
+ DB *secondary = NULL;
+
+ list_for_each_entry_safe (trav, tmp, head, list) {
+ LOCK (&trav->lock);
+ {
+ storage = trav->primary;
+ trav->primary = NULL;
+
+ secondary = trav->secondary;
+ trav->secondary = NULL;
+
+ list_del_init (&trav->list);
+ }
+ UNLOCK (&trav->lock);
+
+ if (storage) {
+ storage->close (storage, 0);
+ storage = NULL;
+ }
+
+ if (secondary) {
+ secondary->close (secondary, 0);
+ secondary = NULL;
+ }
+ }
+ return;
+}
+
+void
+fini (xlator_t *this)
+{
+ struct bdb_private *private = NULL;
+ int32_t ret = 0;
+
+ private = this->private;
+
+ if (B_TABLE(this)) {
+ /* close all the dbs from lru list */
+ bctx_cleanup (&(B_TABLE(this)->b_lru));
+ bctx_cleanup (&(B_TABLE(this)->active));
+
+ if (BDB_ENV(this)) {
+ LOCK (&private->active_lock);
+ {
+ private->active = 0;
+ }
+ UNLOCK (&private->active_lock);
+
+ ret = pthread_join (private->checkpoint_thread, NULL);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_CRITICAL,
+ "could not complete checkpointing "
+ "database environment. this might "
+ "result in inconsistencies in few"
+ " recent data and meta-data "
+ "operations");
+ }
+
+ BDB_ENV(this)->close (BDB_ENV(this), 0);
+ } else {
+ /* impossible to reach here */
+ }
+
+ GF_FREE (B_TABLE(this));
+ }
+ GF_FREE (private);
+ return;
+}
+
+
+struct xlator_fops fops = {
+ .lookup = bdb_lookup,
+ .stat = bdb_stat,
+ .opendir = bdb_opendir,
+ .readdir = bdb_readdir,
+ .readlink = bdb_readlink,
+ .mknod = bdb_mknod,
+ .mkdir = bdb_mkdir,
+ .unlink = bdb_unlink,
+ .rmdir = bdb_rmdir,
+ .symlink = bdb_symlink,
+ .rename = bdb_rename,
+ .link = bdb_link,
+ .truncate = bdb_truncate,
+ .create = bdb_create,
+ .open = bdb_open,
+ .readv = bdb_readv,
+ .writev = bdb_writev,
+ .statfs = bdb_statfs,
+ .flush = bdb_flush,
+ .fsync = bdb_fsync,
+ .setxattr = bdb_setxattr,
+ .getxattr = bdb_getxattr,
+ .removexattr = bdb_removexattr,
+ .fsyncdir = bdb_fsyncdir,
+ .access = bdb_access,
+ .ftruncate = bdb_ftruncate,
+ .fstat = bdb_fstat,
+ .lk = bdb_lk,
+ .inodelk = bdb_inodelk,
+ .finodelk = bdb_finodelk,
+ .entrylk = bdb_entrylk,
+ .fentrylk = bdb_fentrylk,
+ .setdents = bdb_setdents,
+ .getdents = bdb_getdents,
+ .checksum = bdb_checksum,
+ .setattr = bdb_setattr,
+ .fsetattr = bdb_fsetattr,
+};
+
+struct xlator_cbks cbks = {
+ .release = bdb_release,
+ .releasedir = bdb_releasedir
+};
+
+
+struct volume_options options[] = {
+ { .key = { "directory" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "export directory"
+ },
+ { .key = { "logdir" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "directory to be used by libdb for writing"
+ "transaction logs. NOTE: in absence of 'logdir' "
+ "export directory itself will be used as 'logdir' also"
+ },
+ { .key = { "errfile" },
+ .type = GF_OPTION_TYPE_PATH,
+ .description = "path to be used for libdb error logging. "
+ "NOTE: absence of 'errfile' will disable any "
+ "error logging by libdb."
+ },
+ { .key = { "dir-mode" },
+ .type = GF_OPTION_TYPE_ANY /* base 8 number */
+ },
+ { .key = { "file-mode" },
+ .type = GF_OPTION_TYPE_ANY,
+ .description = "file mode for regular files. stat() on a regular file"
+ " returns the mode specified by this option. "
+ "NOTE: specify value in octal"
+ },
+ { .key = { "page-size" },
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 512,
+ .max = 16384,
+ .description = "size of pages used to hold data by libdb. set it to "
+ "block size of exported filesystem for "
+ "optimal performance"
+ },
+ { .key = { "open-db-lru-limit" },
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 2048,
+ .description = "maximum number of per directory databases that can "
+ "be kept open. NOTE: for _advanced_ users only."
+ },
+ { .key = { "lock-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 4260000,
+ .description = "define the maximum time a lock request can "
+ "be blocked by libdb. NOTE: only for _advanced_ users."
+ " do not specify this option when not sure."
+ },
+ { .key = { "checkpoint-interval" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 1,
+ .max = 86400,
+ .description = "define the time interval between two consecutive "
+ "libdb checpoints. setting to lower value will leave "
+ "bdb perform slowly, but guarantees that minimum data"
+ " will be lost in case of a crash. NOTE: this option "
+ "is valid only when "
+ "'option mode=\"persistent\"' is set."
+ },
+ { .key = { "transaction-timeout" },
+ .type = GF_OPTION_TYPE_TIME,
+ .min = 0,
+ .max = 4260000,
+ .description = "maximum time for which a transaction can block "
+ "waiting for required resources."
+ },
+ { .key = { "mode" },
+ .type = GF_OPTION_TYPE_BOOL,
+ .value = { "cache", "persistent" },
+ .description = "cache: data recovery is not guaranteed in case "
+ "of crash. persistent: data recovery is guaranteed, "
+ "since all operations are transaction protected."
+ },
+ { .key = { "access-mode" },
+ .type = GF_OPTION_TYPE_STR,
+ .value = {"btree", "hash" },
+ .description = "chose the db access method. "
+ "NOTE: for _advanced_ users. leave the choice to "
+ "glusterfs when in doubt."
+ },
+ { .key = { NULL } }
+};
diff --git a/xlators/storage/bdb/src/bdb.h b/xlators/storage/bdb/src/bdb.h
new file mode 100644
index 000000000..6800f3c31
--- /dev/null
+++ b/xlators/storage/bdb/src/bdb.h
@@ -0,0 +1,530 @@
+/*
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BDB_H
+#define _BDB_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <db.h>
+
+#ifdef linux
+#ifdef __GLIBC__
+#include <sys/fsuid.h>
+#else
+#include <unistd.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+
+#include <pthread.h>
+#include "xlator.h"
+#include "inode.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "fd.h"
+#include "syscall.h"
+
+#define BDB_STORAGE "/glusterfs_storage.db"
+
+/* numbers are not so reader-friendly, so lets have ON and OFF macros */
+#define ON 1
+#define OFF 0
+
+#define BDB_DEFAULT_LRU_LIMIT 100
+#define BDB_DEFAULT_HASH_SIZE 100
+
+#define BDB_ENOSPC_THRESHOLD 25600
+
+#define BDB_DEFAULT_CHECKPOINT_INTERVAL 30
+
+#define BCTX_ENV(bctx) (bctx->table->dbenv)
+
+#define BDB_EXPORT_PATH_LEN(_private) \
+ (((struct bdb_private *)_private)->export_path_length)
+
+#define BDB_KEY_FROM_FREQUEST_KEY(_key) (&(key[15]))
+
+#define BDB_EXPORT_PATH(_private) \
+ (((struct bdb_private *)_private)->export_path)
+/* MAKE_REAL_PATH(var,this,path)
+ * make the real path on the underlying file-system
+ *
+ * @var: destination to hold the real path
+ * @this: pointer to xlator_t corresponding to bdb xlator
+ * @path: path, as seen from mount-point
+ */
+#define MAKE_REAL_PATH(var, this, path) do { \
+ int base_len = BDB_EXPORT_PATH_LEN(this->private); \
+ var = alloca (strlen (path) + base_len + 2); \
+ strcpy (var, BDB_EXPORT_PATH(this->private)); \
+ strcpy (&var[base_len], path); \
+ } while (0)
+
+
+#define BDB_TIMED_LOG(_errno,_counter) \
+ ((_errno == ENOTSUP) && (((++_counter) % GF_UNIVERSAL_ANSWER) == 1))
+
+#define GF_FILE_CONTENT_REQUEST ZR_FILE_CONTENT_REQUEST
+
+/* MAKE_REAL_PATH_TO_STORAGE_DB(var,this,path)
+ * make the real path to the storage-database file on file-system
+ *
+ * @var: destination to hold the real path
+ * @this: pointer to xlator_t corresponding to bdb xlator
+ * @path: path of the directory, as seen from mount-point
+ */
+#define MAKE_REAL_PATH_TO_STORAGE_DB(var, this, path) do { \
+ int base_len = BDB_EXPORT_PATH_LEN(this->private); \
+ var = alloca (strlen (path) + \
+ base_len + \
+ strlen (BDB_STORAGE)); \
+ strcpy (var, BDB_EXPORT_PATH(this->private)); \
+ strcpy (&var[base_len], path); \
+ strcat (var, BDB_STORAGE); \
+ } while (0)
+
+/* MAKE_KEY_FROM_PATH(key,path)
+ * make a 'key', which we use as key in the underlying database by using
+ * the path
+ *
+ * @key: destination to hold the key
+ * @path: path to file as seen from mount-point
+ */
+#define MAKE_KEY_FROM_PATH(key, path) do { \
+ char *tmp = alloca (strlen (path)); \
+ strcpy (tmp, path); \
+ key = basename (tmp); \
+ }while (0);
+
+/* IS_BDB_PRIVATE_FILE(name)
+ * check if a given 'name' is bdb xlator's internal file name
+ *
+ * @name: basename of a file.
+ *
+ * bdb xlator reserves file names 'glusterfs_storage.db',
+ * 'glusterfs_ns.db'(used by bdb xlator itself), 'log.*', '__db.*'
+ * (used by libdb)
+ */
+#define IS_BDB_PRIVATE_FILE(name) ((!strncmp(name, "__db.", 5)) || \
+ (!strcmp(name, "glusterfs_storage.db")) || \
+ (!strcmp(name, "glusterfs_ns.db")) || \
+ (!strncmp(name, "log.0000", 8)))
+
+/* check if 'name' is '.' or '..' entry */
+#define IS_DOT_DOTDOT(name) \
+ ((!strncmp(name,".", 1)) || (!strncmp(name,"..", 2)))
+
+/* BDB_ICTX_SET(this,inode,bctx)
+ * pointer to 'struct bdb_ctx' is stored in inode's ctx of all directories.
+ * this will happen either in lookup() or mkdir().
+ *
+ * @this: pointer xlator_t of bdb xlator.
+ * @inode: inode where 'struct bdb_ctx *' has to be stored.
+ * @bctx: a 'struct bdb_ctx *'
+ */
+#define BDB_ICTX_SET(_inode,_this,_bctx) do{ \
+ inode_ctx_put(_inode, _this, (uint64_t)(long)_bctx); \
+ }while (0);
+
+#define BDB_ICTX_GET(_inode,_this,_bctxp) do { \
+ uint64_t tmp_bctx = 0; \
+ inode_ctx_get (_inode, _this, &tmp_bctx); \
+ *_bctxp = tmp_bctx; \
+ }while (0);
+
+/* BDB_FCTX_SET(this,fd,bctx)
+ * pointer to 'struct bdb_ctx' is stored in inode's ctx of all directories.
+ * this will happen either in lookup() or mkdir().
+ *
+ * @this: pointer xlator_t of bdb xlator.
+ * @inode: inode where 'struct bdb_ctx *' has to be stored.
+ * @bctx: a 'struct bdb_ctx *'
+ */
+#define BDB_FCTX_SET(_fd,_this,_bfd) do{ \
+ fd_ctx_set(_fd, _this, (uint64_t)(long)_bfd); \
+ }while (0);
+
+#define BDB_FCTX_GET(_fd,_this,_bfdp) do { \
+ uint64_t tmp_bfd = 0; \
+ fd_ctx_get (_fd, _this, &tmp_bfd); \
+ *_bfdp = (void *)(long)tmp_bfd; \
+ }while (0);
+
+
+/* maximum number of open dbs that bdb xlator will ever have */
+#define BDB_MAX_OPEN_DBS 100
+
+/* convert file size to block-count */
+#define BDB_COUNT_BLOCKS(size,blksize) (((size + blksize - 1)/blksize) - 1)
+
+/* file permissions, again macros are more readable */
+#define RWXRWXRWX 0777
+#define DEFAULT_FILE_MODE 0644
+#define DEFAULT_DIR_MODE 0755
+
+/* see, if have a valid file permissions specification in @mode */
+#define IS_VALID_FILE_MODE(mode) (!(mode & (~RWXRWXRWX)))
+#define IS_VALID_DIR_MODE(mode) (!(mode & (~(RWXRWXRWX)))
+
+/* maximum retries for a failed transactional operation */
+#define BDB_MAX_RETRIES 10
+
+#define BDB_LL_PAGE_SIZE_DEFAULT 4096
+#define BDB_LL_PAGE_SIZE_MIN 4096
+#define BDB_LL_PAGE_SIZE_MAX 65536
+
+#define PAGE_SIZE_IN_RANGE(_page_size) \
+ ((_page_size >= BDB_LL_PAGE_SIZE_MIN) \
+ && (table->page_size <= BDB_LL_PAGE_SIZE_MAX))
+
+typedef struct bctx_table bctx_table_t;
+typedef struct bdb_ctx bctx_t;
+typedef struct bdb_cache bdb_cache_t;
+typedef struct bdb_private bdb_private_t;
+
+struct bctx_table {
+ /* flags to be used for opening each database */
+ uint64_t dbflags;
+
+ /* cache: can be either ON or OFF */
+ uint64_t cache;
+
+ /* used to lock the 'struct bctx_table *' */
+ gf_lock_t lock;
+
+ /* lock for checkpointing */
+ gf_lock_t checkpoint_lock;
+
+ /* hash table of 'struct bdb_ctx' */
+ struct list_head *b_hash;
+
+ /* list of active 'struct bdb_ctx' */
+ struct list_head active;
+
+ /* lru list of inactive 'struct bdb_ctx' */
+ struct list_head b_lru;
+ struct list_head purge;
+ uint32_t lru_limit;
+ uint32_t lru_size;
+ uint32_t hash_size;
+
+ /* access mode for accessing the databases, can be DB_HASH, DB_BTREE */
+ DBTYPE access_mode;
+
+ /* DB_ENV under which every db operation is carried over */
+ DB_ENV *dbenv;
+ int32_t transaction;
+ xlator_t *this;
+
+ /* page-size of DB, DB->set_pagesize(), should be set before DB->open */
+ uint64_t page_size;
+};
+
+struct bdb_ctx {
+ /* controller members */
+
+ /* lru list of 'struct bdb_ctx's, a bdb_ctx can exist in one of
+ * b_hash or lru lists */
+ struct list_head list;
+
+ /* directory 'name' hashed list of 'struct bdb_ctx's */
+ struct list_head b_hash;
+
+ struct bctx_table *table;
+ int32_t ref; /* reference count */
+ gf_lock_t lock; /* used to lock this 'struct bdb_ctx' */
+
+ char *directory; /* directory path */
+
+ /* pointer to open database, that resides inside this directory */
+ DB *primary;
+ DB *secondary;
+ uint32_t cache; /* cache ON or OFF */
+
+ /* per directory cache, bdb xlator's internal cache */
+ struct list_head c_list; /* linked list of cached records */
+ int32_t c_count; /* number of cached records */
+
+ /* index to hash table list, to which this ctx belongs */
+ int32_t key_hash;
+ char *db_path; /* absolute path to db file */
+};
+
+struct bdb_fd {
+ /* pointer to bdb_ctx of the parent directory */
+ struct bdb_ctx *ctx;
+
+ /* name of the file. NOTE: basename, not the complete path */
+ char *key;
+ int32_t flags; /* open flags */
+};
+
+struct bdb_dir {
+ /* pointer to bdb_ctx of this directory */
+ struct bdb_ctx *ctx;
+
+ /* open directory pointer, as returned by opendir() */
+ DIR *dir;
+
+ char *path; /* path to this directory */
+};
+
+/* cache */
+struct bdb_cache {
+ /* list of 'struct bdb_cache' under a 'struct bdb_ctx' */
+ struct list_head c_list;
+
+ /* name of the file this cache holds. NOTE: basename of file */
+ char *key;
+ char *data; /* file content */
+
+ /* size of the file content that this cache holds */
+ size_t size;
+};
+
+
+struct bdb_private {
+ /* pointer to inode table that we use */
+ inode_table_t *itable;
+ int32_t temp; /**/
+ char is_stateless; /**/
+
+ /* path to the export directory
+ * (option directory <export-path>) */
+ char *export_path;
+
+ /* length of 'export_path' string */
+ int32_t export_path_length;
+
+ /* statistics */
+ /* Statistics, provides activity of the server */
+ struct xlator_stats stats;
+
+ struct timeval prev_fetch_time;
+ struct timeval init_time;
+ int32_t max_read; /* */
+ int32_t max_write; /* */
+
+ /* Used to calculate the max_read value */
+ int64_t interval_read;
+
+ /* Used to calculate the max_write value */
+ int64_t interval_write;
+ int64_t read_value; /* Total read, from init */
+ int64_t write_value; /* Total write, from init */
+
+ /* bdb xlator specific private data */
+
+ /* flags used for opening DB_ENV for this xlator */
+ uint64_t envflags;
+
+ /* flags to be used for opening each database */
+ uint64_t dbflags;
+
+ /* cache: can be either ON or OFF */
+ uint64_t cache;
+
+ /* transaction: can be either ON or OFF */
+ uint32_t transaction;
+ uint32_t active;
+ gf_lock_t active_lock;
+ struct bctx_table *b_table;
+
+ /* access mode for accessing the databases, can be DB_HASH, DB_BTREE
+ * (option access-mode <mode>) */
+ DBTYPE access_mode;
+
+ /* mode for each and every file stored on bdb
+ * (option file-mode <mode>) */
+ mode_t file_mode;
+
+ /* mode for each and every directory stored on bdb
+ * (option dir-mode <mode>) */
+ mode_t dir_mode;
+
+ /* mode for each and every symlink stored on bdb */
+ mode_t symlink_mode;
+
+ /* pthread_t object used for creating checkpoint thread */
+ pthread_t checkpoint_thread;
+
+ /* time duration between two consecutive checkpoint operations.
+ * (option checkpoint-interval <time-in-seconds>) */
+ uint32_t checkpoint_interval;
+
+ /* environment log directory (option logdir <directory>) */
+ char *logdir;
+
+ /* errfile path, used by environment to print detailed error log.
+ * (option errfile <errfile-path>) */
+ char *errfile;
+
+ /* DB_ENV->set_errfile() expects us to fopen
+ * the errfile before doing DB_ENV->set_errfile() */
+ FILE *errfp;
+
+ /* used by DB_ENV->set_timeout to set the timeout for
+ * a transactionally encapsulated DB->operation() to
+ * timeout before waiting for locks to be released.
+ * (option transaction-timeout <time-in-milliseconds>)
+ */
+ uint32_t txn_timeout;
+ uint32_t lock_timeout;
+
+ /* DB_AUTO_LOG_REMOVE flag for DB_ENV*/
+ uint32_t log_auto_remove;
+ uint32_t log_region_max;
+};
+
+
+static inline int32_t
+bdb_txn_begin (DB_ENV *dbenv,
+ DB_TXN **ptxnid)
+{
+ return dbenv->txn_begin (dbenv, NULL, ptxnid, 0);
+}
+
+static inline int32_t
+bdb_txn_abort (DB_TXN *txnid)
+{
+ return txnid->abort (txnid);
+}
+
+static inline int32_t
+bdb_txn_commit (DB_TXN *txnid)
+{
+ return txnid->commit (txnid, 0);
+}
+
+void *
+bdb_db_stat (bctx_t *bctx,
+ DB_TXN *txnid,
+ uint32_t flags);
+
+/*int32_t
+bdb_db_get(struct bdb_ctx *bctx,
+ DB_TXN *txnid,
+ const char *key_string,
+ char **buf,
+ size_t size,
+ off_t offset);
+*/
+int32_t
+bdb_db_fread (struct bdb_fd *bfd, char *bufp, size_t size, off_t offset);
+
+int32_t
+bdb_db_iread (struct bdb_ctx *bctx, const char *key, char **bufp);
+
+#define BDB_TRUNCATE_RECORD 0xcafebabe
+
+/*int32_t
+bdb_db_put (struct bdb_ctx *bctx,
+ DB_TXN *txnid,
+ const char *key_string,
+ const char *buf,
+ size_t size,
+ off_t offset,
+ int32_t flags);
+*/
+int32_t
+bdb_db_icreate (struct bdb_ctx *bctx, const char *key);
+
+int32_t
+bdb_db_fwrite (struct bdb_fd *bfd, char *buf, size_t size, off_t offset);
+
+int32_t
+bdb_db_iwrite (struct bdb_ctx *bctx, const char *key, char *buf, size_t size);
+
+int32_t
+bdb_db_itruncate (struct bdb_ctx *bctx, const char *key);
+
+int32_t
+bdb_db_iremove (struct bdb_ctx *bctx,
+ const char *key);
+
+ino_t
+bdb_inode_transform (ino_t parent,
+ const char *name,
+ size_t namelen);
+
+int32_t
+bdb_cursor_open (struct bdb_ctx *bctx,
+ DBC **cursorp);
+
+int32_t
+bdb_cursor_get (DBC *cursorp,
+ DBT *sec, DBT *pri,
+ DBT *value,
+ int32_t flags);
+
+
+int32_t
+bdb_cursor_close (struct bdb_ctx *ctx,
+ DBC *cursorp);
+
+
+int32_t
+bdb_dirent_size (DBT *key);
+
+int32_t
+dirent_size (struct dirent *entry);
+
+int
+bdb_db_init (xlator_t *this,
+ dict_t *options);
+
+void
+bdb_dbs_from_dict_close (dict_t *this,
+ char *key,
+ data_t *value,
+ void *data);
+
+bctx_t *
+bctx_lookup (struct bctx_table *table,
+ const char *path);
+
+bctx_t *
+bctx_parent
+(struct bctx_table *table,
+ const char *path);
+
+bctx_t *
+bctx_unref (bctx_t *ctx);
+
+bctx_t *
+bctx_ref (bctx_t *ctx);
+
+#endif /* _BDB_H */
diff --git a/xlators/storage/posix/src/Makefile.am b/xlators/storage/posix/src/Makefile.am
index 4eae9798b..b8d1668ae 100644
--- a/xlators/storage/posix/src/Makefile.am
+++ b/xlators/storage/posix/src/Makefile.am
@@ -4,14 +4,14 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/storage
posix_la_LDFLAGS = -module -avoidversion
-posix_la_SOURCES = posix.c posix-helpers.c posix-handle.c posix-aio.c
-posix_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la $(LIBAIO)
+posix_la_SOURCES = posix.c
+posix_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = posix.h posix-mem-types.h posix-handle.h posix-aio.h
+noinst_HEADERS = posix.h posix-mem-types.h
AM_CFLAGS = -fPIC -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \
-D$(GF_HOST_OS) -Wall -I$(top_srcdir)/libglusterfs/src -shared \
- -nostartfiles -I$(top_srcdir)/rpc/xdr/src \
+ -nostartfiles -I$(top_srcdir)/contrib/md5 -I$(top_srcdir)/rpc/xdr/src \
-I$(top_srcdir)/rpc/rpc-lib/src $(GF_CFLAGS)
CLEANFILES =
diff --git a/xlators/storage/posix/src/posix-aio.c b/xlators/storage/posix/src/posix-aio.c
deleted file mode 100644
index a673c2c15..000000000
--- a/xlators/storage/posix/src/posix-aio.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "glusterfs.h"
-#include "posix.h"
-#include <sys/uio.h>
-
-#ifdef HAVE_LIBAIO
-#include <libaio.h>
-
-
-struct posix_aio_cb {
- struct iocb iocb;
- call_frame_t *frame;
- struct iobuf *iobuf;
- struct iobref *iobref;
- struct iatt prebuf;
- int fd;
- int op;
- off_t offset;
-};
-
-
-int
-posix_aio_readv_complete (struct posix_aio_cb *paiocb, int res, int res2)
-{
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- struct iobuf *iobuf = NULL;
- struct iatt postbuf = {0,};
- int _fd = -1;
- int op_ret = -1;
- int op_errno = 0;
- struct iovec iov;
- struct iobref *iobref = NULL;
- int ret = 0;
- off_t offset = 0;
- struct posix_private * priv = NULL;
-
-
- frame = paiocb->frame;
- this = frame->this;
- priv = this->private;
- iobuf = paiocb->iobuf;
- _fd = paiocb->fd;
- offset = paiocb->offset;
-
- if (res < 0) {
- op_ret = -1;
- op_errno = -res;
- gf_log (this->name, GF_LOG_ERROR,
- "readv(async) failed fd=%d,size=%lu,offset=%llu (%d/%s)",
- _fd, paiocb->iocb.u.c.nbytes,
- (unsigned long long) paiocb->offset,
- res, strerror (op_errno));
- goto out;
- }
-
- ret = posix_fdstat (this, _fd, &postbuf);
- if (ret != 0) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "fstat failed on fd=%d: %s", _fd,
- strerror (op_errno));
- goto out;
- }
-
- op_ret = res;
- op_errno = 0;
-
- iobref = iobref_new ();
- if (!iobref) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
-
- iobref_add (iobref, iobuf);
-
- iov.iov_base = iobuf_ptr (iobuf);
- iov.iov_len = op_ret;
-
-
- /* Hack to notify higher layers of EOF. */
- if (postbuf.ia_size == 0)
- op_errno = ENOENT;
- else if ((offset + iov.iov_len) == postbuf.ia_size)
- op_errno = ENOENT;
- else if (offset > postbuf.ia_size)
- op_errno = ENOENT;
-
- LOCK (&priv->lock);
- {
- priv->read_value += op_ret;
- }
- UNLOCK (&priv->lock);
-
-out:
- STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, &iov, 1,
- &postbuf, iobref, NULL);
- if (iobuf)
- iobuf_unref (iobuf);
- if (iobref)
- iobref_unref (iobref);
-
- GF_FREE (paiocb);
-
- return 0;
-}
-
-
-int
-posix_aio_readv (call_frame_t *frame, xlator_t *this, fd_t *fd,
- size_t size, off_t offset, uint32_t flags, dict_t *xdata)
-{
- int32_t op_errno = EINVAL;
- int _fd = -1;
- struct iobuf *iobuf = NULL;
- struct posix_fd * pfd = NULL;
- int ret = -1;
- struct posix_aio_cb *paiocb = NULL;
- struct posix_private *priv = NULL;
- struct iocb *iocb = NULL;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- priv = this->private;
-
- ret = posix_fd_ctx_get_off (fd, this, &pfd, offset);
- if (ret < 0) {
- op_errno = -ret;
- gf_log (this->name, GF_LOG_WARNING,
- "pfd is NULL from fd=%p", fd);
- goto err;
- }
- _fd = pfd->fd;
-
- if (!size) {
- op_errno = EINVAL;
- gf_log (this->name, GF_LOG_WARNING, "size=%"GF_PRI_SIZET, size);
- goto err;
- }
-
- iobuf = iobuf_get2 (this->ctx->iobuf_pool, size);
- if (!iobuf) {
- op_errno = ENOMEM;
- goto err;
- }
-
- paiocb = GF_CALLOC (1, sizeof (*paiocb), gf_posix_mt_paiocb);
- if (!paiocb) {
- op_errno = ENOMEM;
- goto err;
- }
-
-
- paiocb->frame = frame;
- paiocb->iobuf = iobuf;
- paiocb->offset = offset;
- paiocb->fd = _fd;
- paiocb->op = GF_FOP_READ;
-
- paiocb->iocb.data = paiocb;
- paiocb->iocb.aio_fildes = _fd;
- paiocb->iocb.aio_lio_opcode = IO_CMD_PREAD;
- paiocb->iocb.aio_reqprio = 0;
- paiocb->iocb.u.c.buf = iobuf_ptr (iobuf);
- paiocb->iocb.u.c.nbytes = size;
- paiocb->iocb.u.c.offset = offset;
-
- iocb = &paiocb->iocb;
-
- ret = io_submit (priv->ctxp, 1, &iocb);
- if (ret != 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "io_submit() returned %d", ret);
- op_errno = -ret;
- goto err;
- }
-
- return 0;
-err:
- STACK_UNWIND_STRICT (readv, frame, -1, op_errno, 0, 0, 0, 0, 0);
- if (iobuf)
- iobuf_unref (iobuf);
-
- if (paiocb)
- GF_FREE (paiocb);
-
- return 0;
-}
-
-
-int
-posix_aio_writev_complete (struct posix_aio_cb *paiocb, int res, int res2)
-{
- call_frame_t *frame = NULL;
- xlator_t *this = NULL;
- struct iatt prebuf = {0,};
- struct iatt postbuf = {0,};
- int _fd = -1;
- int op_ret = -1;
- int op_errno = 0;
- int ret = 0;
- struct posix_private * priv = NULL;
-
-
- frame = paiocb->frame;
- this = frame->this;
- priv = this->private;
- prebuf = paiocb->prebuf;
- _fd = paiocb->fd;
-
- if (res < 0) {
- op_ret = -1;
- op_errno = -res;
- gf_log (this->name, GF_LOG_ERROR,
- "writev(async) failed fd=%d,offset=%llu (%d/%s)",
- _fd, (unsigned long long) paiocb->offset, res,
- strerror (op_errno));
-
- goto out;
- }
-
- ret = posix_fdstat (this, _fd, &postbuf);
- if (ret != 0) {
- op_ret = -1;
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "fstat failed on fd=%d: %s", _fd,
- strerror (op_errno));
- goto out;
- }
-
-
- op_ret = res;
- op_errno = 0;
-
- LOCK (&priv->lock);
- {
- priv->write_value += op_ret;
- }
- UNLOCK (&priv->lock);
-
-out:
- STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, &prebuf, &postbuf,
- NULL);
-
- if (paiocb) {
- if (paiocb->iobref)
- iobref_unref (paiocb->iobref);
- GF_FREE (paiocb);
- }
-
- return 0;
-}
-
-
-int
-posix_aio_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *iov, int count, off_t offset, uint32_t flags,
- struct iobref *iobref, dict_t *xdata)
-{
- int32_t op_errno = EINVAL;
- int _fd = -1;
- struct posix_fd * pfd = NULL;
- int ret = -1;
- struct posix_aio_cb *paiocb = NULL;
- struct posix_private *priv = NULL;
- struct iocb *iocb = NULL;
-
-
- VALIDATE_OR_GOTO (frame, err);
- VALIDATE_OR_GOTO (this, err);
- VALIDATE_OR_GOTO (fd, err);
-
- priv = this->private;
-
- ret = posix_fd_ctx_get_off (fd, this, &pfd, offset);
- if (ret < 0) {
- op_errno = -ret;
- gf_log (this->name, GF_LOG_WARNING,
- "pfd is NULL from fd=%p", fd);
- goto err;
- }
- _fd = pfd->fd;
-
- paiocb = GF_CALLOC (1, sizeof (*paiocb), gf_posix_mt_paiocb);
- if (!paiocb) {
- op_errno = ENOMEM;
- goto err;
- }
-
-
- paiocb->frame = frame;
- paiocb->offset = offset;
- paiocb->fd = _fd;
- paiocb->op = GF_FOP_WRITE;
-
- paiocb->iocb.data = paiocb;
- paiocb->iocb.aio_fildes = _fd;
- paiocb->iobref = iobref_ref (iobref);
- paiocb->iocb.aio_lio_opcode = IO_CMD_PWRITEV;
- paiocb->iocb.aio_reqprio = 0;
- paiocb->iocb.u.v.vec = iov;
- paiocb->iocb.u.v.nr = count;
- paiocb->iocb.u.v.offset = offset;
-
- iocb = &paiocb->iocb;
-
- ret = posix_fdstat (this, _fd, &paiocb->prebuf);
- if (ret != 0) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "fstat failed on fd=%p: %s", fd,
- strerror (op_errno));
- goto err;
- }
-
-
- ret = io_submit (priv->ctxp, 1, &iocb);
- if (ret != 1) {
- gf_log (this->name, GF_LOG_ERROR,
- "io_submit() returned %d", ret);
- op_errno = -ret;
- goto err;
- }
-
- return 0;
-err:
- STACK_UNWIND_STRICT (writev, frame, -1, op_errno, 0, 0, 0);
-
- if (paiocb) {
- if (paiocb->iobref)
- iobref_unref (paiocb->iobref);
- GF_FREE (paiocb);
- }
-
- return 0;
-}
-
-
-void *
-posix_aio_thread (void *data)
-{
- xlator_t *this = NULL;
- struct posix_private *priv = NULL;
- int ret = 0;
- int i = 0;
- struct io_event events[POSIX_AIO_MAX_NR_GETEVENTS];
- struct io_event *event = NULL;
- struct posix_aio_cb *paiocb = NULL;
-
- this = data;
- THIS = this;
- priv = this->private;
-
- for (;;) {
- memset (&events[0], 0, sizeof (events));
- ret = io_getevents (priv->ctxp, 1, POSIX_AIO_MAX_NR_GETEVENTS,
- &events[0], NULL);
- if (ret <= 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "io_getevents() returned %d", ret);
- if (ret == -EINTR)
- continue;
- break;
- }
-
- for (i = 0; i < ret; i++) {
- event = &events[i];
-
- paiocb = event->data;
-
- switch (paiocb->op) {
- case GF_FOP_READ:
- posix_aio_readv_complete (paiocb, event->res,
- event->res2);
- break;
- case GF_FOP_WRITE:
- posix_aio_writev_complete (paiocb, event->res,
- event->res2);
- break;
- default:
- gf_log (this->name, GF_LOG_ERROR,
- "unknown op %d found in piocb",
- paiocb->op);
- break;
- }
- }
- }
-
- return NULL;
-}
-
-
-int
-posix_aio_init (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
-
- priv = this->private;
-
- ret = io_setup (POSIX_AIO_MAX_NR_EVENTS, &priv->ctxp);
- if ((ret == -1 && errno == ENOSYS) || ret == -ENOSYS) {
- gf_log (this->name, GF_LOG_WARNING,
- "Linux AIO not availble at run-time."
- " Continuing with synchronous IO");
- ret = 0;
- goto out;
- }
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "io_setup() failed. ret=%d, errno=%d",
- ret, errno);
- goto out;
- }
-
- ret = pthread_create (&priv->aiothread, NULL,
- posix_aio_thread, this);
- if (ret != 0) {
- io_destroy (priv->ctxp);
- goto out;
- }
-
- this->fops->readv = posix_aio_readv;
- this->fops->writev = posix_aio_writev;
-out:
- return ret;
-}
-
-
-int
-posix_aio_on (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
-
- priv = this->private;
-
- if (!priv->aio_init_done) {
- ret = posix_aio_init (this);
- if (ret == 0)
- priv->aio_capable = _gf_true;
- else
- priv->aio_capable = _gf_false;
- priv->aio_init_done = _gf_true;
- }
-
- if (priv->aio_capable) {
- this->fops->readv = posix_aio_readv;
- this->fops->writev = posix_aio_writev;
- }
-
- return ret;
-}
-
-int
-posix_aio_off (xlator_t *this)
-{
- this->fops->readv = posix_readv;
- this->fops->writev = posix_writev;
-
- return 0;
-}
-
-
-#else
-
-
-int
-posix_aio_on (xlator_t *this)
-{
- gf_log (this->name, GF_LOG_INFO,
- "Linux AIO not availble at build-time."
- " Continuing with synchronous IO");
- return 0;
-}
-
-int
-posix_aio_off (xlator_t *this)
-{
- gf_log (this->name, GF_LOG_INFO,
- "Linux AIO not availble at build-time."
- " Continuing with synchronous IO");
- return 0;
-}
-
-#endif
diff --git a/xlators/storage/posix/src/posix-aio.h b/xlators/storage/posix/src/posix-aio.h
deleted file mode 100644
index 545130a28..000000000
--- a/xlators/storage/posix/src/posix-aio.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _POSIX_AIO_H
-#define _POSIX_AIO_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include "xlator.h"
-#include "glusterfs.h"
-
-// Maximum number of concurrently submitted IO events. The heaviest load
-// GlusterFS has been able to handle had 60-80 concurrent calls
-#define POSIX_AIO_MAX_NR_EVENTS 256
-
-// Maximum number of completed IO operations to reap per getevents syscall
-#define POSIX_AIO_MAX_NR_GETEVENTS 16
-
-
-int posix_aio_on (xlator_t *this);
-int posix_aio_off (xlator_t *this);
-
-int posix_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
- off_t offset, uint32_t flags, dict_t *xdata);
-
-int posix_writev (call_frame_t *frame, xlator_t *this, fd_t *fd,
- struct iovec *vector, int32_t count, off_t offset,
- uint32_t flags, struct iobref *iobref, dict_t *xdata);
-
-#endif /* !_POSIX_AIO_H */
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c
deleted file mode 100644
index a06e6430f..000000000
--- a/xlators/storage/posix/src/posix-handle.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <libgen.h>
-#ifdef GF_LINUX_HOST_OS
-#include <alloca.h>
-#endif
-
-#include "posix-handle.h"
-#include "posix.h"
-#include "xlator.h"
-#include "syscall.h"
-
-
-#define HANDLE_PFX ".glusterfs"
-#define TRASH_DIR "landfill"
-
-#define UUID0_STR "00000000-0000-0000-0000-000000000000"
-#define SLEN(str) (sizeof(str) - 1)
-
-
-int
-posix_handle_relpath (xlator_t *this, uuid_t gfid, const char *basename,
- char *buf, size_t buflen)
-{
- char *uuid_str = NULL;
- int len = 0;
-
- len = SLEN("../")
- + SLEN("../")
- + SLEN("00/")
- + SLEN("00/")
- + SLEN(UUID0_STR)
- + 1 /* '\0' */
- ;
-
- if (basename) {
- len += (strlen (basename) + 1);
- }
-
- if (buflen < len || !buf)
- return len;
-
- uuid_str = uuid_utoa (gfid);
-
- if (basename) {
- len = snprintf (buf, buflen, "../../%02x/%02x/%s/%s",
- gfid[0], gfid[1], uuid_str, basename);
- } else {
- len = snprintf (buf, buflen, "../../%02x/%02x/%s",
- gfid[0], gfid[1], uuid_str);
- }
-
- return len;
-}
-
-
-/*
- TODO: explain how this pump fixes ELOOP
-*/
-int
-posix_handle_pump (xlator_t *this, char *buf, int len, int maxlen,
- char *base_str, int base_len, int pfx_len)
-{
- char linkname[512] = {0,}; /* "../../<gfid>/<NAME_MAX>" */
- int ret = 0;
- int blen = 0;
- int link_len = 0;
-
- /* is a directory's symlink-handle */
- ret = readlink (base_str, linkname, 512);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_ERROR,
- "internal readlink failed on %s (%s)",
- base_str, strerror (errno));
- goto err;
- }
-
- if (ret < 512)
- linkname[ret] = 0;
-
- link_len = ret;
-
- if ((ret == 8) && memcmp (linkname, "../../..", 8) == 0) {
- if (strcmp (base_str, buf) == 0) {
- strcpy (buf + pfx_len, "..");
- }
- goto out;
- }
-
- if (ret < 50 || ret >= 512) {
- gf_log (this->name, GF_LOG_ERROR,
- "malformed internal link %s for %s",
- linkname, base_str);
- goto err;
- }
-
- if (memcmp (linkname, "../../", 6) != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "malformed internal link %s for %s",
- linkname, base_str);
- goto err;
- }
-
- if ((linkname[2] != '/') ||
- (linkname[5] != '/') ||
- (linkname[8] != '/') ||
- (linkname[11] != '/') ||
- (linkname[48] != '/')) {
- gf_log (this->name, GF_LOG_ERROR,
- "malformed internal link %s for %s",
- linkname, base_str);
- goto err;
- }
-
- if ((linkname[20] != '-') ||
- (linkname[25] != '-') ||
- (linkname[30] != '-') ||
- (linkname[35] != '-')) {
- gf_log (this->name, GF_LOG_ERROR,
- "malformed internal link %s for %s",
- linkname, base_str);
- goto err;
- }
-
- blen = link_len - 48;
- memmove (buf + base_len + blen, buf + base_len,
- (strlen (buf) - base_len) + 1);
-
- strncpy (base_str + pfx_len, linkname + 6, 42);
-
- if (len + blen < maxlen)
- strncpy (buf + pfx_len, linkname + 6, link_len - 6);
-out:
- return len + blen;
-err:
- return -1;
-}
-
-
-/*
- posix_handle_path differs from posix_handle_gfid_path in the way that the
- path filled in @buf by posix_handle_path will return type IA_IFDIR when
- an lstat() is performed on it, whereas posix_handle_gfid_path returns path
- to the handle symlink (typically used for the purpose of unlinking it).
-
- posix_handle_path also guarantees immunity to ELOOP on the path returned by it
-*/
-
-int
-posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename,
- char *ubuf, size_t size)
-{
- struct posix_private *priv = NULL;
- char *uuid_str = NULL;
- int len = 0;
- int ret = -1;
- struct stat stat;
- char *base_str = NULL;
- int base_len = 0;
- int pfx_len;
- int maxlen;
- char *buf;
-
- priv = this->private;
-
- uuid_str = uuid_utoa (gfid);
-
- if (ubuf) {
- buf = ubuf;
- maxlen = size;
- } else {
- maxlen = PATH_MAX;
- buf = alloca (maxlen);
- }
-
- base_len = (priv->base_path_length + SLEN(HANDLE_PFX) + 45);
- base_str = alloca (base_len + 1);
- base_len = snprintf (base_str, base_len + 1, "%s/%s/%02x/%02x/%s",
- priv->base_path, HANDLE_PFX, gfid[0], gfid[1],
- uuid_str);
-
- pfx_len = priv->base_path_length + 1 + SLEN(HANDLE_PFX) + 1;
-
- if (basename) {
- len = snprintf (buf, maxlen, "%s/%s", base_str, basename);
- } else {
- len = snprintf (buf, maxlen, "%s", base_str);
- }
-
- ret = lstat (base_str, &stat);
-
- if (!(ret == 0 && S_ISLNK(stat.st_mode) && stat.st_nlink == 1))
- goto out;
-
- do {
- errno = 0;
- ret = posix_handle_pump (this, buf, len, maxlen,
- base_str, base_len, pfx_len);
- if (ret == -1)
- break;
-
- len = ret;
-
- ret = lstat (buf, &stat);
- } while ((ret == -1) && errno == ELOOP);
-
-out:
- return len + 1;
-}
-
-
-int
-posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename,
- char *buf, size_t buflen)
-{
- struct posix_private *priv = NULL;
- char *uuid_str = NULL;
- int len = 0;
-
- priv = this->private;
-
- len = priv->base_path_length /* option directory "/export" */
- + SLEN("/")
- + SLEN(HANDLE_PFX)
- + SLEN("/")
- + SLEN("00/")
- + SLEN("00/")
- + SLEN(UUID0_STR)
- + 1 /* '\0' */
- ;
-
- if (basename) {
- len += (strlen (basename) + 1);
- } else {
- len += 256; /* worst-case for directory's symlink-handle expansion */
- }
-
- if ((buflen < len) || !buf)
- return len;
-
- uuid_str = uuid_utoa (gfid);
-
- if (__is_root_gfid (gfid)) {
- if (basename) {
- len = snprintf (buf, buflen, "%s/%s", priv->base_path,
- basename);
- } else {
- strncpy (buf, priv->base_path, buflen);
- }
- goto out;
- }
-
- if (basename) {
- len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s/%s", priv->base_path,
- HANDLE_PFX, gfid[0], gfid[1], uuid_str, basename);
- } else {
- len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s", priv->base_path,
- HANDLE_PFX, gfid[0], gfid[1], uuid_str);
- }
-out:
- return len;
-}
-
-
-int
-posix_handle_init (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- char *handle_pfx = NULL;
- int ret = 0;
- int len = 0;
- struct stat stbuf;
- struct stat rootbuf;
- struct stat exportbuf;
- char *rootstr = NULL;
- uuid_t gfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
-
- priv = this->private;
-
- ret = stat (priv->base_path, &exportbuf);
- if (ret || !S_ISDIR (exportbuf.st_mode)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Not a directory: %s", priv->base_path);
- return -1;
- }
-
- handle_pfx = alloca (priv->base_path_length + 1 + strlen (HANDLE_PFX)
- + 1);
-
- sprintf (handle_pfx, "%s/%s", priv->base_path, HANDLE_PFX);
-
- ret = stat (handle_pfx, &stbuf);
- switch (ret) {
- case -1:
- if (errno == ENOENT) {
- ret = mkdir (handle_pfx, 0600);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Creating directory %s failed: %s",
- handle_pfx, strerror (errno));
- return -1;
- }
- } else {
- gf_log (this->name, GF_LOG_ERROR,
- "Checking for %s failed: %s",
- handle_pfx, strerror (errno));
- return -1;
- }
- break;
- case 0:
- if (!S_ISDIR (stbuf.st_mode)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Not a directory: %s",
- handle_pfx);
- return -1;
- }
- break;
- default:
- break;
- }
-
- stat (handle_pfx, &priv->handledir);
-
- len = posix_handle_path (this, gfid, NULL, NULL, 0);
- rootstr = alloca (len);
- posix_handle_path (this, gfid, NULL, rootstr, len);
-
- ret = stat (rootstr, &rootbuf);
- switch (ret) {
- case -1:
- if (errno != ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "%s: %s", priv->base_path,
- strerror (errno));
- return -1;
- }
-
- ret = posix_handle_mkdir_hashes (this, rootstr);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "mkdir %s failed (%s)",
- rootstr, strerror (errno));
- return -1;
- }
-
- ret = symlink ("../../..", rootstr);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "symlink %s creation failed (%s)",
- rootstr, strerror (errno));
- return -1;
- }
- break;
- case 0:
- if ((exportbuf.st_ino == rootbuf.st_ino) &&
- (exportbuf.st_dev == rootbuf.st_dev))
- return 0;
-
- gf_log (this->name, GF_LOG_ERROR,
- "Different dirs %s (%lld/%lld) != %s (%lld/%lld)",
- priv->base_path, (long long) exportbuf.st_ino,
- (long long) exportbuf.st_dev, rootstr,
- (long long) rootbuf.st_ino, (long long) rootbuf.st_dev);
- return -1;
-
- break;
- }
-
- return 0;
-}
-
-gf_boolean_t
-posix_does_old_trash_exists (char *old_trash)
-{
- uuid_t gfid = {0};
- gf_boolean_t exists = _gf_false;
- struct stat stbuf = {0};
- int ret = 0;
-
- ret = lstat (old_trash, &stbuf);
- if ((ret == 0) && S_ISDIR (stbuf.st_mode)) {
- ret = sys_lgetxattr (old_trash, "trusted.gfid", gfid, 16);
- if ((ret < 0) && (errno == ENODATA))
- exists = _gf_true;
- }
- return exists;
-}
-
-int
-posix_handle_new_trash_init (xlator_t *this, char *trash)
-{
- int ret = 0;
- struct stat stbuf = {0};
-
- ret = lstat (trash, &stbuf);
- switch (ret) {
- case -1:
- if (errno == ENOENT) {
- ret = mkdir (trash, 0755);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "Creating directory %s failed: %s",
- trash, strerror (errno));
- }
- } else {
- gf_log (this->name, GF_LOG_ERROR, "Checking for %s "
- "failed: %s", trash, strerror (errno));
- }
- break;
- case 0:
- if (!S_ISDIR (stbuf.st_mode)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Not a directory: %s", trash);
- ret = -1;
- }
- break;
- default:
- break;
- }
- return ret;
-}
-
-int
-posix_mv_old_trash_into_new_trash (xlator_t *this, char *old, char *new)
-{
- char dest_old[PATH_MAX] = {0};
- int ret = 0;
- uuid_t dest_name = {0};
-
- if (!posix_does_old_trash_exists (old))
- goto out;
- uuid_generate (dest_name);
- snprintf (dest_old, sizeof (dest_old), "%s/%s", new,
- uuid_utoa (dest_name));
- ret = rename (old, dest_old);
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR, "Not able to move "
- "%s -> %s (%s)", old, dest_old, strerror (errno));
- }
-out:
- return ret;
-}
-
-int
-posix_handle_trash_init (xlator_t *this)
-{
- int ret = -1;
- struct posix_private *priv = NULL;
- char old_trash[PATH_MAX] = {0};
-
- priv = this->private;
-
- priv->trash_path = GF_CALLOC (1, priv->base_path_length + strlen ("/")
- + strlen (HANDLE_PFX) + strlen ("/")
- + strlen (TRASH_DIR) + 1,
- gf_posix_mt_trash_path);
-
- if (!priv->trash_path)
- goto out;
-
- strncpy (priv->trash_path, priv->base_path, priv->base_path_length);
- strcat (priv->trash_path, "/" HANDLE_PFX "/" TRASH_DIR);
- ret = posix_handle_new_trash_init (this, priv->trash_path);
- if (ret)
- goto out;
- snprintf (old_trash, sizeof (old_trash), "%s/.landfill",
- priv->base_path);
- ret = posix_mv_old_trash_into_new_trash (this, old_trash,
- priv->trash_path);
-out:
- return ret;
-}
-
-int
-posix_handle_mkdir_hashes (xlator_t *this, const char *newpath)
-{
- char *duppath = NULL;
- char *parpath = NULL;
- int ret = 0;
-
- duppath = strdupa (newpath);
- parpath = dirname (duppath);
- parpath = dirname (duppath);
-
- ret = mkdir (parpath, 0700);
- if (ret == -1 && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR,
- "error mkdir hash-1 %s (%s)",
- parpath, strerror (errno));
- return -1;
- }
-
- strcpy (duppath, newpath);
- parpath = dirname (duppath);
-
- ret = mkdir (parpath, 0700);
- if (ret == -1 && errno != EEXIST) {
- gf_log (this->name, GF_LOG_ERROR,
- "error mkdir hash-2 %s (%s)",
- parpath, strerror (errno));
- return -1;
- }
-
- return 0;
-}
-
-
-int
-posix_handle_hard (xlator_t *this, const char *oldpath, uuid_t gfid, struct stat *oldbuf)
-{
- char *newpath = NULL;
- struct stat newbuf;
- int ret = -1;
-
-
- MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
-
- ret = lstat (newpath, &newbuf);
- if (ret == -1 && errno != ENOENT) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: %s", newpath, strerror (errno));
- return -1;
- }
-
- if (ret == -1 && errno == ENOENT) {
- ret = posix_handle_mkdir_hashes (this, newpath);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "mkdir %s failed (%s)",
- newpath, strerror (errno));
- return -1;
- }
-
-#ifdef HAVE_LINKAT
- /*
- * Use linkat if the target may be a symlink to a directory
- * or without an existing target. See comment about linkat()
- * usage in posix_link() in posix.c for details
- */
- ret = linkat (AT_FDCWD, oldpath, AT_FDCWD, newpath, 0);
-#else
- ret = link (oldpath, newpath);
-#endif
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "link %s -> %s failed (%s)",
- oldpath, newpath, strerror (errno));
- return -1;
- }
-
- ret = lstat (newpath, &newbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "lstat on %s failed (%s)",
- newpath, strerror (errno));
- return -1;
- }
- }
-
- ret = lstat (newpath, &newbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "lstat on %s failed (%s)", newpath, strerror (errno));
- return -1;
- }
-
- if (newbuf.st_ino != oldbuf->st_ino ||
- newbuf.st_dev != oldbuf->st_dev) {
- gf_log (this->name, GF_LOG_WARNING,
- "mismatching ino/dev between file %s (%lld/%lld) "
- "and handle %s (%lld/%lld)",
- oldpath, (long long) oldbuf->st_ino, (long long) oldbuf->st_dev,
- newpath, (long long) newbuf.st_ino, (long long) newbuf.st_dev);
- ret = -1;
- }
-
- return ret;
-}
-
-
-int
-posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc,
- uuid_t gfid, struct stat *oldbuf)
-{
- char *oldpath = NULL;
- char *newpath = NULL;
- struct stat newbuf;
- int ret = -1;
-
-
- MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
- MAKE_HANDLE_RELPATH (oldpath, this, loc->pargfid, loc->name);
-
-
- ret = lstat (newpath, &newbuf);
- if (ret == -1 && errno != ENOENT) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: %s", newpath, strerror (errno));
- return -1;
- }
-
- if (ret == -1 && errno == ENOENT) {
- ret = posix_handle_mkdir_hashes (this, newpath);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "mkdir %s failed (%s)",
- newpath, strerror (errno));
- return -1;
- }
-
- ret = symlink (oldpath, newpath);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "symlink %s -> %s failed (%s)",
- oldpath, newpath, strerror (errno));
- return -1;
- }
-
- ret = lstat (newpath, &newbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "stat on %s failed (%s)",
- newpath, strerror (errno));
- return -1;
- }
- }
-
- ret = stat (real_path, &newbuf);
- if (ret) {
- gf_log (this->name, GF_LOG_WARNING,
- "stat on %s failed (%s)", newpath, strerror (errno));
- return -1;
- }
-
- if (!oldbuf)
- return ret;
-
- if (newbuf.st_ino != oldbuf->st_ino ||
- newbuf.st_dev != oldbuf->st_dev) {
- gf_log (this->name, GF_LOG_WARNING,
- "mismatching ino/dev between file %s (%lld/%lld) "
- "and handle %s (%lld/%lld)",
- oldpath, (long long) oldbuf->st_ino, (long long) oldbuf->st_dev,
- newpath, (long long) newbuf.st_ino, (long long) newbuf.st_dev);
- ret = -1;
- }
-
- return ret;
-}
-
-
-static int
-posix_handle_unset_gfid (xlator_t *this, uuid_t gfid)
-{
- char *path = NULL;
- int ret = 0;
- struct stat stat;
-
- MAKE_HANDLE_GFID_PATH (path, this, gfid, NULL);
-
- ret = lstat (path, &stat);
-
- if (ret == -1) {
- if (errno != ENOENT) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: %s", path, strerror (errno));
- }
- goto out;
- }
-
- ret = unlink (path);
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "unlink %s failed (%s)", path, strerror (errno));
- }
-
-out:
- return ret;
-}
-
-
-int
-posix_handle_unset (xlator_t *this, uuid_t gfid, const char *basename)
-{
- int ret;
- struct iatt stat;
- char *path = NULL;
-
-
- if (!basename) {
- ret = posix_handle_unset_gfid (this, gfid);
- return ret;
- }
-
- MAKE_HANDLE_PATH (path, this, gfid, basename);
-
- ret = posix_istat (this, gfid, basename, &stat);
-
- if (ret == -1) {
- gf_log (this->name, GF_LOG_WARNING,
- "%s: %s", path, strerror (errno));
- return -1;
- }
-
- ret = posix_handle_unset_gfid (this, stat.ia_gfid);
-
- return ret;
-}
-
-
-int
-posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid,
- char *real_path)
-{
- int ret = -1;
- struct stat stbuf = {0,};
- char *newpath = NULL;
-
- MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
- ret = lstat (newpath, &stbuf);
- if (!ret) {
-#ifdef HAVE_LINKAT
- /*
- * Use linkat if the target may be a symlink to a directory
- * or without an existing target. See comment about linkat()
- * usage in posix_link() in posix.c for details
- */
- ret = linkat (AT_FDCWD, newpath, AT_FDCWD, real_path, 0);
-#else
- ret = link (newpath, real_path);
-#endif
- }
-
- return ret;
-}
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h
deleted file mode 100644
index 560d7aac8..000000000
--- a/xlators/storage/posix/src/posix-handle.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _POSIX_HANDLE_H
-#define _POSIX_HANDLE_H
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include "xlator.h"
-
-
-#define LOC_HAS_ABSPATH(loc) ((loc) && (loc->path) && (loc->path[0] == '/'))
-
-#define MAKE_REAL_PATH(var, this, path) do { \
- var = alloca (strlen (path) + POSIX_BASE_PATH_LEN(this) + 2); \
- strcpy (var, POSIX_BASE_PATH(this)); \
- strcpy (&var[POSIX_BASE_PATH_LEN(this)], path); \
- } while (0)
-
-
-#define MAKE_HANDLE_PATH(var, this, gfid, base) do { \
- int __len; \
- __len = posix_handle_path (this, gfid, base, NULL, 0); \
- if (__len <= 0) \
- break; \
- var = alloca (__len); \
- __len = posix_handle_path (this, gfid, base, var, __len); \
- } while (0)
-
-
-#define MAKE_HANDLE_GFID_PATH(var, this, gfid, base) do { \
- int __len = 0; \
- __len = posix_handle_gfid_path (this, gfid, base, NULL, 0); \
- if (__len <= 0) \
- break; \
- var = alloca (__len); \
- __len = posix_handle_gfid_path (this, gfid, base, var, __len); \
- } while (0)
-
-
-#define MAKE_HANDLE_RELPATH(var, this, gfid, base) do { \
- int __len; \
- __len = posix_handle_relpath (this, gfid, base, NULL, 0); \
- if (__len <= 0) \
- break; \
- var = alloca (__len); \
- __len = posix_handle_relpath (this, gfid, base, var, __len); \
- } while (0)
-
-
-#define MAKE_INODE_HANDLE(rpath, this, loc, iatt_p) do { \
- if (uuid_is_null (loc->gfid)) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "null gfid for path %s", loc->path); \
- break; \
- } \
- if (LOC_HAS_ABSPATH (loc)) { \
- MAKE_REAL_PATH (rpath, this, loc->path); \
- op_ret = posix_pstat (this, loc->gfid, rpath, iatt_p); \
- break; \
- } \
- errno = 0; \
- op_ret = posix_istat (this, loc->gfid, NULL, iatt_p); \
- if (errno != ELOOP) { \
- MAKE_HANDLE_PATH (rpath, this, loc->gfid, NULL); \
- break; \
- } \
- /* __ret == -1 && errno == ELOOP */ \
- } while (0)
-
-
-#define MAKE_ENTRY_HANDLE(entp, parp, this, loc, ent_p) do { \
- char *__parp; \
- \
- if (uuid_is_null (loc->pargfid) || !loc->name) { \
- gf_log (this->name, GF_LOG_ERROR, \
- "null pargfid/name for path %s", loc->path); \
- break; \
- } \
- \
- if (LOC_HAS_ABSPATH (loc)) { \
- MAKE_REAL_PATH (entp, this, loc->path); \
- __parp = strdupa (entp); \
- parp = dirname (__parp); \
- op_ret = posix_pstat (this, NULL, entp, ent_p); \
- break; \
- } \
- errno = 0; \
- op_ret = posix_istat (this, loc->pargfid, loc->name, ent_p); \
- if (errno != ELOOP) { \
- MAKE_HANDLE_PATH (parp, this, loc->pargfid, NULL); \
- MAKE_HANDLE_PATH (entp, this, loc->pargfid, loc->name); \
- break; \
- } \
- /* __ret == -1 && errno == ELOOP */ \
- /* expand ELOOP */ \
- } while (0)
-
-
-
-int
-posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename, char *buf,
- size_t len);
-int
-posix_handle_path_safe (xlator_t *this, uuid_t gfid, const char *basename,
- char *buf, size_t len);
-
-int
-posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename,
- char *buf, size_t len);
-
-int
-posix_handle_hard (xlator_t *this, const char *path, uuid_t gfid,
- struct stat *buf);
-
-
-int
-posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc,
- uuid_t gfid, struct stat *buf);
-
-int
-posix_handle_unset (xlator_t *this, uuid_t gfid, const char *basename);
-
-int posix_handle_mkdir_hashes (xlator_t *this, const char *newpath);
-
-int posix_handle_init (xlator_t *this);
-
-int posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid,
- char *real_path);
-
-int
-posix_handle_trash_init (xlator_t *this);
-#endif /* !_POSIX_HANDLE_H */
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
deleted file mode 100644
index c1fc9721e..000000000
--- a/xlators/storage/posix/src/posix-helpers.c
+++ /dev/null
@@ -1,1093 +0,0 @@
-/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
- This file is part of GlusterFS.
-
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _CONFIG_H
-#define _CONFIG_H
-#include "config.h"
-#endif
-
-#define __XOPEN_SOURCE 500
-
-#include <stdint.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <errno.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <ftw.h>
-#include <sys/stat.h>
-
-#ifndef GF_BSD_HOST_OS
-#include <alloca.h>
-#endif /* GF_BSD_HOST_OS */
-
-#include "glusterfs.h"
-#include "checksum.h"
-#include "dict.h"
-#include "logging.h"
-#include "posix.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "compat-errno.h"
-#include "compat.h"
-#include "byte-order.h"
-#include "syscall.h"
-#include "statedump.h"
-#include "locking.h"
-#include "timer.h"
-#include "glusterfs3-xdr.h"
-#include "hashfn.h"
-#include <fnmatch.h>
-
-typedef struct {
- xlator_t *this;
- const char *real_path;
- dict_t *xattr;
- struct iatt *stbuf;
- loc_t *loc;
-} posix_xattr_filler_t;
-
-char *marker_xattrs[] = {"trusted.glusterfs.quota.*",
- "trusted.glusterfs.*.xtime",
- NULL};
-
-static char* posix_ignore_xattrs[] = {
- "gfid-req",
- GLUSTERFS_ENTRYLK_COUNT,
- GLUSTERFS_INODELK_COUNT,
- GLUSTERFS_POSIXLK_COUNT,
- NULL
-};
-
-gf_boolean_t
-posix_special_xattr (char **pattern, char *key)
-{
- int i = 0;
- gf_boolean_t flag = _gf_false;
-
- GF_VALIDATE_OR_GOTO ("posix", pattern, out);
- GF_VALIDATE_OR_GOTO ("posix", key, out);
-
- for (i = 0; pattern[i]; i++) {
- if (!fnmatch (pattern[i], key, 0)) {
- flag = _gf_true;
- break;
- }
- }
-out:
- return flag;
-}
-
-static gf_boolean_t
-posix_xattr_ignorable (char *key, posix_xattr_filler_t *filler)
-{
- int i = 0;
- gf_boolean_t ignore = _gf_false;
-
- GF_ASSERT (key);
- if (!key)
- goto out;
- for (i = 0; posix_ignore_xattrs[i]; i++) {
- if (!strcmp (key, posix_ignore_xattrs[i])) {
- ignore = _gf_true;
- goto out;
- }
- }
- if ((!strcmp (key, GF_CONTENT_KEY))
- && (!IA_ISREG (filler->stbuf->ia_type)))
- ignore = _gf_true;
-out:
- return ignore;
-}
-
-static void
-_posix_xattr_get_set (dict_t *xattr_req,
- char *key,
- data_t *data,
- void *xattrargs)
-{
- posix_xattr_filler_t *filler = xattrargs;
- char *value = NULL;
- ssize_t xattr_size = -1;
- int ret = -1;
- char *databuf = NULL;
- int _fd = -1;
- loc_t *loc = NULL;
- ssize_t req_size = 0;
-
-
- if (posix_xattr_ignorable (key, filler))
- goto out;
- /* should size be put into the data_t ? */
- if (!strcmp (key, GF_CONTENT_KEY)
- && IA_ISREG (filler->stbuf->ia_type)) {
-
- /* file content request */
- req_size = data_to_uint64 (data);
- if (req_size >= filler->stbuf->ia_size) {
- _fd = open (filler->real_path, O_RDONLY);
- if (_fd == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Opening file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- databuf = GF_CALLOC (1, filler->stbuf->ia_size,
- gf_posix_mt_char);
- if (!databuf) {
- goto err;
- }
-
- ret = read (_fd, databuf, filler->stbuf->ia_size);
- if (ret == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Read on file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- ret = close (_fd);
- _fd = -1;
- if (ret == -1) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "Close on file %s failed: %s",
- filler->real_path, strerror (errno));
- goto err;
- }
-
- ret = dict_set_bin (filler->xattr, key,
- databuf, filler->stbuf->ia_size);
- if (ret < 0) {
- gf_log (filler->this->name, GF_LOG_ERROR,
- "failed to set dict value. key: %s, path: %s",
- key, filler->real_path);
- goto err;
- }
-
- /* To avoid double free in cleanup below */
- databuf = NULL;
- err:
- if (_fd != -1)
- close (_fd);
- GF_FREE (databuf);
- }
- } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) {
- loc = filler->loc;
- if (loc && !list_empty (&loc->inode->fd_list)) {
- ret = dict_set_uint32 (filler->xattr, key, 1);
- if (ret < 0)
- gf_log (filler->this->name, GF_LOG_WARNING,
- "Failed to set dictionary value for %s",
- key);
- } else {
- ret = dict_set_uint32 (filler->xattr, key, 0);
- if (ret < 0)
- gf_log (filler->this->name, GF_LOG_WARNING,
- "Failed to set dictionary value for %s",
- key);
- }
- } else {
- xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0);
-
- if (xattr_size > 0) {
- value = GF_CALLOC (1, xattr_size + 1,
- gf_posix_mt_char);
- if (!value)
- return;
-
- xattr_size = sys_lgetxattr (filler->real_path, key, value,
- xattr_size);
- if (xattr_size <= 0) {
- gf_log (filler->this->name, GF_LOG_WARNING,
- "getxattr failed. path: %s, key: %s",
- filler->real_path, key);
- GF_FREE (value);
- return;
- }
-
- value[xattr_size] = '\0';
- ret = dict_set_bin (filler->xattr, key,
- value, xattr_size);
- if (ret < 0) {
- gf_log (filler->this->name, GF_LOG_DEBUG,
- "dict set failed. path: %s, key: %s",
- filler->real_path, key);
- GF_FREE (value);
- }
- }
- }
-out:
- return;
-}
-
-
-int
-posix_fill_gfid_path (xlator_t *this, const char *path, struct iatt *iatt)
-{
- int ret = 0;
- ssize_t size = 0;
-
- if (!iatt)
- return 0;
-
- size = sys_lgetxattr (path, GFID_XATTR_KEY, iatt->ia_gfid, 16);
- /* Return value of getxattr */
- if ((size == 16) || (size == -1))
- ret = 0;
- else
- ret = size;
-
- return ret;
-}
-
-
-int
-posix_fill_gfid_fd (xlator_t *this, int fd, struct iatt *iatt)
-{
- int ret = 0;
- ssize_t size = 0;
-
- if (!iatt)
- return 0;
-
- size = sys_fgetxattr (fd, GFID_XATTR_KEY, iatt->ia_gfid, 16);
- /* Return value of getxattr */
- if ((size == 16) || (size == -1))
- ret = 0;
- else
- ret = size;
-
- return ret;
-}
-
-void
-posix_fill_ino_from_gfid (xlator_t *this, struct iatt *buf)
-{
- uint64_t temp_ino = 0;
- int j = 0;
- int i = 0;
-
- /* consider least significant 8 bytes of value out of gfid */
- if (uuid_is_null (buf->ia_gfid)) {
- buf->ia_ino = -1;
- goto out;
- }
- for (i = 15; i > (15 - 8); i--) {
- temp_ino += (uint64_t)(buf->ia_gfid[i]) << j;
- j += 8;
- }
- buf->ia_ino = temp_ino;
-out:
- return;
-}
-
-int
-posix_fdstat (xlator_t *this, int fd, struct iatt *stbuf_p)
-{
- int ret = 0;
- struct stat fstatbuf = {0, };
- struct iatt stbuf = {0, };
-
- ret = fstat (fd, &fstatbuf);
- if (ret == -1)
- goto out;
-
- if (fstatbuf.st_nlink && !S_ISDIR (fstatbuf.st_mode))
- fstatbuf.st_nlink--;
-
- iatt_from_stat (&stbuf, &fstatbuf);
-
- ret = posix_fill_gfid_fd (this, fd, &stbuf);
- if (ret)
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
-
- posix_fill_ino_from_gfid (this, &stbuf);
-
- if (stbuf_p)
- *stbuf_p = stbuf;
-
-out:
- return ret;
-}
-
-
-int
-posix_istat (xlator_t *this, uuid_t gfid, const char *basename,
- struct iatt *buf_p)
-{
- char *real_path = NULL;
- struct stat lstatbuf = {0, };
- struct iatt stbuf = {0, };
- int ret = 0;
- struct posix_private *priv = NULL;
-
-
- priv = this->private;
-
- MAKE_HANDLE_PATH (real_path, this, gfid, basename);
-
- ret = lstat (real_path, &lstatbuf);
-
- if (ret == -1) {
- if (errno != ENOENT && errno != ELOOP)
- gf_log (this->name, GF_LOG_WARNING,
- "lstat failed on %s (%s)",
- real_path, strerror (errno));
- goto out;
- }
-
- if ((lstatbuf.st_ino == priv->handledir.st_ino) &&
- (lstatbuf.st_dev == priv->handledir.st_dev)) {
- errno = ENOENT;
- return -1;
- }
-
- if (!S_ISDIR (lstatbuf.st_mode))
- lstatbuf.st_nlink --;
-
- iatt_from_stat (&stbuf, &lstatbuf);
-
- if (basename)
- posix_fill_gfid_path (this, real_path, &stbuf);
- else
- uuid_copy (stbuf.ia_gfid, gfid);
-
- posix_fill_ino_from_gfid (this, &stbuf);
-
- if (buf_p)
- *buf_p = stbuf;
-out:
- return ret;
-}
-
-
-
-int
-posix_pstat (xlator_t *this, uuid_t gfid, const char *path,
- struct iatt *buf_p)
-{
- struct stat lstatbuf = {0, };
- struct iatt stbuf = {0, };
- int ret = 0;
- struct posix_private *priv = NULL;
-
-
- priv = this->private;
-
- ret = lstat (path, &lstatbuf);
-
- if (ret == -1) {
- if (errno != ENOENT)
- gf_log (this->name, GF_LOG_WARNING,
- "lstat failed on %s (%s)",
- path, strerror (errno));
- goto out;
- }
-
- if ((lstatbuf.st_ino == priv->handledir.st_ino) &&
- (lstatbuf.st_dev == priv->handledir.st_dev)) {
- errno = ENOENT;
- return -1;
- }
-
- if (!S_ISDIR (lstatbuf.st_mode))
- lstatbuf.st_nlink --;
-
- iatt_from_stat (&stbuf, &lstatbuf);
-
- if (gfid && !uuid_is_null (gfid))
- uuid_copy (stbuf.ia_gfid, gfid);
- else
- posix_fill_gfid_path (this, path, &stbuf);
-
- posix_fill_ino_from_gfid (this, &stbuf);
-
- if (buf_p)
- *buf_p = stbuf;
-out:
- return ret;
-}
-
-
-dict_t *
-posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc,
- dict_t *xattr_req, struct iatt *buf)
-{
- dict_t *xattr = NULL;
- posix_xattr_filler_t filler = {0, };
-
- xattr = get_new_dict();
- if (!xattr) {
- goto out;
- }
-
- filler.this = this;
- filler.real_path = real_path;
- filler.xattr = xattr;
- filler.stbuf = buf;
- filler.loc = loc;
-
- dict_foreach (xattr_req, _posix_xattr_get_set, &filler);
-out:
- return xattr;
-}
-
-
-int
-posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req)
-{
- void *uuid_req = NULL;
- uuid_t uuid_curr;
- int ret = 0;
- ssize_t size = 0;
- struct stat stat = {0, };
-
-
- if (!xattr_req)
- goto out;
-
- if (sys_lstat (path, &stat) != 0)
- goto out;
-
- size = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
- if (size == 16) {
- ret = 0;
- goto verify_handle;
- }
-
- ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req);
- if (ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get the gfid from dict for %s",
- loc->path);
- goto out;
- }
-
- ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
- if (ret != 0) {
- gf_log (this->name, GF_LOG_WARNING,
- "setting GFID on %s failed (%s)", path,
- strerror (errno));
- goto out;
- }
- uuid_copy (uuid_curr, uuid_req);
-
-verify_handle:
- if (!S_ISDIR (stat.st_mode))
- ret = posix_handle_hard (this, path, uuid_curr, &stat);
- else
- ret = posix_handle_soft (this, path, loc, uuid_curr, &stat);
-
-out:
- return ret;
-}
-
-
-int
-posix_set_file_contents (xlator_t *this, const char *path, data_pair_t *trav,
- int flags)
-{
- char * key = NULL;
- char real_path[PATH_MAX];
- int32_t file_fd = -1;
- int op_ret = 0;
- int ret = -1;
-
-
- /* XXX: does not handle assigning GFID to created files */
- return -1;
-
- key = &(trav->key[15]);
- sprintf (real_path, "%s/%s", path, key);
-
- if (flags & XATTR_REPLACE) {
- /* if file exists, replace it
- * else, error out */
- file_fd = open (real_path, O_TRUNC|O_WRONLY);
-
- if (file_fd == -1) {
- goto create;
- }
-
- if (trav->value->len) {
- ret = write (file_fd, trav->value->data,
- trav->value->len);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "write failed while doing setxattr "
- "for key %s on path %s: %s",
- key, real_path, strerror (errno));
- goto out;
- }
-
- ret = close (file_fd);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "close failed on %s: %s",
- real_path, strerror (errno));
- goto out;
- }
- }
-
- create: /* we know file doesn't exist, create it */
-
- file_fd = open (real_path, O_CREAT|O_WRONLY, 0644);
-
- if (file_fd == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "failed to open file %s with O_CREAT: %s",
- key, strerror (errno));
- goto out;
- }
-
- ret = write (file_fd, trav->value->data, trav->value->len);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "write failed on %s while setxattr with "
- "key %s: %s",
- real_path, key, strerror (errno));
- goto out;
- }
-
- ret = close (file_fd);
- if (ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR,
- "close failed on %s while setxattr with "
- "key %s: %s",
- real_path, key, strerror (errno));
- goto out;
- }
- }
-
-out:
- return op_ret;
-}
-
-
-int
-posix_get_file_contents (xlator_t *this, uuid_t pargfid,
- const char *name, char **contents)
-{
- char *real_path = NULL;
- int32_t file_fd = -1;
- struct iatt stbuf = {0,};
- int op_ret = 0;
- int ret = -1;
-
-
- MAKE_HANDLE_PATH (real_path, this, pargfid, name);
-
- op_ret = posix_istat (this, pargfid, name, &stbuf);
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s",
- real_path, strerror (errno));
- goto out;
- }
-
- file_fd = open (real_path, O_RDONLY);
-
- if (file_fd == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "open failed on %s: %s",
- real_path, strerror (errno));
- goto out;
- }
-
- *contents = GF_CALLOC (stbuf.ia_size + 1, sizeof(char),
- gf_posix_mt_char);
- if (! *contents) {
- op_ret = -errno;
- goto out;
- }
-
- ret = read (file_fd, *contents, stbuf.ia_size);
- if (ret <= 0) {
- op_ret = -1;
- gf_log (this->name, GF_LOG_ERROR, "read on %s failed: %s",
- real_path, strerror (errno));
- goto out;
- }
-
- *contents[stbuf.ia_size] = '\0';
-
- op_ret = close (file_fd);
- file_fd = -1;
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log (this->name, GF_LOG_ERROR, "close on %s failed: %s",
- real_path, strerror (errno));
- goto out;
- }
-
-out:
- if (op_ret < 0) {
- GF_FREE (*contents);
- if (file_fd != -1)
- close (file_fd);
- }
-
- return op_ret;
-}
-
-static int gf_xattr_enotsup_log;
-
-int
-posix_handle_pair (xlator_t *this, const char *real_path,
- data_pair_t *trav, int flags)
-{
- int sys_ret = -1;
- int ret = 0;
-
- if (ZR_FILE_CONTENT_REQUEST(trav->key)) {
- ret = posix_set_file_contents (this, real_path, trav, flags);
- } else {
- sys_ret = sys_lsetxattr (real_path, trav->key,
- trav->value->data,
- trav->value->len, flags);
-
- if (sys_ret < 0) {
- if (errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY(gf_xattr_enotsup_log,
- this->name,GF_LOG_WARNING,
- "Extended attributes not "
- "supported (try remounting "
- "brick with 'user_xattr' "
- "flag)");
- } else if (errno == ENOENT) {
- if (!posix_special_xattr (marker_xattrs,
- trav->key)) {
- gf_log (this->name, GF_LOG_ERROR,
- "setxattr on %s failed: %s",
- real_path, strerror (errno));
- }
- } else {
-
-#ifdef GF_DARWIN_HOST_OS
- gf_log (this->name,
- ((errno == EINVAL) ?
- GF_LOG_DEBUG : GF_LOG_ERROR),
- "%s: key:%s error:%s",
- real_path, trav->key,
- strerror (errno));
-#else /* ! DARWIN */
- gf_log (this->name, GF_LOG_ERROR,
- "%s: key:%s error:%s",
- real_path, trav->key,
- strerror (errno));
-#endif /* DARWIN */
- }
-
- ret = -errno;
- goto out;
- }
- }
-out:
- return ret;
-}
-
-int
-posix_fhandle_pair (xlator_t *this, int fd,
- data_pair_t *trav, int flags)
-{
- int sys_ret = -1;
- int ret = 0;
-
- sys_ret = sys_fsetxattr (fd, trav->key, trav->value->data,
- trav->value->len, flags);
-
- if (sys_ret < 0) {
- if (errno == ENOTSUP) {
- GF_LOG_OCCASIONALLY(gf_xattr_enotsup_log,
- this->name,GF_LOG_WARNING,
- "Extended attributes not "
- "supported (try remounting "
- "brick with 'user_xattr' "
- "flag)");
- } else if (errno == ENOENT) {
- gf_log (this->name, GF_LOG_ERROR,
- "fsetxattr on fd=%d failed: %s", fd,
- strerror (errno));
- } else {
-
-#ifdef GF_DARWIN_HOST_OS
- gf_log (this->name,
- ((errno == EINVAL) ?
- GF_LOG_DEBUG : GF_LOG_ERROR),
- "fd=%d: key:%s error:%s",
- fd, trav->key,
- strerror (errno));
-#else /* ! DARWIN */
- gf_log (this->name, GF_LOG_ERROR,
- "fd=%d: key:%s error:%s",
- fd, trav->key,
- strerror (errno));
-#endif /* DARWIN */
- }
-
- ret = -errno;
- goto out;
- }
-
-out:
- return ret;
-}
-
-
-static int
-janitor_walker (const char *fpath, const struct stat *sb,
- int typeflag, struct FTW *ftwbuf)
-{
- struct iatt stbuf = {0, };
- xlator_t *this = NULL;
-
- this = THIS;
- posix_pstat (this, NULL, fpath, &stbuf);
- switch (sb->st_mode & S_IFMT) {
- case S_IFREG:
- case S_IFBLK:
- case S_IFLNK:
- case S_IFCHR:
- case S_IFIFO:
- case S_IFSOCK:
- gf_log (THIS->name, GF_LOG_TRACE,
- "unlinking %s", fpath);
- unlink (fpath);
- if (stbuf.ia_nlink == 1)
- posix_handle_unset (this, stbuf.ia_gfid, NULL);
- break;
-
- case S_IFDIR:
- if (ftwbuf->level) { /* don't remove top level dir */
- gf_log (THIS->name, GF_LOG_TRACE,
- "removing directory %s", fpath);
-
- rmdir (fpath);
- posix_handle_unset (this, stbuf.ia_gfid, NULL);
- }
- break;
- }
-
- return 0; /* 0 = FTW_CONTINUE */
-}
-
-
-static struct posix_fd *
-janitor_get_next_fd (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- struct posix_fd *pfd = NULL;
-
- struct timespec timeout;
-
- priv = this->private;
-
- pthread_mutex_lock (&priv->janitor_lock);
- {
- if (list_empty (&priv->janitor_fds)) {
- time (&timeout.tv_sec);
- timeout.tv_sec += priv->janitor_sleep_duration;
- timeout.tv_nsec = 0;
-
- pthread_cond_timedwait (&priv->janitor_cond,
- &priv->janitor_lock,
- &timeout);
- goto unlock;
- }
-
- pfd = list_entry (priv->janitor_fds.next, struct posix_fd,
- list);
-
- list_del (priv->janitor_fds.next);
- }
-unlock:
- pthread_mutex_unlock (&priv->janitor_lock);
-
- return pfd;
-}
-
-
-static void *
-posix_janitor_thread_proc (void *data)
-{
- xlator_t * this = NULL;
- struct posix_private *priv = NULL;
- struct posix_fd *pfd;
-
- time_t now;
-
- this = data;
- priv = this->private;
-
- THIS = this;
-
- while (1) {
- time (&now);
- if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor cleaning out %s", priv->trash_path);
-
- nftw (priv->trash_path,
- janitor_walker,
- 32,
- FTW_DEPTH | FTW_PHYS);
-
- priv->last_landfill_check = now;
- }
-
- pfd = janitor_get_next_fd (this);
- if (pfd) {
- if (pfd->dir == NULL) {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor: closing file fd=%d", pfd->fd);
- close (pfd->fd);
- } else {
- gf_log (this->name, GF_LOG_TRACE,
- "janitor: closing dir fd=%p", pfd->dir);
- closedir (pfd->dir);
- }
-
- GF_FREE (pfd);
- }
- }
-
- return NULL;
-}
-
-
-void
-posix_spawn_janitor_thread (xlator_t *this)
-{
- struct posix_private *priv = NULL;
- int ret = 0;
-
- priv = this->private;
-
- LOCK (&priv->lock);
- {
- if (!priv->janitor_present) {
- ret = pthread_create (&priv->janitor, NULL,
- posix_janitor_thread_proc, this);
-
- if (ret < 0) {
- gf_log (this->name, GF_LOG_ERROR,
- "spawning janitor thread failed: %s",
- strerror (errno));
- goto unlock;
- }
-
- priv->janitor_present = _gf_true;
- }
- }
-unlock:
- UNLOCK (&priv->lock);
-}
-
-int
-posix_acl_xattr_set (xlator_t *this, const char *path, dict_t *xattr_req)
-{
- int ret = 0;
- data_t *data = NULL;
- struct stat stat = {0, };
-
- if (!xattr_req)
- goto out;
-
- if (sys_lstat (path, &stat) != 0)
- goto out;
-
- data = dict_get (xattr_req, "system.posix_acl_access");
- if (data) {
- ret = sys_lsetxattr (path, "system.posix_acl_access",
- data->data, data->len, 0);
- if (ret != 0)
- goto out;
- }
-
- data = dict_get (xattr_req, "system.posix_acl_default");
- if (data) {
- ret = sys_lsetxattr (path, "system.posix_acl_default",
- data->data, data->len, 0);
- if (ret != 0)
- goto out;
- }
-
-out:
- return ret;
-}
-
-int
-posix_entry_create_xattr_set (xlator_t *this, const char *path,
- dict_t *dict)
-{
- data_pair_t *trav = NULL;
- int ret = -1;
-
- if (!dict)
- goto out;
-
- trav = dict->members_list;
- while (trav) {
- if (!strcmp (GFID_XATTR_KEY, trav->key) ||
- !strcmp ("gfid-req", trav->key) ||
- !strcmp ("system.posix_acl_default", trav->key) ||
- !strcmp ("system.posix_acl_access", trav->key) ||
- ZR_FILE_CONTENT_REQUEST(trav->key)) {
- trav = trav->next;
- continue;
- }
-
- ret = posix_handle_pair (this, path, trav, XATTR_CREATE);
- if (ret < 0) {
- errno = -ret;
- ret = -1;
- goto out;
- }
- trav = trav->next;
- }
-
- ret = 0;
-
-out:
- return ret;
-}
-
-
-static int
-__posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p)
-{
- uint64_t tmp_pfd = 0;
- struct posix_fd *pfd = NULL;
- int ret = -1;
- char *real_path = NULL;
- int _fd = -1;
- DIR *dir = NULL;
-
- ret = __fd_ctx_get (fd, this, &tmp_pfd);
- if (ret == 0) {
- pfd = (void *)(long) tmp_pfd;
- ret = 0;
- goto out;
- }
-
- if (fd->pid != -1)
- /* anonymous fd */
- goto out;
-
- MAKE_HANDLE_PATH (real_path, this, fd->inode->gfid, NULL);
-
- pfd = GF_CALLOC (1, sizeof (*pfd), gf_posix_mt_posix_fd);
- if (!pfd) {
- goto out;
- }
- pfd->fd = -1;
-
- if (fd->inode->ia_type == IA_IFDIR) {
- dir = opendir (real_path);
- if (!dir) {
- GF_FREE (pfd);
- pfd = NULL;
- goto out;
- }
- _fd = dirfd (dir);
- }
-
- if (fd->inode->ia_type == IA_IFREG) {
- _fd = open (real_path, O_RDWR|O_LARGEFILE);
- if (_fd == -1) {
- GF_FREE (pfd);
- pfd = NULL;
- goto out;
- }
- }
-
- pfd->fd = _fd;
- pfd->dir = dir;
-
- ret = __fd_ctx_set (fd, this, (uint64_t) (long) pfd);
- if (ret != 0) {
- if (_fd != -1)
- close (_fd);
- if (dir)
- closedir (dir);
- GF_FREE (pfd);
- pfd = NULL;
- goto out;
- }
-
- ret = 0;
-out:
- if (pfd_p)
- *pfd_p = pfd;
- return ret;
-}
-
-
-int
-posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd)
-{
- int ret;
-
- LOCK (&fd->inode->lock);
- {
- ret = __posix_fd_ctx_get (fd, this, pfd);
- }
- UNLOCK (&fd->inode->lock);
-
- return ret;
-}
-
-
-int
-posix_fd_ctx_get_off (fd_t *fd, xlator_t *this, struct posix_fd **pfd,
- off_t offset)
-{
- int ret;
- int flags;
-
- LOCK (&fd->inode->lock);
- {
- ret = __posix_fd_ctx_get (fd, this, pfd);
- if (ret)
- goto unlock;
-
- if ((offset & 0xfff) && (*pfd)->odirect) {
- flags = fcntl ((*pfd)->fd, F_GETFL);
- ret = fcntl ((*pfd)->fd, F_SETFL, (flags & (~O_DIRECT)));
- (*pfd)->odirect = 0;
- }
-
- if (((offset & 0xfff) == 0) && (!(*pfd)->odirect)) {
- flags = fcntl ((*pfd)->fd, F_GETFL);
- ret = fcntl ((*pfd)->fd, F_SETFL, (flags | O_DIRECT));
- (*pfd)->odirect = 1;
- }
- }
-unlock:
- UNLOCK (&fd->inode->lock);
-
- return ret;
-}
diff --git a/xlators/storage/posix/src/posix-mem-types.h b/xlators/storage/posix/src/posix-mem-types.h
index b8d81248c..940e21cc7 100644
--- a/xlators/storage/posix/src/posix-mem-types.h
+++ b/xlators/storage/posix/src/posix-mem-types.h
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2008-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -30,7 +30,6 @@ enum gf_posix_mem_types_ {
gf_posix_mt_int32_t,
gf_posix_mt_posix_dev_t,
gf_posix_mt_trash_path,
- gf_posix_mt_paiocb,
gf_posix_mt_end
};
#endif
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index e2f1bbd5f..0cd6883c1 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -1,18 +1,18 @@
/*
- Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
This file is part of GlusterFS.
GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
+ it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
GlusterFS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ Affero General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
@@ -24,7 +24,6 @@
#define __XOPEN_SOURCE 500
-#include <openssl/md5.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -38,11 +37,8 @@
#include <alloca.h>
#endif /* GF_BSD_HOST_OS */
-#ifdef HAVE_LINKAT
-#include <fcntl.h>
-#endif /* HAVE_LINKAT */
-
#include "glusterfs.h"
+#include "md5.h"
#include "checksum.h"
#include "dict.h"
#include "logging.h"
@@ -59,9 +55,7 @@
#include "timer.h"
#include "glusterfs3-xdr.h"
#include "hashfn.h"
-#include "posix-aio.h"
-extern char *marker_xattrs[];
#undef HAVE_SET_FSID
#ifdef HAVE_SET_FSID
@@ -86,6 +80,14 @@ extern char *marker_xattrs[];
#endif
+typedef struct {
+ xlator_t *this;
+ const char *real_path;
+ dict_t *xattr;
+ struct iatt *stbuf;
+ loc_t *loc;
+} posix_xattr_filler_t;
+
int
posix_forget (xlator_t *this, inode_t *inode)
{
@@ -96,95 +98,379 @@ posix_forget (xlator_t *this, inode_t *inode)
return 0;
}
-/* Regular fops */
+static void
+_posix_xattr_get_set (dict_t *xattr_req,
+ char *key,
+ data_t *data,
+ void *xattrargs)
+{
+ posix_xattr_filler_t *filler = xattrargs;
+ char *value = NULL;
+ ssize_t xattr_size = -1;
+ int ret = -1;
+ char *databuf = NULL;
+ int _fd = -1;
+ loc_t *loc = NULL;
+ ssize_t req_size = 0;
+
+
+ /* should size be put into the data_t ? */
+ if (!strcmp (key, GF_CONTENT_KEY)
+ && IA_ISREG (filler->stbuf->ia_type)) {
+
+ /* file content request */
+ req_size = data_to_uint64 (data);
+ if (req_size >= filler->stbuf->ia_size) {
+ _fd = open (filler->real_path, O_RDONLY);
+ if (_fd == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Opening file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ databuf = GF_CALLOC (1, filler->stbuf->ia_size,
+ gf_posix_mt_char);
+ if (!databuf) {
+ goto err;
+ }
+
+ ret = read (_fd, databuf, filler->stbuf->ia_size);
+ if (ret == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Read on file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ ret = close (_fd);
+ _fd = -1;
+ if (ret == -1) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "Close on file %s failed: %s",
+ filler->real_path, strerror (errno));
+ goto err;
+ }
+
+ ret = dict_set_bin (filler->xattr, key,
+ databuf, filler->stbuf->ia_size);
+ if (ret < 0) {
+ gf_log (filler->this->name, GF_LOG_ERROR,
+ "failed to set dict value. key: %s, path: %s",
+ key, filler->real_path);
+ goto err;
+ }
+
+ /* To avoid double free in cleanup below */
+ databuf = NULL;
+ err:
+ if (_fd != -1)
+ close (_fd);
+ if (databuf)
+ GF_FREE (databuf);
+ }
+ } else if (!strcmp (key, GLUSTERFS_OPEN_FD_COUNT)) {
+ loc = filler->loc;
+ if (!list_empty (&loc->inode->fd_list)) {
+ ret = dict_set_uint32 (filler->xattr, key, 1);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_WARNING,
+ "Failed to set dictionary value for %s",
+ key);
+ } else {
+ ret = dict_set_uint32 (filler->xattr, key, 0);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_WARNING,
+ "Failed to set dictionary value for %s",
+ key);
+ }
+ } else {
+ xattr_size = sys_lgetxattr (filler->real_path, key, NULL, 0);
+
+ if (xattr_size > 0) {
+ value = GF_CALLOC (1, xattr_size + 1,
+ gf_posix_mt_char);
+ if (!value)
+ return;
+
+ sys_lgetxattr (filler->real_path, key, value,
+ xattr_size);
+
+ value[xattr_size] = '\0';
+ ret = dict_set_bin (filler->xattr, key,
+ value, xattr_size);
+ if (ret < 0)
+ gf_log (filler->this->name, GF_LOG_DEBUG,
+ "dict set failed. path: %s, key: %s",
+ filler->real_path, key);
+ }
+ }
+}
+
+
+int
+posix_fill_gfid_path (xlator_t *this, const char *path, struct iatt *iatt)
+{
+ int ret = 0;
+
+ if (!iatt)
+ return 0;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, iatt->ia_gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16)
+ ret = 0;
+
+ return ret;
+}
+
+
+int
+posix_fill_gfid_fd (xlator_t *this, int fd, struct iatt *iatt)
+{
+ int ret = 0;
+
+ if (!iatt)
+ return 0;
+
+ ret = sys_fgetxattr (fd, GFID_XATTR_KEY, iatt->ia_gfid, 16);
+ /* Return value of getxattr */
+ if (ret == 16)
+ ret = 0;
+
+ return ret;
+}
+
+
+int
+posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *stbuf_p)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+ struct stat lstatbuf = {0, };
+ struct iatt stbuf = {0, };
+
+ priv = this->private;
+
+ ret = lstat (path, &lstatbuf);
+ if (ret == -1)
+ goto out;
+
+ iatt_from_stat (&stbuf, &lstatbuf);
+
+ ret = posix_fill_gfid_path (this, path, &stbuf);
+ if (ret)
+ gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
+
+ if (stbuf_p)
+ *stbuf_p = stbuf;
+out:
+ return ret;
+}
+
+
+int
+posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+ struct stat fstatbuf = {0, };
+ struct iatt stbuf = {0, };
+
+ priv = this->private;
+
+ ret = fstat (fd, &fstatbuf);
+ if (ret == -1)
+ goto out;
+
+ iatt_from_stat (&stbuf, &fstatbuf);
+
+ ret = posix_fill_gfid_fd (this, fd, &stbuf);
+ if (ret)
+ gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
+
+ if (stbuf_p)
+ *stbuf_p = stbuf;
+
+out:
+ return ret;
+}
+
+
+dict_t *
+posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc,
+ dict_t *xattr_req, struct iatt *buf)
+{
+ dict_t *xattr = NULL;
+ posix_xattr_filler_t filler = {0, };
+
+ xattr = get_new_dict();
+ if (!xattr) {
+ goto out;
+ }
+
+ filler.this = this;
+ filler.real_path = real_path;
+ filler.xattr = xattr;
+ filler.stbuf = buf;
+ filler.loc = loc;
+
+ dict_foreach (xattr_req, _posix_xattr_get_set, &filler);
+out:
+ return xattr;
+}
+
+
+/*
+ * If the parent directory of {real_path} has the setgid bit set,
+ * then set {gid} to the gid of the parent. Otherwise,
+ * leave {gid} unchanged.
+ */
+
+int
+setgid_override (xlator_t *this, char *real_path, gid_t *gid)
+{
+ char * tmp_path = NULL;
+ char * parent_path = NULL;
+ struct iatt parent_stbuf;
+
+ int op_ret = 0;
+
+ tmp_path = gf_strdup (real_path);
+ if (!tmp_path) {
+ op_ret = -ENOMEM;
+ goto out;
+ }
+
+ parent_path = dirname (tmp_path);
+
+ op_ret = posix_lstat_with_gfid (this, parent_path, &parent_stbuf);
+ if (op_ret == -1) {
+ op_ret = -errno;
+ gf_log_callingfn (this->name, GF_LOG_ERROR,
+ "lstat on parent directory (%s) failed: %s",
+ parent_path, strerror (errno));
+ goto out;
+ }
+
+ if (parent_stbuf.ia_prot.sgid) {
+ /*
+ * Entries created inside a setgid directory
+ * should inherit the gid from the parent
+ */
+
+ *gid = parent_stbuf.ia_gid;
+ }
+out:
+
+ if (tmp_path)
+ GF_FREE (tmp_path);
+
+ return op_ret;
+}
+
+
+int
+posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req)
+{
+ void *uuid_req = NULL;
+ uuid_t uuid_curr;
+ int ret = 0;
+ struct stat stat = {0, };
+
+ if (!xattr_req)
+ goto out;
+
+ if (sys_lstat (path, &stat) != 0)
+ goto out;
+
+ ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
+ if (ret == 16) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req);
+ if (ret) {
+ gf_log_callingfn (this->name, GF_LOG_DEBUG,
+ "failed to get the gfid from dict");
+ goto out;
+ }
+
+ ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
+
+out:
+ return ret;
+}
+
int32_t
posix_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+ loc_t *loc, dict_t *xattr_req)
{
struct iatt buf = {0, };
+ char * real_path = NULL;
int32_t op_ret = -1;
int32_t entry_ret = 0;
int32_t op_errno = 0;
dict_t * xattr = NULL;
- char * real_path = NULL;
- char * par_path = NULL;
+ char * pathdup = NULL;
+ char * parentpath = NULL;
struct iatt postparent = {0,};
- int32_t gfidless = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
VALIDATE_OR_GOTO (loc->path, out);
- /* The Hidden directory should be for housekeeping purpose and it
- should not get any gfid on it */
- if (__is_root_gfid (loc->pargfid) &&
- (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) {
- gf_log (this->name, GF_LOG_WARNING,
- "Lookup issued on %s, which is not permitted",
- GF_HIDDEN_PATH);
- op_errno = EPERM;
- op_ret = -1;
- goto out;
- }
+ MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = dict_get_int32 (xdata, GF_GFIDLESS_LOOKUP, &gfidless);
- op_ret = -1;
- if (uuid_is_null (loc->pargfid)) {
- /* nameless lookup */
- MAKE_INODE_HANDLE (real_path, this, loc, &buf);
- } else {
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf);
-
- if (uuid_is_null (loc->inode->gfid)) {
- posix_gfid_set (this, real_path, loc, xdata);
- MAKE_ENTRY_HANDLE (real_path, par_path, this,
- loc, &buf);
- }
- }
+ posix_gfid_set (this, real_path, xattr_req);
+ op_ret = posix_lstat_with_gfid (this, real_path, &buf);
op_errno = errno;
if (op_ret == -1) {
if (op_errno != ENOENT) {
gf_log (this->name, GF_LOG_ERROR,
"lstat on %s failed: %s",
- real_path, strerror (op_errno));
+ loc->path, strerror (op_errno));
}
entry_ret = -1;
goto parent;
}
- if (xdata && (op_ret == 0)) {
+ if (xattr_req && (op_ret == 0)) {
xattr = posix_lookup_xattr_fill (this, real_path, loc,
- xdata, &buf);
+ xattr_req, &buf);
}
parent:
- if (par_path) {
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
+ if (loc->parent) {
+ pathdup = gf_strdup (real_path);
+ GF_VALIDATE_OR_GOTO (this->name, pathdup, out);
+
+ parentpath = dirname (pathdup);
+
+ op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent %s failed: %s",
- par_path, strerror (op_errno));
+ "post-operation lstat on parent of %s failed: %s",
+ loc->path, strerror (op_errno));
goto out;
}
}
op_ret = entry_ret;
out:
+ if (pathdup)
+ GF_FREE (pathdup);
+
if (xattr)
dict_ref (xattr);
- if (!op_ret && !gfidless && uuid_is_null (buf.ia_gfid)) {
- gf_log (this->name, GF_LOG_ERROR, "buf->ia_gfid is null for "
- "%s", (real_path) ? real_path: "");
- op_ret = -1;
- op_errno = ENODATA;
- }
STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno,
(loc)?loc->inode:NULL, &buf, xattr, &postparent);
@@ -196,13 +482,13 @@ out:
int32_t
-posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
struct iatt buf = {0,};
+ char * real_path = NULL;
int32_t op_ret = -1;
int32_t op_errno = 0;
struct posix_private *priv = NULL;
- char *real_path = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -214,13 +500,13 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
VALIDATE_OR_GOTO (priv, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
+ MAKE_REAL_PATH (real_path, this, loc->path);
- MAKE_INODE_HANDLE (real_path, this, loc, &buf);
-
+ op_ret = posix_lstat_with_gfid (this, real_path, &buf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s", real_path,
+ "lstat on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
@@ -229,7 +515,7 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
out:
SET_TO_OLD_FS_ID();
- STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, &buf, NULL);
+ STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, &buf);
return 0;
}
@@ -335,7 +621,7 @@ out:
int
posix_setattr (call_frame_t *frame, xlator_t *this,
- loc_t *loc, struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ loc_t *loc, struct iatt *stbuf, int32_t valid)
{
int32_t op_ret = -1;
int32_t op_errno = 0;
@@ -350,8 +636,9 @@ posix_setattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_INODE_HANDLE (real_path, this, loc, &statpre);
+ MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = posix_lstat_with_gfid (this, real_path, &statpre);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -405,7 +692,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_pstat (this, loc->gfid, real_path, &statpost);
+ op_ret = posix_lstat_with_gfid (this, real_path, &statpost);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -420,7 +707,7 @@ out:
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno,
- &statpre, &statpost, NULL);
+ &statpre, &statpost);
return 0;
}
@@ -470,13 +757,14 @@ posix_do_futimes (xlator_t *this,
int
posix_fsetattr (call_frame_t *frame, xlator_t *this,
- fd_t *fd, struct iatt *stbuf, int32_t valid, dict_t *xdata)
+ fd_t *fd, struct iatt *stbuf, int32_t valid)
{
int32_t op_ret = -1;
int32_t op_errno = 0;
struct iatt statpre = {0,};
struct iatt statpost = {0,};
struct posix_fd *pfd = NULL;
+ uint64_t tmp_pfd = 0;
int32_t ret = -1;
DECLARE_OLD_FS_ID_VAR;
@@ -487,15 +775,16 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
- ret = posix_fd_ctx_get (fd, this, &pfd);
+ ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_DEBUG,
"pfd is NULL from fd=%p", fd);
goto out;
}
+ pfd = (struct posix_fd *)(long)tmp_pfd;
- op_ret = posix_fdstat (this, pfd->fd, &statpre);
+ op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpre);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -550,7 +839,7 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_fdstat (this, pfd->fd, &statpost);
+ op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpost);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -565,14 +854,14 @@ out:
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (fsetattr, frame, op_ret, op_errno,
- &statpre, &statpost, NULL);
+ &statpre, &statpost);
return 0;
}
int32_t
posix_opendir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, fd_t *fd, dict_t *xdata)
+ loc_t *loc, fd_t *fd)
{
char * real_path = NULL;
int32_t op_ret = -1;
@@ -589,16 +878,15 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_INODE_HANDLE (real_path, this, loc, NULL);
+ MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = -1;
dir = opendir (real_path);
if (dir == NULL) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"opendir failed on %s: %s",
- real_path, strerror (op_errno));
+ loc->path, strerror (op_errno));
goto out;
}
@@ -607,7 +895,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"dirfd() failed on %s: %s",
- real_path, strerror (op_errno));
+ loc->path, strerror (op_errno));
goto out;
}
@@ -619,12 +907,16 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
pfd->dir = dir;
pfd->fd = dirfd (dir);
+ pfd->path = gf_strdup (real_path);
+ if (!pfd->path) {
+ goto out;
+ }
op_ret = fd_ctx_set (fd, this, (uint64_t)(long)pfd);
if (op_ret)
gf_log (this->name, GF_LOG_WARNING,
"failed to set the fd context path=%s fd=%p",
- real_path, fd);
+ loc->path, fd);
op_ret = 0;
@@ -635,13 +927,15 @@ out:
dir = NULL;
}
if (pfd) {
+ if (pfd->path)
+ GF_FREE (pfd->path);
GF_FREE (pfd);
pfd = NULL;
}
}
SET_TO_OLD_FS_ID ();
- STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd, NULL);
+ STACK_UNWIND_STRICT (opendir, frame, op_ret, op_errno, fd);
return 0;
}
@@ -668,12 +962,19 @@ posix_releasedir (xlator_t *this,
pfd = (struct posix_fd *)(long)tmp_pfd;
if (!pfd->dir) {
gf_log (this->name, GF_LOG_WARNING,
- "pfd->dir is NULL for fd=%p", fd);
+ "pfd->dir is NULL for fd=%p path=%s",
+ fd, pfd->path ? pfd->path : "<NULL>");
goto out;
}
priv = this->private;
+ if (!pfd->path) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "pfd->path was NULL. fd=%p pfd=%p",
+ fd, pfd);
+ }
+
pthread_mutex_lock (&priv->janitor_lock);
{
INIT_LIST_HEAD (&pfd->list);
@@ -689,10 +990,11 @@ out:
int32_t
posix_readlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, size_t size, dict_t *xdata)
+ loc_t *loc, size_t size)
{
char * dest = NULL;
int32_t op_ret = -1;
+ int32_t lstat_ret = -1;
int32_t op_errno = 0;
char * real_path = NULL;
struct iatt stbuf = {0,};
@@ -705,29 +1007,33 @@ posix_readlink (call_frame_t *frame, xlator_t *this,
dest = alloca (size + 1);
- MAKE_INODE_HANDLE (real_path, this, loc, &stbuf);
+ MAKE_REAL_PATH (real_path, this, loc->path);
+
+ op_ret = readlink (real_path, dest, size);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s", real_path,
+ "readlink on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
- op_ret = readlink (real_path, dest, size);
- if (op_ret == -1) {
+ dest[op_ret] = 0;
+
+ lstat_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ if (lstat_ret == -1) {
+ op_ret = -1;
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "readlink on %s failed: %s", real_path,
+ "lstat on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
- dest[op_ret] = 0;
out:
SET_TO_OLD_FS_ID ();
- STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, dest, &stbuf, NULL);
+ STACK_UNWIND_STRICT (readlink, frame, op_ret, op_errno, dest, &stbuf);
return 0;
}
@@ -735,20 +1041,20 @@ out:
int
posix_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata)
+ loc_t *loc, mode_t mode, dev_t dev, dict_t *params)
{
int tmp_fd = 0;
int32_t op_ret = -1;
int32_t op_errno = 0;
char *real_path = 0;
- char *par_path = 0;
struct iatt stbuf = { 0, };
char was_present = 1;
struct posix_private *priv = NULL;
gid_t gid = 0;
+ char *pathdup = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
- void * uuid_req = NULL;
+ char *parentpath = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -759,49 +1065,32 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
+ MAKE_REAL_PATH (real_path, this, loc->path);
gid = frame->root->gid;
+ op_ret = setgid_override (this, real_path, &gid);
+ if (op_ret < 0) {
+ op_errno = -op_ret;
+ op_ret = -1;
+ goto out;
+ }
+
SET_FS_ID (frame->root->uid, gid);
+ pathdup = gf_strdup (real_path);
+ GF_VALIDATE_OR_GOTO (this->name, pathdup, out);
+
+ parentpath = dirname (pathdup);
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
+ op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"pre-operation lstat on parent of %s failed: %s",
- real_path, strerror (op_errno));
+ loc->path, strerror (op_errno));
goto out;
}
- if (preparent.ia_prot.sgid) {
- gid = preparent.ia_gid;
- }
-
- /* Check if the 'gfid' already exists, because this mknod may be an
- internal call from distribute for creating 'linkfile', and that
- linkfile may be for a hardlinked file */
- if (dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
- dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY);
- op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
- if (op_ret) {
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to get the gfid from dict for %s",
- loc->path);
- goto real_op;
- }
- op_ret = posix_create_link_if_gfid_exists (this, uuid_req,
- real_path);
- if (!op_ret)
- goto post_op;
- }
-
-real_op:
-#ifdef __NetBSD__
- if (S_ISFIFO(mode))
- op_ret = mkfifo (real_path, mode);
- else
-#endif /* __NetBSD__ */
op_ret = mknod (real_path, mode, dev);
if (op_ret == -1) {
@@ -813,23 +1102,23 @@ real_op:
if (tmp_fd == -1) {
gf_log (this->name, GF_LOG_ERROR,
"create failed on %s: %s",
- real_path, strerror (errno));
+ loc->path, strerror (errno));
goto out;
}
close (tmp_fd);
} else {
gf_log (this->name, GF_LOG_ERROR,
- "mknod on %s failed: %s", real_path,
+ "mknod on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
}
- op_ret = posix_gfid_set (this, real_path, loc, xdata);
+ op_ret = posix_gfid_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting gfid on %s failed", real_path);
+ "setting gfid on %s failed", loc->path);
}
#ifndef HAVE_SET_FSID
@@ -837,53 +1126,40 @@ real_op:
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lchown on %s failed: %s", real_path,
+ "lchown on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
#endif
-post_op:
- op_ret = posix_acl_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting ACLs on %s failed (%s)", real_path,
- strerror (errno));
- }
-
- op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_log (this->name, GF_LOG_ERROR,
- "setting xattrs on %s failed (%s)", real_path,
- strerror (errno));
- }
-
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
+ op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "mknod on %s failed: %s", real_path,
+ "mknod on %s failed: %s", loc->path,
strerror (op_errno));
goto out;
}
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
+ op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent %s failed: %s",
- par_path, strerror (op_errno));
+ "post-operation lstat on parent of %s failed: %s",
+ loc->path, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
+ if (pathdup)
+ GF_FREE (pathdup);
+
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno,
- (loc)?loc->inode:NULL, &stbuf, &preparent,
- &postparent, NULL);
+ (loc)?loc->inode:NULL, &stbuf, &preparent, &postparent);
if ((op_ret == -1) && (!was_present)) {
unlink (real_path);
@@ -893,18 +1169,164 @@ out:
}
+static int
+janitor_walker (const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ switch (sb->st_mode & S_IFMT) {
+ case S_IFREG:
+ case S_IFBLK:
+ case S_IFLNK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFSOCK:
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "unlinking %s", fpath);
+ unlink (fpath);
+ break;
+
+ case S_IFDIR:
+ if (ftwbuf->level) { /* don't remove top level dir */
+ gf_log (THIS->name, GF_LOG_TRACE,
+ "removing directory %s", fpath);
+
+ rmdir (fpath);
+ }
+ break;
+ }
+
+ return 0; /* 0 = FTW_CONTINUE */
+}
+
+
+static struct posix_fd *
+janitor_get_next_fd (xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ struct posix_fd *pfd = NULL;
+
+ struct timespec timeout;
+
+ priv = this->private;
+
+ pthread_mutex_lock (&priv->janitor_lock);
+ {
+ if (list_empty (&priv->janitor_fds)) {
+ time (&timeout.tv_sec);
+ timeout.tv_sec += priv->janitor_sleep_duration;
+ timeout.tv_nsec = 0;
+
+ pthread_cond_timedwait (&priv->janitor_cond,
+ &priv->janitor_lock,
+ &timeout);
+ goto unlock;
+ }
+
+ pfd = list_entry (priv->janitor_fds.next, struct posix_fd,
+ list);
+
+ list_del (priv->janitor_fds.next);
+ }
+unlock:
+ pthread_mutex_unlock (&priv->janitor_lock);
+
+ return pfd;
+}
+
+
+static void *
+posix_janitor_thread_proc (void *data)
+{
+ xlator_t * this = NULL;
+ struct posix_private *priv = NULL;
+ struct posix_fd *pfd;
+
+ time_t now;
+
+ this = data;
+ priv = this->private;
+
+ THIS = this;
+
+ while (1) {
+ time (&now);
+ if ((now - priv->last_landfill_check) > priv->janitor_sleep_duration) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor cleaning out /" GF_REPLICATE_TRASH_DIR);
+
+ nftw (priv->trash_path,
+ janitor_walker,
+ 32,
+ FTW_DEPTH | FTW_PHYS);
+
+ priv->last_landfill_check = now;
+ }
+
+ pfd = janitor_get_next_fd (this);
+ if (pfd) {
+ if (pfd->dir == NULL) {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor: closing file fd=%d", pfd->fd);
+ close (pfd->fd);
+ } else {
+ gf_log (this->name, GF_LOG_TRACE,
+ "janitor: closing dir fd=%p", pfd->dir);
+ closedir (pfd->dir);
+ }
+
+ if (pfd->path)
+ GF_FREE (pfd->path);
+
+ GF_FREE (pfd);
+ }
+ }
+
+ return NULL;
+}
+
+
+static void
+posix_spawn_janitor_thread (xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ int ret = 0;
+
+ priv = this->private;
+
+ LOCK (&priv->lock);
+ {
+ if (!priv->janitor_present) {
+ ret = pthread_create (&priv->janitor, NULL,
+ posix_janitor_thread_proc, this);
+
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "spawning janitor thread failed: %s",
+ strerror (errno));
+ goto unlock;
+ }
+
+ priv->janitor_present = _gf_true;
+ }
+ }
+unlock:
+ UNLOCK (&priv->lock);
+}
+
+
int
posix_mkdir (call_fr